cloudcode-pi-provider

Use CloudCode.ONE pay-as-you-go models (DeepSeek V4, GLM, Kimi) inside the pi coding agent, with live pricing and automatic vision routing.

Packages

Package details

extension

Install cloudcode-pi-provider from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:cloudcode-pi-provider
Package
cloudcode-pi-provider
Version
0.1.0
Published
Aug 18, 2026
Downloads
161/mo · 18/wk
Author
tatuhelander
License
MIT
Types
extension
Size
28.6 KB
Dependencies
0 dependencies · 2 peers
Pi manifest JSON
{
  "extensions": [
    "./extensions/cloudcode.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

cloudcode-pi-provider

Adds CloudCode.ONE as a model provider for the pi coding agent.

Pay-as-you-go agentic coding — no subscription, credit from $2 — with live prices pulled from the public catalog and images routed automatically to a vision model.

Install

pi install npm:cloudcode-pi-provider

Project-local instead of global:

pi install npm:cloudcode-pi-provider -l

Try it without installing:

pi -e npm:cloudcode-pi-provider

Configure

Either sign in from inside pi:

/login cloudcode

That opens the CloudCode.ONE consent page in your browser (PKCE, loopback callback), trades the one-time code for your sk-… key, and stores it in pi's credential store. The same dialog also offers API key if you would rather paste one — use that on a headless or remote machine, where the browser cannot reach the loopback callback.

Or set the key in the environment:

export CLOUDCODE_API_KEY=sk-...      # add to ~/.bashrc or ~/.zshrc
setx CLOUDCODE_API_KEY "sk-..."      # Windows

CLOUDCODE_TOKEN is accepted too, so a machine already set up for the CloudCode.ONE desktop harness needs no second variable. A credential stored by /login takes precedence over the environment.

Get a key from your dashboard either way.

Use

pi
# /model → cloudcode → deepseek-v4-pro

Or start directly on a model:

pi --model cloudcode/deepseek-v4-pro

What it does

  • Registers a cloudcode provider against https://api.cloudcode.one/v1/messages
  • Fetches the model catalog from https://cloudcode.one/models.json at startup and on every model-list refresh, with a bundled snapshot as the offline fallback
  • Prices every turn from that catalog, so pi's session cost is the real cost
  • Lists only the models your key is actually provisioned for, so /model never offers something that 403s (see below)
  • Advertises every model as image-capable, since the gateway reroutes image requests to a vision model on its own

Per-key model list

Keys are provisioned with a model allowlist, and the gateway's /v1/models is filtered by it — so it answers "what may this key use?", which the one public models.json cannot. The provider intersects the two: prices and context sizes come from the catalog, the set of models from your key.

If /v1/models cannot be reached, or no key is configured yet, you get the full catalog instead — a list that may be too generous is better than an empty picker. The filter re-applies on the next model-list refresh, which is also when a key stored by /login first gets to narrow the list: pi's startup refresh runs with networking disabled, so until you open /model the list comes from the environment key alone.

Why the Anthropic API and not the OpenAI-compatible one

The gateway speaks both, but its preserved-thinking rewrite — handing the model's own reasoning from earlier turns back to the upstream instead of dropping it — only runs on the /v1/messages path. OpenAI-shape clients get their reasoning stripped, which costs continuity and prompt-cache hits across a long coding loop. So the provider registers with api: "anthropic-messages", the same path the CloudCode.ONE desktop app uses.

Why the portal catalog and not /v1/models

The gateway's /v1/models also lists its -direct fallback deployments (glm-5.2-direct and friends), which exist only so a call can fail over when the primary backend returns 503 — and which bill at 3-4x the primary rate. Listing them as ordinary choices would put a much more expensive model one keystroke away in /model. models.json is the customer-facing catalog and carries the prices, so that is what this provider reads.

Models and prices

Prices are whatever models.json says at startup; the table below is the bundled snapshot, in USD per 1M tokens.

Model Input Output Cached input Notes
deepseek-v4-pro 1.705 5.115 0.0568 Main coding model · 1M context
deepseek-v4-flash 0.176 0.528 0.0056 Fast subagents · 1M context
glm-5.2 0.56 1.76 0.104 Flagship coding agent · 1M context
glm-5.1 0.56 1.76 0.104 200K context
glm-5v-turbo 2.4 8.0 0.48 Vision
kimi-k3 1.5 7.5 0.15 Vision + reasoning · 1M context
kimi-k2.6 0.38 1.6 0.064 Vision + reasoning · 256K context
kimi-k2.5 0.24 1.2 0.04 Vision + reasoning · 256K context
glm-4.7-flash 0 0 Free tier
glm-4.6v-flash 0 0 Free tier · vision

Three things the catalog cannot express through pi's per-token cost model, and how this provider handles them:

  • Images cost a flat $0.02 surcharge per distinct image on top of tokens, because the gateway reroutes image requests to a vision model. It is charged once per image per key per UTC day — resending the same screenshot is free — and capped at 10 new images a day, after which image requests get a 429. pi has no per-request cost field, so a session that sends screenshots reads under its true cost twice over: the surcharge is invisible, and the rerouted turn is billed at the vision model's token rate while pi prices it at the rate of the model you selected.
  • Cache writes are priced at the normal input rate, because the gateway sets no cache-creation rate for any deployment: these upstreams (DeepSeek, z.ai, Moonshot) do not add Anthropic's 1.25x write surcharge. A model with no published cache discount prices cache reads at the input rate too, so the estimate errs high rather than low.
  • Context windows are read from each catalog entry's blurb, treating K and M as 1e3/1e6 rather than 1024-based — a "256K" model registers as 256,000 against a real 262,144. Undercounting is the safe direction: pi compacts a little early instead of walking into an overflow. Entries whose blurb names no context size fall back to 128K.

Separately, keys are rate-limited to 200 requests per rolling 5 hours; over that the gateway returns a 429 with a retry-after, which pi backs off and retries.

Thinking

Every model here reasons, but the models are registered with reasoning: false so pi asks for nothing: thinking is configured per deployment inside the gateway, which drops a client-sent thinking parameter for its OpenAI-shape upstreams (GLM, Kimi) and passes it straight through to DeepSeek's Anthropic endpoint, where pi's display: "summarized" field is unvalidated territory. The CloudCode.ONE desktop app sends no thinking parameter for the same reason.

Nothing is lost in the transcript: reasoning still streams back as thinking blocks and pi renders them, and pi replays those signed blocks on later turns — which is exactly what the gateway's preserved-thinking rewrite consumes. The only visible difference is that /model shows these models as non-reasoning and the thinking-level picker does not apply to them.

If you want the picker anyway — on deepseek-v4-pro and deepseek-v4-flash a thinking budget does reach the upstream — turn it on per model in ~/.pi/agent/models.json:

{
  "providers": {
    "cloudcode": {
      "modelOverrides": {
        "deepseek-v4-pro": { "reasoning": true }
      }
    }
  }
}

Overrides

Point at a different endpoint (staging, self-hosted):

export CLOUDCODE_BASE_URL=https://staging.cloudcode.one    # /v1 suffix is accepted and stripped
export CLOUDCODE_PORTAL_URL=https://staging.cloudcode.one  # where /login and models.json live

Per-model tweaks without touching the package go in ~/.pi/agent/models.json under modelOverrides, which accepts name, reasoning, thinkingLevelMap, input, cost, contextWindow, maxTokens, headers, and compat:

{
  "providers": {
    "cloudcode": {
      "modelOverrides": {
        "deepseek-v4-pro": { "maxTokens": 16384 }
      }
    }
  }
}

maxTokens defaults to 32768 for every model. Lower values truncate large tool calls mid-JSON — an editor write of a few hundred lines is comfortably past 8192 tokens — which surfaces as unparseable tool arguments from the weaker models, so raise it back if you hit that.

Development

npm install
npm run check                                   # tsc --noEmit
CLOUDCODE_API_KEY=sk-... pi -ne -e . --list-models cloudcode

License

MIT