You've used Google Antigravity, where the agent, the models, and the billing come pre-wired. Here you assemble the same thing yourself — and learn exactly where it breaks.
Google Antigravity is an agentic IDEA code editor with an AI agent living inside it — you chat, it reads and edits your files and runs commands.: you chat with an agent, pick a model from a dropdown, and it spends quota tied to your plan. The agent, the model access, and the billing are bundled and pre-wired. You open it and type.
pi is that same agent, unbundled — delivered as text in a terminal, free to point at any AI provider. Wire it to Cloudflare and you rebuild the whole Antigravity experience from parts:
| The agent chat in the editor | → pi, run in a terminal |
| The model dropdown | → a model name in a config file (@cf/…) |
| Your Google login + plan | → a Cloudflare account + an API token |
| Credits that refill on a timer | → Neurons, Cloudflare's daily AI allowance |
Everything Antigravity hides behind a graphical shell, you provide as three things: an agent (pi), a credential (one specific kind of token), and a route to the model (a URL in a config file). Get those three right and it just works. Get the token or the config subtly wrong and it fails in ways that look random — which is exactly what the rest of this page teaches you to see coming.
When pi answers you, it sends an HTTP request to a Cloudflare model. Two things ride along: an Authorization headerA line on the request that carries your secret token, proving who you are — like showing a badge at a door. carrying your token, and a base URLThe address the request is sent to. Change it and the same request goes somewhere else — this is the one lever that routes you through the Gateway. that decides where it lands. Flip the switch and watch the path change:
That switch is a single line in a file called models.json: set baseUrl to the Gateway address and every model call detours through it — same token, same models, now with a dashboard of logs. Leave it out and you go direct. That's the entire difference.
The number-one beginner trap isn't a typo — it's using the wrong kind of token. Cloudflare has two, and they look similar but behave nothing alike. Pick one and scrub time forward to see what a real setup does over the following days:
A token starting with cfoat_ is a Cloudflare OAuth Access Token — the short-lived kind wrangler login mints. It's valid right after sign-in, then its refresh chain silently lapses and every call returns 401/403. Because it works at first, the failure looks random and shows up hours later. Scrub the OAuth timeline past its expiry and watch green turn to red. The dashboard API token has no expiry — it stays green forever.
You've installed nothing — no wrangler — so you can't accidentally make a cfoat_ token. You create the right one with clicks in the Cloudflare dashboard, scoped to Workers AI + AI GatewayThree permission rows on the token: Workers AI · Read, AI Gateway · Read, AI Gateway · Edit — all set to "Account". The Edit row lets a default gateway create itself.. Ignore any tutorial that says wrangler login.
pi reads your secret from ~/.pi/agent/auth.json. Three tiny mistakes each break it in a different, silent way — and beginners hit all three. Build the file with the switches and watch pi's verdict update live:
1 · Key in the wrong place. pi reads the secret from the top-level "key" field only. Put it under env.CLOUDFLARE_API_KEY and pi acts like it has no credentials — no error, just nothing.
2 · A trailing comma. The file is parsed with strict JSON. One comma after the last item throws, and that voids the whole file: pi ignores your credential and refuses to save new ones.
3 · The wrong token (from part 03). Toggle each switch and read how the verdict changes.
One last surprise. Some models come back empty — no error you can see, just blank. It's a token-budget overflow, and it's a knob you can watch tip over. pi asks the model to reserve room for its reply; if the input + reserved replyEvery request spends tokens on your prompt (input) plus the space reserved for the model's answer (completion). Their sum must fit under the model's real context limit. exceeds the model's real limit, Cloudflare rejects the whole call.
pi's built-in metadata claims glm-5.2 holds 262,144 tokens, but Cloudflare's real cap is 256,000. Left at the default, pi reserves the whole (wrong, bigger) window for the reply, so input + reply overshoots by a hair and every call returns a 400 — surfacing as empty output. The fix is one line in models.json: cap maxTokens to a sane 32000. Slide it down and watch the gauge drop under the ceiling.
You've seen every failure mode. One question to prove it stuck:
And a word on cost, so nothing surprises you: Cloudflare meters AI in NeuronsCloudflare's unit for the GPU work a request uses. 10,000 free every day on any plan, resetting at 00:00 UTC.. Every account gets 10,000 free per day (reset at 00:00 UTC); past that you either wait for the reset or upgrade to Workers Paid at $0.011 / 1k. If calls suddenly fail after a heavy day, that's the meter — not your config.
pi + Cloudflare is Antigravity unbundled: an agent you run, a long-lived API token (never cfoat_) placed in the top-level "key" of comma-clean JSON, and a base URL that routes you direct or through the Gateway. Three things right, and the terminal answers back.