Spaces:
Running on Zero
Running on Zero
Upload folder using huggingface_hub
Browse files
app.py
CHANGED
|
@@ -17,43 +17,49 @@ QUESTIONS = [
|
|
| 17 |
"key": "input",
|
| 18 |
"title": "\u7b2c1\u8f6e\uff1a\u8f93\u5165",
|
| 19 |
"question": "\u8fd9\u4e2a\u5de5\u4f5c\u7684\u8f93\u5165\u662f\u4ec0\u4e48\uff1f\u4ece\u54ea\u91cc\u6765\uff1f\u4ec0\u4e48\u683c\u5f0f\uff1f",
|
| 20 |
-
"
|
| 21 |
-
"
|
|
|
|
| 22 |
},
|
| 23 |
{
|
| 24 |
"key": "workflow",
|
| 25 |
"title": "\u7b2c2\u8f6e\uff1a\u5904\u7406\u52a8\u4f5c",
|
| 26 |
"question": "\u62ff\u5230\u8f93\u5165\u540e\uff0c\u5177\u4f53\u8981\u505a\u54ea\u51e0\u6b65\uff1f\u8bf7\u63cf\u8ff0\u4e3b\u8981\u52a8\u4f5c\uff0c\u6211\u4f1a\u5e2e\u4f60\u62c6\u6210 3-8 \u4e2a\u6b65\u9aa4\u3002",
|
| 27 |
-
"
|
| 28 |
-
"
|
|
|
|
| 29 |
},
|
| 30 |
{
|
| 31 |
"key": "output",
|
| 32 |
"title": "\u7b2c3\u8f6e\uff1a\u8f93\u51fa",
|
| 33 |
"question": "\u505a\u5b8c\u4e4b\u540e\u8f93\u51fa\u4ec0\u4e48\uff1f\u653e\u54ea\u91cc\uff1f\u4ec0\u4e48\u683c\u5f0f\uff1f",
|
| 34 |
-
"
|
| 35 |
-
"
|
|
|
|
| 36 |
},
|
| 37 |
{
|
| 38 |
"key": "success",
|
| 39 |
"title": "\u7b2c4\u8f6e\uff1a\u6210\u529f\u6807\u51c6",
|
| 40 |
"question": "\u600e\u4e48\u5224\u65ad\u505a\u5bf9\u4e86\uff1f\u600e\u4e48\u5224\u65ad\u505a\u9519\u4e86\uff1f",
|
| 41 |
-
"
|
| 42 |
-
"
|
|
|
|
| 43 |
},
|
| 44 |
{
|
| 45 |
"key": "fallback",
|
| 46 |
"title": "\u7b2c5\u8f6e\uff1a\u4eba\u5de5\u515c\u5e95",
|
| 47 |
"question": "\u4ec0\u4e48\u60c5\u51b5\u9700\u8981\u4eba\u5de5\u4ecb\u5165\uff1f\u4f60\u5e0c\u671b\u5728\u54ea\u4e2a\u73af\u8282\u68c0\u67e5\uff1f",
|
| 48 |
-
"
|
| 49 |
-
"
|
|
|
|
| 50 |
},
|
| 51 |
{
|
| 52 |
"key": "out_of_scope",
|
| 53 |
"title": "\u7b2c6\u8f6e\uff1a\u672c\u671f\u4e0d\u505a",
|
| 54 |
"question": "\u6709\u4ec0\u4e48\u662f\u8fd9\u4e2a Agent \u73b0\u5728\u660e\u786e\u4e0d\u5e94\u8be5\u505a\u7684\uff1f\u8bf7\u5217 3-5 \u6761\u3002",
|
| 55 |
-
"
|
| 56 |
-
"
|
|
|
|
| 57 |
},
|
| 58 |
]
|
| 59 |
|
|
@@ -105,7 +111,8 @@ def _format_question(question: dict[str, str]) -> str:
|
|
| 105 |
return (
|
| 106 |
f"{question['title']}\n\n"
|
| 107 |
f"{question['question']}\n\n"
|
| 108 |
-
f"
|
|
|
|
| 109 |
f"{question.get('sample', '')}"
|
| 110 |
)
|
| 111 |
|
|
@@ -115,7 +122,13 @@ def _current_helper_text(state: dict[str, Any]) -> str:
|
|
| 115 |
if state.get("done"):
|
| 116 |
return "已生成 Agent 变身包。你可以下载 ZIP,或在对话框里继续提出修改意见。"
|
| 117 |
question = QUESTIONS[min(step, len(QUESTIONS) - 1)]
|
| 118 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
|
| 121 |
def _progress_text(state: dict[str, Any]) -> str:
|
|
@@ -201,16 +214,18 @@ def _llm_next_reply(summary: str, state: dict[str, Any], next_question: dict[str
|
|
| 201 |
Current summary:
|
| 202 |
{summary}
|
| 203 |
|
| 204 |
-
Write the next message to the user in natural Chinese.
|
| 205 |
Requirements:
|
| 206 |
- First confirm the summary in one concise sentence starting with "归纳确认:".
|
| 207 |
- Then ask only this one next question:
|
| 208 |
{next_question['title']}: {next_question['question']}
|
| 209 |
-
-
|
| 210 |
-
-
|
| 211 |
-
-
|
|
|
|
| 212 |
- Do not ask multiple questions.
|
| 213 |
- Do not output English labels such as "Hint" or "Example".
|
|
|
|
| 214 |
"""
|
| 215 |
else:
|
| 216 |
user_prompt = f"""Confirmed information:
|
|
@@ -357,7 +372,7 @@ def _save_card(card: str) -> str:
|
|
| 357 |
return str(file_path)
|
| 358 |
|
| 359 |
|
| 360 |
-
def _build_agent_spec(card: str, answers: dict[str, str]) -> dict[str, Any]:
|
| 361 |
suitability = {
|
| 362 |
"repeatable": "unknown",
|
| 363 |
"stable_input": "confirmed" if answers.get("input") else "unknown",
|
|
@@ -384,11 +399,33 @@ def _build_agent_spec(card: str, answers: dict[str, str]) -> dict[str, Any]:
|
|
| 384 |
"human_fallback": answers.get("fallback", "Ask for human intervention when key information is missing or risk is high."),
|
| 385 |
"constraints": _split_items(answers.get("out_of_scope", ""), "Do not invent unconfirmed details."),
|
| 386 |
"platforms": ["generic", "codex"],
|
| 387 |
-
"source_card": card,
|
| 388 |
-
}
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 392 |
return f"""# { _agent_name(answers) }
|
| 393 |
|
| 394 |
You are this repository's active Agent worker. Follow the role card below as your operating contract.
|
|
@@ -525,6 +562,7 @@ def _build_install_prompt(answers: dict[str, str]) -> str:
|
|
| 525 |
|
| 526 |
- AGENTS.md
|
| 527 |
- agent-spec.json
|
|
|
|
| 528 |
- docs/01-role-card.md
|
| 529 |
- docs/02-workflow.md
|
| 530 |
- docs/03-profile.md
|
|
@@ -568,8 +606,9 @@ def _save_agent_package(card: str, answers: dict[str, str]) -> str:
|
|
| 568 |
(package_dir / "START_HERE.md").write_text(_build_start_here(answers), encoding="utf-8")
|
| 569 |
(package_dir / "INSTALL_PROMPT.md").write_text(_build_install_prompt(answers), encoding="utf-8")
|
| 570 |
(package_dir / "AGENTS.md").write_text(_build_agents_md(card, answers), encoding="utf-8")
|
| 571 |
-
(package_dir / "agent-spec.json").write_text(json.dumps(spec, ensure_ascii=False, indent=2), encoding="utf-8")
|
| 572 |
-
(docs_dir / "
|
|
|
|
| 573 |
(docs_dir / "02-workflow.md").write_text(_build_workflow_doc(answers), encoding="utf-8")
|
| 574 |
(docs_dir / "03-profile.md").write_text(_build_profile_doc(card, answers), encoding="utf-8")
|
| 575 |
(docs_dir / "04-test-log.md").write_text(_build_test_log_doc(), encoding="utf-8")
|
|
@@ -586,7 +625,7 @@ This package was generated by Agent Architect.
|
|
| 586 |
1. Unzip this package.
|
| 587 |
2. Put `AGENTS.md` at the root of your Codex-style project.
|
| 588 |
3. Keep `agent-spec.json` as the structured agent contract.
|
| 589 |
-
4. Read `docs/01-role-card.md`, `docs/02-workflow.md`, and `docs/03-profile.md`.
|
| 590 |
5. Use `docs/04-test-log.md` to record real tests before long-term use.
|
| 591 |
|
| 592 |
This package follows a role-card-first Agent project structure: role card, workflow, profile, test log, usage guide, and showcase notes.
|
|
@@ -688,17 +727,28 @@ def respond(message: str, history: list[dict[str, str]], state: dict[str, Any]):
|
|
| 688 |
summary = _summarize(key, message)
|
| 689 |
state["summaries"][key] = summary
|
| 690 |
|
| 691 |
-
if len(message) < 4:
|
| 692 |
-
history.append(_chat_line(
|
|
|
|
|
|
|
|
|
|
| 693 |
return _ui_result(history, state, state.get("file_path"))
|
| 694 |
|
| 695 |
state["step"] += 1
|
| 696 |
if state["step"] < len(QUESTIONS):
|
| 697 |
next_q = QUESTIONS[state["step"]]
|
| 698 |
-
try:
|
| 699 |
-
assistant_reply = _llm_next_reply(summary, state, next_q)
|
| 700 |
-
except Exception as exc:
|
| 701 |
-
assistant_reply =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 702 |
history.append(_chat_line("assistant", assistant_reply))
|
| 703 |
return _ui_result(history, state, state.get("file_path"))
|
| 704 |
|
|
|
|
| 17 |
"key": "input",
|
| 18 |
"title": "\u7b2c1\u8f6e\uff1a\u8f93\u5165",
|
| 19 |
"question": "\u8fd9\u4e2a\u5de5\u4f5c\u7684\u8f93\u5165\u662f\u4ec0\u4e48\uff1f\u4ece\u54ea\u91cc\u6765\uff1f\u4ec0\u4e48\u683c\u5f0f\uff1f",
|
| 20 |
+
"why": "先确认输入是否稳定、容易识别。输入越稳定,这个工作越适合做成 Agent。",
|
| 21 |
+
"options": "可选回答:A. 用户在对话框输入文字;B. 用户上传文件;C. 来自表格/表单;D. 来自固定文件夹;E. 还不确定,需要 Agent 追问。",
|
| 22 |
+
"sample": "参考回答:输入是用户在网页对话框里发来的文案需求,格式是一段自然语言文本。",
|
| 23 |
},
|
| 24 |
{
|
| 25 |
"key": "workflow",
|
| 26 |
"title": "\u7b2c2\u8f6e\uff1a\u5904\u7406\u52a8\u4f5c",
|
| 27 |
"question": "\u62ff\u5230\u8f93\u5165\u540e\uff0c\u5177\u4f53\u8981\u505a\u54ea\u51e0\u6b65\uff1f\u8bf7\u63cf\u8ff0\u4e3b\u8981\u52a8\u4f5c\uff0c\u6211\u4f1a\u5e2e\u4f60\u62c6\u6210 3-8 \u4e2a\u6b65\u9aa4\u3002",
|
| 28 |
+
"why": "这里用“先定岗位,再拆流程”的方法,把重复工作变成 Agent 能执行的动作。",
|
| 29 |
+
"options": "可选动作:识别需求、判断是否适合 Agent 化、追问缺失信息、生成初稿、检查质量、导出文件、支持用户修改。",
|
| 30 |
+
"sample": "参考回答:1. 识别 Agent 类型;2. 追问缺失信息;3. 整理岗位卡;4. 生成项目包;5. 支持用户修改。",
|
| 31 |
},
|
| 32 |
{
|
| 33 |
"key": "output",
|
| 34 |
"title": "\u7b2c3\u8f6e\uff1a\u8f93\u51fa",
|
| 35 |
"question": "\u505a\u5b8c\u4e4b\u540e\u8f93\u51fa\u4ec0\u4e48\uff1f\u653e\u54ea\u91cc\uff1f\u4ec0\u4e48\u683c\u5f0f\uff1f",
|
| 36 |
+
"why": "Agent 的交付物要清晰、可验收,用户拿到后要知道怎么用。",
|
| 37 |
+
"options": "可选输出:一段回复、Markdown 文件、表格、图片提示词、ZIP 项目包、下载链接、保存到指定文件夹。",
|
| 38 |
+
"sample": "参考回答:输出一个 Agent 变身包 ZIP,在页面下载按钮提供,里面包含 AGENTS.md、agent-spec.json、docs 和 skills。",
|
| 39 |
},
|
| 40 |
{
|
| 41 |
"key": "success",
|
| 42 |
"title": "\u7b2c4\u8f6e\uff1a\u6210\u529f\u6807\u51c6",
|
| 43 |
"question": "\u600e\u4e48\u5224\u65ad\u505a\u5bf9\u4e86\uff1f\u600e\u4e48\u5224\u65ad\u505a\u9519\u4e86\uff1f",
|
| 44 |
+
"why": "这里是在写验收标准。没有验收标准,Agent 很容易看似完成,实际不可用。",
|
| 45 |
+
"options": "可选标准:文件齐全、格式正确、步骤可执行、输出符合用户需求、能被另一个 Agent 读取、遇到不清楚会追问。",
|
| 46 |
+
"sample": "参考回答:做对了是 ZIP 能下载、文件齐全、AGENTS.md 可以指导 Agent 工作;做错了是缺字段、指令空泛或无法使用。",
|
| 47 |
},
|
| 48 |
{
|
| 49 |
"key": "fallback",
|
| 50 |
"title": "\u7b2c5\u8f6e\uff1a\u4eba\u5de5\u515c\u5e95",
|
| 51 |
"question": "\u4ec0\u4e48\u60c5\u51b5\u9700\u8981\u4eba\u5de5\u4ecb\u5165\uff1f\u4f60\u5e0c\u671b\u5728\u54ea\u4e2a\u73af\u8282\u68c0\u67e5\uff1f",
|
| 52 |
+
"why": "好 Agent 不是全自动乱跑,而是在关键风险点停下来让人确认。",
|
| 53 |
+
"options": "可选介入条件:需求矛盾、信息不足、用户目标不适合 Agent 化、涉及账号权限、对外发布、付费操作、高风险或违规内容。",
|
| 54 |
+
"sample": "参考回答:用户需求冲突、信息不足、涉及对外发布或账号权限时需要人工介入;在每轮归纳后和生成前检查。",
|
| 55 |
},
|
| 56 |
{
|
| 57 |
"key": "out_of_scope",
|
| 58 |
"title": "\u7b2c6\u8f6e\uff1a\u672c\u671f\u4e0d\u505a",
|
| 59 |
"question": "\u6709\u4ec0\u4e48\u662f\u8fd9\u4e2a Agent \u73b0\u5728\u660e\u786e\u4e0d\u5e94\u8be5\u505a\u7684\uff1f\u8bf7\u5217 3-5 \u6761\u3002",
|
| 60 |
+
"why": "小岗位优先。先做一个边界清楚、能跑通闭环的 Agent,再逐步扩展。",
|
| 61 |
+
"options": "可选边界:不登录账号、不自动发布、不付款、不处理违法违规内容、不承诺结果、不在信息不足时编造、不做万能助手。",
|
| 62 |
+
"sample": "参考回答:不自动操作用户账号;不绕过平台权限;不生成违法违规 Agent;不在信息不清楚时编造细节。",
|
| 63 |
},
|
| 64 |
]
|
| 65 |
|
|
|
|
| 111 |
return (
|
| 112 |
f"{question['title']}\n\n"
|
| 113 |
f"{question['question']}\n\n"
|
| 114 |
+
f"为什么问这个:{question.get('why', '')}\n\n"
|
| 115 |
+
f"不会答可以选:{question.get('options', '')}\n\n"
|
| 116 |
f"{question.get('sample', '')}"
|
| 117 |
)
|
| 118 |
|
|
|
|
| 122 |
if state.get("done"):
|
| 123 |
return "已生成 Agent 变身包。你可以下载 ZIP,或在对话框里继续提出修改意见。"
|
| 124 |
question = QUESTIONS[min(step, len(QUESTIONS) - 1)]
|
| 125 |
+
return (
|
| 126 |
+
f"{question['title']}\n\n"
|
| 127 |
+
f"五维筛选:重复出现 / 输入稳定 / 步骤明确 / 输出可验收 / 人工兜底\n\n"
|
| 128 |
+
f"为什么问这个:{question.get('why', '')}\n\n"
|
| 129 |
+
f"不会答可以选:{question.get('options', '')}\n\n"
|
| 130 |
+
f"{question.get('sample', '')}"
|
| 131 |
+
)
|
| 132 |
|
| 133 |
|
| 134 |
def _progress_text(state: dict[str, Any]) -> str:
|
|
|
|
| 214 |
Current summary:
|
| 215 |
{summary}
|
| 216 |
|
| 217 |
+
Write the next message to the user in natural Chinese, using the OpenClaw-style Agent architect guidance.
|
| 218 |
Requirements:
|
| 219 |
- First confirm the summary in one concise sentence starting with "归纳确认:".
|
| 220 |
- Then ask only this one next question:
|
| 221 |
{next_question['title']}: {next_question['question']}
|
| 222 |
+
- After the question, include exactly these three Chinese guidance labels:
|
| 223 |
+
- "为什么问这个:" followed by: {next_question.get('why', '')}
|
| 224 |
+
- "不会答可以选:" followed by: {next_question.get('options', '')}
|
| 225 |
+
- Then include this reference answer exactly once: {next_question.get('sample', '')}
|
| 226 |
- Do not ask multiple questions.
|
| 227 |
- Do not output English labels such as "Hint" or "Example".
|
| 228 |
+
- Do not use the old labels "提示:" or "示例:".
|
| 229 |
"""
|
| 230 |
else:
|
| 231 |
user_prompt = f"""Confirmed information:
|
|
|
|
| 372 |
return str(file_path)
|
| 373 |
|
| 374 |
|
| 375 |
+
def _build_agent_spec(card: str, answers: dict[str, str]) -> dict[str, Any]:
|
| 376 |
suitability = {
|
| 377 |
"repeatable": "unknown",
|
| 378 |
"stable_input": "confirmed" if answers.get("input") else "unknown",
|
|
|
|
| 399 |
"human_fallback": answers.get("fallback", "Ask for human intervention when key information is missing or risk is high."),
|
| 400 |
"constraints": _split_items(answers.get("out_of_scope", ""), "Do not invent unconfirmed details."),
|
| 401 |
"platforms": ["generic", "codex"],
|
| 402 |
+
"source_card": card,
|
| 403 |
+
}
|
| 404 |
+
|
| 405 |
+
|
| 406 |
+
def _build_screening_doc(answers: dict[str, str]) -> str:
|
| 407 |
+
return f"""# 五维筛选
|
| 408 |
+
|
| 409 |
+
这份 Agent 采用“先判断是否适合 Agent 化,再定岗位、拆流程、写 Profile”的制作方式。
|
| 410 |
+
|
| 411 |
+
## 筛选结果
|
| 412 |
+
|
| 413 |
+
- 是否重复出现:由用户需求场景确认,若只是一次性创意任务,建议先做成辅助 Agent。
|
| 414 |
+
- 输入是否稳定、容易识别:{answers.get("input", "待确认")}
|
| 415 |
+
- 处理步骤和判断规则是否明确:{answers.get("workflow", "待确认")}
|
| 416 |
+
- 输出是否清晰、可验收:{answers.get("success", "待确认")}
|
| 417 |
+
- 出问题时是否可以人工兜底:{answers.get("fallback", "待确认")}
|
| 418 |
+
|
| 419 |
+
## 制作原则
|
| 420 |
+
|
| 421 |
+
1. 小岗位优先:先做一个边界清楚的岗位,不做万能助手。
|
| 422 |
+
2. 交付可验收:输出必须能被用户检查、下载或复用。
|
| 423 |
+
3. 失败可兜底:遇到缺信息、冲突、高风险动作时停下来问人。
|
| 424 |
+
4. 最小闭环优先:先跑通输入、处理、输出、验收,再扩展自动化。
|
| 425 |
+
"""
|
| 426 |
+
|
| 427 |
+
|
| 428 |
+
def _build_agents_md(card: str, answers: dict[str, str]) -> str:
|
| 429 |
return f"""# { _agent_name(answers) }
|
| 430 |
|
| 431 |
You are this repository's active Agent worker. Follow the role card below as your operating contract.
|
|
|
|
| 562 |
|
| 563 |
- AGENTS.md
|
| 564 |
- agent-spec.json
|
| 565 |
+
- docs/00-five-dimension-screening.md
|
| 566 |
- docs/01-role-card.md
|
| 567 |
- docs/02-workflow.md
|
| 568 |
- docs/03-profile.md
|
|
|
|
| 606 |
(package_dir / "START_HERE.md").write_text(_build_start_here(answers), encoding="utf-8")
|
| 607 |
(package_dir / "INSTALL_PROMPT.md").write_text(_build_install_prompt(answers), encoding="utf-8")
|
| 608 |
(package_dir / "AGENTS.md").write_text(_build_agents_md(card, answers), encoding="utf-8")
|
| 609 |
+
(package_dir / "agent-spec.json").write_text(json.dumps(spec, ensure_ascii=False, indent=2), encoding="utf-8")
|
| 610 |
+
(docs_dir / "00-five-dimension-screening.md").write_text(_build_screening_doc(answers), encoding="utf-8")
|
| 611 |
+
(docs_dir / "01-role-card.md").write_text(card, encoding="utf-8")
|
| 612 |
(docs_dir / "02-workflow.md").write_text(_build_workflow_doc(answers), encoding="utf-8")
|
| 613 |
(docs_dir / "03-profile.md").write_text(_build_profile_doc(card, answers), encoding="utf-8")
|
| 614 |
(docs_dir / "04-test-log.md").write_text(_build_test_log_doc(), encoding="utf-8")
|
|
|
|
| 625 |
1. Unzip this package.
|
| 626 |
2. Put `AGENTS.md` at the root of your Codex-style project.
|
| 627 |
3. Keep `agent-spec.json` as the structured agent contract.
|
| 628 |
+
4. Read `docs/00-five-dimension-screening.md`, `docs/01-role-card.md`, `docs/02-workflow.md`, and `docs/03-profile.md`.
|
| 629 |
5. Use `docs/04-test-log.md` to record real tests before long-term use.
|
| 630 |
|
| 631 |
This package follows a role-card-first Agent project structure: role card, workflow, profile, test log, usage guide, and showcase notes.
|
|
|
|
| 727 |
summary = _summarize(key, message)
|
| 728 |
state["summaries"][key] = summary
|
| 729 |
|
| 730 |
+
if len(message) < 4:
|
| 731 |
+
history.append(_chat_line(
|
| 732 |
+
"assistant",
|
| 733 |
+
f"归纳确认:{summary}\n\n这个回答还比较短,我怕生成出来会太空。你可以按下面任选一种补充:\n\n不会答可以选:{question.get('options', '')}\n\n{question.get('sample', '')}",
|
| 734 |
+
))
|
| 735 |
return _ui_result(history, state, state.get("file_path"))
|
| 736 |
|
| 737 |
state["step"] += 1
|
| 738 |
if state["step"] < len(QUESTIONS):
|
| 739 |
next_q = QUESTIONS[state["step"]]
|
| 740 |
+
try:
|
| 741 |
+
assistant_reply = _llm_next_reply(summary, state, next_q)
|
| 742 |
+
except Exception as exc:
|
| 743 |
+
assistant_reply = (
|
| 744 |
+
f"归纳确认:{summary}\n\n"
|
| 745 |
+
f"{next_q['title']}\n\n"
|
| 746 |
+
f"{next_q['question']}\n\n"
|
| 747 |
+
f"为什么问这个:{next_q.get('why', '')}\n\n"
|
| 748 |
+
f"不会答可以选:{next_q.get('options', '')}\n\n"
|
| 749 |
+
f"{next_q.get('sample', '')}\n\n"
|
| 750 |
+
f"系统说明:模型暂时不可用,已切换为规则追问。错误:{exc}"
|
| 751 |
+
)
|
| 752 |
history.append(_chat_line("assistant", assistant_reply))
|
| 753 |
return _ui_result(history, state, state.get("file_path"))
|
| 754 |
|