feat(coding-agent): accept native extension providers
Allow extensions to register complete pi-ai Provider objects while preserving models.json composition and resolved provider auth access. Refs #4823 and #4824.
This commit is contained in:
@@ -977,7 +977,7 @@ ctx.sessionManager.getLeafId() // Current leaf entry ID
|
||||
|
||||
### ctx.modelRegistry / ctx.model
|
||||
|
||||
Access to models and API keys.
|
||||
Access to models, providers, and resolved authentication. `ctx.modelRegistry.getProvider(id)` returns the effective pi-ai provider, while `getProviderAuth(id)` resolves its current API key, headers, base URL, and provider-scoped environment without requiring a loaded model. `ctx.model` is the active model.
|
||||
|
||||
### ctx.signal
|
||||
|
||||
@@ -1679,7 +1679,37 @@ Calls made during the extension factory function are queued and applied once the
|
||||
|
||||
Dynamic providers can implement `refreshModels`. Pi calls it during model refresh, publishes the returned list synchronously through the provider, and passes the canonical credential/store/network/signal context. The extension decides whether to persist the catalog through `context.store`; live servers such as llama.cpp can ignore it.
|
||||
|
||||
Extensions that need native provider auth, filtering, refresh, or stream behavior can register a complete `Provider` from `@earendil-works/pi-ai`. The provider becomes the composition base and `models.json` overrides still apply above it.
|
||||
|
||||
```typescript
|
||||
import { createProvider, openAICompletionsApi } from "@earendil-works/pi-ai";
|
||||
|
||||
const provider = createProvider({
|
||||
id: "local-server",
|
||||
name: "Local Server",
|
||||
baseUrl: "http://localhost:8080/v1",
|
||||
auth: {
|
||||
apiKey: {
|
||||
name: "Local server setup",
|
||||
async login(interaction) {
|
||||
return {
|
||||
type: "api_key",
|
||||
key: await interaction.prompt({ type: "secret", message: "API key" }),
|
||||
};
|
||||
},
|
||||
async resolve({ credential }) {
|
||||
return credential?.key
|
||||
? { auth: { apiKey: credential.key }, source: "stored API key" }
|
||||
: undefined;
|
||||
},
|
||||
},
|
||||
},
|
||||
models: [],
|
||||
api: openAICompletionsApi(),
|
||||
});
|
||||
|
||||
pi.registerProvider(provider);
|
||||
|
||||
// Register a new provider with custom models
|
||||
pi.registerProvider("my-proxy", {
|
||||
name: "My Proxy",
|
||||
@@ -1748,7 +1778,9 @@ pi.registerProvider("corporate-ai", {
|
||||
});
|
||||
```
|
||||
|
||||
**Config options:**
|
||||
The object form accepts a complete pi-ai `Provider`, including native `auth`, `getModels`, `refreshModels`, `filterModels`, `stream`, and `streamSimple` behavior.
|
||||
|
||||
**Legacy config options:**
|
||||
- `name` - Display name for the provider in UI such as `/login`.
|
||||
- `baseUrl` - API endpoint URL. Required when defining models.
|
||||
- `apiKey` - API key literal, environment interpolation (`$ENV_VAR` or `${ENV_VAR}`), or leading `!command`. Required when defining models (unless `oauth` provided). `$$` escapes `$`, and `$!` escapes a literal `!` without triggering command execution.
|
||||
|
||||
Reference in New Issue
Block a user