跳至內容

行動

操作是可訂閱狀態的唯一突變機制。它們形成一個以 type 為鍵的判別聯集。每個操作都包含在 ActionEnvelope 中,用於排序和起源追蹤。

行動信封

typescript
ActionEnvelope {
  channel: URI                                          // channel the action targets
  action: Action
  serverSeq: number                                     // monotonic, assigned by server
  origin: { clientId: string, clientSeq: number } | undefined  // undefined = server-originated
  rejectionReason?: string                              // present when the server rejected the action
}
  • channel — 此操作目標的通道 URI。路由是透過信封進行的,而不是透過內部操作上的欄位進行的。請參閱通道和訂閱
  • serverSeq — 由伺服器指派的單調遞增序號,用於排序和重播。
  • origin — 標識誰發起了此操作。 undefined 表示伺服器本身(例如來自代理後端)。否則標識調度它的用戶端。
  • rejectionReason — 如果存在,則表示伺服器拒絕了該操作。用戶端應該恢復其樂觀預測。包含人類可讀的解釋(例如 "no active turn to cancel""tool call not pending confirmation")。

各個操作有效負載攜帶自己的 session: URIterminal: URI 欄位 - 目標通道來自信封。

根操作

這些變異根狀態並在 根通道 上傳播。一個根運算 — root/configChanged — 是用戶端可調度的;其餘的都是源自伺服器。

型別用戶端-可調度?
root/agentsChanged沒有可用的代理後端或其模型已更改
root/activeSessionsChanged沒有活動工作階段的計數已更改
root/terminalsChanged沒有輕量級終端機目錄已更改(完全替換)
root/configChanged主機層級設定值已變更

工作階段和聊天操作

操作在以其前綴命名的通道上傳輸:工作階段通道 (ahp-session:/<uuid>) 上的 session/* 操作,以及 聊天通道 (ahp-chat:/<cid>) 上的 chat/* 操作。工作階段是聊天目錄;它的每次對話活動(回合、串流、工具呼叫、待處理訊息和輸入請求)存在於聊天通道中,而生命週期、元資料、工具註冊表和自訂操作則存在於工作階段通道中。某些操作僅是伺服器(由代理後端產生),其他操作是可調度的用戶端。

當用戶端分派操作時,伺服器將其應用於狀態並對其做出副作用(例如,chat/turnStarted 觸發代理處理,chat/turnCancelled 中止它)。這避免了針對常見互動情況的單獨命令→動作轉換層。

生命週期(工作階段通道)

型別用戶端-可調度?
session/ready沒有工作階段後端初始化成功
session/creationFailed沒有工作階段後端初始化失敗

Turn Lifecycle(聊天通道)

型別用戶端-可調度?
chat/turnStarted使用者傳送訊息;伺服器開始處理
chat/delta沒有partId
chat/responsePart沒有建立新的回應部分(降價、推理、內容引用、工具呼叫)
chat/reasoning沒有partId
chat/usage沒有活躍回合的代幣使用報告
chat/turnComplete沒有轉轉完畢(副怠速)
chat/turnCancelled回合被中止;伺服器停止處理
chat/error沒有回合處理時出錯
chat/truncated截斷歷史記錄(帶有可選的 turnId 截斷)

工具呼叫(聊天通道)

工具呼叫遵循判別聯集狀態機器 - 有關完整圖表,請參閱狀態模型 - 工具呼叫生命週期

型別用戶端-可調度?
chat/toolCallStart沒有建立工具呼叫;LM 開始傳輸參數
chat/toolCallDelta沒有附加串流部分參數
chat/toolCallReady沒有參數完整(或執行工具需要重新確認)
chat/toolCallConfirmed用戶端核准或拒絕待處理的工具呼叫
chat/toolCallComplete1工具執行完成
chat/toolCallResultConfirmed用戶端核准或拒絕待處理結果
chat/toolCallContentChanged1在工具執行時間串流中間內容
chat/toolCallAuthRequired沒有執行 MCP 貢獻的工具呼叫會暫停待處理的驗證
chat/toolCallAuthResolved沒有驗證已解決;工具呼叫恢復到 running

¹ 用戶端 - 僅可調度 用戶端 - 提供的工具(其中工具呼叫的 contributor.clientId 與調度用戶端相符)。對於伺服器端工具,只有伺服器會產生這些運算。

活動和元資料

型別用戶端-可調度?
session/titleChanged工作階段標題已更新(自動產生或用戶端重新命名)
session/activityChanged沒有伺服器更新了工作階段的目前活動描述
chat/activityChanged沒有伺服器更新了聊天的當前活動描述
session/changesetsChanged沒有主機為此工作階段通告的變更集目錄已更改(完全替換)
session/isReadChanged用戶端將工作階段標記為已讀或未讀
session/isArchivedChanged用戶端已存檔或未存檔工作階段
session/configChanged可變工作階段設定值已變更
session/metaChanged沒有工作階段的 _meta 側通道已被取代

伺服器和 Active-用戶端工具(工作階段通道)

型別用戶端-可調度?
session/serverToolsChanged沒有伺服器-提供的工具清單已更改(完全替換)
session/activeClientSet用戶端作為活動的用戶端(由 clientId 鍵入)加入或刷新,並具有其工具和自訂設定
session/activeClientRemovedA 用戶端離開活動集(由 clientId

請參閱自訂和用戶端工具 以了解完整流程。

待處理訊息(聊天通道)

型別用戶端-可調度?
chat/pendingMessageSet設定了轉向或排隊訊息(更新插入)
chat/pendingMessageRemoved待處理訊息已被取消(由用戶端)或已消耗(由伺服器)
chat/queuedMessagesReordered排隊的訊息已重新排序

pendingMessageSetpendingMessageRemoved 運算有 kind 判別式('steering''queued')。請參閱 狀態模型 — 待處理訊息 以了解語意。

輸入請求(聊天通道)

型別用戶端-可調度?
chat/inputRequested沒有伺服器請求使用者的結構化輸入(upsert)
chat/inputAnswerChanged用戶端更新了單一草稿/提交/跳過的答案
chat/inputCompleted用戶端接受、拒絕或取消輸入請求

請參閱Elicitation 以了解請求生命週期。

定制

型別用戶端-可調度?
session/customizationsChanged沒有伺服器取代了工作階段的頂級自訂清單(完全替換)
session/customizationToggled用戶端按 ID 開啟或關閉容器或子自訂
session/customizationUpdated沒有伺服器按 id 更新插入頂級容器(插件或目錄)(全條目替換,包括子項目)
session/customizationRemoved沒有伺服器刪除了按 id 進行的自訂(容器級聯到子級)

請參閱自訂指南 以了解完整流程。

終端機操作

終端機操作在相關的 終端機通道 上傳播。

型別用戶端-可調度?
terminal/data沒有pty 輸出流向用戶端(附加到尾部內容部分)
terminal/input鍵盤輸入轉送到 pty(僅副作用)
terminal/resized終端機尺寸已更改
terminal/claimed索賠已轉移 (用戶端 ↔ 工作階段)
terminal/titleChanged標題已更新
terminal/cwdChanged沒有工作目錄已更改
terminal/exited沒有行程已退出(退出代碼集)
terminal/cleared回溯/內容重設
terminal/commandDetectionAvailable沒有外殼整合載入;現在報告命令邊界
terminal/commandExecuted沒有指令已提交到 shell,正在執行
terminal/commandFinished沒有指令已完成執行(退出代碼、持續時間)

有關使用流程,請參閱終端指南

註解操作

註釋操作在工作階段的註釋通道 (ahp-session:/<uuid>/annotations) 上傳送。每個註釋操作都是用戶端可分派的 — 用戶端透過直接分派來建立、重新錨定、解析和刪除註釋及其條目(分配 Annotation.id / AnnotationEntry.id 本身並樂觀地應用它們),並且代理主機也可以發起它們。

型別用戶端-可調度?
annotations/set更新插入註釋 — 建立一個帶有強制第一個條目的註釋,或重新錨定/解析現有註釋
annotations/updated部分更新註解自己的屬性(解析/重新開啟、重新錨定),無需重新傳送其條目
annotations/removed刪除整個註釋(及其包含的每個條目)
annotations/entrySet在註釋中更新插入單一條目(新增或編輯)
annotations/entryRemoved刪除單一條目;分派 annotations/removed 而非刪除最後剩餘的條目

有關完整的狀態形狀,請參閱註釋通道參考

用戶端-分派操作

用戶端透過將操作視為即發即忘通知分派來與伺服器互動:

jsonc
// Client → Server
{
  "jsonrpc": "2.0",
  "method": "dispatchAction",
  "params": {
    "channel": "ahp-chat:/<cid>",
    "clientSeq": 1,
    "action": { "type": "chat/turnStarted", "turnId": "t1", ... }
  }
}

用戶端在發送之前樂觀地將操作應用到其本地狀態。當伺服器在 ActionEnvelope 中回顯時,用戶端會進行協調(請參閱預寫入協調)。

行動伺服器-副作用
chat/turnStarted開始新一輪的代理處理
chat/toolCallConfirmed核准或拒絕待處理的工具呼叫;解除封鎖或取消工具執行
chat/turnCancelled中止正在進行的回合
session/titleChanged更新工作階段標題(重新命名)
chat/pendingMessageSet儲存轉向或排隊訊息(upsert);如果排隊且空閒,則自動開始輪次
chat/pendingMessageRemoved在消費之前取消待處理的訊息
chat/queuedMessagesReordered重新排序排隊的訊息;未知 ID 被忽略,未提及的訊息保留在最後
session/customizationToggled按 id 開啟或關閉容器或子自訂
session/isReadChanged將工作階段標記為已讀或未讀
session/isArchivedChanged歸檔或取消歸檔工作階段

reducer

狀態由純粹 reducer 函式變異-每個帶有狀態的通道型別變異一個:

typescript
rootReducer(state: RootState, action: RootAction): RootState
sessionReducer(state: SessionState, action: SessionAction): SessionState
chatReducer(state: ChatState, action: ChatAction): ChatState
terminalReducer(state: TerminalState, action: TerminalAction): TerminalState

給定操作信封的 reducer 由 envelope.channel 的 URI 方案選取。reducer是純粹的——沒有副作用,沒有 I/O。相同的 reducer 程式碼在伺服器和用戶端上運行,這使得預寫成為可能。伺服器副作用(例如,將訊息轉送給代理程式 SDK)由單獨的調度層處理,而不是在 reducer 中處理。

操作 type 上的 reducer switch 非常詳盡 - 如果缺少大小寫,編譯器會出錯。這保證了每個操作型別都得到處理。

後續步驟

以 MIT 授權發布。