Provider module acceptance

August 21, 2026 · View on GitHub

Grok is one agent module in server/providers.js + OPENAI_WIRE_CLIENTS (not a separate product). This file is the acceptance checklist for that module.

Quick matrix

LayerCommandWhat it proves
Unit (wire + pricing + launcher)see belowsession/agent/cwd/noise/cost without network
E2E (real proxy + mock xAI)see belowend-to-end entry recording
Live (real Grok CLI)optionalreal auth + cli-chat-proxy

Always isolate storage:

export CCXRAY_HOME=$(mktemp -d)

1. Automated suite (CI-safe)

From worktree:

# repo root of feat/grok-cli-support (or worktree)

CCXRAY_HOME=$(mktemp -d) node --test \
  test/grok-wire.test.js \
  test/grok-proxy.e2e.test.js \
  test/providers.test.js \
  test/wire-parsers-openai.test.js \
  test/config.test.js \
  test/pricing.test.js

Full suite:

CCXRAY_HOME=$(mktemp -d) npm test

Fixtures

Synthetic only (no real usernames/paths from ~/.grok):

test/fixtures/wire-parsers/grok/
  main_req.json          # POST /v1/responses body (system in input)
  title_req.json         # parallel title-gen (forced session_title tool)
  main_sse_events.json   # parsed SSE events with usage
  headers_main.json      # x-grok-session-id populated
  headers_title.json     # empty session headers (grok-raw path)

What grok-wire.test.js covers

  • Client detect + xAI vs OpenAI upstream routing
  • Session: real UUID from headers; empty headers → grok-raw (not codex-raw)
  • Agent = grok from headers / model
  • System prompt from input[role=system]
  • Cwd from Workspace Path: in user_info
  • Control-plane noise
  • buildEntryFields cost (~$0.05 style) + 500k context + usage normalize
  • Launcher env GROK_CLI_CHAT_PROXY_BASE_URL

What grok-proxy.e2e.test.js covers

Spawns real server/index.js with XAI_BASE_URL → mock HTTP server:

  1. Grok-header GET /v1/settings|feedback|models0 dashboard entries
  2. Title-gen POST → entry agent=grok, sessionId=grok-raw
  3. Main POST → entry agent=grok, real session UUID, cwd, cost, maxContext 500k
  4. No codex-raw in index

2. Live smoke (optional, needs grok login)

cd .claude/worktrees/grok-wire-experiment
export CCXRAY_HOME=$(mktemp -d)
PORT=5612

CCXRAY_EXPORT_DISABLE=1 node server/index.js --port $PORT --no-browser &
# wait for listen…

mkdir -p /tmp/grok-ccxray-smoke && cd /tmp/grok-ccxray-smoke
GROK_CLI_CHAT_PROXY_BASE_URL=http://127.0.0.1:$PORT/v1 \
  grok -p "Reply with exactly one word: pong" \
  --always-approve --max-turns 1 --no-subagents --disable-web-search

open "http://127.0.0.1:$PORT"

Dashboard checklist

CheckExpect
Projectpath under /tmp/... (not (unknown)) when user_info has Workspace Path
Main sessionUUID short id, not Codex Raw
Title-gen sessionGrok Raw (if present), not Codex Raw
Modelgrok-4.5 · 500K
Cost~$0.05 range, not Unknown model
Timelinepong (+ reasoning)
Usage tabfilter Grok present; daily/monthly byAccount['grok-default'] includes proxy cost (from index.ndjson, not ~/.grok — Grok sessions do not store token usage)
Usage AccountsGrok card mirrors CLI /usage: Weekly SuperGrok Limit from GET /v1/billing?format=credits (creditUsagePercent, currentPeriod.end). No 5h window; no Today/Month $ on the Grok rate card. Soft-refresh while Usage tab is open.

One-shot launcher

CCXRAY_HOME=$(mktemp -d) CCXRAY_EXPORT_DISABLE=1 node server/index.js --port 5613 grok

3. Acceptance criteria (product)

  • Automated unit + e2e green under empty CCXRAY_HOME
  • Live main turn: agent=grok, UUID session, cost non-null
  • Title-gen never creates codex-raw / "Codex Raw" (uses grok-raw)
  • Control-plane settings/feedback do not flood index
  • [~] Title-gen stamps parent session card title via session_title tool — conditional, not unconditional: it resolves only while the parent turn is still in flight when the title turn completes. Measured 3/4 live runs on 0.2.114; the failing one was an agentic prompt whose title turn finished 7.2s before the parent's first request opened. Tracked in #399
  • LITELLM_LAG_OVERRIDES only for models still missing from LiteLLM (grok-build; see issue #202)

3b. Browser verification (2026-08-01, merged tree @ 0274cf7)

CLAUDE.md requires UI or server changes to be verified in a real browser, not only by unit tests. Done once against the merged tree, isolated CCXRAY_HOME, port 5615, one agentic Grok run (browser-harness / CDP against a real Chrome):

SurfaceObserved
Sessions columnGrok session renders: grok-4.5-build · 2t, $0.08, 7% of 500K, cache 99% hit · 34K tok
Swimlanemain lane drawn, grok-4.5-build · 500K, sys hash, faults/ctx/mutate/safety tracks
Detail panelpeak 6.8% · window 500K · compacts 0 · cache 100% · cost $0.0794 · 29K in / 352 out
Timeline10 steps, grok · f6e11, "View in System Prompt" link live
Usage tabGrok filter chip present; Grok account card shows Weekly SuperGrok Limit 99% left, resets in 3d 22h, period 2026-07-29 → 2026-08-05; Grok segment visible in the daily-cost bars
Page errors0 (error hook empty, no .error nodes)

Two honest notes from that pass:

  • grok-raw did not appear as its own sidebar card. Its cwd is null, so it belongs to no project and the project filter hides it. Pre-existing rawSessionId behaviour, not a regression.
  • That same run is the one where title-gen attribution returned null (see the acceptance note above) — the session card showed the raw prompt, not the generated title.