fix(agent): 修复工具结果system_message注入夹断tool序列导致的API 400
- execute_tool_calls 循环内改为收集 pending_tool_system_messages, 整轮工具结束后统一注入,避免并行 tool_calls 中途插入 user 消息 - terminate_sub_agent handler 摘除结果中的 system_message, 主智能体自行终结子智能体时不再注入冗余 user 消息
This commit is contained in:
parent
dd2f00276d
commit
1cd3a742af
@ -2062,6 +2062,12 @@ class MainTerminalToolsExecutionMixin:
|
||||
result = self.sub_agent_manager.terminate_sub_agent(
|
||||
agent_id=arguments.get("agent_id")
|
||||
)
|
||||
# 主智能体主动终结时,tool 结果(message)已包含结论,
|
||||
# 摘掉 system_message 避免工具循环再注入一条冗余 user 消息
|
||||
# (且「已被手动关闭」措辞对此场景是误导)。
|
||||
# 前端 UI 手动终止走 server/conversation.py API 直调 manager,不受影响。
|
||||
if isinstance(result, dict):
|
||||
result.pop("system_message", None)
|
||||
# 多智能体模式:同步状态到 MultiAgentState
|
||||
if getattr(self, "multi_agent_mode", False):
|
||||
try:
|
||||
|
||||
@ -352,6 +352,9 @@ async def execute_tool_calls(*, web_terminal, tool_calls, sender, messages, clie
|
||||
|
||||
# 执行每个工具
|
||||
pending_runtime_mode_notices: List[str] = []
|
||||
# 工具结果附带的 system_message 先收集、整轮工具循环结束后统一注入,
|
||||
# 避免并行 tool_calls 中途插入 user 消息夹断 assistant.tool_calls 的 tool 序列。
|
||||
pending_tool_system_messages: List[Dict[str, Any]] = []
|
||||
last_completed_tool_call_id: Optional[str] = None
|
||||
deep_compression_pending = False
|
||||
for tool_call in tool_calls:
|
||||
@ -1229,17 +1232,13 @@ async def execute_tool_calls(*, web_terminal, tool_calls, sender, messages, clie
|
||||
debug_log(f"💾 增量保存:工具结果 {function_name}")
|
||||
system_message = result_data.get("system_message") if isinstance(result_data, dict) else None
|
||||
if system_message:
|
||||
inject_runtime_user_message(
|
||||
web_terminal=web_terminal,
|
||||
messages=messages,
|
||||
text=system_message,
|
||||
source="sub_agent",
|
||||
sender=sender,
|
||||
conversation_id=conversation_id,
|
||||
after_tool_call_id=tool_call_id,
|
||||
inline=False,
|
||||
extra_metadata={"task_id": result_data.get("task_id")},
|
||||
)
|
||||
# 不在此立即注入:若本轮是并行 tool_calls,其余 tool 结果尚未写入,
|
||||
# 此时插入 user 消息会夹断 assistant.tool_calls 的 tool 序列,触发 API 400
|
||||
# (tool_calls must be followed by tool messages)。统一延迟到循环结束后注入。
|
||||
pending_tool_system_messages.append({
|
||||
"text": system_message,
|
||||
"task_id": result_data.get("task_id"),
|
||||
})
|
||||
|
||||
# 自动深层压缩(工具调用后触发)
|
||||
current_context_tokens = web_terminal.context_manager.get_current_context_tokens(conversation_id)
|
||||
@ -1262,6 +1261,22 @@ async def execute_tool_calls(*, web_terminal, tool_calls, sender, messages, clie
|
||||
|
||||
await asyncio.sleep(0.2)
|
||||
|
||||
# 工具结果附带的 system_message:必须等待同一轮全部 tool_call 的 tool 消息
|
||||
# 都已写入 messages/历史后再注入,避免夹断 assistant.tool_calls 的 tool 序列。
|
||||
# 注意放在深层压缩分支之前,防止压缩提前 return 导致通知丢失。
|
||||
for pending_system_message in pending_tool_system_messages:
|
||||
inject_runtime_user_message(
|
||||
web_terminal=web_terminal,
|
||||
messages=messages,
|
||||
text=pending_system_message["text"],
|
||||
source="sub_agent",
|
||||
sender=sender,
|
||||
conversation_id=conversation_id,
|
||||
after_tool_call_id=last_completed_tool_call_id,
|
||||
inline=False,
|
||||
extra_metadata={"task_id": pending_system_message.get("task_id")},
|
||||
)
|
||||
|
||||
# 自动深层压缩必须等待同一轮全部 tool_call 的 tool 消息都已写入 messages/历史后再触发。
|
||||
if deep_compression_pending and not web_terminal.context_manager.is_compression_in_progress():
|
||||
web_terminal.context_manager._set_meta_flag("is_ultra_long_conversation", True)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user