# 代码库「工作流(Workflow)功能」挂载点调研报告 > 调研目标:为即将新增的「工作流(Workflow)功能」定位代码库内的接入挂载点。 > 前提理解:工作流 = 用户把「一套既定流程:工作方式→验证方式→结束方式」存为一个工作流文件夹(类似现有 skill 文件夹机制,可附带验证过的脚本/代码文件);之后在对话中复用以现有智能体循环+执行引擎运行它;可能有独立 URL(如 `/workflow/new`)或作为普通对话的一种运行方式;阶段/整体结束时由审核智能体审核(复用两套现有审核:工具审核 + 目标模式 goal_review)。 > > **调研约束**:仅只读操作,未修改任何项目文件。所有结论均基于实际读到的代码,标注文件路径与行号;不确定处明确写「未确认」。 > 所有代码路径均以项目根 `/Users/jojo/Desktop/agents/正在修复中/agents` 为准(相对路径书写)。 --- ## 1. Skill 系统全链路(工作流文件夹需仿照它) ### 1.1 目录结构与 SKILL.md frontmatter - **源码树 skill 库**:`agentskills/`(每个 skill 一个子目录,内含 `SKILL.md`,可含 `references/`、`scripts/` 等附带文件)。示例:`agentskills/terminal-guide/SKILL.md`、`agentskills/skill-creator/SKILL.md`。 - **SKILL.md frontmatter 格式**(YAML 简单解析): ``` --- name: terminal-guide description: 持久化终端使用指南。…… --- ``` 后端校验逻辑见 `modules/skills_manager.py::validate_skill_directory`(第 146 行起),**只强制要求存在 `name:` 与 `description:`**(`re.search(r"(?m)^\s*name\s*:", content)` 与 description 同理)。frontmatter 全文解析见 `_parse_frontmatter`(L174)。 - **目录名校验**:`_is_valid_skill_id`(L202),用 `SKILL_ID_PATTERN`。 **工作流接入判断**:工作流文件夹可直接复用这套「SKILL.md + 附带脚本」结构。建议新增一个 `WORKFLOW.md`(或复用 frontmatter 扩展字段),并在目录中携带验证过的 `scripts/` 目录。校验时除 SKILL.md 的 name/description 外,可扩展校验「工作方式→验证方式→结束方式」三段定义。 ### 1.2 skill 创建/归档工具后端实现 - **工具定义**:`core/main_terminal_parts/tools_definition/file_tools.py` L139 定义 `create_skill`(描述「验证并归档一个已创建好的 skill 文件夹」)。 - **handler**:`core/main_terminal_parts/tools_execution.py` - `_resolve_create_skill_source_dir`(L525):解析 source_dir(相对/绝对/宿主机任意路径)。 - `_get_create_skill_target_root`(L539):归档目标根目录 —— 优先 `infer_private_skills_dir(self.data_dir)`,否则 `data_dir` 父级下 `agentskills`。 - `_handle_create_skill_tool`(L545):调用 `archive_skill_directory(source, target_root)` 归档;成功后同步工作区 skills(`sync_workspace_skills`)。 - **归档函数**:`modules/skills_manager.py::archive_skill_directory`(L182)——先 `validate_skill_directory` 校验,再 `shutil.move` 移动到目标库;目标存在则拒绝(不覆盖)。 - **私有 skill 目录推断**:`modules/skills_manager.py::infer_private_skills_dir`(L97)——host 模式统一 `~/.astrion/astrion//agentskills`;web/docker 按用户路径推断。 **工作流接入判断**:可仿 create_skill 新增 `create_workflow` 工具(或复用同一归档通道),handler 在 `tools_execution.py` 的 `handle_tool_call` 分发链(L960,elif tool_name 分支约 L1130)注册;归档逻辑复用 `archive_skill_directory` 的校验+移动+拒绝覆盖机制。 ### 1.3 skill 如何注入提示词 - 注入点:`core/main_terminal_parts/context/messages.py` L305-320,`build_messages` 内按 system prompt 顺序追加 skills 列表: ```python skills_catalog = get_skills_catalog(private_dir=infer_private_skills_dir(self.data_dir)) enabled_skills = merge_enabled_skills(...) def _build_skills_system_prompt(): template = self.load_prompt("skills_system") return build_skills_prompt(template, build_skills_list(...)) skills_prompt = self._get_or_init_frozen_prompt("frozen_skills_prompt", _build_skills_system_prompt) if skills_prompt: messages.append({"role":"system","content":skills_prompt}) ``` - **模板**:`prompts/skills_system.txt`(占位 `{skills_list}`,提示用 `read_skill` 读取)。 - **enabled/sync**:`merge_enabled_skills`(skills_manager L373)、`sync_workspace_skills`(L409)——把启用 skill 复制到工作区 `.astrion/skills/`。 - **skill_hints 意图识别**:`config/skill_hints.json`(关键词→hint),用于在用户消息中检测相关 skill 并注入提示(读 `_inject_intent` 相关)。 **工作流接入判断**:工作流列表可仿 skills_prompt 在 `messages.py` `build_messages` 增加一段 system prompt 注入当前工作流上下文(当前已激活工作流的流程说明),复用 `_get_or_init_frozen_prompt` 冻结机制与 `load_prompt` 模板机制。 ### 1.4 skill 列表/读取 API - **列表 API**:`server/tasks/skills.py` `GET /api/skills`(L126,`@tasks_bp.route`)→ `_list_workspace_skills`(L83)读取工作区 `.astrion/skills/*/SKILL.md`,解析 name/description/path。 - **读取**:工具 `read_skill`(file_tools.py L132)→ handler `_handle_read_skill_tool`(tools_execution.py 中)。 **工作流接入判断**:仿 `server/tasks/skills.py` 新增 `GET /api/workflows`(读工作流库目录),用于前端列表展示与「作为对话新类型创建」时选择工作流。 --- ## 2. 两套审核智能体架构(工作流阶段审核复用) ### 2.1 工具审核 approval_agent - **实现**:`modules/approval_agent.py`(由配置 `CONFIG_PATH = Path(resolve_deploy_config("auto_approval.json"))` 指定,L16 → `config/auto_approval.json[.example]`)。 - **调用方式**:`modules/auto_approval_service.py::run_auto_approval`(L84)构造 `ApprovalAgent(web_terminal=web_terminal)` 并 `await agent.review(payload_text=..., progress_cb=..., cancel_check=...)`。`build_auto_approval_payload`(L15)组装用户输入+最近工具操作+触发风险标记。 - **输入**:payload 纯文本(审批场景上下文 + 当前工具调用函数名/参数)。 - **输出**:`{"decision": "approved"|"rejected", "reason": str, "source": "approval_agent"}`。内部通过工具 `approve_decision`(L168)返回,异常/配置缺失时兜底 `{"decision":"rejected", ...}`。 - **执行模式**:readonly 或注入只读 run_command 取证(与 goal_review 同构)。 **工作流接入判断**:工作流的「工具/操作级」安全审核可直接复用 `ApprovalAgent`,通过 `auto_approval_service` 同构入口调用;无需新造。若需按工作流阶段应用不同审核,可在 `run_auto_approval` 之外包装一个「阶段审核」封装函数。 ### 2.2 目标审核 goal_review - **实现**:`modules/goal_review_agent.py`(配置 `CONFIG_PATH = resolve_deploy_config("goal_review.json")`,L20)。`GoalReviewAgent(web_terminal=...)`,`async review(payload_text, review_mode, progress_cb, cancel_check)`。 - **输出**:`{"status":"done"|"continue", "message": str, "source":"goal_review_agent"}`;兜底保守返回 continue。review_mode 由 `modules/goal_state_manager.py` 常量 `REVIEW_MODE_READONLY="readonly"` / `REVIEW_MODE_ACTIVE="active"`(L34-35)决定是否注入只读 run_command。 - **目标模式如何触发审核**:`server/goal_flow.py`: - `maybe_start_goal`(L56):用户显式开启目标模式时启动(读 personalization 的 review_mode/end_conditions)。 - `inject_goal_prompt`(L88):注入目标模式提示词。 - `handle_goal_after_turn`(L147):**在主循环「主模型一轮无 tool_calls」时拦截**——先空转保护/边界检查,再调 `GoalReviewAgent.review`; - `status=="continue"` → `append_review` 记录审核历史 + `inject_runtime_user_message(CONTINUE_PREFIX + message)` **回写续命 user 消息到 messages**,调用方 `continue` 回主循环开下一轮; - `status=="done"` → `mark_done`,任务结束。 - **状态落盘**:`modules/goal_state_manager.py`,工作区 `{data_dir}/goal_state.json`(含 goal、review_mode、turns、review_history 等)。 - **触发入口**(后端):创建任务时传 `goal_mode` → `server/tasks/models.py` `create_chat_task` 存 session_data → `run_chat_task_sync` 时置 `terminal._goal_mode_requested=True`(models.py L961/L998-999)→ `chat_flow_task_main.py L1863` 检测并 `maybe_start_goal`。 **工作流接入判断(关键复用点)**:工作流的「阶段结束/整体结束审核」几乎可 1:1 复用 goal_review 的回写机制——在 `chat_flow_task_main.py` 主循环的 no-tool-call 结束判定处(L2226 附近 `if not tool_calls:`),当前已有 `if goal_is_active(workspace): handle_goal_after_turn(...)` 分支;工作流运行时可仿照新增「工作流阶段/整体审核」调用 `GoalReviewAgent`(或新 `WorkflowReviewAgent`),并把 continue/done 语义映射为「进入下一阶段/结束工作流」。建议抽出一个与 `goal_flow.py` 同构的 `workflow_flow.py` 编排模块,减少对主循环侵入。 --- ## 3. 智能体循环与执行引擎(工作流运行时复用) ### 3.1 主循环入口链路(骨架级) - **唯一入口(门闸)**:`server/chat_flow.py::process_message_task`(L130)——先 `acquire_adopted_main_task_gate` 拿对话级门闸(§12 单写者不变量),然后 `loop.create_task(handle_task_with_sender(...))`。**任何新增的主任务入口必须走此门闸**(AGENTS.md §12.4)。 - **实际任务执行**:`server/chat_flow_task_main.py::handle_task_with_sender`(L1411): - L1855 `messages = web_terminal.build_messages(context, message)`;`tools = web_terminal.define_tools()`。 - L1863 目标模式启动/续注入。 - L1962 `while max_iterations is None or iteration < max_iterations:` 主循环迭代: - 每轮 `run_streaming_attempts(messages=messages, tools=tools, ...)`(L2082,导入自 `server/chat_flow_stream_loop.py`)调模型,返回 full_response / tool_calls。 - **有 tool_calls** → L2325 `execute_tool_calls(...)` 执行工具(结果 append 到 messages/对话历史),`continue` 下一轮。 - **无 tool_calls**(L2226 `if not tool_calls:`)→ 目标审核分支(L2230)→ 多智能体注入分支(L2314)→ 否则 `break` 结束。 - **工具执行循环**:`server/chat_flow_tool_loop.py::execute_tool_calls`(L409)→ `_execute_tool_calls_impl`(L426,守护包装 try/finally 复位 `_tool_loop_active`): - 白名单校验(allowed_tool_names)→ 权限评估 `web_terminal.evaluate_tool_permission` → 逐个 `tool_call` 解析/执行,结果 `web_terminal.context_manager.add_conversation("tool", ...)` + `messages.append({"role":"tool", ...})`。 - 工具真实执行在 `core/main_terminal_parts/tools_execution.py::handle_tool_call`(L960,elif tool_name = handler 分发大表)。 **工作流接入判断**:工作流运行**不需要**新增主循环,直接复用 `process_message_task` 门闸 + `handle_task_with_sender` 迭代即可(把工作流定义作为额外的 system 上下文 + 结束阶段审核挂钩即可)。若想「阶段结束审核后进入下一阶段并继续迭代」,参照 goal_review 的 continue → `inject_runtime_user_message` + `continue` 模式,完全在现有消息/迭代机制内实现。 ### 3.2 运行模式 work_mode 三档(plan/ask/execute)——新增一种运行方式的最相近参照 - **核心实现**:`core/main_terminal_parts/tools_policy.py`:`WORK_MODES = {"plan","ask","execute"}`, `WORK_MODE_DEFAULT="plan"`(L88);`set_work_mode` / `switch_work_mode`(处理 plan⇄只读权限+沙箱联动)/ `get_work_mode`;权限模式 `PERMISSION_MODES` 与 plan 锁。 - **怎么注入提示词规则**:`core/main_terminal_parts/context/mode.py` - `_build_work_mode_rules(mode)`(L192):三档规则文本唯一来源(plan/ask/execute 各自的 detailed_rules)。 - `_build_work_mode_message`(L220):`load_prompt("work_mode")` 模板 + `replace work_mode/work_mode_label/mode_description/detailed_rules`。 - 属于 `_RUNTIME_MODE_KINDS`(L133,含 permission_mode/execution_mode/network_permission/work_mode),切换走 drift 通知(`_RUNTIME_MODE_SOURCE` 第 花 种 "work_mode_change")。 - **冻结注入**:`messages.py::build_messages` L203-208 `_get_or_init_frozen_mode_prompt("frozen_work_mode_prompt", self._build_work_mode_message)`。 - **怎么影响工具可用性**:work_mode 主要通过**提示词**约束(三档规则正文),而非硬性工具过滤(行为差异在规则里,如 ask 禁用 ask_user 工具由提示词说明;plan 的只读是权限层联动)。工具的硬开关由 `tool_category_states`/`disabled_tools`(同一文件 tools_policy.py)控制。 **工作流接入判断**:若把「工作流运行」作为与 work_mode 平行的「一种运行方式」,可仿此模式:新增一类提示词规则(如 `workflow.txt` 模板 + `_build_workflow_rules`)+ 在 `messages.py` 追加一段冻结注入;运行会话期间注入工作流当前阶段上下文。但注意 work_mode 是「与用户交互节奏」正交档位,与工作流(一套流程)语义不同——更倾向工作流作为「消息级上下文+审核挂钩」,而非新增第四档 work_mode。建议工作流保持并在 `_RUNTIME_MODE_KINDS` 之外独立管理(不要混入 work_mode 切档,避免交互节奏冲突)。 ### 3.3 提示词模板机制(prompts/ 组织 + mode.py 构建) - **目录**:`prompts/*.txt`(如 `main_system.txt`、`work_mode.txt`、`skills_system.txt`、`goal_review_agent.txt`、`execution_mode/`、`multi_agent/`、`sub_agent/`)。 - **加载**:`core/main_terminal_parts/context/prompt.py::load_prompt(name)`(L157)——`Path(PROMPTS_DIR)/f"{name}.txt"`,存在则读,否则返回兜底文案。 - **构建规则**:`context/mode.py` 负责把「运行期状态」渲染进 prompt(permission/execution/work_mode/network),`context/messages.py` 在 `build_messages`(L109)按固定 order 追加各 system prompt:主 prompt → 权限 → 执行环境 → 运行模式 → 最近对话 → 个性化 → 工作区 → AGENTS.md → skills → 记忆 → 自定义 → 禁用提示。 - **冻结机制**:`_get_or_init_frozen_prompt` / `_get_or_init_frozen_mode_prompt` 对可变但需稳定的 system 段做一次性构建缓存。 **工作流接入判断**:新增 `prompts/workflow.txt` 模板(或 `prompts/workflow/` 子目录),在 `messages.py::build_messages` 适当的 order 位(建议主 prompt 后、skills 前/后)插入工作流上下文 system 段,并用 `load_prompt("workflow")` 加载。完全复用现有模板/冻结机制。 --- ## 4. 前端入口与路由(/workflow/new 怎么挂) ### 4.1 路由定义位置与现有 /multiagent 兼容重定向 - **前端未用 vue-router**,而是手动处理 `window.location.pathname`(无 createRouter/createWebHistory,全库无 vue-router)。 - **路由解析/重定向核心**:`static/src/app/methods/ui/route.ts::bootstrapRoute`(L26 起): ``` let path = window.location.pathname.replace(/^\/+/, ''); if (path === 'multiagent/new' || path === 'multiagent') { history.replaceState({}, '', '/new'); path = 'new'; } else if (path.startsWith('multiagent/')) { const bareId = ...; history.replaceState({}, '', `/${bareId}`); path = bareId; } ``` 即旧 `/multiagent/*` → 重定向到裸 `/conv_xxx`;`/multiagent/new` → `/new`(对话类型是 metadata 属性,不再是路由概念)。 - 若裸新建路由:清空当前对话、恢复 draft → 结束。 - 否则按 `conv_` 调 `this.enterConversation(convId, ...)`(`app/methods/conversation/bootstrap.ts`)加载并恢复。 - `isExplicitNewConversationRoute()`:判断是否显式新建路由。 **工作流接入判断**:`/workflow/new` 可在 `bootstrapRoute` 增加一个分支:`if (path === 'workflow/new' || path === 'workflow')` → 进入「新建工作流对话」模式(清空 + 标记 `newConversationType='workflow'`),`history.replaceState` 保持 URL 为 `/workflow/new`。后端需相应 `with_terminal`/路由能接受该路径(未确认:当前 route 无条件把 path 当 conv id,需额外分支避开)。 ### 4.2 对话类型机制(newConversationType / currentConversationType) - **状态定义**:`static/src/app/state.ts` - `currentConversationType`(L57):当前已打开对话类型 `'normal'|'multi_agent'|null`,由 `enterConversation` 从 metadata 恢复(`bootstrap.ts` L66)。 - `newConversationType`(L59):空对话待创建类型 `'agent'|'multi_agent'`,localStorage 持久化(key 见 state.ts 上方 `NEW_CONVERSATION_TYPE_STORAGE_KEY`),由 input composer 的 `agent-type-switcher` 修改。 - **创建对话按类型选 API**: - 首条消息创建:`static/src/app/methods/message/send.ts` L269:`const isMultiAgent = this.newConversationType === 'multi_agent'; const createUrl = isMultiAgent ? '/api/multiagent/conversations' : '/api/conversations';` - 侧边栏新建:`static/src/app/methods/conversation/action.ts` L134/L276:按 `useConversationStore().sidebarConversationType` 选同两个 URL。 - **输入栏类型选择器**:`components/input/InputComposer.vue` L328 `agent-type-switcher`(渲染 `newConversationType` 选项:智能体/多智能体)。 **工作流接入判断(关键)**:若工作流作为新对话类型:需在 `newConversationType`/`currentConversationType` 类型联合中增加 `'workflow'`;`send.ts L269` 与 `action.ts L134/276` 增加「工作流创建」的 URL 分支(如 `/api/workflow/conversations` 或复用 `/api/conversations`+`workflow_id` 参数);`InputComposer.vue` 的 agent-type-switcher 增加工作流选项。注意 types 是字符串字面量联合(L780 `newConversationType?: 'agent'|'multi_agent'`),需同步扩展 TS 类型与所有 switch 点。 ### 4.3 输入栏运行模式切换器 work-mode-switcher - **实现位置**:`static/src/components/input/InputComposer.vue` L354:`
`,渲染 `workModeOptions`,`@click` 开 `workModeMenuOpen` 菜单。 - **切换逻辑**:`static/src/app/methods/ui/workMode.ts`:`fetchWorkMode`(GET /api/work-mode,带 conversation_id)、`changeWorkMode`(POST /api/work-mode,409 空闲才可切)、`toggleWorkModeMenu`/`closeWorkModeMenu`。plan 联动更新前端 permissionMode/executionMode 显示。 - **后端 API**:`server/chat/permission.py` `GET/POST /api/work-mode`(L402/L418)。 **工作流接入判断**:若工作流作为「普通对话的一种运行方式」(而非新 URL),可在 work-mode-switcher 同区域加一个「工作流选择器」(选当前激活的工作流 / 另存为新工作流),方法放 `static/src/app/methods/ui/workflow.ts`(同构 workMode.ts),后端提供 `GET/POST /api/workflow` 子资源。 --- ## 5. 数据存储约定(工作流文件夹放哪) - **运行态数据根**:`config/paths.py`:`RUNTIME_ROOT = ~/.astrion/astrion`(L83-84,可 `ASTRION_DATA_ROOT` 覆盖);`_MODE = _runtime_mode()` 分流 host/web(`TERMINAL_SANDBOX_MODE` 决定)。各目录见 §1.5:`DATA_DIR/LOGS_DIR/USER_SPACE_DIR/API_USER_SPACE_DIR`(L102-106)。 - **CUSTOM_SKILLS_DIR**:`str(Path(RUNTIME_ROOT)/_MODE/"agentskills")`(L109)——私有 skill/工作流的运行态位置。host 模式 `IS_HOST_MODE`(L112)。 - **源码树 seed**:`AGENT_SKILLS_DIR`(默认 `./agentskills`,L163)、`PROMPTS_DIR`(`./prompts`,L162)、`AGENT_SKILLS_DIR` 默认源码树。 - **resolve_deploy_config 回退链**(L135):`/config/`(部署者真实配置)→ 源码树 `config/`(seed)→ 源码树 `config/.example`(示例兜底)。`deploy_config_path`(L126)用于可写配置(不回退)。 - **工作区级 .astrion**:`WORKSPACE_SKILLS_DIRNAME=".astrion/skills"`(L170)、`WORKSPACE_MEMORY_DIRNAME=".astrion/memory"`(L171)、`WORKSPACE_REVIEW_DIRNAME=".astrion/review"`(L172)。**注意:这是工作区项目内(源码树或其他工作目录)的 `.astrion`,与运行态 `~/.astrion/astrion/` 不同。** **工作流接入判断(关键决策点)**: - **源码树 vs 运行态**:skill 采用「源码树 seed(`agentskills/`)” + “运行态私有(`~/.astrion/astrion//agentskills/`,CUSTOM_SKILLS_DIR)双源」,通过 `get_skills_catalog(base_dir=AGENT_SKILLS_DIR, private_dir=CUSTOM_SKILLS_DIR)` 合并(skills_manager.py L282);启用后同步到工作区 `.astrion/skills/`(`sync_workspace_skills`)。 - 现有机制**同时支持**两种:工作流库若仿 skill,可在源码树 `workflows/`(seed)+ 运行态 `~/.astrion/astrion//workflows`(CUSTOM_SKILLS_DIR 同级)建库,再按启用/激活同步到工作区 `.astrion/workflows/`。**判断**:用户创建的工作流属「运行态/用户私有」,应落运行态(含脚本的可执行文件),源码树只放内置种子示例;这与 AGENTS.md §1.5「运行态数据不落源码树」一致。 - 部署级配置(如 `auto_approval`、`goal_review`)走 `resolve_deploy_config`;工作流若需独立审核配置可仿 `config/workflow_review.json[.example]` 加入该回退链。 --- ## 总结:新增工作流功能的最小改动路径建议(文件级) 基于上述调研,判断实现「工作流」的最小改动路径如下(按依赖顺序,每个文件给出改动性质): 1. **`config/paths.py`**(改动):新增 `CUSTOM_WORKFLOWS_DIR`(运行态,仿 `CUSTOM_SKILLS_DIR` L109)、`WORKFLOWS_DIR`(源码树 seed,仿 `AGENT_SKILLS_DIR` L163)、`WORKSPACE_WORKFLOWS_DIRNAME`(仿 L170 `.astrion/workflows`)三个路径常量。 2. **`modules/workflows_manager.py`**(新增):仿 `modules/skills_manager.py` 提供 `validate_workflow_directory` / `archive_workflow_directory` / `get_workflows_catalog` / `sync_workspace_workflows`,校验「工作方式→验证方式→结束方式」三段 + 附带 scripts。 3. **`core/main_terminal_parts/tools_definition/file_tools.py` + `tools_execution.py`**(改动):新增 `create_workflow` 工具定义(仿 create_skill L139)与 handler `_handle_create_workflow_tool`(仿 L545/530),在 `handle_tool_call` 分发链(L960 的 elif 分支)注册;归档复用 `modules/workflows_manager`。 4. **`prompts/workflow.txt`**(新增)+ **`core/main_terminal_parts/context/messages.py`**(改动):新增工作流上下文模板;在 `build_messages`(L109,skills 段 L305 附近)追加「当前激活工作流」的 system 上下文注入(复用 `load_prompt` + `_get_or_init_frozen_prompt` 冻结)。 5. **`server/workflow_flow.py`**(新增)+ **`server/chat_flow_task_main.py`**(改动):仿 `server/goal_flow.py` 编排「阶段/整体审核」。接入点:主循环 `if not tool_calls:` 结束判定(L2226)处,仿 goal 分支(L2230)增加工作流审核调用——复用 `modules/goal_review_agent.py`(或其派生 `WorkflowReviewAgent`)返回 done/continue;continue 注入续命 user 消息回写 messages(复用 `chat_flow_task_support.inject_runtime_user_message`)。**注意**:任何新增主任务入口必须遵守 §12 门闸(`process_message_task`)。 6. **`server/tasks/workflows.py`**(新增,可并入 skills.py)仿 `server/tasks/skills.py`:`GET /api/workflows`(列表/选择)+ 创建工作流对话的后端端点(如 `/api/workflow/conversations` 或复用 `/api/conversations`+`workflow_id`)。 7. **`static/src/app/methods/ui/route.ts`**(改动):`bootstrapRoute`(L26)增加 `/workflow/new`(及 `/workflow`)分支,进入「新建工作流对话」模式并 `history.replaceState`;避免被当作 conv id 解析。 8. **前端对话类型链路**(改动):`static/src/app/state.ts`(L57/59 类型联合加 `'workflow'`)、`static/src/app/methods/message/send.ts`(L269 createUrl 分支)、`static/src/app/methods/conversation/action.ts`(L134/276 分支)、`static/src/components/input/InputComposer.vue`(L328 agent-type-switcher / L354 work-mode-switcher 区域加「工作流选择器」)。若新增「选择/另存工作流」UI,仿 `static/src/app/methods/ui/workMode.ts` 建 `static/src/app/methods/ui/workflow.ts`。 > 附注 / 未确认项: > - `/workflow/new` 后端的 `with_terminal` 路由是否接受该路径、前端是否需新 socket/status 兼容——**未确认**,需在实现时验证。 > - 工作流「阶段结束审核后进入下一阶段」与 goal mode「目标完成后结束」的边界语义略有差异,需在 `workflow_flow.py` 内明确「阶段衔接」与「整体结束」的状态机,避免与 `chat_flow_task_main.py` 现有 break/continue 逻辑冲突。 > - work_mode 三档(plan/ask/execute)是「交互节奏」正交档位;工作流不应作为第四档 work_mode,而应作为独立的「消息级上下文 + 审核挂钩」,避免与现有 `_RUNTIME_MODE_KINDS` drift 通知机制冲突。