/** * GrokAgentRunner — AgentRunner impl backed by the Grok Build CLI (`grok`, * xAI's agentic coding CLI: https://docs.x.ai/build/cli). * * Architectural pattern: SAME as CodexAgentRunner/AntigravityAgentRunner/ * KimiCodeAgentRunner — spawn the vendor's CLI binary, parse its NDJSON * stream, normalize to AgentMessage. No SDK dependency. * * Auth: inherited from the CLI's own login flow (subscription/API key * managed by `grok` itself). No env vars set by this runner. * * Streaming / liveness — WHY INCREMENTAL (#204): * This runner originally buffered ALL of grok's stdout until the * subprocess exited before parsing anything, so any turn longer than * session.ts's 4-minute silent-stream watchdog (SILENT_SESSION_MS) yielded * zero messages in time — abort, retry, kill, circuit breaker. Same bug * class the codex/kimi/antigravity runners had (#204 audit). This runner * now parses stdout LINE BY LINE as data arrives: a liveness `tool_use` * message is yielded the instant the subprocess spawns (deterministically * winning the watchdog's first-pull race regardless of model latency), and * each parsed assistant event is yielded as its line lands rather than * accumulated until process exit. grok's own tool calls arrive as * `tool_use` blocks in assistant frames and their results as * `tool_result` blocks in user frames (`streaming-messages-json`, below); * both are forwarded as rich tool_use/tool_result pairs matched by grok's * call id. Fatal provider errors (auth/quota) are classified via * the shared classifyStderr helper (same as kimi/codex/antigravity) and * tagged non-retryable. The STARTUP_GRACE_MS first-run-prompt hang * detection below is unrelated to #204 (it guards a different failure * mode — a stuck interactive trust prompt, not a slow-but-alive turn) and * is unchanged by this fix. * * Org tools (org_send, knowledge_search, ask_human, …) — FENCE PROTOCOL: * Same approach as codex/kimi/opencode. Tools are rendered INTO the first * prompt; the model emits ```tool_call fences; this runner parses them out * of the assistant text, executes the real OrgToolDef handlers in-process * (gated through canUseTool), and feeds results back as the next prompt. * * Subprocess protocol — per public docs (docs.x.ai/build/cli/reference), * PARTIALLY byte-verified against a live v1.0.5 install (`npm install -g * @xai-official/grok`; see #178). CONFIRMED LIVE: the flag was wrong — this * runner used to pass `--format json`, which grok rejects outright * ("unexpected argument '--format' found" — no such flag exists). Fixed to * `--output-format json`, confirmed correct by getting past argument * parsing straight to an auth error ("Not signed in") with no XAI_API_KEY * available to test further. * * STILL UNVERIFIED (no XAI_API_KEY in the environment this fix was made * in): grok's `--output-format` has FOUR documented values — `plain`, * `json`, `streaming-json` (NDJSON of native ACP session updates), and * `streaming-messages-json` (NDJSON in the Anthropic Messages API wire * format). This runner uses plain `json`, but events are parsed as * one-JSON-object-per-line (NDJSON) — worth checking live whether `json` * actually emits NDJSON, or a single (possibly multi-line-formatted) JSON * blob that would break the line-based parser. If it's the latter, * `streaming-messages-json` looks like the better fit (NDJSON, and a * documented wire format this codebase already knows how to parse * elsewhere) — untested, flagging rather than guessing. The exact NDJSON * event field names for whichever format is correct were STILL not * available at fix time, so event parsing tolerates several plausible * shapes (codex-style `item.type === 'agent_message'`, a flat `role: * 'assistant'` shape, and a flat `type: 'assistant'`/`'message'` shape) * rather than committing to one. Verify against a real XAI_API_KEY and * tighten this parser if the real shape differs — a wrong guess here fails * closed (no text extracted, not a crash), which is what the "no known * shape matched" path is for. * - Invocation: `grok -p "" --output-format streaming-messages-json * --always-approve [--sandbox workspace] [--model X] * [--reasoning-effort L] [--max-turns N] --cwd Y [--resume ]` * (the sandbox profile follows the role's policy.git level — cli-sandbox.ts; * `--access full` drops it). SUPERSEDES the `json` notes below: the * format switch is documented in grok-runner-stream.ts. * - Session continuity: `-r/--resume []` resumes a specific session, * `-c/--continue` resumes the most recent one. Session id is captured * from any event carrying `session_id` / `sessionId` / `thread_id`. * - stderr is human diagnostics; buffered and surfaced on non-zero exit. * * File-size sweep: the NDJSON event extractors + batch parser live in * grok-runner-parse.ts, and the subprocess turn runner (streamTurn) and * turn-error builder (turnError) live in grok-runner-stream.ts — both * re-exported below where other modules import them from here. */ import type { AgentMessage, AgentRunArgs, AgentRunner } from './agent-runner.js'; export type { GrokStreamEvent } from './grok-runner-parse.js'; export { parseGrokEvents } from './grok-runner-parse.js'; export declare class GrokAgentRunner implements AgentRunner { private grokBin?; constructor(grokBin?: string | undefined); run(args: AgentRunArgs): AsyncIterable; } //# sourceMappingURL=grok-runner.d.ts.map