fix: 修复 5 项确定 bug + Provider UX 重做 + 文档统一
Bug fixes: - fix(dao): AsyncSession.delete 补齐漏掉的 await(provider/user/individual 共 4 处) - fix(worker): result.data.output → result.output.output(pydantic-ai 1.x API 适配) - fix(api): 删除 create_worker_from_template 死端点(ORM 字段不匹配必崩) - fix(api): /provider/test 按 provider_type 分支适配 Anthropic/Gemini/OpenAI 三种协议 - fix(chat): SSE 流式聊天在 distributed 模式 fallback 到非流式,避免 asyncio.Queue 序列化崩溃 Features (previously unstaged): - feat(provider): Provider 管理页重做(品牌图标、5 种类型、Test Connection、编辑模式) - feat(provider): 新增 Gemini provider_type 支持 - feat(workflow): Finalize 节点输出 blackboard 摘要 + 失败原因;步骤完成/失败实时推送 SSE - feat(i18n): regulatory_node 提示词从路由模式改为直接对话模式(中英双语) - feat(consciousness): dynamic_prompt 支持 locale 国际化 - feat(logs): SystemLogsView 自动刷新 + 暂停按钮 Docs: - docs: README/README-EN 统一为"开源通用多 Agent 协作平台"口径 - docs: ROADMAP 按 v0.1.x / v0.2.x / v0.3.x 重组 - docs: project.md 重写为结构化项目介绍 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -223,11 +223,28 @@ class Finalize(BaseNode[WorkflowGraphState, WorkflowDeps, str]):
|
||||
) -> End[str]:
|
||||
ctx.state.final_status = self.status
|
||||
await ctx.deps.update_workflow_status(ctx.state.trace_id, self.status)
|
||||
msg = (
|
||||
"工作流执行完成!"
|
||||
if self.status == WorkflowStatus.COMPLETED.value
|
||||
else "工作流执行失败。"
|
||||
)
|
||||
|
||||
if self.status == WorkflowStatus.COMPLETED.value:
|
||||
summary_parts = []
|
||||
for key, val in ctx.state.blackboard.items():
|
||||
text = str(val)[:200]
|
||||
summary_parts.append(f"• {key}: {text}")
|
||||
summary = "\n".join(summary_parts) if summary_parts else ""
|
||||
msg = f"工作流执行完成!\n{summary}" if summary else "工作流执行完成!"
|
||||
else:
|
||||
failed_logs = [
|
||||
entry for entry in ctx.state.logs
|
||||
if any(
|
||||
isinstance(v, (list, tuple)) and len(v) >= 2 and v[1] == "failed"
|
||||
for v in (entry.values() if isinstance(entry, dict) else [])
|
||||
)
|
||||
]
|
||||
msg = "工作流执行失败。"
|
||||
if failed_logs:
|
||||
last = list(failed_logs[-1].values())[0]
|
||||
if isinstance(last, (list, tuple)) and len(last) >= 3:
|
||||
msg += f"\n失败原因: {last[2][:300]}"
|
||||
|
||||
await ctx.deps.put_pending(ctx.state.trace_id, msg)
|
||||
return End(self.status)
|
||||
|
||||
@@ -295,9 +312,13 @@ async def _execute_step(
|
||||
state.logs[-1][str(state.current_step_index)] = [
|
||||
str(datetime.datetime.now()),
|
||||
"completed",
|
||||
f"成功: {step_data.get('action', '')}",
|
||||
output_text,
|
||||
]
|
||||
await _persist_context(ctx, status=WorkflowStatus.RUNNING.value)
|
||||
await ctx.deps.put_pending(
|
||||
state.trace_id,
|
||||
f"✅ 步骤 {state.current_step_index + 1} ({step_data.get('name', '')}) 完成:\n{output_text[:500]}",
|
||||
)
|
||||
|
||||
logic_gate = step_data.get("logic_gate") or {}
|
||||
if logic_gate.get("if_pass") == "exit":
|
||||
@@ -314,6 +335,10 @@ async def _execute_step(
|
||||
"failed",
|
||||
output_text,
|
||||
]
|
||||
await ctx.deps.put_pending(
|
||||
state.trace_id,
|
||||
f"❌ 步骤 {state.current_step_index + 1} ({step_data.get('name', '')}) 失败:\n{output_text[:300]}",
|
||||
)
|
||||
logic_gate = step_data.get("logic_gate") or {}
|
||||
fail_target = logic_gate.get("if_fail")
|
||||
if fail_target and "jump_to_step_" in fail_target:
|
||||
|
||||
Reference in New Issue
Block a user