@openclaw/copilot 外掛會透過 GitHub Copilot 命令列介面(@github/copilot-sdk)執行內嵌訂閱 Copilot
代理程式輪次,而不是使用 OpenClaw 的內建控管機制。Copilot 命令列介面工作階段負責底層
代理程式迴圈:原生工具執行、原生壓縮(infiniteSessions),以及
位於 copilotHome 下、由命令列介面管理的執行緒狀態。OpenClaw 仍負責聊天
頻道、工作階段檔案、模型選擇、動態工具(透過橋接)、核准、
媒體傳遞、可見的文字記錄鏡像、/btw 附帶問題(請參閱
附帶問題(/btw)),以及 openclaw doctor。
若要瞭解更廣泛的模型/供應商/執行階段劃分,請先參閱
代理程式執行階段。
需求
- 已安裝
@openclaw/copilot外掛的 OpenClaw。 - 如果你的設定使用
plugins.allow,請包含copilot(外掛所宣告的資訊清單 ID)。 npm 套件名稱@openclaw/copilot的允許清單項目不會相符,即使已設定agentRuntime.id: "copilot",外掛仍會遭到封鎖。 - 可驅動 Copilot 命令列介面的 GitHub Copilot 訂閱,或供無介面或排程執行使用的
gitHubToken環境變數/驗證設定檔項目。 - 可寫入的
copilotHome目錄。當 OpenClaw 提供代理程式目錄時, 預設為<agentDir>/copilot,否則為~/.openclaw/agents/<agentId>/copilot。
openclaw doctor 會針對工作階段狀態擁有權及未來設定遷移,執行外掛的
doctor 合約。它不會探測 Copilot 命令列介面環境。
安裝
Copilot 執行階段以外部外掛形式提供,因此核心openclaw
套件不會攜帶 @github/copilot-sdk 或其平台專用的
@github/copilot-<platform>-<arch> 命令列介面二進位檔(合計約 260 MB)。
僅針對選擇使用此執行階段的代理程式安裝:
github-copilot/* 模型,且設定透過
agentRuntime: { id: "copilot" } 將該模型(或其供應商)路由至 Copilot 執行階段時,設定精靈會自動安裝此外掛;請參閱
快速入門。若未選擇使用,OpenClaw 會使用其內建的
GitHub Copilot 供應商,且絕不會安裝此外掛。
執行階段會依下列順序解析 SDK:
- 來自已安裝
@openclaw/copilot套件的import("@github/copilot-sdk")。 - 備用目錄
~/.openclaw/npm-runtime/copilot/(舊版隨需安裝 目標)。
COPILOT_SDK_MISSING,並附上
上述重新安裝命令。
快速入門
將一個模型(或一個供應商)固定至控管機制:agentRuntime.id,即可僅透過
此控管機制路由該模型;或在供應商上設定,以路由該供應商下的每個模型。
github-copilot/auto 是可攜式起點。具名 Copilot 模型會因
帳戶及組織政策而異;固定模型前,請確認已驗證的
Copilot 命令列介面確實公開該模型。
支援的供應商
此控管機制支援標準github-copilot 供應商(由
extensions/github-copilot 擁有),也支援自訂 models.providers 項目,前提是
模型具有非空白的 baseUrl,且使用下列其中一種 api 格式:
anthropic-messagesazure-openai-responsesollama(OpenAI 相容的補全)openai-completionsopenai-responses
openai、anthropic、google、ollama)仍由
其原生執行階段擁有。若要透過 Copilot BYOK 路由端點,請改用不同的自訂供應商 ID。
Copilot BYOK 端點必須是公開的 HTTPS URL。此控管機制會為每次嘗試向
Copilot SDK 提供一個回送代理伺服器,接著透過 OpenClaw 的受保護擷取路徑轉送供應商流量,
使 DNS 固定及 SSRF 政策仍由 OpenClaw 負責。若使用本機 Ollama、LM
Studio 或區域網路模型伺服器,請使用原生 OpenClaw 執行階段。
BYOK
Copilot BYOK 使用 SDK 的工作階段層級自訂供應商合約。OpenClaw 會傳遞已解析的模型端點、API 金鑰、持有人權杖模式、標頭、模型 ID,以及內容/輸出限制;供應商傳輸邏輯保留在 SDK 中,而非核心。驗證
在runCopilotAttempt 期間,依各代理程式套用以下優先順序:
-
嘗試輸入上的明確
useLoggedInUser: true— 使用代理程式copilotHome下 Copilot 命令列介面的已登入使用者。 -
嘗試輸入上的明確
gitHubToken(需要profileId+profileVersion)。供需要略過驗證設定檔解析的直接命令列介面叫用及測試使用。 -
由合約解析的
resolvedApiKey+authProfileId— 正式環境的 主要路徑。核心會在叫用控管機制前解析代理程式已設定的github-copilot驗證 設定檔(src/infra/provider-usage.auth.ts:resolveProviderAuths),因此github-copilot:<profile>驗證設定檔可在 無介面、排程或多設定檔環境中端對端運作,無需環境變數。 -
環境變數備援,依此順序檢查(第一個非空白值優先,
空字串視為不存在;比照
extensions/github-copilot/auth.ts中已發行的github-copilot供應商優先順序):OPENCLAW_GITHUB_TOKEN— 控管機制專用覆寫;可為 OpenClaw 控管機制固定 權杖,而不影響系統層級的gh/ Copilot 命令列介面設定。COPILOT_GITHUB_TOKEN— 標準 Copilot SDK/命令列介面環境變數。GH_TOKEN— 標準gh命令列介面環境變數。GITHUB_TOKEN— 通用 GitHub 權杖備援。
env:<NAME>;設定檔版本是權杖的 不可逆 sha256 指紋,因此輪替環境變數值時, 會完整清除用戶端集區。 -
沒有可用的權杖訊號時,使用預設
useLoggedInUser。
copilotHome,因此同一台機器上的代理程式之間
絕不會洩漏 Copilot 命令列介面權杖、工作階段和設定。預設值:
<agentDir>/copilot(使 SDK 狀態不會與 OpenClaw 的
models.json/auth-profiles.json 位於同一目錄),若未提供代理程式目錄,
則為 ~/.openclaw/agents/<agentId>/copilot。
若要使用自訂位置(例如供遷移使用的共用掛載點),請在嘗試輸入上以
copilotHome: <path> 覆寫。
即時控管機制測試使用 OPENCLAW_COPILOT_AGENT_LIVE_TOKEN 傳入直接
權杖。共用即時測試設定會在將實際驗證設定檔暫存至隔離測試
主目錄後,清除 COPILOT_GITHUB_TOKEN、GH_TOKEN
和 GITHUB_TOKEN,因此透過專用變數傳入 gh auth token 值可避免
錯誤略過,同時不會洩漏至無關的測試套件。
設定介面
此控管機制會從每次嘗試輸入(runCopilotAttempt({...}))
以及 extensions/copilot/src/ 內的一小組環境預設值讀取設定:
OpenClaw 外掛掛鉤不需要 Copilot 專用的嘗試設定。此
控管機制會透過標準控管機制輔助程式執行
before_prompt_build、llm_input、llm_output 和 agent_end。
成功的 SDK 壓縮也會執行
before_compaction 和 after_compaction。橋接的 OpenClaw 工具會執行
before_tool_call 並回報 after_tool_call;hooksConfig 仍用於
沒有可攜式對應項目的原生 SDK 專用回呼。
OpenClaw 中的其他部分不需要知道這些欄位。其他外掛、
頻道及核心程式碼只會看到標準 AgentHarnessAttemptParams/
AgentHarnessAttemptResult 格式。
壓縮
當harness.compact 執行時,Copilot SDK 控管機制會:
- 恢復追蹤中的 SDK 工作階段,但不繼續處理待執行工作。
- 呼叫 SDK 的工作階段範圍歷程記錄壓縮 RPC。
- 傳回 SDK 壓縮結果,而不在工作區下寫入相容性標記 檔案。
文字記錄鏡像
runCopilotAttempt 會將每一輪可鏡像的訊息雙重寫入
OpenClaw 稽核逐字稿,並透過
extensions/copilot/src/dual-write-transcripts.ts 執行。鏡像以工作階段
(copilot:${sessionId})為範圍,並以每則訊息
(${role}:${sha256_16(role,content)})為鍵,因此重新發出的先前輪次項目
會與磁碟上現有的鍵衝突,而不會重複建立。
鏡像外圍有兩層故障隔離,因此逐字稿寫入
失敗絕不會導致該次嘗試失敗:內部的盡力而為包裝器,以及
嘗試層級的縱深防禦 .catch(...)。失敗會記錄至日誌,而不會
向外呈現。
附帶問題(/btw)
/btw 在此執行框架上不是原生功能。createCopilotAgentHarness()
刻意讓 harness.runSideQuestion 保持未定義
(於 extensions/copilot/harness.test.ts、describe("runSideQuestion") 中斷言),
因此 OpenClaw 的 /btw 分派器(src/agents/btw.ts)會轉而使用
每個非 Codex 執行階段所採用的相同路徑:直接呼叫已設定的模型供應商,
並提供簡短的附帶問題提示,再透過
streamSimple 串流傳回(無命令列介面工作階段,也不占用額外的集區插槽)。
如此可將 Copilot CLI 工作階段保留給代理程式的主要輪次迴圈,並使
/btw 的行為與其他非 Codex 執行階段一致。
Doctor
extensions/copilot/doctor-contract-api.ts 由
src/plugins/doctor-contract-registry.ts 自動載入。它提供:
- 空的
legacyConfigRules(目前尚無已淘汰欄位)。 - 不執行任何操作的
normalizeCompatibilityConfig(予以保留,讓未來淘汰欄位時 在原始碼樹中有穩定的歸屬位置)。 - 一個
sessionRouteStateOwners項目:供應商github-copilot、執行階段copilot、命令列介面工作階段鍵copilot、驗證設定檔前綴github-copilot:。
限制
- 此執行框架會宣告
github-copilot,以及沒有擁有者的自訂 BYOK 供應商 ID。 由資訊清單擁有的原生供應商 ID 仍會留在其所屬的執行階段,即使agentRuntime.id被強制設為copilot亦然。 - 沒有終端介面介面;對於沒有對等介面的執行階段,PI 的終端介面仍是備援方案。
- 當代理程式切換至
copilot時,不會遷移 PI 工作階段狀態。 每次嘗試都會個別選擇;現有 PI 工作階段仍然有效。 ask_user使用不綁定供應商的閘道問題執行階段。Control UI 會顯示與其他 OpenClaw 問題相同的問題卡片,支援的 頻道會呈現選項按鈕,而下一則排入佇列的純文字訊息 會在 SDK 要求傳回前解析該閘道記錄。
權限與 ask_user
橋接式 OpenClaw 工具的權限強制執行發生在工具 包裝器內部,而非透過 SDK 的onPermissionRequest 回呼。PI 使用的同一個
wrapToolWithBeforeToolCallHook
(src/agents/agent-tools.before-tool-call.ts)會由
createOpenClawCodingTools 套用至每個程式設計工具:迴圈偵測、受信任的
外掛政策、工具呼叫前掛鉤,以及透過
閘道(plugin.approval.request)進行的兩階段外掛核准,全都會經過與原生 PI 嘗試
完全相同的程式碼路徑。
Copilot 工具橋接器傳回的每個 SDK 工具都會標記:
overridesBuiltInTool: true— 取代 Copilot CLI 中同名的內建工具 (edit、read、write、bash,……),使每次工具呼叫都會路由回 OpenClaw。skipPermission: true— 指示 SDK 不要在叫用工具前觸發onPermissionRequest({kind: "custom-tool"})。 包裝後的execute()已執行更完整的 OpenClaw 政策檢查;SDK 層級的提示不是會略過 OpenClaw 的強制執行 (全部允許),就是會封鎖每次工具呼叫(全部拒絕)— 兩者都不符合 PI 的同等行為。
extensions/codex/src/app-server/dynamic-tools.ts),而
codex-app-server 本身的原生核准種類
(item/commandExecution/requestApproval、item/fileChange/requestApproval、
item/permissions/requestApproval)會透過 plugin.approval.request
(extensions/codex/src/app-server/approval-bridge.ts)進行路由。Copilot SDK
中的對應機制 — 對任何實際傳至 onPermissionRequest 的非 custom-tool 種類
採取失敗時關閉的 rejectAllPolicy — 是相同的安全網,而且實務上
永遠不會觸發,因為 overridesBuiltInTool: true 會取代每個
內建工具。
為了讓包裝工具層能做出與 PI 等效的政策決策,
執行框架會將完整的 PI 嘗試工具情境轉送至
createOpenClawCodingTools:身分(senderIsOwner、memberRoleIds、
ownerOnlyToolAllowlist,……)、頻道/路由(groupId、
currentChannelId、replyToMode、訊息工具切換項目)、驗證
(authProfileStore)、執行身分(衍生自
sandboxSessionKey、runId 的 sessionKey/runSessionKey)、
模型情境(modelApi、
modelContextWindowTokens、modelCompat、modelHasVision),以及執行掛鉤
(onToolOutcome、onYield)。缺少這些欄位時,僅限擁有者的允許清單
預設會無聲拒絕,外掛信任政策無法解析至正確的
範圍,而 session_status: "current" 會解析為過時的沙箱鍵。
橋接器建構工具為 extensions/copilot/src/tool-bridge.ts,其對應於 PI
在 src/agents/embedded-agent-runner/run/attempt.ts:1262 的權威呼叫。
runAttempt 透過共用的
resolveSandboxContext 接合處解析沙箱情境、將有效的工作目錄傳給 SDK,
並將 sandbox 及子代理程式產生用的工作區轉送至工具
橋接器。橋接器也會轉送它能在 SDK 邊界強制執行的有限工具建構控制項:
includeCoreTools、執行階段工具
允許清單,以及 toolConstructionPlan。
橋接器也使用來自
openclaw/plugin-sdk/agent-harness-tool-runtime 的共用執行框架工具介面輔助程式,以實現與 PI 同等的行為。啟用
工具搜尋時,SDK 看到的是精簡的控制工具加上隱藏的
目錄執行器,而非每個 OpenClaw 工具結構描述。啟用程式碼模式時,
輔助程式會建構與其他代理程式執行框架相同的程式碼模式控制介面與目錄
生命週期。本機模型的精簡預設值、
與執行階段相容的結構描述篩選、目錄載入及目錄
清理全都保留在共用輔助程式中,因此 Copilot 與 Codex 相鄰的
執行框架不會產生差異。
工作階段層級的 GitHub 權杖
Copilot SDK 合約會區分用戶端層級的 GitHub 權杖 (CopilotClientOptions.gitHubToken,用於驗證 CLI 程序本身)
與工作階段層級的權杖(SessionConfig.gitHubToken,決定
該工作階段的內容排除、模型路由與配額;在
createSession 和 resumeSession 上皆會採用)。執行框架會透過
resolveCopilotAuth 解析一次驗證,並在驗證模式為 gitHubToken
時設定這兩個欄位(明確的 auth.gitHubToken,或從
已設定的 github-copilot 驗證設定檔依合約解析出的 resolvedApiKey)。
當解析出的模式為
useLoggedInUser 時,會省略工作階段層級欄位,讓 SDK 繼續
從已登入的身分推導身分資訊。
ask_user 使用 SessionConfig.onUserInputRequest。橋接器會將 SDK
選項或無選項的自由文字提示登錄為閘道問題;對固定選項要求,
接受選項索引或標籤;當 SDK 要求允許時,也接受自由格式的答案。
中止 OpenClaw 嘗試會取消
閘道記錄,並傳回空白的 SDK 答案。