v1.3.11

Execution Engine

最後更新


所有綁定 session 的進入點(TUI —— v1.2.0 起不再自行執行,改經 Unix socket 交由 daemon 執行 ——、/v1/send、pending 續行、Telegram、Discord)走同一套啟動流程:exec.Prepare 從輸入比對 skill,接著 exec.Run 解析呼叫端指名的 skill、發出 skill 與模型選擇事件、透過 exec/model.Route 挑選模型與 fallback,再交給 exec.Execute()。Subagent 與 scheduler 以 isSub=true 直接呼叫 exec.Run,略過 exec.Prepare;無狀態的 /v1/chat/completions 兩者皆略過,直接呼叫 exec.Execute()。exec.Start 於 v1.2.1 改名為 exec.Run,ResolveAgent 也在同一版改為 exec/model.Route。自 v1.1.0 起 reasoning 為 per-session 設定:設為 auto(或未設定)時,exec/model.Route 內的 selector 會依工作類型一併決定 reasoning 等級,全域的 auto_reasoning 開關已移除。自動路由永不選用 pass tier 模型 —— 即使訊息直接點名也一樣 —— 且這類模型不列入 fallback 清單;只有綁定該模型的 session,或呼叫端以明確的 model 指定時才會使用它。
exec.Execute() 執行主迴圈,最多 256 次迭代(limits.max_tool_iterations;v1.1.2 前為 128)。每次迭代:
  1. 組裝 messages:SystemPrompts + ContextHistories(排除 guardrail 拒絕)+ turn context(若有)+ UserMessage + ToolHistories(ContextHistories 與 UserMessage 在 v1.2.1 前為 OldHistories 與 UserInput) —— 依此順序 append,執行中途不改寫,讓 prompt cache 的前綴保持穩定。v1.3.7 起已連線 MCP server 提供的 instructions 改為渲染在主 system prompt 內、guardrail 區塊之前,不再另外作為第二則 system message 送出,system prompt 範本也一律改為英文。v1.2.0 起 turn context 為 assignTurnContext 每輪產生的一則 user 訊息:工作目錄(無狀態的 /v1/chat/completions 執行不帶)、須經 run_tool 呼叫的工具名稱(v1.3.7 起 MCP 工具依 server 分組寫成 mcp__<server>__{a, b})、skill 清單(run_skill 被排除時不帶)、同一個任務仍在執行中的背景任務(v1.3.7 起,讓接回的 turn 知道哪些結果還在路上)、以 Prior summary JSON 區塊呈現的滾動式 summary(v1.3.7 起;先前是夾在歷史與 turn context 之間的獨立訊息),以及 guide 開關開啟時的 CLAUDE.md / AGENTS.md;這些先前放在 system prompt,每變一次就讓快取重置。permission mode 已不再寫進 turn context 或 system prompt(移除於 v1.3.7)。v1.3.7 起 summary 的 key_decisions、past_discussions 與 current_discussion 條目會先由 decision model 篩到只剩與這次請求相關者——沒有 decision model 或呼叫失敗時全部保留,沒有任何相關條目則不放 summary——其使用規則則寫在 system prompt。v1.3.1 起若設定了 decision model,迴圈開始前還會與上述篩選並行跑兩項判斷:需求所需的能力沒有任何現有工具提供時,加入一行工具缺口提示,要求模型先呼叫 reasoning_guide(topics=["tool_generate"])(reasoning_guide 或 edit_tool 被排除時不判斷);另一項把判定與需求無關的 skill 從清單移除(判斷失敗則保留全部 skill)
  2. 對所選 provider 呼叫 Agent.Send()
  3. 從 response 解析 tool_calls
  4. 透過 toolCall.go 分派 tool call(見工具調度)
  5. 將結果 append 至 ToolHistories;工具回傳的圖片接在該輪結果之後,以一則 user 訊息 append(v1.1.1 起 —— 先前是注入 UserInput,會改寫已快取的前綴)
  6. 當無 tool_calls 剩餘或撞到迭代上限時停止

v1.3.0 起 TUI 執行可把工作留在背景,v1.3.2 起經由 background_command 與 background_subagents;請求不是來自 TUI(cli- 來源且無 deliver 目標)時,兩者都會從該次執行中排除。run_command_background 更名為 background_command(移除於 v1.3.2);run_websocket 與 subagents 的 background: true 模式已移除(移除於 v1.3.2),請改用 background_command 與 background_subagents。v1.3.8 起即使背景工作仍在跑,任務也照常結束:任務執行中或 pending 時報告會送進該任務;任務結束後,整組完成的背景工作以其 objective 與 next 另開新任務;任務為背景工作維持 pending 的行為移除於 v1.3.8——見待決任務與取消。
每次 Send 會在 SQLite usage 表寫入一列(模型、input / output / cache-write / cache-hit tokens、耗時);自 v1.0.26 起該列另記錄此回應要求的 tool call ID。自 v1.1.0 起完成事件不再附帶 provider 剩餘額度,改由 GET /v1/providers/quota 依需求提供。
無 inter-round delay — rate-limit 保護來自 provider round-trip 延遲、per-model cooldown 以及各 tool 的 timeout。

跨 turn workdir 重置


Workdir 由每次請求提供,而非從歷史沿用:TUI 傳入自身的工作目錄、/v1/send 解析 work_dir 欄位、subagent 沿用或自行解析。v1.2.0 起每次執行都把它寫進 turn context 而非 system prompt,因此切換目錄不會讓已快取的 system 前綴失效;先前 turn 提過的目錄不會經由歷史沿用。
  • Turn context — Work directory: ... 行,說明該目錄為本輪權威基準、忽略歷史中較早的目錄,且 run_command 已從該目錄開始。無狀態的 /v1/chat/completions 執行則仍將此行放在其自有的 system prompt
  • TUI — 由使用者以 Shift+P 設定目錄(絕對路徑、~/... 或相對於目前目錄的路徑,且必須存在),之後每次請求都帶入。移除於 v1.3.0:agent 透過 run_command 執行 cd,以及把新目錄推回 TUI 的 workdir frame;run_command 現在會拒絕 cd,改提示使用絕對路徑,或單次指令用 ['sh','-c','cd <dir> && <command>']

逐則訊息的 metadata header(包在每則 user message 外的時間戳與工作目錄)及其 TUI 剝除函式 stripUserMetaHeader 已移除;turn context 的工作目錄行是唯一的 workdir 錨點。
EN