pi-provider-kit

Provider extension toolkit for Pi to integrate and manage custom LLM providers with dynamic models, request tuners, and account status.

Packages

Package details

extension

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

$ pi install npm:pi-provider-kit
Package
pi-provider-kit
Version
0.4.0
Published
Aug 4, 2026
Downloads
431/mo · 431/wk
Author
huanghui-dev
License
MIT
Types
extension
Size
319.8 KB
Dependencies
0 dependencies · 1 peer
Pi manifest JSON
{
  "extensions": [
    "./index.ts",
    "./providers/*.ts",
    "./status/*.ts",
    "./preflight/*.ts",
    "./tuners/*.ts"
  ]
}

Security note

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

README

pi-provider-kit

简体中文

A Provider extension toolkit for Pi. It helps Pi users and extension authors register LLM Providers, discover models, tune requests, and inspect account status without replacing Pi's native Footer.

Status: Active 0.x development. The current manifest version is 0.4.0; the public API may change before 1.0. The tested compatibility baseline is Pi 0.83.x.

Maintained by huanghui.

Issues · Security · Contributing · Support · Changelog

Features

  • Provider Kit Host: One runtime owns Provider registration, Status, Preflight, live availability checks, and request tuners.
  • Dynamic adapter extensions: Add Provider, Status, Preflight, or Tuner files through Pi's manifest and activate them after /reload.
  • Cached model catalogs: Charm Hyper starts with a network-free fallback, restores a Provider-scoped last-known catalog, and refreshes it in the background with timeouts, cancellation, single-flight requests, and stale preservation.
  • Pricing and quality metadata: Provider prices take precedence; OpenRouter metadata can fill missing fields and expose read-only Artificial Analysis quality metrics. Explicit Provider/model pricing adjustments retain their provenance.
  • Explicit diagnostics: /status is cache-only, /status refresh performs free status checks, and /status check is the only mode that sends a real model request.
  • Built-in integrations: Charm Hyper, DeepSeek, Google Gemini, OpenAI Codex, OpenCode Zen, and OpenCode Go preflight/status adapters, plus a DeepSeek request tuner.

Installation

Install the package through Pi:

pi install npm:pi-provider-kit

The published package intentionally contains TypeScript source files rather than a compiled dist/ directory. Pi is the host and loads the package through its extension loader; this is not a standalone Node CLI.

Requirements

  • Node.js 22.19.0 or later.
  • Pi 0.83.x (@earendil-works/pi-coding-agent ^0.83.0). Later Pi versions are not supported until tested.
  • Credentials for the Provider you use. Charm Hyper supports $HYPER_API_KEY or Pi's /login OAuth flow; credentials for native Pi Providers are resolved by Pi's own Provider/auth configuration.

Quick start

  1. Configure the target Provider credential in Pi. For Charm Hyper, set $HYPER_API_KEY, or run /login and choose SubscriptionCharm Hyper. Never commit or paste a real key into project files.

  2. Start Pi and select a Charm Hyper model:

    /model charm-hyper/deepseek-v4-pro
    
  3. Inspect the result:

    /status
    

/status shows the active Provider/model, route, authentication state, catalog, preflight, availability, and account information from cache. Use /status refresh for free remote checks, or /status check when you explicitly accept a real model request and possible usage charges.

Configuration

Credentials and local state

Name Required Default Effect
HYPER_API_KEY API-key mode for Charm Hyper None Pi resolves the key referenced by the built-in charm-hyper Provider. OAuth users can authenticate with /login.
PI_CODING_AGENT_DIR No ~/.pi/agent Changes the base directory for the persisted OpenRouter metadata cache.

Other built-in status and preflight adapters use the credential resolved by Pi's ModelRegistry; they do not read arbitrary environment variables themselves. Status reports never print credentials, OAuth tokens, or account IDs.

The default OpenRouter metadata cache is stored at <agent-dir>/provider-kit/openrouter-model-metadata.json. It contains the last successful public metadata snapshot, not Provider credentials or prompts.

Runtime options

Programmatic integrations can pass the following fields to createProviderKitRuntime() or createProviderKitHost(). The public TypeScript source of truth is ProviderKitDependencies.

Option Required Default Effect
enableOfficialPricingFallback No true Enables public OpenRouter metadata lookup during startup/reload.
pricingPolicies No {} Applies one explicit Provider/model price adjustment without changing the Provider adapter.
modelDiscoveryTimeoutMs No 3000 ms Bounds dynamic Provider catalog requests.
statusRequestTimeoutMs No 8000 ms Bounds status and preflight requests.
liveCheckRequestTimeoutMs No 8000 ms Bounds the opt-in live model request.
officialPricingUrl No OpenRouter models endpoint Selects the public metadata source.
openRouterMetadataCachePath No <agent-dir>/provider-kit/openrouter-model-metadata.json Selects the persistent metadata cache file.

For details on adapter definitions, validation, conflict handling, reload behavior, and lifecycle boundaries, see the Adapter Extension contract.

DeepSeek tuner flags

The built-in tuner only matches the official deepseek Provider and deepseek-v4-pro/deepseek-v4-flash. Flags are disabled unless set to 1 or true:

Variable Default Effect when enabled
PI_DEEPSEEK_TUNER_CHURN_FILTER Off Removes volatile session-overview sections from the system prompt.
PI_DEEPSEEK_TUNER_NO_STRIP Off Keeps historical reasoning/content instead of applying the default cleanup.
PI_DEEPSEEK_TUNER_NO_TOOL_REPAIR Off Disables interrupted tool-pair repair.
PI_DEEPSEEK_TUNER_NO_THINKING_INJECT Off Disables automatic thinking injection for DeepSeek Pro.

API and commands

Pi commands

Command Network/cost behavior
/status Reads the current report from cache; performs no network request.
/status refresh Refreshes account status and free endpoint/auth/catalog checks; never generates model output.
/status check Performs the refresh above and one real request for the active Provider/model; may incur usage.

Modes are positional. Flags, multiple modes, and unknown arguments are rejected without a request. Status failures appear in the report with an error category and retry information where available; they are not standalone process exit codes because this package runs inside Pi.

Public TypeScript API

index.ts is the package entry point and public API source. It exports:

  • createProviderKitRuntime() and createProviderKitHost();
  • defineProviderExtension(), defineStatusExtension(), definePreflightExtension(), and defineTunerExtension();
  • adapter, manager, pricing, diagnostics, and Provider Kit type definitions;
  • built-in Charm Hyper, DeepSeek, Google, Codex, and OpenCode factories and parsers.

The root export is .; the package also exposes ./package.json. Capability files are loaded by Pi through the pi.extensions manifest rather than through Node subpath imports.

Dynamic adapter extensions

The default entry point is one Provider Kit Host. Pi discovers capability files from the package manifest, so a separate trusted package can add an adapter without editing index.ts:

providers/*.ts    # Provider Adapter Extensions
status/*.ts       # Status Adapter Extensions
preflight/*.ts    # Preflight Adapter Extensions
tuners/*.ts       # Tuner Adapter Extensions

A capability entry point must default-export its dedicated helper:

import { defineProviderExtension } from "pi-provider-kit";

export default defineProviderExtension({
  id: "example-provider",
  create: async () => ({
    id: "example-provider",
    provider: {
      name: "Example Provider",
      baseUrl: "https://api.example.com/v1",
      apiKey: "$EXAMPLE_PROVIDER_API_KEY",
      api: "openai-completions",
      models: [{ id: "example-model" }],
    },
  }),
});

Declare the capability globs in the package manifest:

{
  "pi": {
    "extensions": [
      "./index.ts",
      "./providers/*.ts",
      "./status/*.ts",
      "./preflight/*.ts",
      "./tuners/*.ts"
    ]
  }
}

Adapter changes take effect after /reload; there is no file watcher or session-time hot-plugging. A Pi runtime should enable one Host and only trusted Adapter Extensions. See the Adapter Extension contract for Status, Preflight, Tuner, validation, conflicts, and reload behavior.

Custom providers

A Provider, optional free Preflight, account Status, and request Tuner are separate adapters. ProviderAdapter intentionally has no quota field:

import {
  createProviderKitRuntime,
  type ProviderAdapter,
  type ProviderKitDefinition,
} from "pi-provider-kit";

const provider: ProviderAdapter = {
  id: "example-provider",
  provider: {
    name: "Example Provider",
    baseUrl: "https://api.example.com/v1",
    apiKey: "$EXAMPLE_PROVIDER_API_KEY",
    api: "openai-completions",
    models: [{ id: "example-model" }],
  },
};

export default createProviderKitRuntime(async (): Promise<ProviderKitDefinition> => ({
  providers: [provider],
  preflights: [],
  statuses: [],
  tuners: [],
}));

A Provider can expose an explicit price adjustment, or a runtime can supply pricingPolicies without changing the adapter:

provider.pricing = {
  defaultAdjustment: {
    multiplier: 0.8,
    label: "20% provider discount",
    source: "provider contract",
    appliesToReference: true,
  },
};

Pricing rates are local estimates per 1M tokens. The base-price order is Provider catalog, Provider fallback, OpenRouter, then unavailable. A discount without a base price remains unavailable, never free. Native Pi models keep their configured price; status output annotates actual field sources and lists conditional token tiers separately.

Built-in provider contracts

  • Charm Hyper: the current catalog endpoint is https://hyper.charm.land/v1/provider; the adapter temporarily falls back to the legacy /v1/models endpoint on HTTP 404. The credits status endpoint is https://hyper.charm.land/v1/credits. Model prices and capabilities come from the catalog, OAuth is supported through Pi /login, and the account status reports Hypercredits plus the OAuth team name when available. The catalog request is separate from status and uses a cached fallback when unavailable.
  • DeepSeek: preflight uses /models; account status uses /user/balance and displays the preferred USD total. Grant and top-up components are intentionally not shown.
  • Google Gemini: preflight uses /v1beta/models and requires generateContent support for the active model.
  • OpenCode Zen/Go: public model catalogs can report endpoint/catalog without proving API-key model access. OpenCode Go status uses /zen/go/v1/usage and displays rolling 5-hour, weekly, and monthly dollar-value windows plus the Zen balance fallback state.
  • OpenAI Codex: preflight uses the ChatGPT OAuth token, its chatgpt_account_id, and the ChatGPT backend catalog. Status uses /backend-api/wham/usage and reports the plan plus the main codex windows. These backend contracts may change independently of Pi.

Limitations and compatibility

  • This is a Pi extension package, not a standalone server or CLI. It requires the host's extension loader and Provider APIs.
  • The tested host compatibility range is Pi 0.83.x. The live check uses the public ModelRegistry and Provider streamSimple() path; on Pi 0.83 it does not replay other extensions' unexposed request-preparation or response hooks.
  • Only one Provider Kit Host is supported per Pi runtime. Adapter discovery and removal take effect after /reload.
  • Startup/reload may make public requests for Charm Hyper model discovery and OpenRouter metadata. Account status is not polled in the background. A live check is always explicit and may consume Provider quota.
  • Provider endpoints, pricing, OAuth backend schemas, and model catalogs are external contracts and can change or become unavailable independently of this package. Charm Hyper model discovery accepts the current /v1/provider contract and a temporary legacy /v1/models response.
  • The package does not model Batch, account-plan, private-contract, route, region, or time-window pricing; Pi's static cost model has no request context for those conditions.

Security and data boundaries

Pi extensions execute with the user's system privileges. Install only packages whose source you trust. The extension sends configured credentials only to their Provider-specific endpoints, validates remote JSON before using it, applies request deadlines/cancellation, and persists only public OpenRouter metadata in its cache. Live checks use a minimal prompt, do not write to the session, and may incur usage.

Do not put API keys, OAuth tokens, private fixtures, or personal data in issues, examples, tests, or commits. See the security policy for private vulnerability reporting.

Development and verification

Use a clean dependency install and run the same gate used by CI:

npm ci
npm run audit:runtime
npm run check
npm test
npm run artifact:check

npm run audit:runtime checks published runtime dependencies for high-severity advisories. npm run check runs Biome and TypeScript type checking. npm test runs the mocked behavior and contract tests. npm run artifact:check creates a temporary npm tarball, checks its allowlist, installs it in a temporary consumer with the tested Pi peer, and loads the published Pi entry points. Ordinary checks do not call paid Provider APIs or run a live model check.

The repository layout is intentional for Pi's source-based package contract:

index.ts                 # Host entry point and public exports
core/                    # shared runtime and adapter implementation
providers/ status/       # Provider and account-status entry points
preflight/ tuners/       # free checks and request tuners
test/                    # behavior and artifact-boundary tests
docs/                    # public contract, glossary, and ADRs
scripts/                 # maintainer-only verification helpers

The npm artifact includes the Host, built-in capability entry points, core/, public documentation, README*, CHANGELOG.md, LICENSE, and package metadata. It excludes tests, maintainer scripts, local configuration, and the ignored pi-provider-kit/ private overlay. Inspect the actual artifact with npm run artifact:check before publishing.

Contributing

Issues and focused pull requests are welcome. Please read CONTRIBUTING.md, search existing issues, and run the complete verification gate before submitting a change. Public behavior changes should update both the canonical README and its Chinese translation, tests, and the changelog when appropriate.

Support and releases

Support is best effort for the latest published release line; this project does not promise long-term support. Use SUPPORT.md for defect and usage-reporting guidance. Releases use SemVer for the public TypeScript API; before 1.0, compatible behavior is not guaranteed across minor versions. CHANGELOG.md is the authoritative release history. No release is supported after its contents have been replaced; publish a new version instead.

License

MIT