omp packages

pi-inferhub0.4.0

Pi extension for the InferHub inference provider

damnmersault Published 2 days ago MIT ~731 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-inferhub

A Pi extension that registers the InferHub inference provider with Pi, exposing your InferHub combos as selectable chat models.

InferHub pools AI subscriptions behind one OpenAI-compatible endpoint. Combos are its server-side routed bundles — failover, cache-sticky, billed in USDC — and they are the primary consumption surface. This extension exposes combos only by default: each combo on your account appears as exactly one model named combo/<slug>. Upstream prefix/model entries, bare-name aliases, and free-tier models are not exposed unless you opt in with publishUpstream.

Install

Add the package to your Pi settings:

// ~/.pi/agent/settings.json
{
	"packages": ["npm:pi-inferhub"]
}

or run pi install npm:pi-inferhub.

For local development against a checkout:

pi -e /path/to/pi-inferhub

Auth

Either:

  • set INFERHUB_API_KEY in your environment (sk-airo-…), or
  • run /login inferhub and paste the key at the prompt.

/login inferhub prompts for the key (input is masked), validates it against GET https://inferhub.dev/api/me, and only then hands it to Pi's credential store (auth.json). A rejected key (HTTP 401) notifies you and re-prompts; after three failed attempts the login aborts without storing anything.

When both exist, the stored credential wins; INFERHUB_API_KEY is the fallback when nothing is stored.

/inferhub-login reports whether the provider is currently configured and points you to /login inferhub if not.

Model selection

Send /model and filter by provider name inferhub or by combo/. Each combo model id is combo/<slug> — the routable inference name on https://api.inferhub.dev/v1.

Configuration

Optional ~/.pi/agent/pi-inferhub.json (or $PI_AGENT_DIR/pi-inferhub.json). A missing file means defaults; a malformed one logs an issue and keeps the defaults — it never breaks startup.

{ "publishUpstream": true }

Full upstream catalog (optional)

publishUpstream (default false) additionally publishes every chat model from /v1/models as a direct-selectable prefix/model entry, listed after the combos. This bypasses combo routing — you pick one specific serving — and is intended for pinning a particular upstream. Alias rows, free/ tiers, and image/video generation models are never published, even with the option on.

The INFERHUB_PUBLISH_UPSTREAM environment variable overrides the file in both directions (1/true/yes/on, 0/false/no/off).

Catalog derivation

On refresh the extension makes two authenticated GETs — GET https://inferhub.dev/api/combos (the account's combos) and GET https://api.inferhub.dev/v1/models (per-model metadata) — and maps each combo to one model:

  • Context/output limits — minimum across resolvable members (input_token_limit / max_output_tokens), so a combo is only as large as its smallest member. When no resolvable member supplies limits, fallbacks apply: 256k context / 128k max output. A limit of 0 is treated as missing data rather than a real ceiling.
  • Output cap enforcement — max_tokens is sent rather than max_completion_tokens, because InferHub ignores the latter (a request capped at 20 tokens still produced 107).
  • Image input — offered (text + image) only when every resolvable member's modality includes image; otherwise text-only.
  • Reasoning — combos are always marked reasoning-capable: a false negative hides Pi's thinking knob (the worse error), while a false positive only shows an inert one. Where members advertise reasoning_levels, Pi's levels map onto that union; when none advertise a ladder the map is omitted so every level stays selectable.
  • Surface — each combo rides the API its membership implies: Anthropic messages for Claude-only combos, [OI] responses for GPT-only combos, and chat completions for everything else — including combos that mix both native families. Family is decided from the model name, not the serving prefix.
  • Cost — per-direction minimum of resolvable members' official rates (see below). Cache reads bill at 0.1x the input rate (owner-confirmed); cache writes are left at 0 because no write rate is published.

Member resolution is conservative but forgiving: a member resolves directly from /v1/models when its prefixed row carries data; otherwise it joins the prefixed servings of the same model name (exact suffix first, then a normalized last-segment match, which covers multi-segment prefixes such as cp/cline-pass/<model>). Combos whose members resolve to nothing at all get safe defaults: text-only, reasoning-capable, 0 cost, and the fallback limits.

Refresh semantics

The catalog is fetched on demand via the provider's fetchModels; the extension keeps no snapshot of its own. Every refresh hits both endpoints live, so combos added, removed, or changed server-side appear on the next refresh instead of being served stale. When no credential is configured the refresh is a no-op returning an empty list — no unauthenticated upstream call and no silent fake catalog.

[!NOTE] Pi refreshes provider model catalogs in TUI and RPC modes; other non-interactive modes use the latest persisted catalog. Open the TUI to discover new combos.

Cost estimates

The per-model cost is an upper-bound estimate: the cheapest resolvable member's official list rates (official_in / official_out) per direction. InferHub's marketplace bills below list, so the real usage.cost reported per request comes in at or under the displayed estimate.

Cached input is priced at 0.1x the input rate, the rate InferHub charges (confirmed by its owner). On the Anthropic surface this is not theoretical: sending the same prefix twice cut a request's real cost by roughly 16x in testing, because the second call billed its 1218-token prefix as a cache read instead of fresh input.

Surfaces

InferHub exposes three compatible APIs. The extension picks per model:

membership API endpoint
Claude models only Anthropic messages api.inferhub.dev/v1/messages
GPT models only [OI] responses api.inferhub.dev/v1/responses
both families, or neither chat completions api.inferhub.dev/v1/chat/completions

This buys native behaviour where it is unambiguous: structured thinking control, cache_control breakpoints, and the responses surface's typed tool calls. Mixed combos deliberately fall back to chat completions, which InferHub translates for every model.

Design rationale

The full design — why combos only, why /v1/models supplies member metadata instead of the management /catalog endpoint, why the OpenAI completions surface, and the conservative-defaults philosophy — is in the design spec.

Development

npm install
npm test          # vitest
npm run typecheck

License

MIT