@rise-so/pi-grok-build

xAI Grok Build provider for pi: OAuth login (borrowed Grok CLI client) plus Grok chat models over the OpenAI Responses API. OAuth only. Usable as a pi extension or as a pi-ai library provider.

Packages

Package details

extension

Install @rise-so/pi-grok-build from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@rise-so/pi-grok-build
Package
@rise-so/pi-grok-build
Version
0.4.0
Published
Jul 16, 2026
Downloads
1,420/mo · 173/wk
Author
viktortnk
License
MIT
Types
extension
Size
87.4 KB
Dependencies
0 dependencies · 1 peer
Pi manifest JSON
{
  "extensions": [
    "./src/extension.ts"
  ]
}

Security note

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

README

pi-grok-build

xAI Grok Build for pi: OAuth login (Grok subscription) plus Grok chat models over the OpenAI Responses API. OAuth only — API keys are deliberately unsupported in this project.

One dependency-free core with two adapters:

Entry point File Use it for
@rise-so/pi-grok-build/extension src/extension.ts pi coding-agent extension: /login offers "xAI (Grok subscription)", pi --list-models shows the models
@rise-so/pi-grok-build src/provider.ts a pi-ai Provider<"openai-responses"> for programs composing their own Models registry (pi-ai / pi-agent core)
@rise-so/pi-grok-build/core src/xai-grok-build.ts the raw OAuth flow (loginXai, refreshXai) and model metadata, no pi-ai runtime imports

Models

Model Context Pricing (per Mtok in/out/cache-read) Notes
grok-4.5 500k $2.00 / $6.00 / $0.50 reasoning model; documented efforts low / medium / high (default high, can't be disabled); pricing live-verified; encoded long-context tier doubles past 200k
grok-composer-2.5-fast 200k $3.00 / $15.00 / $0.50 listed by the CLI proxy; prompt-sensitive; context/output metadata from third-party registries

grok-build-0.1 is deliberately not registered. It can emit reasoning tokens but rejects explicit reasoning effort, which makes it a poor fit for Pi's reasoning-level controls.

Composer works under Pi's normal system prompt and output budget, but live probes found that tiny output caps can spend the budget on thinking without a visible answer. Raw calls without a strong system prompt can also drift into unrelated task/tool-looking text. It remains reasoning: false because xAI rejects explicit reasoning effort for it; Pi can still parse thinking blocks when the model emits them.

Reasoning models always request include: ["reasoning.encrypted_content"] without forcing an effort. Pi uses store: false and replays full history from session files, so opaque reasoning data remains available after reload.

Use as a pi extension

For development, load the extension directly from a checkout:

pi -e /path/to/pi-grok-build

To test the same physical-copy shape used by a stable home-directory install, pack the current checkout and replace ~/.pi/agent/extensions/pi-grok-build:

make install-extension

The target refuses to run while the npm-managed package is installed or still configured, because loading both copies would register the provider and its request hook twice. Override the Pi home for isolated tests with PI_AGENT_DIR=/path/to/test-agent make install-extension.

For a permanent install, copy the project into pi's extensions directory — a copy gives pi a stable snapshot that won't shift underneath it as the checkout changes:

cp -R /path/to/pi-grok-build ~/.pi/agent/extensions/pi-grok-build

Then pick a model:

pi --model xai-grok-build/grok-4.5
pi --model xai-grok-build/grok-4.5 -p "one-shot prompt"
pi --model xai-grok-build/grok-4.5:high -p "harder task"
pi --model xai-grok-build/grok-composer-2.5-fast -p "one-shot prompt"

No npm install is needed for pi imports — pi's loader aliases @earendil-works/pi-* to its own bundled copies. The extension registers the provider id xai-grok-build; log in with /login (OAuth is the only credential — the provider intentionally has no API-key path).

Install as a pi package

This repo is a pi package (package.json declares the extension under the pi key), so pi install can manage it — pi records the source in ~/.pi/agent/settings.json and loads the extension on every run:

pi install /path/to/pi-grok-build                # from a local checkout
pi install git:github.com/rise-so/pi-grok-build  # from a git remote (@tag to pin)

pi list                                      # confirm it's installed
pi remove /path/to/pi-grok-build             # uninstall

Add -l to pi install to record it in the project's .pi/settings.json instead of your user settings.

Use as a library provider

import { createModels } from "@earendil-works/pi-ai";
import { xaiGrokBuildResponsesProvider } from "@rise-so/pi-grok-build";

const models = createModels({ credentials: myCredentialStore }); // holds the OAuth credential
models.setProvider(
  xaiGrokBuildResponsesProvider(),
);

const model = models.getModel("xai-grok-build", "grok-4.5");
if (!model) throw new Error("model not registered");
const reply = await models.completeSimple(model, {
  messages: [{ role: "user", content: "hello", timestamp: Date.now() }],
});

The host owns credential storage: pass a CredentialStore holding the OAuth credential (obtained via the provider's auth.oauth.login), and pi-ai handles refresh through the provider's own refresh. live/support.ts has a working file-backed example. Model constants (GROK_MODELS, GROK_45_MODEL, …) are exported from the package root.

@earendil-works/pi-ai is a peer dependency (pinned to >=0.80.0 <0.81.0). The package exports built output (dist/, .js + .d.ts), so it installs cleanly from npm, a tarball, or a git dependency — Node refuses to type-strip raw .ts under node_modules, so the build step is what makes copy-based installs work. pnpm install builds dist/ automatically (prepare script), as does pnpm when consuming this repo as a git dependency.

Provider id: xai-grok-build, never xai

Credentials live in pi's shared ~/.pi/agent/auth.json, keyed by provider id. Registering OAuth under "xai" would capture pi's built-in xAI provider: every built-in Grok model would be billed to the subscription token, registerProvider would wipe pi's built-in xAI models, and /login would offer an API-key row that silently overwrites the OAuth credential. A distinct id makes all of that structurally impossible.

Load-bearing constraint (extension path)

src/extension.ts — and everything it imports at runtime — must never import a @earendil-works/pi-ai subpath (api/*, providers/*) and must never import src/provider.ts. pi's extension loader aliases the bare package prefix to its compat bundle, so subpath specifiers resolve to nonexistent paths: silent at typecheck, fatal at extension load. extension.test.ts guards this with an import grep; keep it green.

Caveats

  • The OAuth device flow borrows the Grok CLI's public client id because xAI has no public client registration. xAI can break it at any time. Login polling is cancellable, honors the device-code expiry, and is capped at 30 minutes.
  • OAuth is the only auth path, by policy. There is no $XAI_API_KEY handling, no API-key login row, and no reading of other programs' credential files.
  • The Grok CLI proxy's live GET /v1/models lists both registered models. maxTokens output caps are registry metadata only; Composer's context/output figures and pricing come from third-party registries, not from xAI documentation.

Development

pnpm install          # also builds dist/ via the prepare script
pnpm check            # oxlint + tsc --noEmit + unit tests (offline, always safe)
pnpm fmt              # oxfmt over the repo
pnpm build            # emit dist/ (.js + .d.ts) for library consumers
pnpm test:live        # live acceptance against the Grok CLI proxy (skips without a credential)
pnpm smoke:models     # print the live model catalog for your credential
pnpm smoke:extension  # end-to-end through a real `pi` binary
pnpm smoke:session    # two-process fixed-session-id reload smoke through pi

Type-checking and declaration/JavaScript emit use the TypeScript 7 native compiler directly. This project does not consume the compiler API.

Releases

pnpm release increments the patch version, runs the full release gate, commits Release X.Y.Z, and creates vX.Y.Z locally. By default it prints the push and npm publish commands instead of running them:

pnpm release                 # increment patch; commit + tag locally
pnpm release 0.3.0           # explicit exact X.Y.Z version
pnpm release 0.3.0 --push    # also atomically push main and the tag
pnpm release 0.3.0 --push --publish  # also publish publicly with npm tag latest

Explicit versions reject a v prefix, prerelease/build suffixes, leading zeroes, downgrades, existing tags, and versions already present on npm. Passing the current version resumes a prepared release only when its tag points at HEAD, which is useful after completing npm web/OTP authorization.

The pi extension path (pi -e, pi install, the extensions directory) needs no build: pi's loader executes src/extension.ts directly, per the pi key in package.json. Only library consumers go through dist/.

Unit tests (src/*.test.ts) run offline and capture the final serialized wire payload where needed. Live tests (live/*.test.ts) hit the Grok CLI proxy with the stored Pi OAuth credential and are never part of pnpm check; they include focused prompt-cache and low-effort reasoning probes. Acceptance criteria and the full test layering are documented in ACCEPTANCE.md.