feat: route workflow image inputs natively
This commit is contained in:
@@ -9,6 +9,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
from collections.abc import Callable
|
||||
from copy import deepcopy
|
||||
from typing import Any
|
||||
|
||||
from loguru import logger
|
||||
@@ -24,6 +25,32 @@ STAY_ON_CURRENT_AGENT = STAY_ON_CURRENT_NODE
|
||||
MAX_ROUTING_HISTORY_ENTRIES = 20
|
||||
|
||||
|
||||
def _routing_user_message(
|
||||
routing_input: str,
|
||||
current_user_message: dict[str, Any] | None,
|
||||
) -> dict[str, Any]:
|
||||
"""Combine routing metadata with the current text or multimodal turn."""
|
||||
if not current_user_message:
|
||||
return {"role": "user", "content": routing_input}
|
||||
|
||||
content = current_user_message.get("content")
|
||||
if not isinstance(content, list):
|
||||
current_text = str(content or "").strip()
|
||||
suffix = f"\n\n[当前用户输入]\n{current_text}" if current_text else ""
|
||||
return {"role": "user", "content": f"{routing_input}{suffix}"}
|
||||
|
||||
return {
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": f"{routing_input}\n\n[当前用户输入如下]",
|
||||
},
|
||||
*deepcopy(content),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
class WorkflowLLMRouter:
|
||||
"""Select one LLM edge without allowing the router to speak."""
|
||||
|
||||
@@ -40,6 +67,7 @@ class WorkflowLLMRouter:
|
||||
variables: dict[str, Any],
|
||||
edge_name: Callable[[dict[str, Any]], str],
|
||||
edge_description: Callable[[dict[str, Any]], str],
|
||||
current_user_message: dict[str, Any] | None = None,
|
||||
) -> LLMRouteResult:
|
||||
"""Return a typed match, no-match or technical error."""
|
||||
if not edges:
|
||||
@@ -85,7 +113,13 @@ class WorkflowLLMRouter:
|
||||
f"当前节点任务:{node_prompt or '未配置'}\n"
|
||||
f"转移条件:\n{ordered_conditions}"
|
||||
)
|
||||
recent_history = history[-MAX_ROUTING_HISTORY_ENTRIES:]
|
||||
# WorkflowBrain records the current turn before routing. When the full
|
||||
# current message is supplied separately, keep only earlier history so
|
||||
# the text is not duplicated and the image remains attached to its turn.
|
||||
routing_history = (
|
||||
history[:-1] if current_user_message and history else history
|
||||
)
|
||||
recent_history = routing_history[-MAX_ROUTING_HISTORY_ENTRIES:]
|
||||
routing_input = json.dumps(
|
||||
{
|
||||
"conversation": recent_history,
|
||||
@@ -108,7 +142,7 @@ class WorkflowLLMRouter:
|
||||
model=self._cfg.model,
|
||||
messages=[
|
||||
{"role": "system", "content": router_prompt},
|
||||
{"role": "user", "content": routing_input},
|
||||
_routing_user_message(routing_input, current_user_message),
|
||||
],
|
||||
tools=tools,
|
||||
tool_choice="required",
|
||||
|
||||
Reference in New Issue
Block a user