@milespossing/pi-copilot-discovery
Dynamic GitHub Copilot model discovery for pi — replaces pi-ai's static catalog with the live /models list from your Copilot tenant.
Package details
Install @milespossing/pi-copilot-discovery from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@milespossing/pi-copilot-discovery- Package
@milespossing/pi-copilot-discovery- Version
0.3.0- Published
- Jun 16, 2026
- Downloads
- not available
- Author
- milespossing
- License
- MIT
- Types
- extension
- Size
- 30.8 KB
- Dependencies
- 0 dependencies · 0 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-copilot-discovery
A pi extension that replaces pi's
built-in github-copilot provider with one that discovers your Copilot
tenant's full model catalog at runtime instead of using pi-ai's bundled
static list.
Why
pi-ai ships a hand-curated models.generated.js listing the GitHub Copilot
models pi knows about. That list lags real Copilot tenants in two ways:
- Preview / tenant-private models are invisible. Internal model families,
early-access SKUs, and anything your enterprise has been allow-listed for
never show up in
/model. - New public models need a pi-ai release. When Copilot exposes a new model id, pi can't talk to it until pi-ai cuts a release that adds it.
This extension solves both by calling Copilot's own /models endpoint on
startup and registering every chat-capable model the signed-in account is
entitled to. Routing to the right pi-ai streamer (anthropic-messages,
openai-responses, openai-completions) is derived from each model's
family.
What it does
- Replaces the built-in
github-copilotprovider. Same provider name, so existing credentials, sessions, and/login github-copilotworkflows keep working.pi --list-modelsand/modelsimply show a larger, more accurate catalog. - Live discovery on start, login, and command. Fetches
/modelsonce on extension load (async), once after successful/login github-copilot, and on demand via/copilot-refresh. - Re-injects Copilot dynamic headers. pi-ai's built-in streamers add
X-Initiator,Openai-Intent, andCopilot-Vision-Requestonly when the built-in handler is the one running; this extension installs its ownstreamSimplewrapper that re-adds them, preserving agent-vs-user quota accounting and vision support. - Enables tenant policies post-login. Runs
POST /models/<id>/policy {state:"enabled"}against every discovered model after/login github-copilot, so preview-tier models accept requests on first use. (pi-ai's built-in flow only enables its hardcoded list.) - Supports GitHub Enterprise. The login flow prompts for an enterprise
domain;
enterpriseUrlis preserved across pi restarts viaOAuthCredentials's open-ended index signature.
The personal github-copilot credentials, sessions, and behavior stay
intact — this is a drop-in upgrade of the provider, not a parallel one.
Install
As a pi package (recommended once published)
pi install npm:@milespossing/pi-copilot-discovery
Or try it for one session without installing:
pi -e npm:@milespossing/pi-copilot-discovery
Directly from git
pi install git:github.com/milespossing/pi-copilot-discovery
pi -e git:github.com/milespossing/pi-copilot-discovery
From a local checkout
git clone https://github.com/milespossing/pi-copilot-discovery ~/src/pi-copilot-discovery
ln -s ~/src/pi-copilot-discovery ~/.pi/agent/extensions/copilot-discovery
Either form auto-discovers as a global pi extension. Restart pi (or run
/reload) and the live model list takes effect.
After installing
- If you already have a
github-copilotentry in~/.pi/agent/auth.json, no action needed — the existing token is reused. - Otherwise:
/login github-copilot. The flow prompts for an enterprise host (leave blank forgithub.com).
Commands
| Command | What it does |
|---|---|
/login github-copilot |
Device-code login + enable policies on all live models |
/copilot-refresh |
Re-fetch the /models catalog without restarting pi |
/copilot-discovery-refresh |
Alias of /copilot-refresh (back-compat) |
/logout github-copilot |
(Built-in) Clear stored credentials |
How it works
pi starts
└─ extension factory runs
├─ register provider override immediately (without `models`)
│ └─ keeps pi's built-in static github-copilot catalog usable
└─ async startup discovery
├─ read ~/.pi/agent/auth.json["github-copilot"]
├─ if credentials present: GET <proxy>/models → ProviderModelConfig[]
└─ pi.registerProvider("github-copilot", { models, oauth, streamSimple, ... })
/login github-copilot
└─ oauth.login mints fresh creds, enables model policies, then triggers one
model discovery pass so /model updates immediately
/copilot-refresh
└─ one manual re-fetch of /models
per request
└─ pi resolves apiKey via oauth.getApiKey(creds)
└─ pi auth-storage owns token refresh + persistence
Family → API routing
| Model family pattern | pi-ai api | Reasoning |
|---|---|---|
claude-* (3.5+, 4.x, 5.x) |
anthropic-messages |
yes |
claude-2.x, claude-3 (3.0–3.4) |
anthropic-messages |
no |
gpt-5*, o1, o3 |
openai-responses |
yes |
gpt-4*, gemini-*, grok-*, other |
openai-completions |
no |
Heuristics live in families.ts and are intentionally conservative — when
uncertain we choose an api the model is usable under even if not optimal.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
/model shows no Copilot entries before login |
No credentials yet. | Run /login github-copilot. |
/model empty after login on a fresh pi start |
Startup discovery failed (network/auth/tenant outage) before the live catalog could load. | Run /copilot-refresh; if that also fails, re-run /login github-copilot. |
| Some model returns 403 the first time you use it | Tenant policy was "unconfigured" and post-login policy enable didn't succeed. |
Run /copilot-refresh (or re-run /login github-copilot). |
| Editor-Version / User-Agent rejected by the work proxy | pi-ai bumped its hardcoded Copilot client strings. | Update COPILOT_HEADERS in models.ts and index.ts to the new values. |
A new family is misrouted to openai-completions |
Default fallback. | Open an issue with the model id and tenant capabilities.family, or send a PR refining families.ts. |
Compatibility
- pi-coding-agent ≥ 0.78.0 (uses the async extension factory, per-model
apioverride, OAuthProviderConfig, and thestreamSimpleescape hatch). - pi-ai ≥ 0.78.0 (uses
loginGitHubCopilot,refreshGitHubCopilotToken,getGitHubCopilotBaseUrl,normalizeDomain, and thestreamSimple*family). - Node.js ≥ 22.19.0 (matches pi's
enginesrequirement).
Publishing
npm version patch
git push origin main --follow-tags
Pushing a v*.*.* tag triggers the npm publish workflow, which verifies the
tag matches package.json and publishes the package to npm.
Layout
.
├── package.json pi extension manifest, no runtime npm deps
├── src/
│ ├── index.ts async factory: registerProvider + /command
│ ├── oauth.ts wraps pi-ai loginGitHubCopilot/refresh; enables policies
│ ├── models.ts fetch /models, build ProviderModelConfig[]
│ ├── families.ts pure: family/id → { api, reasoning, thinkingLevelMap, compat }
│ ├── stream.ts streamSimple wrapper: inject headers, dispatch
│ └── headers.ts local re-impl of pi-ai's Copilot dynamic headers
├── docs/
│ └── PLAN.md original design / build plan
├── AGENTS.md contributor guide for AI agents
├── README.md
└── LICENSE