- 首頁
- Documentation
- 工作階段
- 非壓縮自動重試策略
非壓縮自動重試策略
本文件描述 AgentSession 中標準的 API 錯誤重試路徑。
本文件明確排除透過自動壓縮進行的上下文溢位恢復。溢位由壓縮邏輯處理,並另行記載於 compaction.md。
../src/session/agent-session.ts../src/config/settings-schema.ts../src/modes/controllers/event-controller.ts../src/modes/rpc/rpc-mode.ts../src/modes/rpc/rpc-client.ts../src/modes/rpc/rpc-types.ts
範圍界限與壓縮的關係
Section titled “範圍界限與壓縮的關係”重試與壓縮從相同的 agent_end 路徑進行檢查,但它們被刻意分離:
agent_end檢查最後一則助理訊息。#isRetryableError(...)首先執行。- 如果啟動重試,該回合會跳過壓縮檢查。
- 上下文溢位錯誤被硬性排除在重試分類之外(
isContextOverflow(...)會短路重試)。 - 因此溢位會落入
#checkCompaction(...)而非標準重試。
所以:過載/速率限制/伺服器/網路類型的失敗使用此重試策略;上下文視窗溢位則使用壓縮恢復。
#isRetryableError(...) 需要同時滿足以下所有條件:
- 助理的
stopReason === "error" errorMessage存在- 訊息不是上下文溢位
errorMessage匹配#isRetryableErrorMessage(...)
目前可重試的模式集合(基於正規表達式):
- overloaded
- rate limit / usage limit / too many requests
- 類 HTTP 伺服器狀態碼:429、500、502、503、504
- service unavailable / server error / internal error
- connection error / fetch failed
retry delay相關措辭
這是字串模式分類,而非型別化的提供者錯誤碼。
重試生命週期與狀態轉換
Section titled “重試生命週期與狀態轉換”重試使用的工作階段狀態:
#retryAttempt: number(0表示閒置)#retryPromise: Promise<void> | undefined(追蹤進行中的重試生命週期)#retryResolve: (() => void) | undefined(解決#retryPromise)#retryAbortController: AbortController | undefined(取消退避等待)
流程(#handleRetryableError):
- 讀取
retry設定群組。 - 如果
retry.enabled === false,立即停止(false,不啟動重試)。 - 遞增
#retryAttempt。 - 首次嘗試時建立
#retryPromise(鏈中的第一次嘗試)。 - 如果嘗試次數超過
retry.maxRetries,發出最終失敗事件並停止。 - 計算延遲:
retry.baseDelayMs * 2^(attempt-1)。 - 對於用量限制錯誤,解析重試提示並呼叫認證儲存(
markUsageLimitReached(...));如果提供者/模型切換成功,將延遲強制設為0。 - 發出
auto_retry_start。 - 從代理執行時狀態中移除尾端的助理錯誤訊息(保留在持久化的工作階段歷史中)。
- 以支援中止的方式進入等待。
- 喚醒後,透過
setTimeout(..., 0)排程agent.continue()。
什麼會重設重試計數器
Section titled “什麼會重設重試計數器”#retryAttempt 在以下情況重設為 0:
- 重試開始後首次成功的非錯誤、非中止助理訊息(發出
auto_retry_end { success: true }) - 退避等待期間的重試取消
- 最大重試次數已超過的路徑
#retryPromise 在重試鏈結束時(成功、取消或超過最大次數)透過 #resolveRetry() 解決/清除。
退避與最大嘗試次數語義
Section titled “退避與最大嘗試次數語義”設定:
retry.enabled(預設true)retry.maxRetries(預設3)retry.baseDelayMs(預設2000)
嘗試次數編號:
- 嘗試計數器在最大值檢查之前遞增
- 開始事件使用目前的嘗試次數(從 1 開始)
- 超過最大次數的結束事件回報
attempt: this.#retryAttempt - 1(最後嘗試的重試次數)
使用預設設定的退避序列:
- 第 1 次嘗試:2000 毫秒
- 第 2 次嘗試:4000 毫秒
- 第 3 次嘗試:8000 毫秒
延遲覆寫輸入僅用於用量限制處理路徑,且僅用於影響認證儲存的模型/帳戶切換決策。在主要的非壓縮重試路徑中,退避保持本地指數延遲,除非切換成功(delayMs = 0)。
明確的重試中止
Section titled “明確的重試中止”abortRetry():
- 中止
#retryAbortController(如果存在) - 解決重試 Promise(
#resolveRetry()),使等待者不被阻塞
如果中止發生在等待期間,捕獲路徑會發出:
auto_retry_end { success: false, finalError: "Retry cancelled" }- 重設嘗試次數/控制器
全域操作中止交互
Section titled “全域操作中止交互”abort() 在中止活動的代理串流之前呼叫 abortRetry()。這確保當使用者發出一般性中止時,重試退避會被取消。
TUI 交互
Section titled “TUI 交互”收到 auto_retry_start 時,EventController:
- 將
Esc處理器切換為session.abortRetry() - 呈現載入文字:
Retrying (attempt/maxAttempts) in Ns… (esc to cancel)
收到 auto_retry_end 時,恢復先前的 Esc 處理器並清除載入狀態。
串流與提示完成行為
Section titled “串流與提示完成行為”prompt() 最終在 agent.prompt(...) 回傳後等待 #waitForRetry()。
效果:
- 一次提示呼叫在任何已啟動的重試鏈完成(成功/失敗/取消)之前不會完全解決
- 重試生命週期是一次邏輯提示執行邊界的一部分
這防止呼叫者過早將正在重試的回合視為已完成。
控制:設定與 RPC
Section titled “控制:設定與 RPC”定義在設定結構描述的 retry 群組下:
retry.enabledretry.maxRetriesretry.baseDelayMs
工作階段中的程式化切換:
setAutoRetryEnabled(enabled)寫入retry.enabledautoRetryEnabled讀取retry.enabledisRetrying回報重試生命週期 Promise 是否活動中
RPC 控制
Section titled “RPC 控制”RPC 命令介面:
set_auto_retry→session.setAutoRetryEnabled(command.enabled)abort_retry→session.abortRetry()
客戶端輔助方法:
RpcClient.setAutoRetry(enabled)RpcClient.abortRetry()
兩個命令都回傳成功回應;重試進度/失敗詳情來自串流的工作階段事件,而非命令回應的酬載。
事件發出與失敗呈現
Section titled “事件發出與失敗呈現”工作階段層級的重試事件:
auto_retry_start { attempt, maxAttempts, delayMs, errorMessage }auto_retry_end { success, attempt, finalError? }
傳播:
- 透過
AgentSession.subscribe(...)發出 - 以擴充功能事件的形式轉發至擴充功能執行器
- 在 RPC 模式中,直接以 JSON 事件物件轉發(
session.subscribe(event => output(event))) - 在 TUI 中,由
EventController消費以呈現載入/錯誤 UI
最終失敗呈現:
- 超過最大次數或取消時,
auto_retry_end.success === false - TUI 顯示:
Retry failed after N attempts: <finalError> - 擴充功能/鉤子收到具有相同欄位的
auto_retry_end - RPC 消費者在 stdout 串流上收到相同的事件物件
永久停止條件
Section titled “永久停止條件”當發生以下任何情況時,重試會停止且不會自動繼續:
retry.enabled為 false- 錯誤未被分類為可重試
- 錯誤為上下文溢位(委派至壓縮路徑)
- 超過最大重試次數
- 使用者取消重試(重試載入器期間使用
abort_retry或Esc) - 全域中止(
abort)會先取消重試
在計數器重設後,未來遇到可重試錯誤時仍可啟動新的重試鏈。
操作注意事項
Section titled “操作注意事項”- 分類是正規表達式文字匹配;此處未使用提供者特定的結構化錯誤。
- 重試在重新繼續前會從執行時上下文中移除失敗的助理錯誤,但工作階段歷史仍保留該錯誤條目。
RpcSessionState目前公開autoCompactionEnabled但未公開autoRetryEnabled欄位;RPC 呼叫者必須自行追蹤切換狀態,或透過其他 API 查詢設定。