Loslegen
Copilot-SDK-Harness
Das externe Plugin @openclaw/copilot führt eingebettete Agent-Durchläufe des Copilot-Abonnements
über die GitHub Copilot CLI (@github/copilot-sdk) statt über
das integrierte Harness von OpenClaw aus. Die Copilot-CLI-Sitzung verwaltet die untergeordnete
Agent-Schleife: native Werkzeugausführung, native Compaction (infiniteSessions) und
CLI-verwalteten Thread-Status unter copilotHome. OpenClaw verwaltet weiterhin Chat-
Kanäle, Sitzungsdateien, Modellauswahl, dynamische Werkzeuge (über eine Bridge), Genehmigungen,
Medienzustellung, die sichtbare Transkriptspiegelung, /btw Nebenfragen (siehe
Nebenfragen (/btw)) und openclaw doctor.
Einen Überblick über die umfassendere Aufteilung zwischen Modell, Provider und Laufzeit finden Sie unter Agent-Laufzeiten.
Anforderungen
- OpenClaw mit installiertem Plugin
@openclaw/copilot. - Wenn Ihre Konfiguration
plugins.allowverwendet, nehmen Siecopilotauf (die vom Plugin deklarierte Manifest-ID). Ein Eintrag für den npm-Paketnamen@openclaw/copilotin der Zulassungsliste stimmt nicht überein und das Plugin bleibt blockiert, selbst wennagentRuntime.id: "copilot"festgelegt ist. - Ein GitHub-Copilot-Abonnement, das die Copilot CLI verwenden kann, oder eine
Umgebungsvariable
gitHubTokenbzw. ein Authentifizierungsprofileintrag für Headless- oder Cron-Ausführungen. - Ein beschreibbares Verzeichnis
copilotHome. Standardmäßig<agentDir>/copilot, wenn OpenClaw ein Agent-Verzeichnis bereitstellt, andernfalls~/.openclaw/agents/<agentId>/copilot.
openclaw doctor führt den Doctor-Vertrag des Plugins für
die Zuständigkeit für den Sitzungsstatus und zukünftige Konfigurationsmigrationen aus. Die
Copilot-CLI-Umgebung wird dabei nicht geprüft.
Installation
Die Copilot-Laufzeit wird als externes Plugin ausgeliefert, damit das zentrale Paket openclaw
weder @github/copilot-sdk noch dessen plattformspezifische
CLI-Binärdatei @github/copilot-<platform>-<arch> enthält (zusammen etwa 260 MB).
Installieren Sie es nur für Agenten, die diese Laufzeit ausdrücklich verwenden:
openclaw plugins install @openclaw/copilotDer Einrichtungsassistent installiert das Plugin automatisch, wenn Sie erstmals
ein Modell github-copilot/* auswählen und Ihre Konfiguration dieses Modell (oder dessen
Provider) über agentRuntime: { id: "copilot" } an die Copilot-Laufzeit weiterleitet; siehe
Schnellstart. Ohne diese Aktivierung verwendet OpenClaw seinen integrierten
GitHub-Copilot-Provider und installiert dieses Plugin nicht.
Die Laufzeit sucht das SDK in dieser Reihenfolge:
import("@github/copilot-sdk")aus dem installierten Paket@openclaw/copilot.- Das Ausweichverzeichnis
~/.openclaw/npm-runtime/copilot/(veraltetes Ziel für die bedarfsgesteuerte Installation).
Bei einem fehlenden SDK wird ein einzelner Fehler mit dem Code COPILOT_SDK_MISSING und dem
obigen Befehl zur Neuinstallation ausgegeben.
Schnellstart
Binden Sie ein Modell (oder einen Provider) an das Harness:
{ agents: { defaults: { model: "github-copilot/auto", models: { "github-copilot/auto": { agentRuntime: { id: "copilot" }, }, }, }, },}Legen Sie agentRuntime.id für einen einzelnen Modelleintrag fest, um nur dieses Modell über
das Harness weiterzuleiten, oder für einen Provider, um jedes Modell dieses Providers weiterzuleiten.
github-copilot/auto ist der portable Ausgangspunkt. Benannte Copilot-Modelle hängen
von Konto- und Organisationsrichtlinien ab; vergewissern Sie sich, dass Ihre authentifizierte
Copilot CLI ein Modell tatsächlich bereitstellt, bevor Sie es fest vorgeben.
Unterstützte Provider
Das Harness unterstützt den kanonischen Provider github-copilot (verwaltet von
extensions/github-copilot) sowie benutzerdefinierte Einträge models.providers, wenn das
Modell einen nicht leeren Wert für baseUrl und eine dieser Formen von api aufweist:
anthropic-messagesazure-openai-responsesollama(OpenAI-kompatible Vervollständigungen)openai-completionsopenai-responses
Native Provider-IDs (openai, anthropic, google, ollama) verbleiben in der Zuständigkeit
ihrer nativen Laufzeiten. Verwenden Sie stattdessen eine eigene benutzerdefinierte Provider-ID, um einen Endpunkt
über Copilot BYOK weiterzuleiten.
Copilot-BYOK-Endpunkte müssen öffentliche HTTPS-URLs sein. Das Harness stellt dem Copilot SDK für jeden Versuch einen Loopback-Proxy bereit und leitet anschließend den Provider-Datenverkehr über den geschützten Abrufpfad von OpenClaw weiter, sodass DNS-Pinning und SSRF-Richtlinien in der Zuständigkeit von OpenClaw bleiben. Verwenden Sie die native OpenClaw-Laufzeit für lokale Ollama-, LM-Studio- oder LAN-Modellserver.
BYOK
Copilot BYOK verwendet den sitzungsbezogenen Vertrag des SDK für benutzerdefinierte Provider. OpenClaw übergibt den aufgelösten Modellendpunkt, API-Schlüssel, Bearer-Token-Modus, Header, die Modell- ID sowie Kontext- und Ausgabelimits; die Provider-Transportlogik verbleibt im SDK und nicht im Kern.
{ 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 erhalten eigene Schlüssel, getrennt von Abonnementsitzungen sowie von anderen BYOK-Endpunkten oder Anmeldedaten. Wenn der Schlüssel, die Header, das Modell oder der Endpunkt geändert werden, startet eine neue Copilot-SDK-Sitzung, statt inkompatiblen Status fortzusetzen.
Authentifizierung
Rangfolge, die während runCopilotAttempt für jeden Agenten angewendet wird:
-
Explizites
useLoggedInUser: truein der Eingabe des Versuchs – verwendet den angemeldeten Benutzer der Copilot CLI untercopilotHomedes Agenten. -
Explizites
gitHubTokenin der Eingabe des Versuchs (erfordertprofileId+profileVersion). Für direkte CLI-Aufrufe und Tests, die die Auflösung von Authentifizierungsprofilen umgehen müssen. -
Vertragsseitig aufgelöstes
resolvedApiKey+authProfileId– der primäre Produktionspfad. Der Kern löst das konfigurierte Authentifizierungsprofilgithub-copilot(src/infra/provider-usage.auth.ts:resolveProviderAuths) des Agenten auf, bevor das Harness aufgerufen wird, sodass ein Authentifizierungsprofilgithub-copilot:<profile>für Headless-, Cron- oder Mehrprofilkonfigurationen ohne Umgebungsvariablen durchgängig funktioniert. -
Ausweichlösung über Umgebungsvariablen, in dieser Reihenfolge geprüft (der erste nicht leere Wert wird verwendet, leere Zeichenfolgen gelten als nicht vorhanden; entspricht der ausgelieferten Rangfolge des Providers
github-copilotinextensions/github-copilot/auth.ts):OPENCLAW_GITHUB_TOKEN– Harness-spezifische Überschreibung; ermöglicht die feste Vorgabe eines Tokens für das OpenClaw-Harness, ohne die systemweite Konfiguration vongh/ Copilot CLI zu verändern.COPILOT_GITHUB_TOKEN– standardmäßige Umgebungsvariable des Copilot SDK / der CLI.GH_TOKEN– standardmäßige Umgebungsvariable der CLIgh.GITHUB_TOKEN– generischer Ausweichwert für GitHub-Token.
Die synthetisierte Pool-Profil-ID lautet
env:<NAME>; die Profilversion ist ein nicht umkehrbarer SHA-256-Fingerabdruck des Tokens, sodass eine Änderung des Umgebungswerts den Client-Pool zuverlässig verwirft. -
Standardwert
useLoggedInUser, wenn kein Token-Signal verfügbar ist.
Jeder Agent erhält ein eigenes copilotHome, damit Copilot-CLI-Token, Sitzungen und
Konfigurationen niemals zwischen Agenten auf demselben Rechner übertragen werden. Standard:
<agentDir>/copilot (hält den SDK-Status aus demselben Verzeichnis wie
models.json / auth-profiles.json von OpenClaw heraus) oder
~/.openclaw/agents/<agentId>/copilot, wenn kein Agent-Verzeichnis bereitgestellt wird.
Überschreiben Sie den Wert mit copilotHome: <path> in der Eingabe des Versuchs, um einen benutzerdefinierten
Speicherort zu verwenden (beispielsweise ein freigegebenes Volume für eine Migration).
Live-Harness-Tests verwenden OPENCLAW_COPILOT_AGENT_LIVE_TOKEN für ein direktes
Token. Die gemeinsam genutzte Live-Test-Einrichtung entfernt COPILOT_GITHUB_TOKEN, GH_TOKEN
und GITHUB_TOKEN, nachdem echte Authentifizierungsprofile im isolierten Test-
Home-Verzeichnis bereitgestellt wurden. Dadurch verhindert ein über die dedizierte Variable übergebener Wert gh auth token
fälschliche Überspringvorgänge, ohne in andere Testsuiten zu gelangen.
Konfigurationsoberfläche
Das Harness liest die Konfiguration aus der versuchsbezogenen Eingabe (runCopilotAttempt({...}))
und aus einer kleinen Gruppe von Umgebungsstandardwerten innerhalb von extensions/copilot/src/:
| Feld | Zweck |
|---|---|
copilotHome |
Agentenspezifisches CLI-Statusverzeichnis (Standardwerte siehe oben). |
model |
Zeichenfolge oder { provider, id, api?, baseUrl?, headers?, authHeader? }. Weglassen, um die normale Modellauswahl des Agenten zu verwenden; das Harness prüft, ob der aufgelöste Provider unterstützt wird. |
reasoningEffort |
"low" | "medium" | "high" | "xhigh". Wird aus der Auflösung von ThinkLevel / ReasoningLevel durch OpenClaw in auto-reply/thinking.ts abgeleitet. |
infiniteSessionConfig |
Optionale Überschreibung für den vom SDK-Block infiniteSessions, der durch harness.compact gesteuert wird. Kann unverändert bleiben. |
hooksConfig |
Optionale native Copilot-SDK-Konfiguration SessionHooks für Werkzeug-/MCP-, Benutzeraufforderungs-, Sitzungs- und Fehlerrückrufe. Unabhängig von den portablen Lebenszyklus-Hooks von OpenClaw. |
permissionPolicy |
Optionale Überschreibung für den Handler onPermissionRequest des SDK für integrierte SDK-Werkzeugtypen (shell, write, read, url, mcp, memory, hook). Standardmäßig rejectAllPolicy als Sicherheitsnetz; unter Berechtigungen und ask_user wird erläutert, warum er tatsächlich nie ausgelöst wird. |
enableSessionTelemetry |
Optionales Telemetrie-Flag für SDK-Sitzungen. |
OpenClaw-Plugin-Hooks benötigen keine Copilot-spezifische Versuchskonfiguration. Das
Harness führt before_prompt_build, llm_input, llm_output und agent_end über die
standardmäßigen Harness-Hilfsfunktionen aus. Erfolgreiche SDK-Compactions führen außerdem
before_compaction und after_compaction aus. Über eine Bridge angebundene OpenClaw-Werkzeuge führen
before_tool_call aus und melden after_tool_call; hooksConfig bleibt
nativen, ausschließlich SDK-internen Rückrufen vorbehalten, für die es keine portable Entsprechung gibt.
Keine andere Komponente in OpenClaw muss diese Felder kennen. Andere Plugins,
Kanäle und der Kern sehen nur die standardmäßige Form AgentHarnessAttemptParams /
AgentHarnessAttemptResult.
Compaction
Wenn harness.compact ausgeführt wird, führt das Copilot-SDK-Harness Folgendes aus:
- Setzt die nachverfolgte SDK-Sitzung fort, ohne ausstehende Arbeit fortzuführen.
- Ruft den sitzungsbezogenen RPC des SDK zur Komprimierung des Verlaufs auf.
- Gibt das Ergebnis der SDK-Compaction zurück, ohne Kompatibilitätsmarkierungsdateien im Arbeitsbereich zu schreiben.
Die OpenClaw-seitige Transkriptspiegelung (unten) empfängt weiterhin Nachrichten nach der Compaction, sodass der für Benutzer sichtbare Chatverlauf konsistent bleibt.
Transkriptspiegelung
runCopilotAttempt schreibt die spiegelbaren Nachrichten jedes Durchlaufs doppelt in das
OpenClaw-Audit-Transkript über
extensions/copilot/src/dual-write-transcripts.ts. Die Spiegelung ist pro
Sitzung (copilot:${sessionId}) begrenzt und pro Nachricht verschlüsselt
(${role}:${sha256_16(role,content)}), sodass erneut ausgegebene Einträge aus vorherigen Durchläufen
mit vorhandenen Schlüsseln auf dem Datenträger kollidieren, anstatt dupliziert zu werden.
Zwei Ebenen der Fehlerbegrenzung umschließen die Spiegelung, sodass ein Fehler beim Schreiben
des Transkripts niemals den Versuch fehlschlagen lässt: ein interner Best-Effort-Wrapper sowie ein
Defense-in-Depth-.catch(...) auf Versuchsebene. Fehler werden protokolliert, nicht
weitergegeben.
Nebenfragen (/btw)
/btw ist auf diesem Harness nicht nativ. createCopilotAgentHarness()
lässt harness.runSideQuestion bewusst undefiniert
(bestätigt in extensions/copilot/harness.test.ts, describe("runSideQuestion")),
sodass der /btw-Dispatcher von OpenClaw (src/agents/btw.ts) auf denselben
Pfad zurückfällt, den er für jede Nicht-Codex-Laufzeit verwendet: Der konfigurierte Modell-Provider
wird direkt mit einem kurzen Nebenfragen-Prompt aufgerufen, und die Antwort wird über
streamSimple zurückgestreamt (keine CLI-Sitzung, kein zusätzlicher Pool-Platz).
Dadurch bleiben Copilot-CLI-Sitzungen für die Hauptdurchlaufschleife des Agenten reserviert und
das Verhalten von /btw bleibt mit anderen Nicht-Codex-Laufzeiten identisch.
Doctor
extensions/copilot/doctor-contract-api.ts wird automatisch von
src/plugins/doctor-contract-registry.ts geladen. Es stellt Folgendes bereit:
- Ein leeres
legacyConfigRules(noch keine veralteten Felder). - Ein wirkungsloses
normalizeCompatibilityConfig(wird beibehalten, damit zukünftige Feldstilllegungen einen stabilen Ort im Quellbaum haben). - Ein
sessionRouteStateOwners-Eintrag: Providergithub-copilot, Laufzeitcopilot, CLI-Sitzungsschlüsselcopilot, Präfix des Authentifizierungsprofilsgithub-copilot:.
Einschränkungen
- Das Harness beansprucht
github-copilotsowie nicht zugeordnete benutzerdefinierte BYOK-Provider-IDs. Manifest-eigene native Provider-IDs verbleiben bei ihrer zugehörigen Laufzeit, selbst wennagentRuntime.idaufcopiloterzwungen wird. - Keine TUI-Oberfläche; die TUI von PI bleibt der Fallback für Laufzeiten ohne gleichwertige Oberfläche.
- Der PI-Sitzungsstatus wird nicht migriert, wenn ein Agent zu
copilotwechselt. Die Auswahl erfolgt pro Versuch; vorhandene PI-Sitzungen bleiben gültig. ask_userverwendet die Provider-neutrale Gateway-Fragenlaufzeit. Die Control UI zeigt dieselbe Fragenkarte wie bei anderen OpenClaw-Fragen, unterstützte Kanäle stellen Auswahlschaltflächen dar, und die nächste eingereihte Klartextnachricht löst diesen Gateway-Eintrag auf, bevor die SDK-Anfrage zurückkehrt.
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. Derselbe
wrapToolWithBeforeToolCallHook, den PI verwendet
(src/agents/agent-tools.before-tool-call.ts), wird durch
createOpenClawCodingTools auf jedes Coding-Tool angewendet: Schleifenerkennung, Richtlinien für
vertrauenswürdige Plugins, Hooks vor Tool-Aufrufen und zweiphasige Plugin-Genehmigungen über
das Gateway (plugin.approval.request) durchlaufen exakt denselben Code-
Pfad wie native PI-Versuche.
Jedes vom Copilot-Tool-Bridge zurückgegebene SDK-Tool ist wie folgt gekennzeichnet:
overridesBuiltInTool: true— ersetzt das integrierte Tool der Copilot CLI mit demselben Namen (edit, read, write, bash, ...), sodass jeder Tool-Aufruf zurück zu OpenClaw geleitet wird.skipPermission: true— weist das SDK an,onPermissionRequest({kind: "custom-tool"})vor dem Aufruf des Tools nicht auszulösen. Der umschlosseneexecute()führt bereits die umfassendere OpenClaw-Richtlinienprüfung durch; ein Prompt auf SDK-Ebene würde entweder die Durchsetzung von OpenClaw umgehen (alles zulassen) oder jeden Tool-Aufruf blockieren (alles ablehnen) — beides entspricht nicht der Parität mit PI.
Das Codex-Harness im Quellbaum 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) geleitet. Das Äquivalent im Copilot SDK
— ein Fail-Closed-rejectAllPolicy für jede Nicht-custom-tool-Art,
die jemals onPermissionRequest erreicht — ist dasselbe Sicherheitsnetz und wird
in der Praxis nie ausgelöst, weil overridesBuiltInTool: true jedes
integrierte Tool verdrängt.
Damit die Ebene der umschlossenen Tools Richtlinienentscheidungen treffen kann, die denen von PI entsprechen,
leitet das Harness den vollständigen PI-Kontext für Tools eines Versuchs an
createOpenClawCodingTools weiter: Identität (senderIsOwner, memberRoleIds,
ownerOnlyToolAllowlist, ...), Kanal/Routing (groupId,
currentChannelId, replyToMode, Umschalter für Nachrichtentools), Authentifizierung
(authProfileStore), Ausführungsidentität (sessionKey / runSessionKey, abgeleitet
aus sandboxSessionKey, runId), Modellkontext (modelApi,
modelContextWindowTokens, modelCompat, modelHasVision) und Ausführungs-Hooks
(onToolOutcome, onYield). Ohne diese Felder lehnen nur für Eigentümer geltende Zulassungslisten
standardmäßig stillschweigend ab, Richtlinien für das Vertrauen in Plugins können nicht auf den richtigen
Geltungsbereich aufgelöst werden, und session_status: "current" wird auf einen veralteten Sandbox-Schlüssel aufgelöst. Der
Bridge-Builder ist extensions/copilot/src/tool-bridge.ts und spiegelt den maßgeblichen PI-
Aufruf unter src/agents/embedded-agent-runner/run/attempt.ts:1262.
runAttempt löst den Sandbox-Kontext über die gemeinsame
resolveSandboxContext-Schnittstelle auf, übergibt dem SDK ein effektives Arbeitsverzeichnis
und leitet sandbox sowie den Arbeitsbereich für das Erzeugen von Subagenten an die Tool-
Bridge weiter. Die Bridge leitet außerdem die begrenzten Steuerelemente für die Tool-Erstellung weiter, die sie
an der SDK-Grenze durchsetzen kann: includeCoreTools, die Tool-
Zulassungsliste der Laufzeit und toolConstructionPlan.
Die Bridge verwendet für die Parität mit PI außerdem den gemeinsamen Harness-Helfer für Tool-Oberflächen aus
openclaw/plugin-sdk/agent-harness-tool-runtime. Wenn
die Tool-Suche aktiviert ist, sieht das SDK kompakte Steuerungstools sowie einen ausgeblendeten
Katalog-Executor anstelle jedes OpenClaw-Tool-Schemas. Wenn der Code-Modus
aktiviert ist, erstellt der Helfer dieselbe Steuerungsoberfläche und denselben Katalog-
Lebenszyklus für den Code-Modus, die von anderen Agenten-Harnesses verwendet werden. Schlanke Standardwerte
für lokale Modelle, laufzeitkompatible Schemafilterung, Verzeichnishydrierung und Katalog-
Bereinigung verbleiben vollständig im gemeinsamen Helfer, damit Copilot und Codex-nahe
Harnesses nicht auseinanderdriften.
GitHub-Token auf Sitzungsebene
Der Vertrag des Copilot SDK unterscheidet das GitHub-Token auf Client-Ebene
(CopilotClientOptions.gitHubToken, authentifiziert den CLI-Prozess selbst)
vom Token auf Sitzungsebene (SessionConfig.gitHubToken, bestimmt
Inhaltsausschluss, Modell-Routing und Kontingent für diese Sitzung; wird sowohl bei
createSession als auch bei resumeSession berücksichtigt). Das Harness löst die Authentifizierung einmal über
resolveCopilotAuth auf und setzt beide Felder, wenn der Authentifizierungsmodus gitHubToken ist
(ein explizites auth.gitHubToken oder ein vertragsgemäß aufgelöstes resolvedApiKey aus
einem konfigurierten github-copilot-Authentifizierungsprofil). Wenn der aufgelöste Modus
useLoggedInUser ist, wird das Feld auf Sitzungsebene weggelassen, sodass das SDK
die Identität weiterhin von der angemeldeten Identität ableitet.
ask_user verwendet SessionConfig.onUserInputRequest. Die Bridge registriert SDK-
Auswahlmöglichkeiten oder optionenlose Freitext-Prompts als Gateway-Fragen, akzeptiert Auswahl-
indizes oder Beschriftungen für Anfragen mit fester Auswahl und akzeptiert Freitextantworten,
wenn die SDK-Anfrage sie zulässt. Das Abbrechen des OpenClaw-Versuchs bricht den
Gateway-Eintrag ab und gibt eine leere SDK-Antwort zurück.