Show HN: The Price of Patience A developer published a companion guide and a single-file TypeScript extension, doubleword.ts, that configures the pi coding agent against the Doubleword Inference API, pulling all 18 chat models live from Doubleword's catalog with per-token pricing mapped to pi's cost fields. The setup defaults every request to Doubleword's cheaper async tier via service_tier: "flex", switchable to realtime with /doubleword-mode realtime or the DOUBLEWORD_EXECUTION_MODE=realtime environment variable, and includes a verification pass for a silent failure that can prevent the system prompt, skills and rules from reaching the model. The guide pins installation to commit SHA 9a452e6, noting that pi executes extensions, so installing from a moving main branch is "policy you didn't choose. This is the companion guide to The Price of Patience https://github.com/konarkmodi/pi-doubleword/blob/main/the-price-of-patience.md — the story of how this setup was built, benchmarked, and audited. The article explains why ; this README shows how . Using Doubleword as your pi daily driver: auto-discovered models, flex billing, and instructions that actually arrive How to configure the pi coding agent https://github.com/badlogic/pi-mono against the Doubleword Inference API https://doubleword.ai — with every model pulled live from their catalog, the cheap async service tier: "flex" tier on by default, and a verification pass that catches the one silent failure that made my skills disappear. A pi setup where: - GET /v1/models?include=pricing is fetched at startup, and all 18 chat models GLM, Qwen, DeepSeek, Kimi, Gemma, … appear with live per-token pricing mapped to pi's cost fields — from the realtime, async, and batch tariffs Doubleword publishes per model. - Flex is the default tier : every request carries service tier: "flex" , Doubleword's cheaper async execution mode. Flipping to realtime is one command: /doubleword-mode realtime per session or export DOUBLEWORD EXECUTION MODE=realtime global . - Your key can live wherever pi already keeps keys — environment variable, models.json , or /login storage — no juggling. - Catalog refresh, model switch, and tier switching all take effect live — the session rebinds to fresh model objects instead of waiting for a restart. - And critically: the system prompt — skills, rules, harness context — actually reaches the model. I'll show you the check for that, because on Doubleword it can silently fail. Grab an API key from your Doubleword dashboard. pi reads provider keys from a few standard places; any one of these works: Option A — environment variable simplest : export DOUBLEWORD API KEY="dw-sk-..." Option B — pi's models.json survives across shells : { "providers": { "doubleword": { "name": "Doubleword", "baseUrl": "https://api.doubleword.ai/v1", "api": "openai-completions", "apiKey": "dw-sk-...", "models": } } } ~/.pi/agent/models.json. The extension replaces the models list with the live catalog at startup; any entries you keep here serve as a fallback when the catalog is temporarily unreachable — one or two definitions are plenty. Option C — just /login in pi and pick the provider there. The extension resolves all three, in that order, at request time. If it can't find one at startup it will ask pi's credential store on first refresh. Save doubleword.ts https://github.com/konarkmodi/pi-doubleword/blob/main/doubleword.ts into ~/.pi/agent/extensions/ : mkdir -p ~/.pi/agent/extensions curl -o ~/.pi/agent/extensions/doubleword.ts \ https://raw.githubusercontent.com/konarkmodi/pi-doubleword/9a452e6/doubleword.ts Pinned to a commit SHA: pi executes extensions, so installing from a moving main is policy you didn't choose. Bump the SHA deliberately when you adopt updates. Or: clone the repo, copy the file. It's one TypeScript file, no dependencies. On next launch, pi loads it, fetches include=pricing immediately, and — if the catalog is reachable — replaces the fallback model list with live models. In pi you'll see: Doubleword: 18 models available. If your key was missing or the network was down, you'll see: Doubleword: catalog unavailable HTTP 401 ... . Run /doubleword-refresh after /login. …then fix auth and run /doubleword-refresh — the fix applies to your open session immediately. Set a model as your daily default in ~/.pi/agent/settings.json : { "defaultProvider": "doubleword", "defaultModel": "zai-org/GLM-5.3-Flash", "defaultThinkingLevel": "medium" } Now launch pi bare — no --model flag needed. One-off runs work from any directory: pi --model doubleword/zai-org/GLM-5.3-Flash "Reply with exactly OTTERS-OK" About flex. Doubleword sells two ways to run a model: realtime standard latency, standard price and async service tier "flex" , discounted price — at the time of writing, e.g. GLM-5.3-Flash goes from $0.15/$0.50 to $0.11/$0.38 per MTok . Under the hood the extension stamps every live model with samplingParams: { service tier: "flex" } — so every chat request carries it and the response echoes it back. Flip per session or globally: /doubleword-mode realtime this session /doubleword-mode async back to the default export DOUBLEWORD EXECUTION MODE=realtime for the shell / CI Realtime mode removes the service tier sampling param entirely there's nothing to echo . Your bill reflects whichever mode was active per request. flex-bench.mjs https://github.com/konarkmodi/pi-doubleword/blob/main/flex-bench.mjs puts a stopwatch on it — same prompt to both tiers, interleaved rounds so time-of-day can't rig the comparison , costs computed from the live catalog rates: MODEL=zai-org/GLM-5.3-Flash node flex-bench.mjs A real run GLM-5.3-Flash, Nov 2026, 5 interleaved rounds/tier : | | realtime | flex service tier:"flex" | Δ | |---|---|---|---| | Catalog rate in/out per MTok | $0.150 / $0.500 | $0.110 / $0.380 | −27% in / −24% out | | TTFT median | 0.17 s | 4.84 s | +4.7 s | | Total latency median | 4.48 s | 4.84 s | +0.37 s ≈8% | | Delivery | progressive stream ~60–95 tok/s visible | one burst | — | | Tier echo | none | "flex" non-streaming responses | — | How to read it: - You pay at the start, not the end. Flex's queue adds seconds to first token , but by the last token the two tiers are a few hundred milliseconds apart. For agents which care when the job is done , flex is nearly free money. For a human watching a stream, it's the difference between a typist and an envelope. - Flex responses arrive as one burst — TTFT equals total latency queued compute flushes complete . Anything building a typing UI should know this. - Reasoning-budget variance dominates per-request cost. Identical prompts ranged 211–1,992 reasoning tokens 3–9× , so compare rates , not per-run medians. - Small sample, one model, one hour of the day — queueing varies. Run it yourself before quoting numbers. This is the step I skipped — and it cost me. Here's what happened, in one paragraph: pi encodes its system prompt harness rules, tool guidance, your