Files
ai-video-fullstack/backend/services/realtime_tool_capabilities.py
T

66 lines
2.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Capability gates for Prompt tools in speech-to-speech runtimes."""
from __future__ import annotations
from collections.abc import Mapping
from services.system_tools import RESERVED_TOOL_NAMES
QWEN_PROMPT_TOOL_FEATURES = {
"externalTypes": ["http", "mcp", "client"],
"builtIns": [
"endConversation",
"updateState",
"requestHumanHandoff",
],
}
def realtime_prompt_tool_features(interface_type: str) -> dict[str, list[str]]:
"""Return the server-trusted runtime capabilities for one provider."""
if interface_type == "qwen-audio-realtime":
return {
key: list(values) for key, values in QWEN_PROMPT_TOOL_FEATURES.items()
}
return {"externalTypes": [], "builtIns": []}
def validate_runtime_prompt_tools(
*,
interface_type: str,
external_types: set[str],
built_in_tools: Mapping[str, object] | None,
external_function_names: set[str] | None = None,
) -> None:
"""Reject stale or inline runtime configurations before opening a socket."""
features = realtime_prompt_tool_features(interface_type)
unsupported_external = external_types - set(features["externalTypes"])
reserved_external = set(external_function_names or set()) & RESERVED_TOOL_NAMES
aliases = {
"end_conversation": "endConversation",
"update_state": "updateState",
"skip_turn": "skipTurn",
"request_human_handoff": "requestHumanHandoff",
}
requested_built_ins = {
aliases.get(str(name), str(name))
for name, config in (built_in_tools or {}).items()
if config is not None
}
unsupported_built_ins = requested_built_ins - set(features["builtIns"])
if unsupported_external or unsupported_built_ins or reserved_external:
details = []
if unsupported_external:
details.append("外部工具:" + ",".join(sorted(unsupported_external)))
if unsupported_built_ins:
details.append("内建工具:" + ",".join(sorted(unsupported_built_ins)))
if reserved_external:
details.append("外部工具使用平台保留名:" + ",".join(sorted(reserved_external)))
raise ValueError(
f"Realtime 接口 {interface_type or 'unknown'} 不支持 "
+ ";".join(details)
)