OpenClaw.NET now supports an OSS-first external coding backend lane for session-capable coding CLIs. This lane stays separate from the native OpenClaw agent runtime and treats Codex CLI, Gemini CLI, and GitHub Copilot CLI as external backends that OpenClaw can probe, start, stream, and stop.
The startup boundaries match the current gateway architecture:
Bootstrap/- binds and normalizes
GatewayConfig.CodingBackends - validates backend ids, timeout values, workspace paths, and credential-source shape before build
- binds and normalizes
Composition/- registers account services, credential resolution, backend registry/coordinator, subprocess host, and real CLI backends in
BackendServicesExtensions
- registers account services, credential resolution, backend registry/coordinator, subprocess host, and real CLI backends in
Endpoints/- exposes modular integration/admin endpoints for accounts and backends without bloating
Program.cs
- exposes modular integration/admin endpoints for accounts and backends without bloating
ConnectedAccountService- creates, lists, loads, and deletes connected accounts
- protects stored secret blobs with ASP.NET Data Protection
BackendCredentialResolver- resolves credentials from env refs, raw secrets, token files, or stored connected accounts
CodingAgentBackendRegistry- exposes registered backends and their definitions
BackendSessionCoordinator- starts/stops backend sessions and persists session records plus ordered events
CodingBackendProcessHost- owns
System.Diagnostics.Process, async stdout/stderr streaming, stdin writes, timeout/cancellation, and exit-code handling
- owns
Persisted records reuse the existing feature-store seams:
connected-accounts- file-backed directory or
connected_accountssqlite table
- file-backed directory or
backend-sessions- file-backed directory or
backend_sessionssqlite table
- file-backed directory or
backend-session-events- file-backed directory or
backend_session_eventssqlite table
- file-backed directory or
Backend sessions are separate from native OpenClaw Session history. A backend session may reference an owning OpenClaw session id, but backend events are not dual-written into the core session transcript in this version.
When OwnerSessionId is supplied, OpenClaw now mirrors key backend events into that owner session history as tagged user, assistant, or system turns so the control-plane session remains readable.
Supported OSS account modes:
- direct secret refs
env:MY_TOKENraw:actual-secret
- direct token file paths
- absolute or expanded local file paths
- stored connected accounts
- protected secret blob
- stored secret ref
- stored token file path
Resolution priority is explicit request source first, then backend default credential config. Stored connected accounts are rejected when inactive or expired.
No OAuth flow is required for local mode.
The canonical gateway config gains CodingBackends with three backend sections:
CodexGeminiCliGitHubCopilotCli
Each section uses the same shape:
{
"Enabled": true,
"BackendId": "codex",
"Provider": "codex",
"DisplayName": "Codex CLI",
"ExecutablePath": "codex",
"Args": ["exec"],
"ProbeArgs": ["--help"],
"TimeoutSeconds": 600,
"Environment": {
"OPENAI_BASE_URL": "env:OPENAI_BASE_URL"
},
"DefaultModel": "gpt-5-codex",
"RequireWorkspace": true,
"DefaultWorkspacePath": "/absolute/workspace",
"ReadOnlyByDefault": false,
"WriteEnabled": true,
"PreferStructuredOutput": true,
"Credentials": {
"SecretRef": "env:OPENAI_API_KEY",
"TokenFilePath": null,
"ConnectedAccountId": null
}
}Example Codex CLI config:
{
"CodingBackends": {
"Codex": {
"Enabled": true,
"BackendId": "codex",
"Provider": "codex",
"ExecutablePath": "codex",
"Args": ["exec"],
"DefaultModel": "gpt-5-codex",
"RequireWorkspace": true,
"ReadOnlyByDefault": false,
"WriteEnabled": true,
"Credentials": {
"SecretRef": "env:OPENAI_API_KEY"
}
}
}
}Example Gemini CLI config:
{
"CodingBackends": {
"GeminiCli": {
"Enabled": true,
"BackendId": "gemini-cli",
"Provider": "gemini-cli",
"ExecutablePath": "gemini",
"Args": ["--checkpointing"],
"DefaultModel": "gemini-2.5-pro",
"ReadOnlyByDefault": true,
"WriteEnabled": true,
"Credentials": {
"TokenFilePath": "/absolute/path/to/gemini.token"
}
}
}
}Example GitHub Copilot CLI config:
{
"CodingBackends": {
"GitHubCopilotCli": {
"Enabled": true,
"BackendId": "copilot-cli",
"Provider": "github-copilot-cli",
"ExecutablePath": "copilot",
"Args": ["chat"],
"DefaultModel": "gpt-4.1",
"ReadOnlyByDefault": false,
"WriteEnabled": true,
"Credentials": {
"ConnectedAccountId": "acct_1234567890abcd"
}
}
}
}Integration endpoints:
GET /api/integration/accountsGET /api/integration/accounts/{id}POST /api/integration/accountsDELETE /api/integration/accounts/{id}GET /api/integration/backendsGET /api/integration/backends/{id}POST /api/integration/backends/{id}/probePOST /api/integration/backends/{id}/sessionsGET /api/integration/backends/{id}/sessions/{sessionId}POST /api/integration/backends/{id}/sessions/{sessionId}/inputDELETE /api/integration/backends/{id}/sessions/{sessionId}GET /api/integration/backends/{id}/sessions/{sessionId}/events?afterSequence=0&limit=100GET /api/integration/backends/{id}/sessions/{sessionId}/events/stream?afterSequence=0&limit=100
Admin endpoints:
POST /admin/accounts/test-resolutionGET /admin/backendsGET /admin/backends/{id}POST /admin/backends/{id}/probe
Accounts:
openclaw accounts list
openclaw accounts add codex --display-name "Local Codex" --secret-ref env:OPENAI_API_KEY
openclaw accounts add gemini-cli --display-name "Gemini Token File" --token-file ~/.config/gemini/token
openclaw accounts remove acct_1234567890abcd
openclaw accounts probe acct_1234567890abcd
openclaw accounts probe codex --backend codexBackends:
openclaw backends list
openclaw backends probe codex --workspace /absolute/workspace
openclaw backends run codex --workspace /absolute/workspace --prompt "Review the current diff"
openclaw backends session send codex bks_1234567890abcdef --text "continue"Backends emit normalized BackendEvent records. Current event types include:
- assistant message
- stdout output
- stderr output
- tool call requested
- shell command proposed
- shell command executed
- patch proposed
- patch applied
- file read
- file write
- error
- session completed
Every backend event can also carry RawLine when it originated from line-oriented process output. This preserves the original CLI output even when OpenClaw also normalizes that line into a higher-level event.
Polling remains available through the JSON events endpoint. Live event delivery is now available through an SSE stream endpoint for backend sessions.
- Backend adapters are best-effort wrappers around vendor CLIs. They normalize what they can, then fall back to raw stdout/stderr events.
- Structured event parsing only works when the underlying CLI exposes a usable structured mode.
- Codex CLI now prefers structured output when the configured args are compatible and probe detection confirms
--jsonsupport. - Gemini CLI and GitHub Copilot CLI currently use text-first normalization because this repo does not assume a stable structured streaming protocol for them yet.
- Plain text fallback is broader now, but still heuristic. Shell, tool, file, and patch events can still fall back to raw stdout/stderr when a vendor CLI changes its output format.
- Authentication is BYO only. This change does not add billing, entitlements, hosted identity, or SaaS plan concepts.
- GitHub Copilot CLI auth is not tied to GitHub repository access in this lane.
- External backend sessions are still persisted separately from native OpenClaw session records even when owner-session history sync is enabled.