fix: 修复 Agent 流式对话无响应和工具 schema 兼容性问题

- 在 `run_stream()` LLM 调用前 yield `think` 事件,前端即时显示"思考中..."
- 修复 tool schema 规范化逻辑:`{"function":{...}}` 格式缺少 `type` 字段导致 LLM API 拒绝
- 启动时从数据库加载自定义工具(`load_tools_from_db`),解决重启后工具丢失
- 前端 SSE 添加 60s 超时保护,任何事件类型均触发 `receivedFirstEvent`
- 流式失败自动降级到非流式 POST
- 添加 `scripts/seed_coding_agent.py` 和 `scripts/test_coding_agent.py`

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
renjianbo
2026-05-02 00:38:41 +08:00
parent 342f3fcb16
commit 7aba0f9bc5
10 changed files with 662 additions and 36 deletions

View File

@@ -1434,9 +1434,13 @@ class WorkflowEngine:
logger.debug(f"[rjb] LLM节点数据: node_id={node_id}, node_data keys={list(node_data.keys())}, api_key={'已配置' if node_data.get('api_key') else '未配置'}")
prompt = node_data.get('prompt', '')
# 如果prompt为空,使用默认提示词
# 如果 prompt 为空:不要用 {input} 展开整包 input_data。
# 预览/执行侧常带 user_id、memory、conversation_history 等大对象,模型易照抄成 ```json 回复。
if not prompt:
prompt = "请处理以下输入数据:\n{input}"
prompt = (
"请根据用户当前问题用自然语言回答;需要时可用工具。"
"不要向用户复述或输出完整的 input_data / API 请求 JSON。"
)
# 格式化prompt替换变量
try:
@@ -1804,6 +1808,15 @@ class WorkflowEngine:
# 记录实际发送给LLM的prompt
logger.info(f"[rjb] 准备调用LLM: node_id={node_id}, provider={provider}, model={model}, prompt前200字符='{prompt[:200] if len(prompt) > 200 else prompt}'")
_raw_sys = node_data.get("system_prompt")
llm_system_prompt: Optional[str] = None
if isinstance(_raw_sys, str) and _raw_sys.strip():
llm_system_prompt = _raw_sys.strip()
elif _raw_sys is not None and not isinstance(_raw_sys, (dict, list)):
_ts = str(_raw_sys).strip()
if _ts:
llm_system_prompt = _ts
# 检查是否启用工具调用
enable_tools = node_data.get('enable_tools', False)
@@ -1872,6 +1885,7 @@ class WorkflowEngine:
execution_logger=self.logger,
tool_choice=_tool_choice,
on_tool_executed=self._on_tool_executed_budget,
system_prompt=llm_system_prompt,
**_merged_tool_kw,
)
result = self._enrich_llm_json_user_profile(result, input_data)
@@ -1882,6 +1896,7 @@ class WorkflowEngine:
model=model,
temperature=temperature,
max_tokens=max_tokens,
system_prompt=llm_system_prompt,
**llm_extra_kw,
)
result = self._enrich_llm_json_user_profile(result, input_data)