# 原生 Claude-Code 模式设计(workspace.assistant 专用) 状态:设计 → 实现中 日期:2026-06-15 关联记忆:claude-code 大会话 resume 卡死、MCP 隔离、文件工具 CWD、目录守卫、401。 ## 1. 动机(一句话) `workspace.assistant`(选文件夹自由对话)现在被套进 **react-over-text** 封装: `claude -p --tools ""` 把 claude-code 阉割成纯文本生成器,平台再用正则从文本里抠 `{"tool":...}` 自己执行、自己管 session。实测这套**不如直接调一次 claude-code**: - 工具调用是模型当散文手写的 JSON → 格式飘(`input` 裸串/`path` vs `file_path`)→ 平台解析失败 → **76 个调用 0 执行 0 落盘**(run_541390a1ea49)。 - 我们自己的 session 轮换/熔断在 API 高延迟下疯狂触发(40 分钟 14 个 session)→ 每次重注入只带原始任务、丢掉已读内容 → agent 永远从零开始、空转到步数耗尽。 - claude-code 的强项(结构化 tool_use、上下文管理、文件编辑、持久会话)**全被关掉**。 **根因:用错模具。** react-over-text 是为**多智能体编排**(orchestrator 必须把活 派给子智能体,故必须禁 native 工具防它自己偷干——run_4e07736d7f60 伪造数据教训) 设计的。但 `workspace.assistant` 是**单体 do-everything** 助手,不是 orchestrator, 套进去只有成本没有收益。 ## 2. 目标 为「工作区对话型」agent 开**第二条执行车道**:让 claude-code **当 agent 本身**—— 在所选文件夹里用 native 工具干活,平台只负责选目录、起进程、流式透传、沙箱与落盘。 **orchestrator / 科研评审 / pipeline 保持现有 react 车道不变。** ## 3. 架构:两条执行车道 ``` run_agent(_stream) ├─ agent_template ∈ {workspace.assistant} 且 inplace_dir 有效 │ → 车道 B:原生 claude-code(本设计) └─ 否则 → 车道 A:现有 react-over-text(不动) ``` 判定点已就绪:`_require_workspace_dir`(强制绑文件夹)+ `inplace_dir`(=所选文件夹)。 新增布尔 `native_workspace`,在 `_execute_agent` 内分流。 ## 4. 原生 runner 规格(新文件 `providers/claude_code_native.py`) `run_native(prompt, *, cwd, model, system_append, session_id, on_event, config) -> NativeResult` ### 4.1 命令 ``` claude -p --output-format stream-json --verbose # 实时事件流 --model --append-system-prompt <平台 system 片段> # 注入工作目录纪律/安全铁律 --add-dir # 文件操作限定在该文件夹 --strict-mcp-config # 隔离用户 MCP(默认;可配开) --permission-mode bypassPermissions # -p 非交互必须,否则工具会卡在审批 [--resume ] # 多轮续接(同一 thread) (cwd = 工作文件夹) ``` - **native 工具开**:不传 `--tools ""`。用 `--allowedTools` 白名单: `Read Write Edit Bash Glob Grep NotebookEdit TodoWrite`(按需加 WebSearch/WebFetch)。 - **不再有** `--tools ""`、react JSON 协议、ConversationLam、session 轮换/熔断、 `file_tools._resolve`。claude-code 用它自己的 native 工具,cwd 已是工作文件夹。 ### 4.2 流式事件解析(stream-json 每行一个 JSON) | claude stream-json 事件 | 平台 on_event(沿用现有 SSE 类型,前端零改动) | |---|---| | `system/init` | 记录 `session_id` | | `assistant` content `text` | `think_chunk`(增量思考) | | `assistant` content `tool_use` | `tool_call`(name + input) | | `user` content `tool_result` | `tool_result`(output) | | `result/success` | `answer` + `done`(result 文本、usage、cost、session_id) | | `result` `is_error`/401 | 走 `_is_auth_error` → `_AUTH_HINT`;其余 → 失败 | ### 4.3 返回 / 落盘 `NativeResult` → 现有 `trace_info` 结构:`input_tokens/output_tokens/cost_usd/ cache_*_tokens/steps/trace_json/workspace_path/session_id`。直接喂回 run 记录, 前端 trace/cost 面板不变。 ### 4.4 多轮(thread)会话续接 claude-code 自管上下文,**无需我们轮换**。需要把上一轮 `session_id` 持久化、下一轮 `--resume`。MVP:sidecar 文件 `/.native_sessions.json` `{thread_id: session_id}`(不污染用户文件夹、不动 DB schema)。resume 失败(session 丢失)→ 退化成新 first-turn(claude 自己重建上下文)。 ### 4.5 超时/容错 - 首字节超时(沿用 60s 思路)+ 硬超时(config.timeout)。 - 401 → `_AUTH_HINT`(已实现,复用)。 - 卡死直接失败(不再轮换;native 单进程长跑由 claude-code 自己管上下文,不会像 resume 那样越长越卡)。 ## 5. 沙箱与安全 - **文件**:`cwd=工作文件夹` + 仅 `--add-dir `(不加别的目录)→ claude-code 的 Read/Write/Edit 限定在该文件夹。 - **Bash**:native Bash 不经平台 guard。MVP 接受此权衡(cwd 限定 + `bypassPermissions`), 与现状(react 车道 Bash 也只靠 CWD)一致。**P1 硬化**:claude-code settings `permissions.deny` 或 PreToolUse hook 拦危险命令/越界写(留迭代)。 - **MCP**:默认 `--strict-mcp-config` 隔离(避免 Gmail/Calendar 干扰); `config.extra["native_allow_mcp"]=true` 可放开。 ## 6. 保留 / 丢弃(仅车道 B) | 丢弃 | 保留/复用 | |---|---| | `--tools ""`、react JSON 协议 | `--strict-mcp-config`(MCP 隔离) | | ConversationLam / compiler react loop | `_is_auth_error` / `_AUTH_HINT`(401) | | session 轮换 / 连卡熔断 | `_require_workspace_dir`(强制绑目录) | | `file_tools._resolve` / 平台文件工具 | on_step→SSE 事件管道(前端不变) | | obs 截断、max_input_chars | run 记录 / trace_info / cost 落盘 | ## 7. 向后兼容 - 仅 `agent_template ∈ {workspace.assistant}` 走车道 B;其余 agent **零影响**。 - 可加 `config.extra["execution_mode"]="react"` 强制退回车道 A(兜底开关)。 - workspace.assistant.yml 标注 `executionMode: native`(声明意图,便于排查)。 ## 8. 测试 - `TestNativeStreamParse`:喂一段录制的 stream-json,断言事件映射正确、result/usage 抽取对。 - `TestNativeAuthError`:result is_error 401 → 抛 `_AUTH_HINT`。 - `TestNativeRouting`:workspace.assistant + 有效 dir → native 分支;其他模板 → react。 - live(skip 默认):真起一次 `claude -p` 在临时目录写一个文件,验证落盘。 ## 9. 开放决策(已选默认,可改) 1. **权限模式**:`bypassPermissions`(-p 必须非交互)— 选定。 2. **MCP**:默认隔离 — 选定。 3. **工具白名单**:`Read Write Edit Bash Glob Grep NotebookEdit TodoWrite` — 选定,可配。 4. **session 持久化**:sidecar JSON(MVP)→ 后续可升 DB 列。 ## 10. 实施顺序 P0(本次):native runner + stream 解析 + agents.py 分流 + 单测 + workspace.yml 标注。 P1(后续):Bash 硬沙箱(deny/hook)、session 持久化升 DB、native_allow_mcp 配置面。