# AIHubMix Pi Provider: Agent Reference

This repository is the official AIHubMix provider extension for the Pi coding agent. Its public npm package is `@aihubmix/pi-provider-aihubmix`; its Pi provider ID is `aihubmix`.

## Objective

Let Pi users authenticate with `AIHUBMIX_API_KEY`, discover AIHubMix LLMs, and call them through Pi's native provider runtime. The package is independently maintained by AIHubMix and is not a built-in provider in `earendil-works/pi`.

## Non-Negotiable Invariants

1. Never add affiliate, referral, attribution, or tracking headers. In particular, do not add `APP-Code` to model requests.
2. Never commit a credential. Configuration examples and test values must use `AIHUBMIX_XXX` placeholders.
3. Never invent model limits or input/output prices. Reject incomplete Models API records.
4. Keep provider identity stable: npm scope `@aihubmix`, provider ID `aihubmix`, environment variable `AIHUBMIX_API_KEY`.
5. Route by the Models API `endpoints` field, not model-name or vendor-name heuristics.
6. Keep `@earendil-works/pi-ai` and `@earendil-works/pi-coding-agent` in `peerDependencies` with version `*`.
7. Do not publish npm releases, create tags, or change public repository settings without explicit human approval.
8. Keep OpenAI-compatible gateway requests vendor-neutral: do not send `store` or the `developer` role, use `max_tokens`, and replay provider-specific thinking as text.

## Repository Map

| Path | Responsibility |
| --- | --- |
| `extensions/index.ts` | Pi extension entry point |
| `extensions/provider.ts` | Complete Pi `Provider` factory and protocol implementations |
| `extensions/catalog.ts` | Strict Models API and models.dev mapping |
| `extensions/fetch-catalog.ts` | Live AIHubMix catalog fetch |
| `extensions/catalog.generated.ts` | Auditable offline snapshot generated from models.dev |
| `scripts/update-catalog.ts` | Snapshot generator |
| `scripts/check-sensitive.ts` | Repository credential and placeholder policy check |
| `tests/` | Mapper, routing, request-header, auth, and provider tests |

## Model Admission Contract

A live catalog record is admitted only when it:

- is an LLM and not a mixed image/audio/video/embedding/rerank record;
- supports text input;
- has a non-empty model ID;
- has positive `context_length` and `max_output`, with output not exceeding context;
- has non-negative input and output prices;
- advertises a supported or legacy-default endpoint.

Pi requires cache price fields. Missing optional cache rates map to zero because the Models API has not declared a separate cache charge; missing input or output prices reject the record.

Endpoint selection order:

1. `chat_completions`, or an empty legacy endpoint, uses `openai-completions` at `https://aihubmix.com/v1`.
2. `claude_api` without Chat Completions uses `anthropic-messages` at `https://aihubmix.com`.
3. `gemini_api` without the previous endpoints uses `google-generative-ai` at `https://aihubmix.com/gemini/v1beta`.
4. Unknown non-empty endpoints reject the record.

## Required Validation

Run before every commit:

```bash
npm install
npm run check
npm pack --dry-run
AIHUBMIX_API_KEY=AIHUBMIX_TEST_API_KEY pi -e ./extensions/index.ts --list-models aihubmix
```

Run `npm run catalog:update` only when intentionally refreshing the committed models.dev snapshot. Review the generated diff before committing it.

Live inference requires a human-approved test credential. Do not print request headers or environment values in logs, issues, pull requests, or reports.

For broad live coverage, test text generation with tools disabled separately from tool calling. A Models API feature can describe intended capability while a selected upstream route still rejects tools; record that as a catalog or routing mismatch rather than a provider transport failure.

## Release Gate

Before a release, verify:

- `npm run check` passes;
- package contents contain only expected public files;
- no real credentials or referral codes exist in source or tarball;
- Pi loads the package and lists AIHubMix models;
- at least one approved live text/tool smoke test passes;
- repository metadata points to `AIhubmix/pi-provider-aihubmix`;
- the npm publisher is authenticated for the `@aihubmix` scope;
- a human explicitly approves the version, tag, push, and npm publish.
