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
| Layer | Command | What it proves |
|---|---|---|
| Unit (wire + pricing + launcher) | see below | session/agent/cwd/noise/cost without network |
| E2E (real proxy + mock xAI) | see below | end-to-end entry recording |
| Live (real Grok CLI) | optional | real 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(notcodex-raw) - Agent =
grokfrom headers / model - System prompt from
input[role=system] - Cwd from
Workspace Path:in user_info - Control-plane noise
buildEntryFieldscost (~$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:
- Grok-header GET
/v1/settings|feedback|models→ 0 dashboard entries - Title-gen POST → entry
agent=grok,sessionId=grok-raw - Main POST → entry
agent=grok, real session UUID, cwd, cost, maxContext 500k - No
codex-rawin 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
| Check | Expect |
|---|---|
| Project | path under /tmp/... (not (unknown)) when user_info has Workspace Path |
| Main session | UUID short id, not Codex Raw |
| Title-gen session | Grok Raw (if present), not Codex Raw |
| Model | grok-4.5 · 500K |
| Cost | ~$0.05 range, not Unknown model |
| Timeline | pong (+ reasoning) |
| Usage tab | filter Grok present; daily/monthly byAccount['grok-default'] includes proxy cost (from index.ndjson, not ~/.grok — Grok sessions do not store token usage) |
| Usage Accounts | Grok 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" (usesgrok-raw) - Control-plane settings/feedback do not flood index
- [~] Title-gen stamps parent session card title via
session_titletool — 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_OVERRIDESonly 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):
| Surface | Observed |
|---|---|
| Sessions column | Grok session renders: grok-4.5-build · 2t, $0.08, 7% of 500K, cache 99% hit · 34K tok |
| Swimlane | main lane drawn, grok-4.5-build · 500K, sys hash, faults/ctx/mutate/safety tracks |
| Detail panel | peak 6.8% · window 500K · compacts 0 · cache 100% · cost $0.0794 · 29K in / 352 out |
| Timeline | 10 steps, grok · f6e11, "View in System Prompt" link live |
| Usage tab | Grok 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 errors | 0 (error hook empty, no .error nodes) |
Two honest notes from that pass:
grok-rawdid not appear as its own sidebar card. Itscwdisnull, so it belongs to no project and the project filter hides it. Pre-existingrawSessionIdbehaviour, 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.
4. Related
- Wire notes:
docs/grok-wire-experiment-2026-07-09.md - Cleanup issue: https://github.com/lis186/ccxray/issues/202
- Hygiene:
docs/testing.md