refactor: remove legacy assistant compatibility

This commit is contained in:
Xin Wang
2026-08-18 10:07:18 +08:00
parent abfcd4cd19
commit d003ee77a5
40 changed files with 505 additions and 729 deletions
+4 -4
View File
@@ -20,7 +20,7 @@ from schemas import (
)
from services.auth import require_admin
from services.masking import mask, resolve_incoming_key
from services.node_specs import graph_references, normalize_graph, validate_graph
from services.node_specs import copy_graph, graph_references, validate_graph
from services.state_expressions import StateExpressionError, validate_update_rules
from services.system_tools import RESERVED_TOOL_NAMES
from services.tool_policy import policy_for_tool
@@ -98,9 +98,9 @@ def _validate_workflow(body: AssistantUpsert) -> None:
if body.graph and str(body.graph.get("specVersion") or "") != "4":
raise HTTPException(
400,
"Workflow API 仅接受 specVersion=4;旧图请先执行数据库迁移",
"Workflow API 仅接受当前 specVersion=4 图结构",
)
body.graph = normalize_graph(body.graph or {})
body.graph = copy_graph(body.graph or {})
errors = validate_graph(body.graph)
settings = body.graph.get("settings") or {}
graph_runtime_mode = str(settings.get("runtimeMode") or "pipeline")
@@ -636,7 +636,7 @@ async def _to_out(session: AsyncSession, assistant: Assistant) -> AssistantOut:
api_key=mask(assistant.api_key),
app_id=assistant.app_id,
graph=(
normalize_graph(assistant.graph or {})
copy_graph(assistant.graph or {})
if assistant.type == "workflow"
else {}
),
+6 -12
View File
@@ -63,24 +63,23 @@ async def _wait_for_pipeline_close(
async def shutdown_active_sessions() -> None:
"""Compatibility proxy; now drains RTVI and OpenAI Realtime sessions."""
"""Drain RTVI and OpenAI Realtime sessions."""
_http_peers.clear()
await realtime_lifecycle.shutdown_active_sessions(
timeout=PIPELINE_CLOSE_GRACE_SECONDS,
)
def _decode_client_tool_names(encoded: str | None) -> list[str] | None:
def _decode_client_tool_names(encoded: str | None) -> list[str]:
"""Decode client capabilities carried outside the WebRTC SDP body.
Pipecat's browser transport replaces the body of a ``Request`` endpoint
with its SDP offer and drops ``APIRequest.requestData``. Request headers are
preserved, so they are the authoritative metadata channel for this path.
``None`` means the header was absent and callers should use the legacy body.
preserved, so they are the single metadata channel for this path.
"""
if encoded is None:
return None
return []
try:
padding = "=" * (-len(encoded) % 4)
value = json.loads(
@@ -134,21 +133,16 @@ async def http_offer(request: Request, payload: dict = Body(...)):
header_variables = json.loads(
base64.urlsafe_b64decode(encoded_variables + padding).decode("utf-8")
)
header_client_tools = _decode_client_tool_names(
client_tool_names = _decode_client_tool_names(
request.headers.get("x-pipecat-client-tools")
)
client_tool_names = (
header_client_tools
if header_client_tools is not None
else request_data.get("client_tool_names") or []
)
logger.debug(f"WebRTC 客户端工具上报: {client_tool_names or '<none>'}")
offer_payload = {
**payload,
"assistant_id": request.headers.get("x-pipecat-assistant-id"),
"dynamic_variables": header_variables,
**request_data,
# Keep header metadata authoritative when both paths are present.
# Client capabilities have one canonical transport: the request header.
"client_tool_names": client_tool_names,
}
answer = await _handle_offer_payload(offer_payload, _http_peers)