feat: add realtime workflow vision tools

This commit is contained in:
Xin Wang
2026-08-05 13:35:00 +08:00
parent 11374238f3
commit 10bea48d72
16 changed files with 362 additions and 103 deletions

View File

@@ -85,6 +85,7 @@ async def _validate_workflow_references(
graph = body.graph
engine = WorkflowEngine(graph)
settings = graph.get("settings") or {}
runtime_mode = str(settings.get("runtimeMode") or "pipeline")
resource_expectations: dict[str, str] = {}
vision_resource_ids: set[str] = set()
for key, capability in (
@@ -118,16 +119,22 @@ async def _validate_workflow_references(
stage = engine.agent_stage_config(node_id)
if not stage.vision_enabled:
continue
resource_id = (
stage.vision_model_resource_id or stage.llm_resource_id
)
if stage.vision_model_resource_id:
resource_id = stage.vision_model_resource_id
capability = "LLM"
elif runtime_mode == "realtime":
resource_id = str(settings.get("defaultRealtimeResourceId") or "")
capability = "Realtime"
else:
resource_id = stage.llm_resource_id
capability = "LLM"
if not resource_id:
raise HTTPException(
400,
f"Agent 节点 {node_id} 开启视觉理解时必须选择"
"支持图片输入的大语言模型或视觉模型",
"支持图片输入的当前模型或独立视觉模型",
)
resource_expectations[resource_id] = "LLM"
resource_expectations[resource_id] = capability
vision_resource_ids.add(resource_id)
for resource_id, capability in resource_expectations.items():
resource = await session.get(ModelResource, resource_id)

View File

@@ -30,6 +30,19 @@ router = APIRouter(
tags=["model-registry"],
dependencies=[Depends(require_admin)],
)
NATIVE_IMAGE_UNSUPPORTED_REALTIME_INTERFACES = frozenset(
{"qwen-audio-realtime"}
)
def _supports_configurable_image_input(definition: InterfaceDefinition) -> bool:
if definition.capability == "LLM":
return True
return (
definition.capability == "Realtime"
and definition.interface_type
not in NATIVE_IMAGE_UNSUPPORTED_REALTIME_INTERFACES
)
def _definition_dict(row: InterfaceDefinition) -> dict:
@@ -156,9 +169,11 @@ async def create_model_resource(
interface_type=definition.interface_type,
values=body.values,
secrets=secrets,
support_image_input=body.support_image_input
if definition.capability == "LLM"
else False,
support_image_input=(
body.support_image_input
if _supports_configurable_image_input(definition)
else False
),
enabled=body.enabled,
is_default=body.is_default,
)
@@ -244,7 +259,9 @@ async def update_model_resource(
row.values = body.values
row.secrets = secrets
row.support_image_input = (
body.support_image_input if definition.capability == "LLM" else False
body.support_image_input
if _supports_configurable_image_input(definition)
else False
)
row.enabled = body.enabled
row.is_default = body.is_default