Route grok-cli model selections through the grok CLI runtime when no Fusion-visible GROK_API_KEY is available. - Add read-only isGrokApiKeyFusionVisible() in packages/core/src/grok-provider.ts, refactored to share user-settings-file reading with hydrateGrokApiKeyFromUserSettings without mutating process.env or logging key material. - In packages/engine/src/agent-session-helpers.ts, auto-derive the existing "grok" runtimeHint when defaultProvider is grok-cli, no key is Fusion-visible, and the grok plugin runtime is registered; explicit runtime hints and mock/test-mode routing remain unchanged, and the provider-qualified model prefix is stripped before handoff. - Normalize provider-qualified model ids (grok-cli/<id>, grok/<id>) in the grok-runtime plugin's runtime-adapter and CLI stream spawn so the concrete model reaches `grok --model`, with the historical grok/default fallback preserved for the no-model path. - Update docs (grok-cli-contract.md, settings-reference.md, plugin README) and add/extend tests covering the new fallback behavior, model normalization, and CLI streaming. - Add changeset fn-7753-grok-cli-no-key-fallback.md (patch, fix). Files changed: .changeset/fn-7753-grok-cli-no-key-fallback.md | 7 ++ docs/grok-cli-contract.md | 83 ++++++++++------ docs/settings-reference.md | 6 +- .../__tests__/grok-provider-user-settings.test.ts | 46 +++++++++ packages/core/src/grok-provider.ts | 39 +++++++- packages/core/src/index.gate.ts | 1 + packages/core/src/index.ts | 1 + .../src/__tests__/grok-runtime-routing.test.ts | 107 +++++++++++++++++++-- packages/engine/src/agent-session-helpers.ts | 52 +++++++++- plugins/fusion-plugin-grok-runtime/README.md | 46 +++++---- .../src/__tests__/cli-stream.test.ts | 70 ++++++++++++++ .../src/__tests__/runtime-adapter.test.ts | 28 ++++++ .../fusion-plugin-grok-runtime/src/cli-stream.ts | 6 ++ .../src/runtime-adapter.ts | 24 ++++- 14 files changed, 443 insertions(+), 73 deletions(-) Fusion-Task-Id: FN-7753 Fusion-Task-Lineage: 30ef7265-1ba9-47fd-8c4e-87b02f6a1d78 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
fusion-plugin-grok-runtime
Grok CLI-backed provider/runtime plugin for Fusion.
Install
This plugin ships bundled with Fusion and is auto-installed like the other
built-in runtime plugins. It shells out to an operator-installed grok
binary on PATH — Fusion never downloads or bundles the CLI itself.
- Canonical upstream repo: https://github.com/superagent-ai/grok-cli
- Docs / homepage: https://github.com/superagent-ai/grok-cli#readme
- Install script: https://raw.githubusercontent.com/superagent-ai/grok-cli/main/install.sh
- npm alternative:
bun add -g grok-dev(see https://github.com/superagent-ai/grok-cli/releases) - Binary name:
grok - This is a community-built project, not affiliated with xAI. No fixed
release artifact is bundled by Fusion, so no checksum is pinned
(
upstream-pending-verification).
Contract summary
- Provider ID:
grok-cli - Binary probe:
grok --version - Auth model — the
grokCLI owns its own authentication; Fusion does not require a Fusion-visible API key to enable/use it (FN-7716). Grok has nostatus/whoamisubcommand, so Fusion probes binary availability only and treats a working binary as "ready" (authenticated: true). The CLI itself resolves credentials from more sources than Fusion can see (GROK_API_KEYenv var, a project.env,grok -k <key>,GROK_BASE_URL, sandbox secrets, etc.). Fusion additionally probes two of those locations — theGROK_API_KEYenv var and~/.grok/user-settings.json→{ "apiKey": "..." }— purely as a non-blocking informational hint (apiKeyDetected); it never gates Enable or the authenticated state, and a missing/unreadable/malformed settings file degrades gracefully (never throws). The direct xAI OpenAI-compatible streaming path (base URLhttps://api.x.ai/v1) still uses$GROK_API_KEYwhen present, independent of the CLI provider. - Model discovery:
grok models(plain-text output, with pricing hints per the upstream README). The exact line shape isupstream-pending-verification, so discovery parses conservatively: the leading token before a-label separator, or before the first multi-space pricing column, is treated as the model id; ids are deduplicated. Output that happens to be JSON is tolerated defensively even though the CLI is not known to emit it.
CLI streaming execution path (FN-7722)
In addition to model discovery/probe, this plugin's GrokRuntimeAdapter can
stream a real Grok response through the CLI itself:
grok --prompt "<text>" --format json
--format jsonemits newline-delimited JSON (NDJSON) — one JSON object per line — with event typesstep_start,text,tool_use,step_finish, anderror(verified against upstream source, not just docs prose; seedocs/grok-cli-contract.md).- The adapter parses that stream (
src/stream-parser.ts) and drivesonTextastextevents arrive. There is nothinking/reasoningevent in the verified schema, soonThinkingis never invoked for this path. - Tool execution bridging (FN-7724): each verified
tool_useevent (toolCall/toolResult/timing) additionally drivesonToolStart(toolName, args)/onToolEnd(toolName, isError, result), mirroring the Droid plugin'sDroidCallbacksshape.toolName/argsaretoolCall.function.name/ parsedtoolCall.function.arguments;isErrorderives fromtoolResult.success === false. No Grok→pi tool-name/arg translation is applied — the verified contract does not pin grok-cli's specific tool-name vocabulary (unlike Droid's Claude-shaped names), so names/args pass through unchanged.step_finishis a per-step boundary (a run can contain multiple), not the run terminal, so it does not finalize the adapter's promise; only subprocessclose/errordoes, unchanged from FN-7722. - Auth implication: because the
grokbinary resolves its own credentials for this path (env var, project.env,grok -k, or~/.grok/user-settings.json), a CLI-routed selection needs no Fusion-visibleGROK_API_KEY— unlike the direct xAI OpenAI-compatible streaming path (https://api.x.ai/v1), which still requires one. When Fusion auto-routes a no-keygrok-cli/*model selection through this adapter (FN-7753), the selected model id is passed to the CLI with--model <id>. - This adapter is reached either when an agent explicitly sets
runtimeConfig.runtimeHint === "grok"or when FN-7753's no-visible-keygrok-cli/*fallback derives that hint automatically. See "Routing Grok through the CLI runtime (FN-7725 / FN-7753)" below anddocs/grok-cli-contract.mdfor the full contract and decision record.
Routing Grok through the CLI runtime (FN-7725 / FN-7753)
By default, selecting a grok-cli/* model for an agent/task routes through
the direct xAI OpenAI-compatible endpoint (https://api.x.ai/v1,
FN-7711/FN-7714) whenever Fusion can see a GROK_API_KEY (environment or
~/.grok/user-settings.json apiKey). If no Fusion-visible key resolves and
the Grok Runtime plugin is registered, Fusion automatically routes that session
through the grok CLI runtime instead, letting the CLI own auth end-to-end.
To route a specific agent's execution through the grok CLI's own
non-interactive streaming mode (grok --prompt --format json) instead:
- Open the agent in the dashboard (New Agent or an existing agent's detail view).
- Under Runtime Source, choose Runtime instead of Built-in Model.
- Select Grok Runtime from the runtime dropdown (sourced from
GET /api/plugins/runtimes, which lists every installed plugin runtime including this one). - Save. The agent's
runtimeConfig.runtimeHintis now"grok"; every session that agent drives (as an assigned executor, column agent, or child agent) resolves throughpackages/engine/src/runtime-resolution.tsto this plugin'sGrokRuntimeAdapterinstead of the default pi runtime.
Automatic fallback precedence (FN-7753): explicit runtime hint >
Fusion-visible key/direct endpoint > automatic CLI fallback. The fallback is
only derived when no explicit runtime hint is set, the provider is grok-cli,
no Fusion-visible key resolves, and runtime id "grok" is registered. The
selected model is normalized from grok-cli/<id> (or grok/<id>) to <id>
and sent as --model <id>.
Known limitation: explicit Runtime-mode is still model-agnostic — it does
not carry a specific grok-cli/* model id through to the adapter, so
GrokRuntimeAdapter.createSession() falls back to "grok/default" and omits
--model. Built-in Model selections preserve the model either through the
direct endpoint (when a key is visible) or through the FN-7753 automatic CLI
fallback (when no key is visible).
Enable via Settings → Authentication
- Install the
grokCLI and authenticate it by any method it supports (env var, project.env,grok -k, etc.) — Fusion does not need to see the key. - Open Settings → Authentication in the Fusion dashboard.
- The "Grok — via Grok CLI" card shows probe status. Click Enable once
the binary is available; a non-blocking hint appears only if Fusion did
not detect a key, noting the direct xAI streaming path uses
GROK_API_KEYwhen present. - Discovered Grok models (via
grok models) then merge into the model picker under thegrok-cliprovider id.
Notes
Do not invent a grok status/whoami JSON auth contract — readiness is
derived from binary availability, mirroring the Cursor CLI provider. See
AGENTS.md's "External-integration evidence" policy for why the
release/checksum fields above stay at upstream-pending-verification.