Get started
Copilot-SDK-Testumgebung
Das externe Plugin @openclaw/copilot ermöglicht OpenClaw, eingebettete Subscription-
Copilot-Agent-Turns über die GitHub Copilot CLI (@github/copilot-sdk)
statt über den integrierten PI-Harness auszuführen.
Verwenden Sie den Copilot SDK-Harness, wenn die Copilot CLI-Sitzung die
Low-Level-Agent-Schleife besitzen soll: native Tool-Ausführung, native Compaction
(infiniteSessions) und CLI-verwalteter Thread-Zustand unter copilotHome.
OpenClaw besitzt weiterhin Chat-Kanäle, Sitzungsdateien, Modellauswahl,
dynamische OpenClaw-Tools (überbrückt), Genehmigungen, Medienzustellung, den
sichtbaren Transcript-Spiegel, /btw-Nebenfragen (verarbeitet durch den
im Repository enthaltenen PI-Fallback – siehe
Nebenfragen (/btw)) und openclaw doctor.
Für die umfassendere Aufteilung von Modell/Provider/Runtime beginnen Sie mit Agent-Runtimes.
Anforderungen
- OpenClaw mit installiertem Plugin
@openclaw/copilot. - Wenn Ihre Konfiguration
plugins.allowverwendet, nehmen Siecopilotauf (die vom Plugin deklarierte Manifest-ID). Eine restriktive Allowlist, die den npm-artigen Paketnamen@openclaw/copilotverwendet, lässt das Plugin blockiert, und die Runtime wird auch mitagentRuntime.id: "copilot"nicht geladen. - Ein GitHub Copilot-Abonnement, das die Copilot CLI steuern kann (oder ein
gitHubToken-Env-/Auth-Profile-Entry für headless-/Cron-Läufe). - Ein beschreibbares
copilotHome-Verzeichnis. Der Harness verwendet standardmäßig<agentDir>/copilot, wenn OpenClaw ein Agent-Verzeichnis bereitstellt, andernfalls~/.openclaw/agents/<agentId>/copilotfür vollständige Isolation pro Agent.
openclaw doctor führt den
Doctor-Vertrag des Plugins für deklarative Zuständigkeit über
Sitzungszustand und zukünftige Kompatibilitätsmigrationen aus. Er führt keine
Umgebungsprüfungen der Copilot CLI aus.
Plugin-Installation
Die Copilot-Runtime ist ein externes Plugin, damit das Kernpaket openclaw
weder die Abhängigkeit @github/copilot-sdk noch deren plattformspezifisches
CLI-Binary @github/copilot-<platform>-<arch> enthält. Zusammen fügen sie etwa
260 MB hinzu; installieren Sie sie daher nur für Agents, die sich für diese
Runtime entscheiden:
openclaw plugins install @openclaw/copilotDer Assistent installiert das Plugin beim ersten Mal, wenn Sie ein
github-copilot/*-Modell auswählen und Ihre Konfiguration das Modell (oder
dessen Provider) über agentRuntime: { id: "copilot" } für die
Copilot-Agent-Runtime auswählt (siehe Schnellstart unten).
Ohne diese Opt-in-Einstellung verwendet openclaw seinen integrierten
GitHub Copilot-Provider und installiert das Runtime-Plugin nie.
Die Runtime löst das SDK in dieser Reihenfolge auf:
import("@github/copilot-sdk")aus dem installierten Paket@openclaw/copilot.- Das bekannte Fallback-Verzeichnis
~/.openclaw/npm-runtime/copilot/(das ältere On-Demand-Installationsziel).
Ein fehlendes SDK erscheint als einzelner Fehler mit dem Code
COPILOT_SDK_MISSING und dem oben genannten Befehl zur Neuinstallation des
Plugins.
Schnellstart
Pinnen Sie ein Modell (oder einen Provider) an den Harness:
{ agents: { defaults: { model: "github-copilot/auto", models: { "github-copilot/auto": { agentRuntime: { id: "copilot" }, }, }, }, },}Beide Wege sind gleichwertig. Verwenden Sie agentRuntime.id bei einem
einzelnen Modelleintrag, wenn nur dieses Modell über den Harness geleitet
werden soll; setzen Sie agentRuntime.id bei einem Provider, wenn jedes Modell
unter diesem Provider ihn verwenden soll.
github-copilot/auto ist der portable Ausgangspunkt. Benannte Copilot-Modelle
hängen von Konto- und Organisationsrichtlinien ab; pinnen Sie daher erst eines,
nachdem Sie bestätigt haben, dass die authentifizierte Copilot CLI es anbietet.
Unterstützte Provider
Der Harness weist Unterstützung für den kanonischen Provider github-copilot
aus (dieselbe ID, die extensions/github-copilot besitzt):
github-copilot
Er unterstützt außerdem benutzerdefinierte models.providers-Einträge, wenn
das ausgewählte Modell eine nicht leere baseUrl und eine dieser API-Formen
hat:
openai-responsesopenai-completionsollama(OpenAI-kompatible Completions)azure-openai-responsesanthropic-messages
Native Provider-IDs wie openai, anthropic, google und ollama bleiben
im Besitz ihrer nativen Runtimes. Verwenden Sie eine eigene benutzerdefinierte
Provider-ID, wenn ein Endpunkt über Copilot BYOK geleitet wird.
Copilot-BYOK-Endpunkte müssen öffentliche HTTPS-URLs sein. Der Harness gibt dem Copilot SDK eine pro Versuch gültige local loopback-Proxy-URL und leitet dann Provider-Traffic über den geschützten Fetch-Pfad von OpenClaw weiter, damit DNS-Pinning und SSRF-Richtlinie bei OpenClaw bleiben. Verwenden Sie die native OpenClaw-Runtime für lokales Ollama, LM Studio oder LAN-Modellserver.
BYOK
Copilot BYOK verwendet den sitzungsbezogenen Custom-Provider-Vertrag des SDK. OpenClaw übergibt den aufgelösten Modellendpunkt, API-Schlüssel, Bearer-Token-Modus, Header, Modell-ID sowie Kontext-/Ausgabelimits, ohne Provider-Transportlogik in den Kern zu verschieben.
Zum Beispiel:
{ agents: { defaults: { model: "custom-proxy/llama-3.1-8b", models: { "custom-proxy/llama-3.1-8b": { agentRuntime: { id: "copilot" }, }, }, }, }, models: { mode: "merge", providers: { "custom-proxy": { baseUrl: "https://api.example.com/v1", apiKey: "${CUSTOM_PROXY_API_KEY}", api: "openai-responses", authHeader: true, models: [{ id: "llama-3.1-8b", name: "Llama 3.1 8B" }], }, }, },}BYOK-Sitzungen werden getrennt von Subscription-Sitzungen und von anderen Endpunkten oder Zugangsdaten-Fingerprints geschlüsselt. Das Rotieren des Schlüssels, der Header, des Modells oder des Endpunkts erzeugt eine neue Copilot SDK-Sitzung, statt inkompatiblen Zustand fortzusetzen.
Authentifizierung
Priorität pro Agent, angewendet während runCopilotAttempt:
-
Explizites
useLoggedInUser: truein der Versuchseingabe. Verwendet den eingeloggten Benutzer der Copilot CLI, aufgelöst unter demcopilotHomedes Agents. -
Explizites
gitHubTokenin der Versuchseingabe (mitprofileId+profileVersion). Nützlich für direkte CLI-Aufrufe und Tests, bei denen der Aufrufer die Auth-Profile-Auflösung umgehen möchte. -
Vertragsseitig aufgelöstes
resolvedApiKey+authProfileIdaus der FormEmbeddedRunAttemptParams. Dies ist der Produktions-Hauptpfad: Der Kern löst das konfigurierte Auth-Profile des Agents fürgithub-copilotauf (übersrc/infra/provider-usage.auth.ts:resolveProviderAuths), bevor er den Harness aufruft, und der Harness nutzt beide Felder direkt. Dadurch funktioniert ein Auth-Profilegithub-copilot:<profile>durchgängig für headless-/Cron-/Multi-Profile-Setups ohne Env-Vars. -
Env-Var-Fallback für direkte CLI-/Dogfood-Läufe, bei denen kein Auth-Profile konfiguriert ist. Die Runtime prüft die folgenden Variablen in Prioritätsreihenfolge und spiegelt damit den ausgelieferten Provider
github-copilot(extensions/github-copilot/auth.ts) sowie die dokumentierte Copilot SDK-Einrichtung:OPENCLAW_GITHUB_TOKEN-- Harness-spezifische Überschreibung; setzen Sie dies, um ein Token für den OpenClaw-Harness zu pinnen, ohne die systemweite Konfiguration vongh/ Copilot CLI zu stören.COPILOT_GITHUB_TOKEN-- Standard-Env-Var des Copilot SDK / der CLI.GH_TOKEN-- Standard-Env-Var derghCLI (entspricht der bestehenden Priorität des Providersgithub-copilot).GITHUB_TOKEN-- generischer GitHub-Token-Fallback.
Der erste nicht leere Wert gewinnt; leere Strings werden als nicht vorhanden behandelt. Die synthetisierte Pool-Profile-ID ist
env:<NAME>, undprofileVersionist ein nicht umkehrbarer sha256-Fingerprint des Tokens, sodass das Rotieren des Env-Werts den Client-Pool sauber invalidiert. -
Standardmäßiges
useLoggedInUser, wenn kein Token-Signal verfügbar ist.
Jeder Agent erhält ein dediziertes copilotHome, damit Copilot CLI-Tokens,
Sitzungen und Konfiguration nicht zwischen Agents auf derselben Maschine
durchsickern. Standard ist <agentDir>/copilot, wenn der Host dem Harness ein
Agent-Verzeichnis übergibt (wodurch SDK-Zustand von OpenClaws models.json /
auth-profiles.json im selben Verzeichnis isoliert wird), andernfalls
~/.openclaw/agents/<agentId>/copilot. Überschreiben Sie dies mit
copilotHome: <path> in der Versuchseingabe, wenn Sie einen eigenen Ort
benötigen (zum Beispiel einen gemeinsamen Mount für eine Migration).
Live-Harness-Tests verwenden OPENCLAW_COPILOT_AGENT_LIVE_TOKEN, wenn ein
direktes Token benötigt wird. Die gemeinsame Live-Test-Einrichtung entfernt
absichtlich COPILOT_GITHUB_TOKEN, GH_TOKEN und GITHUB_TOKEN, nachdem echte
Auth-Profiles im isolierten Test-Home bereitgestellt wurden. Daher vermeidet
das Durchreichen eines gh auth token-Werts über die dedizierte
Live-Test-Variable falsche Skips, ohne das Token für nicht verwandte Suiten
offenzulegen.
Konfigurationsoberfläche
Der Harness liest seine Konfiguration aus der Versuchseingabe
(runCopilotAttempt({...})) plus einer kleinen Menge von Env-Defaults in
extensions/copilot/src/:
copilotHome— CLI-Zustandsverzeichnis pro Agent (Standards oben dokumentiert).model— String oder{ provider, id, api?, baseUrl?, headers?, authHeader? }. Wenn ausgelassen, verwendet OpenClaw die normale Modellauswahl des Agents, und der Harness prüft, ob der aufgelöste Provider unterstützt wird.reasoningEffort—"low" | "medium" | "high" | "xhigh". Wird aus OpenClawsThinkLevel-/ReasoningLevel-Auflösung inauto-reply/thinking.tsabgebildet.infiniteSessionConfig— optionale Überschreibung für den SDK-BlockinfiniteSessions, der vonharness.compactgesteuert wird. Die Defaults können sicher unverändert bleiben.hooksConfig— optionale native Copilot SDK-KompatibilitätskonfigurationSessionHooksfür Tool/MCP-, Benutzer-Prompt-, Sitzungs- und Fehler-Callbacks. Sie ist von OpenClaws portablen Lifecycle-Hooks getrennt.permissionPolicy— optionale Überschreibung für den SDK-HandleronPermissionRequest, der für integrierte SDK-Tool-Arten (shell,write,read,url,mcp,memory,hook) verwendet wird. Standardmäßig wirdrejectAllPolicyals Sicherheitsnetz verwendet; in der Praxis ruft das SDK keine dieser Arten auf, weil jedes überbrückte OpenClaw-Tool mitoverridesBuiltInTool: trueundskipPermission: trueregistriert ist, sodass 100 % der Tool-Aufrufe durch OpenClaws umschlossenesexecute()fließen. Siehe Berechtigungen und ask_user.enableSessionTelemetry— optionales SDK-Flag für Sitzungstelemetrie.
OpenClaw-Plugin-Hooks benötigen keine Copilot-spezifische
Versuchskonfiguration. Der Harness führt before_prompt_build (und den
Legacy-Kompatibilitätshook before_agent_start), llm_input, llm_output und
agent_end über die Standard-Harness-Helfer aus. Erfolgreiche SDK-Compactions
führen außerdem before_compaction und after_compaction aus. Überbrückte
OpenClaw-Tools führen weiterhin before_tool_call aus und melden
after_tool_call; hooksConfig bleibt für native SDK-only-Callbacks bestehen,
für die es kein portables Äquivalent gibt.
Nichts im übrigen OpenClaw muss diese Felder kennen. Andere Plugins, Kanäle und
Kerncode sehen nur die Standardform
AgentHarnessAttemptParams / AgentHarnessAttemptResult.
Compaction
Wenn harness.compact läuft, führt der Copilot SDK-Harness Folgendes aus:
- Er setzt die verfolgte SDK-Sitzung fort, ohne ausstehende Arbeit fortzuführen.
- Er ruft den sitzungsbezogenen History-Compaction-RPC des SDK auf.
- Er gibt das SDK-Compaction-Ergebnis zurück, ohne Kompatibilitätsmarkerdateien unter dem Workspace zu schreiben.
Der OpenClaw-seitige Transcript-Spiegel (siehe unten) erhält weiterhin die Nach-Compaction-Nachrichten, sodass die benutzerseitige Chat-Historie konsistent bleibt.
Transcript-Spiegelung
runCopilotAttempt schreibt die spiegelbaren Nachrichten jedes Turns zusätzlich
in das OpenClaw-Audit-Transcript über
extensions/copilot/src/dual-write-transcripts.ts. Der Spiegel ist pro Sitzung
begrenzt (copilot:${sessionId}) und verwendet eine Identität pro Nachricht
(${role}:${sha256_16(role,content)}), sodass erneut ausgegebene Einträge aus
früheren Turns mit vorhandenen On-Disk-Schlüsseln kollidieren und nicht
dupliziert werden.
Der Spiegel ist in zwei Ebenen der Fehlerbegrenzung eingeschlossen, damit ein
Transcript-Schreibfehler den Versuch nicht fehlschlagen lassen kann: ein
interner Best-Effort-Wrapper und ein Defense-in-Depth-.catch(...) auf
Versuchsebene. Fehler werden protokolliert, aber nicht angezeigt.
Nebenfragen (/btw)
/btw ist auf diesem Harness nicht nativ. createCopilotAgentHarness()
lässt harness.runSideQuestion absichtlich undefiniert, sodass OpenClaws
/btw-Dispatcher (src/agents/btw.ts) auf denselben repositoryinternen
PI-Fallbackpfad zurückfällt, den er für jede Nicht-Codex-Runtime verwendet:
Der konfigurierte Modell-Provider wird direkt mit einem kurzen Nebenfragen-
Prompt aufgerufen und über streamSimple zurückgestreamt (keine CLI-Sitzung,
kein zusätzlicher Pool-Slot).
Dadurch bleiben Copilot-CLI-Sitzungen für die Hauptschleife des Agents
reserviert, und das /btw-Verhalten bleibt identisch mit anderen
PI-gestützten Runtimes. Der Vertrag wird in
extensions/copilot/harness.test.ts
unter describe("runSideQuestion") abgesichert.
Doctor
extensions/copilot/doctor-contract-api.ts wird automatisch von
src/plugins/doctor-contract-registry.ts geladen. Es steuert bei:
- Ein leeres
legacyConfigRules(keine stillgelegten Felder im MVP). - Ein No-op-
normalizeCompatibilityConfig(beibehalten, damit zukünftige Feldstilllegungen einen stabilen repositoryinternen Ort haben). - Einen
sessionRouteStateOwners-Eintrag, der Providergithub-copilot, Runtimecopilot, CLI-Sitzungsschlüsselcopilotund Auth-Profilpräfixgithub-copilot:beansprucht.
Einschränkungen
- Der Harness beansprucht
github-copilotsowie nicht besessene benutzerdefinierte BYOK-Provider-IDs. Manifest-eigene native Provider-IDs bleiben auf ihrer besitzenden Runtime, selbst wennagentRuntime.idaufcopiloterzwungen wird. - Der Harness liefert keine TUI; die TUI von PI bleibt unberührt und bleibt der Fallback für alle Runtimes, die keine gleichrangige Oberfläche haben.
- Der PI-Sitzungszustand wird nicht migriert, wenn ein Agent zu
copilotwechselt. Die Auswahl gilt pro Versuch; vorhandene PI-Sitzungen bleiben gültig. ask_userverwendet denselben Prompt-und-Antwort-Pfad von OpenClaw wie der Codex-Harness. Wenn das Copilot-SDK Benutzereingaben anfordert, postet OpenClaw einen blockierenden Prompt in den aktiven Kanal bzw. die aktive TUI, und die nächste eingereihte Benutzernachricht löst die SDK-Anfrage auf.
Berechtigungen und ask_user
Die Durchsetzung von Berechtigungen für überbrückte OpenClaw-Tools erfolgt
innerhalb des Tool-Wrappers, nicht über den onPermissionRequest-Callback
des SDK. Dasselbe wrapToolWithBeforeToolCallHook, das PI verwendet
(src/agents/pi-tools.before-tool-call.ts), wird von
createOpenClawCodingTools auf jedes Coding-Tool angewendet:
Schleifenerkennung, Richtlinien für vertrauenswürdige Plugins,
Before-Tool-Call-Hooks und zweiphasige Plugin-Genehmigungen über das Gateway
(plugin.approval.request) laufen alle über exakt denselben Codepfad wie
native PI-Versuche.
Damit dieser Wrapper die Entscheidung besitzt, wird das von
convertOpenClawToolToSdkTool zurückgegebene SDK-Tool mit Folgendem markiert:
overridesBuiltInTool: true— ersetzt das eingebaute Tool der Copilot-CLI mit demselben Namen (edit, read, write, bash, …), sodass jeder Tool-Aufruf zurück zu OpenClaw geroutet wird.skipPermission: true— weist das SDK an, vor dem Aufruf des Tools keinonPermissionRequest({kind: "custom-tool"})auszulösen. Das umschlosseneexecute()führt intern die umfassendere OpenClaw-Richtlinienprüfung aus; ein SDK-seitiger Prompt würde entweder die Durchsetzung von OpenClaw umgehen (wenn wir alles erlauben) oder jeden Tool-Aufruf blockieren (wenn wir alles ablehnen) — beides entspricht nicht der PI-Parität.
Der repositoryinterne Codex-Harness verwendet dieselbe Aufteilung:
Überbrückte OpenClaw-Tools werden umschlossen
(extensions/codex/src/app-server/dynamic-tools.ts), und die eigenen
nativen Genehmigungsarten des codex-app-server
(item/commandExecution/requestApproval,
item/fileChange/requestApproval,
item/permissions/requestApproval) werden über
plugin.approval.request
(extensions/codex/src/app-server/approval-bridge.ts) geroutet. Das
Copilot-SDK-Äquivalent — eine fail-closed rejectAllPolicy für jede
Nicht-custom-tool-Art, die jemals onPermissionRequest erreicht — ist
dasselbe Sicherheitsnetz, und es wird praktisch nicht ausgelöst, weil
overridesBuiltInTool: true jedes eingebaute Tool verdrängt.
Damit die Wrapped-Tool-Ebene Richtlinienentscheidungen treffen kann, die PI
entsprechen, leitet der Harness den vollständigen PI-Versuchs-Tool-Kontext an
createOpenClawCodingTools weiter: Identität (senderIsOwner,
memberRoleIds, ownerOnlyToolAllowlist, …), Kanal/Routing
(groupId, currentChannelId, replyToMode, Umschalter für
Nachrichten-Tools), Auth (authProfileStore), Laufidentität
(sessionKey/runSessionKey, abgeleitet aus sandboxSessionKey, runId),
Modellkontext (modelApi, modelContextWindowTokens, modelCompat,
modelHasVision) und Lauf-Hooks (onToolOutcome, onYield). Ohne diese
Felder verhalten sich Owner-only-Allowlists stillschweigend wie Deny-by-default,
Plugin-Vertrauensrichtlinien können nicht auf den richtigen Scope aufgelöst
werden, und session_status: "current" wird auf einen veralteten
Sandbox-Schlüssel aufgelöst. Der Bridge-Builder befindet sich in
extensions/copilot/src/tool-bridge.ts und spiegelt den maßgeblichen
PI-Aufruf unter src/agents/pi-embedded-runner/run/attempt.ts:1029-1117.
runAttempt löst den Sandbox-Kontext bereits über die gemeinsame
resolveSandboxContext-Schnittstelle auf, übergibt dem SDK ein effektives
Arbeitsverzeichnis und leitet sandbox sowie den Workspace für
Subagent-Spawns in die Tool-Bridge weiter. Die Bridge leitet außerdem die
begrenzten Tool-Konstruktionssteuerungen weiter, die sie an der SDK-Grenze
durchsetzen kann: includeCoreTools, die Runtime-Tool-Allowlist und
toolConstructionPlan.
Die Bridge verwendet außerdem den gemeinsamen Harness-Tool-Surface-Helfer aus
openclaw/plugin-sdk/agent-harness-tool-runtime für PI-Parität. Wenn
Tool-Suche aktiviert ist, sieht das SDK kompakte Steuerungs-Tools plus einen
versteckten Katalog-Executor anstelle jedes OpenClaw-Tool-Schemas. Wenn
Code-Modus aktiviert ist, baut der Helfer dieselbe Code-Modus-Steuerungsfläche
und denselben Kataloglebenszyklus auf, die andere Agent-Harnesse verwenden.
Schlanke Standardwerte für lokale Modelle, runtimekompatible Schemafilterung,
Verzeichnis-Hydration und Katalogbereinigung bleiben alle im gemeinsamen
Helfer, damit Copilot- und Codex-nahe Harnesse nicht auseinanderlaufen.
GitHub-Token auf Sitzungsebene
Der Vertrag des Copilot-SDK unterscheidet den clientseitigen GitHub-Token
(CopilotClientOptions.gitHubToken, verwendet zur Authentifizierung des
CLI-Prozesses selbst) vom sitzungsseitigen Token
(SessionConfig.gitHubToken, der Inhaltsausschluss, Modellrouting und Quote
für diese Sitzung bestimmt und sowohl bei createSession als auch bei
resumeSession berücksichtigt wird). Der Harness löst Auth einmal über
resolveCopilotAuth auf und setzt beide Felder, wenn der Auth-Modus
gitHubToken ist (ein explizites auth.gitHubToken oder ein vertragsgemäß
aufgelöstes resolvedApiKey aus einem konfigurierten
github-copilot-Auth-Profil). Wenn der aufgelöste Modus useLoggedInUser
ist, wird das sitzungsseitige Feld ausgelassen, sodass das SDK die Identität
weiterhin aus der angemeldeten Identität ableitet.
ask_user verwendet SessionConfig.onUserInputRequest. Die Bridge akzeptiert
Auswahlindizes oder Labels für Anfragen mit festen Auswahlmöglichkeiten,
akzeptiert Freiformantworten, wenn die SDK-Anfrage sie erlaubt, und bricht eine
ausstehende Anfrage ab, wenn der OpenClaw-Versuch abgebrochen wird.