Grok via subscription: grokAgent driver (Grok Build CLI over ACP) — no API key - #6
Merged
Conversation
…ACP stdio New driver (server/drivers/grokagent.ts) runs the official `grok` CLI headless over ACP — initialize → authenticate(cached_token) → session/load|new → session/prompt — so bots ride the user's grok.com subscription, no xAI API key. It joins the default fleet under the same rule as claude/codex: no credential to manage, just the CLI installed and signed in (unavailable shadow otherwise). The API-key driver stays registered as "Grok (API)" for anyone who brings a key. - Fail-closed permissions: --permission-mode is always explicit (a global always-approve in ~/.grok/config.toml would otherwise make sessions yolo and never fire session/request_permission), and nothing is ever approved without an explicitly allow-kinded ACP option — option order is not a security contract. - XAI_API_KEY is scrubbed from the child env so billing can never silently flip from the subscription to pay-as-you-go. - session/load replays history through the normal update channel, so resume is double-gated (prompt-sent + _meta.isReplay) to keep old messages out of the chat. - --append-system-prompt/--rules are accepted-but-inert for agent stdio (verified against 1.0.0); personas are prepended codex-style. - Onboarding gains a Grok Build engine row; README lists the third CLI; dist-server regenerated. Known MVP gaps, documented in-code: turn.integrations (Composio/computer) not wired yet (the agent advertises MCP http+sse, so it's a follow-up), static model catalog, cost:null (ACP's costUsdTicks has no documented unit). Verified against grok 1.0.0: allow/deny/interrupt/resume at the driver SPI, 12/12 fail-closed permission tests via a fake ACP agent, and harness E2E including resume across a server restart and the approval-card allow flow.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3
What
A new
grokAgentdriver that runs the official Grok Build CLI (grok) headless over its ACP stdio interface (grok agent stdio, JSON-RPC 2.0/NDJSON), so bots ride the user's grok.com subscription login — no xAI API key anywhere.This directly resolves the reason Grok sat outside the default fleet (the old comment in
config.ts: the API key is a credential nobody wants to manage). The new driver plays by the same rule as claude/codex: no credential in the app, just the CLI installed and signed in — otherwise it degrades to the usual unavailable shadow in the model picker. The API-key driver stays registered (now labeled "Grok (API)") for anyone who brings a key via aninstancesentry.One driver file + registration, per the contributing note in the README:
server/drivers/grokagent.ts— the driver (mirrorscodex.tsstructurally: per-turn child process, RPC pending map, permission asks map, native NDJSON tee, process-group teardown)builtIn.ts/config.ts— registration + default fleet entryProviderIcons.tsx,Onboarding.tsx,README.md— Grok mark for the new kind, a "Grok Build" engine row, docsdist-server/regenerated viapnpm build:serverProtocol notes (all verified against grok CLI 1.0.0)
initialize→authenticate {methodId: "cached_token"}→session/load|new→session/prompt. The prompt RPC result is the turn-completion signal (stopReason + usage); ACP has noturn/completednotification.session/loadreplays the whole history through the normalsession/updatechannel, so resume is double-gated (nothing emitted before the prompt is sent + anything flagged_meta.isReplayis dropped) — old messages never duplicate into the chat. resumeCursor is the ACP sessionId.--append-system-prompt/--rulesare accepted-but-inert foragent stdio(proved with a passphrase probe), so personas are prepended codex-style. Recorded in a comment so nobody re-discovers this the hard way.session/request_permissionand surface as the canonical approval cards.Security decisions
--permission-modeis always explicit. A user-levelpermission_mode = "always-approve"in~/.grok/config.tomlsilently makes sessions yolo (verified: tools ran with zero permission requests until the flag forced it back). Bots always broker approvals through the chat regardless of the user's TUI config.fullAutomaps tobypassPermissions, default off.allow-kinded ACP option — option order is never treated as a security contract; malformed/unknown option sets answercancelled. Onlybehavior === "allow"approves; unknown behaviors deny. 12/12 adversarial cases pass against a fake ACP agent (empty options, unknown kinds, reject-only sets, fullAuto without an allow option).XAI_API_KEYis scrubbed from the child env (same spirit as the codex driver'sOPENAI_API_KEYnote) so billing can never silently flip from the subscription to pay-as-you-go.session/promptdeliberately has none (turns legitimately run long; interrupt + process-exit guards cover hangs).Verified
session/cancel, snapshot with a missing CLI → unavailable shadow.grokinstance → streamed reply → resume across a server restart (persisted resumeCursor) → approval card in chat → Allow viaPOST /respond→ command output in the transcript. Both typecheck configs clean.Known MVP gaps (documented in-code)
turn.integrations(Composio / cloud computer / local cua) is not wired yet —mcpServers: []. The agent advertises MCP http+sse capabilities, so mapping Composio onto an ACP mcpServer entry is a natural follow-up PR; until then bots on this driver have Grok Build's native tools only.grok-4.5, what the CLI reports today); the initialize result carriesmodelState.availableModelsfor a future dynamic catalog.cost: null— ACP reportscostUsdTickswith no documented unit; passing a possibly-wrong number seemed worse than null.