Fix first-copy-paste 403 dead-end + derive catalog counts from source (was hand-copied, 3-way drift)
2026-08-09
LOCKSTEP TRACEABILITY MATRIX --- api_endpoints: ["none"] sdk_methods_updated: ["none — README examples only"] mcp_tools_updated: ["none"] ---
What We Built
Two related fixes to the first-run developer experience.
- **The headline copy-paste example in both SDK READMEs (and the mirrored
docs/start/sdk-typescript.mdx quickstart) pinned anthropic/claude-sonnet-4** as the very first thing a new developer would paste into their terminal. On a fresh sandbox tenant with no provider key registered, that call 403s. The example is now model: "auto", which works immediately on a brand-new account, and a short "pin a specific model" follow-up shows client.providers.register(...) (BYOK) before the pinned-model call.
- Model/provider counts had drifted three ways: both READMEs said "31
models / 8 providers", site/public/llms.txt said "45/8", scripts/generate-llms-full.ts hardcoded "31 models from 8 providers", and the live catalog (src/router/provider-catalog-capabilities.ts) actually has 44 models across 9 providers (the READMEs' provider list was also missing Z.ai/GLM entirely). A new scripts/catalog-counts.ts (pure, no I/O) derives {modelCount, providerCount, providerNames} directly from MODEL_CAPABILITIES. scripts/generate-catalog-counts.ts (CLI) writes that into -marked spans in both READMEs and llms.txt; generate-llms-full.ts imports the same pure function for its own count line. Wired into pnpm build (before generate-llms-full.ts) and into CI's verify-docs job via pnpm generate:catalog-counts -- --check (exits 1 on drift, mirroring the existing llms-full.txt diff check).
Why It Matters
The first code a developer runs after npm install brainstormrouter failing with a 403 is the single worst first impression the SDK can give — it looks like the product is broken, not that the example needs a provider key. The count drift is smaller but compounds: three different "how many models" numbers across public-facing docs erodes trust in anything else quoted in those files.
How It Works
getCatalogCounts() in scripts/catalog-counts.ts walks MODEL_CAPABILITIES (provider → modelId → capability info) and counts keys — the same object that clamps maxOutputTokens in the router, so there is exactly one source of truth. formatCatalogSummary / formatCuratedCatalogSummary render the two phrasings used in the wild ("N models from M providers (...)" vs "N curated models from M providers (...)"). The CLI script does simple marker-delimited string replacement, so editors are free to reword the surrounding sentence without breaking the generator.
src/api/server.ts's hand-maintained GET /llms.txt duplicate (flagged for its owning engineer, not touched here) does not state a count at all — it says "Live model count: GET /v1/models" — so it was already immune to this specific drift, though it remains a duplicate surface to keep in sync for other content changes.
The Numbers
Catalog as of this change: 44 models, 9 providers — Anthropic (13), OpenAI (12), Google (3), DeepSeek (4), xAI (2), Groq (3), Perplexity (2), Z.ai (2), Moonshot (3).
Competitive Edge
N/A — internal doc-quality fix.
Lockstep Checklist
- [x] API Routes: none changed.
- [x] TS SDK: README example fixed (no code/type changes needed).
- [x] Python SDK: README example fixed (no code/type changes needed).
- [x] MCP Schemas: not applicable (no API surface changed).
- [ ] Master Record: not applicable — no new capability, doc-accuracy fix only.
Follow-ups (owner-gated / other engineers)
src/api/server.ts'sGET /llms.txtduplicate should be checked for other
drift against site/public/llms.txt (per CLAUDE.md's "edit both copies" note) — its count line is already drift-proof by design, but other prose may still diverge.