@earendil-works/pi-ai 1.4.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -39
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +282 -87
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/dist/api/azure-openai-responses.js +1 -7
- package/dist/api/azure-openai-responses.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +127 -103
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/bedrock-converse-stream.lazy.d.ts +7 -0
- package/dist/api/bedrock-converse-stream.lazy.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.lazy.js +18 -5
- package/dist/api/bedrock-converse-stream.lazy.js.map +1 -1
- package/dist/api/constrained-sampling.d.ts +13 -1
- package/dist/api/constrained-sampling.d.ts.map +1 -1
- package/dist/api/constrained-sampling.js +38 -18
- package/dist/api/constrained-sampling.js.map +1 -1
- package/dist/api/google-generative-ai.d.ts.map +1 -1
- package/dist/api/google-generative-ai.js +0 -6
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts +2 -1
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +57 -2
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/google-vertex.d.ts.map +1 -1
- package/dist/api/google-vertex.js +0 -6
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/lazy.d.ts +1 -1
- package/dist/api/lazy.d.ts.map +1 -1
- package/dist/api/lazy.js +9 -8
- package/dist/api/lazy.js.map +1 -1
- package/dist/api/mistral-conversations.d.ts.map +1 -1
- package/dist/api/mistral-conversations.js +17 -44
- package/dist/api/mistral-conversations.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +7 -8
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts +2 -1
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +55 -59
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +58 -57
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +4 -8
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/openrouter-images.js +1 -0
- package/dist/api/openrouter-images.js.map +1 -1
- package/dist/api/pi-messages.d.ts +2 -0
- package/dist/api/pi-messages.d.ts.map +1 -1
- package/dist/api/pi-messages.js +24 -9
- package/dist/api/pi-messages.js.map +1 -1
- package/dist/api/simple-options.d.ts +1 -0
- package/dist/api/simple-options.d.ts.map +1 -1
- package/dist/api/simple-options.js +16 -2
- package/dist/api/simple-options.js.map +1 -1
- package/dist/api/strict-tool-limits.d.ts +13 -0
- package/dist/api/strict-tool-limits.d.ts.map +1 -0
- package/dist/api/strict-tool-limits.js +50 -0
- package/dist/api/strict-tool-limits.js.map +1 -0
- package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
- package/dist/auth/oauth/github-copilot.js +4 -11
- package/dist/auth/oauth/github-copilot.js.map +1 -1
- package/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
- package/dist/auth/oauth/kimi-coding.js +4 -22
- package/dist/auth/oauth/kimi-coding.js.map +1 -1
- package/dist/auth/oauth/load.d.ts.map +1 -1
- package/dist/auth/oauth/load.js +5 -2
- package/dist/auth/oauth/load.js.map +1 -1
- package/dist/auth/oauth/meta.d.ts.map +1 -1
- package/dist/auth/oauth/meta.js +1 -14
- package/dist/auth/oauth/meta.js.map +1 -1
- package/dist/auth/oauth/radius.d.ts.map +1 -1
- package/dist/auth/oauth/radius.js +9 -3
- package/dist/auth/oauth/radius.js.map +1 -1
- package/dist/auth/oauth/trusted-url.d.ts +7 -0
- package/dist/auth/oauth/trusted-url.d.ts.map +1 -0
- package/dist/auth/oauth/trusted-url.js +12 -0
- package/dist/auth/oauth/trusted-url.js.map +1 -0
- package/dist/auth/types.d.ts +4 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/types.js.map +1 -1
- package/dist/cache-warming.d.ts +53 -0
- package/dist/cache-warming.d.ts.map +1 -0
- package/dist/cache-warming.js +82 -0
- package/dist/cache-warming.js.map +1 -0
- package/dist/cli.js +6 -2
- package/dist/cli.js.map +1 -1
- package/dist/compat/extension-oauth-types.d.ts +4 -0
- package/dist/compat/extension-oauth-types.d.ts.map +1 -1
- package/dist/compat/extension-oauth-types.js.map +1 -1
- package/dist/env-api-keys.d.ts.map +1 -1
- package/dist/env-api-keys.js +1 -0
- package/dist/env-api-keys.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/lazy-bedrock-provider.d.ts +10 -0
- package/dist/lazy-bedrock-provider.d.ts.map +1 -0
- package/dist/lazy-bedrock-provider.js +13 -0
- package/dist/lazy-bedrock-provider.js.map +1 -0
- package/dist/lazy-oauth.d.ts +10 -0
- package/dist/lazy-oauth.d.ts.map +1 -0
- package/dist/lazy-oauth.js +23 -0
- package/dist/lazy-oauth.js.map +1 -0
- package/dist/models.d.ts +7 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.generated.d.ts +4 -0
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +5 -1
- package/dist/models.generated.js.map +1 -1
- package/dist/models.js +20 -11
- package/dist/models.js.map +1 -1
- package/dist/providers/all.d.ts.map +1 -1
- package/dist/providers/all.js +2 -0
- package/dist/providers/all.js.map +1 -1
- package/dist/providers/amazon-bedrock.models.js +1 -1
- package/dist/providers/amazon-bedrock.models.js.map +1 -1
- package/dist/providers/ant-ling.models.js +1 -1
- package/dist/providers/ant-ling.models.js.map +1 -1
- package/dist/providers/anthropic.models.js +1 -1
- package/dist/providers/anthropic.models.js.map +1 -1
- package/dist/providers/azure.models.js +1 -1
- package/dist/providers/azure.models.js.map +1 -1
- package/dist/providers/baseten.models.js +1 -1
- package/dist/providers/baseten.models.js.map +1 -1
- package/dist/providers/cerebras.models.js +1 -1
- package/dist/providers/cerebras.models.js.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.js +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
- package/dist/providers/cloudflare-workers-ai.models.js +1 -1
- package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
- package/dist/providers/compat-schema.d.ts +444 -456
- package/dist/providers/compat-schema.d.ts.map +1 -1
- package/dist/providers/compat-schema.js +166 -112
- package/dist/providers/compat-schema.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/amazon-bedrock.json +1 -1
- package/dist/providers/data/anthropic.json +1 -1
- package/dist/providers/data/azure.json +1 -1
- package/dist/providers/data/baseten.json +1 -1
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/dist/providers/data/fireworks.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/google-vertex.json +1 -1
- package/dist/providers/data/google.json +1 -1
- package/dist/providers/data/huggingface.json +1 -1
- package/dist/providers/data/kimi-coding.json +1 -1
- package/dist/providers/data/mistral.json +1 -1
- package/dist/providers/data/moonshotai-cn.json +1 -1
- package/dist/providers/data/moonshotai.json +1 -1
- package/dist/providers/data/nvidia.json +1 -1
- package/dist/providers/data/openai-codex.json +1 -1
- package/dist/providers/data/openai.json +1 -1
- package/dist/providers/data/opencode-go.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/dist/providers/data/qwen-token-plan-individual-cn.json +1 -0
- package/dist/providers/data/qwen-token-plan-individual.json +1 -1
- package/dist/providers/data/qwen-token-plan.json +1 -1
- package/dist/providers/data/radius.json +1 -1
- package/dist/providers/data/together.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/data/xai.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
- package/dist/providers/data/xiaomi.json +1 -1
- package/dist/providers/data/zai-coding-cn.json +1 -1
- package/dist/providers/data/zai.json +1 -1
- package/dist/providers/deepseek.models.js +1 -1
- package/dist/providers/deepseek.models.js.map +1 -1
- package/dist/providers/faux.d.ts.map +1 -1
- package/dist/providers/faux.js +7 -2
- package/dist/providers/faux.js.map +1 -1
- package/dist/providers/fireworks.models.js +1 -1
- package/dist/providers/fireworks.models.js.map +1 -1
- package/dist/providers/github-copilot.d.ts +3 -1
- package/dist/providers/github-copilot.d.ts.map +1 -1
- package/dist/providers/github-copilot.js +13 -2
- package/dist/providers/github-copilot.js.map +1 -1
- package/dist/providers/github-copilot.models.js +1 -1
- package/dist/providers/github-copilot.models.js.map +1 -1
- package/dist/providers/google-vertex.models.js +1 -1
- package/dist/providers/google-vertex.models.js.map +1 -1
- package/dist/providers/google.models.js +1 -1
- package/dist/providers/google.models.js.map +1 -1
- package/dist/providers/groq.models.js +1 -1
- package/dist/providers/groq.models.js.map +1 -1
- package/dist/providers/huggingface.models.js +1 -1
- package/dist/providers/huggingface.models.js.map +1 -1
- package/dist/providers/kimi-coding.models.js +1 -1
- package/dist/providers/kimi-coding.models.js.map +1 -1
- package/dist/providers/meta.models.js +1 -1
- package/dist/providers/meta.models.js.map +1 -1
- package/dist/providers/minimax-cn.models.js +1 -1
- package/dist/providers/minimax-cn.models.js.map +1 -1
- package/dist/providers/minimax.models.js +1 -1
- package/dist/providers/minimax.models.js.map +1 -1
- package/dist/providers/mistral.models.js +1 -1
- package/dist/providers/mistral.models.js.map +1 -1
- package/dist/providers/model-schema.d.ts +65 -65
- package/dist/providers/model-schema.d.ts.map +1 -1
- package/dist/providers/model-schema.js +41 -30
- package/dist/providers/model-schema.js.map +1 -1
- package/dist/providers/moonshotai-cn.models.js +1 -1
- package/dist/providers/moonshotai-cn.models.js.map +1 -1
- package/dist/providers/moonshotai.models.js +1 -1
- package/dist/providers/moonshotai.models.js.map +1 -1
- package/dist/providers/nvidia.models.js +1 -1
- package/dist/providers/nvidia.models.js.map +1 -1
- package/dist/providers/openai-codex.js +1 -1
- package/dist/providers/openai-codex.js.map +1 -1
- package/dist/providers/openai-codex.models.js +1 -1
- package/dist/providers/openai-codex.models.js.map +1 -1
- package/dist/providers/openai.models.js +1 -1
- package/dist/providers/openai.models.js.map +1 -1
- package/dist/providers/opencode-go.models.js +1 -1
- package/dist/providers/opencode-go.models.js.map +1 -1
- package/dist/providers/opencode.js +1 -1
- package/dist/providers/opencode.js.map +1 -1
- package/dist/providers/opencode.models.js +1 -1
- package/dist/providers/opencode.models.js.map +1 -1
- package/dist/providers/openrouter.models.js +1 -1
- package/dist/providers/openrouter.models.js.map +1 -1
- package/dist/providers/qwen-token-plan-cn.models.js +1 -1
- package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
- package/dist/providers/qwen-token-plan-individual-cn.d.ts +3 -0
- package/dist/providers/qwen-token-plan-individual-cn.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-individual-cn.js +15 -0
- package/dist/providers/qwen-token-plan-individual-cn.js.map +1 -0
- package/dist/providers/qwen-token-plan-individual-cn.models.d.ts +6 -0
- package/dist/providers/qwen-token-plan-individual-cn.models.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-individual-cn.models.js +8 -0
- package/dist/providers/qwen-token-plan-individual-cn.models.js.map +1 -0
- package/dist/providers/qwen-token-plan-individual.models.js +1 -1
- package/dist/providers/qwen-token-plan-individual.models.js.map +1 -1
- package/dist/providers/qwen-token-plan.models.js +1 -1
- package/dist/providers/qwen-token-plan.models.js.map +1 -1
- package/dist/providers/radius-config.d.ts.map +1 -1
- package/dist/providers/radius-config.js +2 -1
- package/dist/providers/radius-config.js.map +1 -1
- package/dist/providers/radius.models.js +1 -1
- package/dist/providers/radius.models.js.map +1 -1
- package/dist/providers/schema-builders.d.ts +10 -0
- package/dist/providers/schema-builders.d.ts.map +1 -0
- package/dist/providers/schema-builders.js +18 -0
- package/dist/providers/schema-builders.js.map +1 -0
- package/dist/providers/together.models.js +1 -1
- package/dist/providers/together.models.js.map +1 -1
- package/dist/providers/typesafe.models.js +1 -1
- package/dist/providers/typesafe.models.js.map +1 -1
- package/dist/providers/vercel-ai-gateway.models.js +1 -1
- package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
- package/dist/providers/xai.models.js +1 -1
- package/dist/providers/xai.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-ams.models.js +1 -1
- package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-cn.models.js +1 -1
- package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-sgp.models.js +1 -1
- package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
- package/dist/providers/xiaomi.models.js +1 -1
- package/dist/providers/xiaomi.models.js.map +1 -1
- package/dist/providers/zai-coding-cn.models.js +1 -1
- package/dist/providers/zai-coding-cn.models.js.map +1 -1
- package/dist/providers/zai.models.js +1 -1
- package/dist/providers/zai.models.js.map +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +2 -1
- package/dist/telemetry.js.map +1 -1
- package/dist/types.d.ts +20 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/error-body.d.ts +8 -0
- package/dist/utils/error-body.d.ts.map +1 -1
- package/dist/utils/error-body.js +30 -2
- package/dist/utils/error-body.js.map +1 -1
- package/dist/utils/openrouter-cost.d.ts +24 -0
- package/dist/utils/openrouter-cost.d.ts.map +1 -0
- package/dist/utils/openrouter-cost.js +34 -0
- package/dist/utils/openrouter-cost.js.map +1 -0
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +2 -0
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +6 -0
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/streaming-json.d.ts +84 -0
- package/dist/utils/streaming-json.d.ts.map +1 -0
- package/dist/utils/streaming-json.js +513 -0
- package/dist/utils/streaming-json.js.map +1 -0
- package/dist/utils/{typebox-helpers.d.ts → string-enum.d.ts} +5 -5
- package/dist/utils/string-enum.d.ts.map +1 -0
- package/dist/utils/{typebox-helpers.js → string-enum.js} +5 -6
- package/dist/utils/string-enum.js.map +1 -0
- package/dist/utils/text.d.ts +7 -0
- package/dist/utils/text.d.ts.map +1 -1
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/transcript.d.ts +1 -1
- package/dist/utils/transcript.js +1 -1
- package/dist/utils/transcript.js.map +1 -1
- package/dist/utils/validation.d.ts +5 -3
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +27 -277
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/version.js +1 -1
- package/dist/utils/version.js.map +1 -1
- package/package.json +19 -10
- package/dist/utils/typebox-helpers.d.ts.map +0 -1
- package/dist/utils/typebox-helpers.js.map +0 -1
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ Unified LLM API with provider collections, automatic auth resolution, token and
|
|
|
64
64
|
- **OpenAI** (including the Decisions classifier API)
|
|
65
65
|
- **Ant Ling**
|
|
66
66
|
- **Azure OpenAI (Responses)**
|
|
67
|
-
- **OpenAI Codex
|
|
67
|
+
- **OpenAI Codex** (ChatGPT Plus/Pro subscription, requires OAuth, see below)
|
|
68
68
|
- **Radius** (API key or OAuth, with a dynamically refreshed gateway catalog)
|
|
69
69
|
- **TypeSafe** (System One classifier API)
|
|
70
70
|
- **DeepSeek**
|
|
@@ -103,15 +103,16 @@ Unified LLM API with provider collections, automatic auth resolution, token and
|
|
|
103
103
|
npm install @earendil-works/pi-ai
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
Tool parameters are JSON Schema. The examples build them with `@earendil-works/pi-schema`, which also types the arguments (`npm install @earendil-works/pi-schema`); TypeBox schemas and plain JSON Schema objects work as well.
|
|
107
107
|
|
|
108
108
|
## Quick Start
|
|
109
109
|
|
|
110
110
|
You build a `Models` collection of providers and stream through it. The quickest start registers every built-in provider; apps that care about bundle size register individual providers instead (see [Provider Factories](#provider-factories) and [Bundling and Tree Shaking](#bundling-and-tree-shaking)).
|
|
111
111
|
|
|
112
112
|
```typescript
|
|
113
|
-
import {
|
|
113
|
+
import { type Context, type Tool } from '@earendil-works/pi-ai';
|
|
114
114
|
import { builtinModels } from '@earendil-works/pi-ai/providers/all';
|
|
115
|
+
import { obj, opt, str } from '@earendil-works/pi-schema';
|
|
115
116
|
|
|
116
117
|
// A Models collection with every built-in provider registered
|
|
117
118
|
const models = builtinModels();
|
|
@@ -119,12 +120,12 @@ const models = builtinModels();
|
|
|
119
120
|
// Sync lookup against the collection
|
|
120
121
|
const model = models.getModel('openai', 'gpt-4o-mini')!;
|
|
121
122
|
|
|
122
|
-
// Define tools with
|
|
123
|
+
// Define tools with JSON Schema; pi-schema's builders also type the arguments
|
|
123
124
|
const tools: Tool[] = [{
|
|
124
125
|
name: 'get_time',
|
|
125
126
|
description: 'Get the current time',
|
|
126
|
-
parameters:
|
|
127
|
-
timezone:
|
|
127
|
+
parameters: obj({
|
|
128
|
+
timezone: opt(str({ description: 'Optional timezone (e.g., America/New_York)' }))
|
|
128
129
|
})
|
|
129
130
|
}];
|
|
130
131
|
|
|
@@ -233,8 +234,12 @@ for (const block of response.content) {
|
|
|
233
234
|
}
|
|
234
235
|
```
|
|
235
236
|
|
|
237
|
+
`usage.cost.totalFromProvider` is `true` when `usage.cost.total` is the billed cost reported by the provider and `false` when it is estimated from the model's catalog rates. A missing value, as in sessions recorded before this field existed, also means `false`.
|
|
238
|
+
|
|
236
239
|
Snippets in the rest of this README assume a `models` collection set up like this (with the relevant providers registered).
|
|
237
240
|
|
|
241
|
+
`usage.cost.total` is the best available total cost. For OpenRouter chat responses, it uses the cost reported by OpenRouter, including both the OpenRouter charge and upstream inference cost for BYOK requests. When provider accounting is unavailable or invalid, it falls back to the model's catalog rates. The `input`, `output`, `cacheRead`, and `cacheWrite` cost components remain catalog estimates and may not sum to a provider-reported total.
|
|
242
|
+
|
|
238
243
|
## Providers and Models
|
|
239
244
|
|
|
240
245
|
A **provider** is the runtime unit: it owns its model catalog, its auth (API key resolution, OAuth flows), and its stream behavior. A `Models` collection holds providers and routes every request to the provider that owns the model.
|
|
@@ -519,6 +524,7 @@ Built-in providers resolve these env vars (Node.js; in browsers pass `apiKey` ex
|
|
|
519
524
|
| Qwen Token Plan (existing catalog) | `QWEN_TOKEN_PLAN_API_KEY` |
|
|
520
525
|
| Qwen Token Plan (Individual) | `QWEN_TOKEN_PLAN_API_KEY` |
|
|
521
526
|
| Qwen Token Plan (China) | `QWEN_TOKEN_PLAN_CN_API_KEY` |
|
|
527
|
+
| Qwen Token Plan (Individual, China) | `QWEN_TOKEN_PLAN_CN_API_KEY` |
|
|
522
528
|
| Xiaomi MiMo (API billing) | `XIAOMI_API_KEY` |
|
|
523
529
|
| Xiaomi MiMo Token Plan (China) | `XIAOMI_TOKEN_PLAN_CN_API_KEY` |
|
|
524
530
|
| Xiaomi MiMo Token Plan (Amsterdam) | `XIAOMI_TOKEN_PLAN_AMS_API_KEY` |
|
|
@@ -528,40 +534,43 @@ Built-in providers resolve these env vars (Node.js; in browsers pass `apiKey` ex
|
|
|
528
534
|
`qwen-token-plan-individual` and `qwen-token-plan` share the international endpoint and
|
|
529
535
|
`QWEN_TOKEN_PLAN_API_KEY`. The Individual provider exposes only the models documented for Individual
|
|
530
536
|
subscriptions, while the existing provider retains its broader catalog for backward compatibility.
|
|
537
|
+
`qwen-token-plan-individual-cn` applies the same Individual catalog to the China endpoint and
|
|
538
|
+
`QWEN_TOKEN_PLAN_CN_API_KEY`.
|
|
531
539
|
Stored credentials remain provider-scoped, so save the key under the provider ID you register.
|
|
532
540
|
|
|
533
541
|
Amazon Bedrock resolves ambient AWS credentials (`AWS_PROFILE`, access key pairs, `AWS_BEARER_TOKEN_BEDROCK`, ECS task roles, web identity tokens); its provider-owned login flow supports bearer tokens, AWS profiles, and the existing credential chain. Vertex AI resolves either an explicit key or gcloud Application Default Credentials plus project/location, with a provider-owned login flow for API keys, ADC, and service-account files.
|
|
534
542
|
|
|
535
543
|
## Tools
|
|
536
544
|
|
|
537
|
-
Tools enable LLMs to interact with external systems.
|
|
545
|
+
Tools enable LLMs to interact with external systems. A tool's `parameters` is a JSON Schema object: built with `@earendil-works/pi-schema`'s builders (which also type the arguments through its `Static`), with TypeBox, or written by hand. `validateToolCall()` and `validateToolArguments()` validate with pi-schema, coercing loosely typed arguments first (numeric strings, `"true"`, a single value for an array, `null` for an omitted optional property). Schemas are plain JSON, so they serialize with the rest of a context.
|
|
538
546
|
|
|
539
547
|
### Defining Tools
|
|
540
548
|
|
|
541
549
|
```typescript
|
|
542
|
-
import {
|
|
550
|
+
import { type Tool, StringEnum } from '@earendil-works/pi-ai';
|
|
551
|
+
import { arr, obj, str } from '@earendil-works/pi-schema';
|
|
543
552
|
|
|
544
|
-
// Define tool parameters with
|
|
553
|
+
// Define tool parameters with pi-schema's builders
|
|
545
554
|
const weatherTool: Tool = {
|
|
546
555
|
name: 'get_weather',
|
|
547
556
|
description: 'Get current weather for a location',
|
|
548
|
-
parameters:
|
|
549
|
-
location:
|
|
557
|
+
parameters: obj({
|
|
558
|
+
location: str({ description: 'City name or coordinates' }),
|
|
550
559
|
units: StringEnum(['celsius', 'fahrenheit'], { default: 'celsius' })
|
|
551
560
|
})
|
|
552
561
|
};
|
|
553
562
|
|
|
554
|
-
// Note:
|
|
555
|
-
//
|
|
563
|
+
// Note: StringEnum gives { type: "string", enum: [...] }, which every provider accepts,
|
|
564
|
+
// including Google's, which rejects anyOf/const patterns
|
|
556
565
|
|
|
557
566
|
const bookMeetingTool: Tool = {
|
|
558
567
|
name: 'book_meeting',
|
|
559
568
|
description: 'Schedule a meeting',
|
|
560
|
-
parameters:
|
|
561
|
-
title:
|
|
562
|
-
startTime:
|
|
563
|
-
endTime:
|
|
564
|
-
attendees:
|
|
569
|
+
parameters: obj({
|
|
570
|
+
title: str({ minLength: 1 }),
|
|
571
|
+
startTime: str({ format: 'date-time' }),
|
|
572
|
+
endTime: str({ format: 'date-time' }),
|
|
573
|
+
attendees: arr(str({ format: 'email' }), { minItems: 1 })
|
|
565
574
|
})
|
|
566
575
|
};
|
|
567
576
|
```
|
|
@@ -574,10 +583,7 @@ Tools can opt in to provider-side constrained sampling. For JSON-schema tools, `
|
|
|
574
583
|
const strictTool: Tool = {
|
|
575
584
|
name: 'edit_file',
|
|
576
585
|
description: 'Edit a file',
|
|
577
|
-
parameters:
|
|
578
|
-
path: Type.String(),
|
|
579
|
-
content: Type.String()
|
|
580
|
-
}, { additionalProperties: false }),
|
|
586
|
+
parameters: obj({ path: str(), content: str() }), // obj() is closed: additionalProperties: false
|
|
581
587
|
constrainedSampling: { type: 'json_schema', strict: 'prefer' }
|
|
582
588
|
};
|
|
583
589
|
```
|
|
@@ -588,9 +594,7 @@ Strict JSON-schema constrained sampling is supported for OpenAI, Anthropic, supp
|
|
|
588
594
|
const patchTool: Tool = {
|
|
589
595
|
name: 'apply_patch',
|
|
590
596
|
description: 'Apply a patch',
|
|
591
|
-
parameters:
|
|
592
|
-
input: Type.String()
|
|
593
|
-
}, { additionalProperties: false }),
|
|
597
|
+
parameters: obj({ input: str() }),
|
|
594
598
|
constrainedSampling: {
|
|
595
599
|
type: 'grammar',
|
|
596
600
|
variants: {
|
|
@@ -694,7 +698,7 @@ for await (const event of s) {
|
|
|
694
698
|
|
|
695
699
|
### Validating Tool Arguments
|
|
696
700
|
|
|
697
|
-
When implementing your own tool execution loop, use `validateToolCall` to validate arguments before passing them to your tools:
|
|
701
|
+
When implementing your own tool execution loop, use `validateToolCall` to validate arguments before passing them to your tools. It coerces loosely typed arguments with pi-schema (`compile(schema, { coerce: true }).parse()`), returns the coerced arguments, and throws an error listing pi-schema's errors (`path: message`) followed by the arguments it received:
|
|
698
702
|
|
|
699
703
|
```typescript
|
|
700
704
|
import { validateToolCall, type Tool } from '@earendil-works/pi-ai';
|
|
@@ -890,7 +894,7 @@ console.log(model.output); // ['image'] or ['image', 'text']
|
|
|
890
894
|
|
|
891
895
|
## Classification
|
|
892
896
|
|
|
893
|
-
Classifier models consume structured JSON state, and optionally images, and answer one or more typed questions. They do not use chat or image-generation APIs. TypeSafe's Jev model, Cloudflare's Clef models,
|
|
897
|
+
Classifier models consume structured JSON state, and optionally images, and answer one or more typed questions. They do not use chat or image-generation APIs. TypeSafe's Jev model, Cloudflare's Clef models, OpenAI's GPT-6 Luna, and Microsoft-Decision-1 are available from these built-in providers:
|
|
894
898
|
|
|
895
899
|
| Provider | Model IDs | Auth |
|
|
896
900
|
| --- | --- | --- |
|
|
@@ -900,6 +904,7 @@ Classifier models consume structured JSON state, and optionally images, and answ
|
|
|
900
904
|
| `vercel-ai-gateway` | `typesafe-ai/jev` | `AI_GATEWAY_API_KEY` |
|
|
901
905
|
| `opencode` | `jev-1.13`, `jev-1.13-free` | `OPENCODE_API_KEY` |
|
|
902
906
|
| `openai` | `gpt-6-luna` | `OPENAI_API_KEY` |
|
|
907
|
+
| `github-copilot` | `microsoft-decision-1` | `COPILOT_GITHUB_TOKEN` or GitHub Copilot OAuth |
|
|
903
908
|
|
|
904
909
|
```typescript
|
|
905
910
|
import { builtinModels } from '@earendil-works/pi-ai/providers/all';
|
|
@@ -1436,6 +1441,8 @@ Built-in API implementations live under `./api/<api-id>`:
|
|
|
1436
1441
|
|
|
1437
1442
|
Importing an implementation module loads its SDK. The `./api/<id>.lazy` wrappers (used by the provider factories) defer that load to the first request when the runtime or bundler supports dynamic import chunking. Legacy raw API subpaths from older releases (`./anthropic`, `./google`, `./mistral`, `./openai-completions`, ...) were removed; use `@earendil-works/pi-ai/api/<api-id>`.
|
|
1438
1443
|
|
|
1444
|
+
**Anthropic message threads:** with `sessionId` set and `cacheRetention` not `"none"`, Anthropic requests continue from the previous reply on the server (`message-threads-2026-08-12` beta) and send only the new messages. When anything earlier in the request changed, or the server can't continue, the full request is sent. Token counts and prompt caching are unchanged. On by default only for the `anthropic` provider on `api.anthropic.com`; set `compat.supportsMessageThreads` to change that, for example for gateways that forward the `thread` field. Set `disableContinuation: true` on requests that repeat an earlier one, such as cache warming. Call `cleanupSessionResources(sessionId)` when a session ends.
|
|
1445
|
+
|
|
1439
1446
|
### OpenAI Compatibility Settings
|
|
1440
1447
|
|
|
1441
1448
|
The `openai-completions` API is implemented by many providers with minor differences. By default, the library auto-detects compatibility settings based on `baseUrl` for a small set of known OpenAI-compatible providers (Cerebras, xAI, Chutes, DeepSeek, NVIDIA NIM, Together AI, zAi, OpenCode, Cloudflare Workers AI, etc.). For custom proxies or unknown endpoints, you can override these settings via the `compat` field. For `openai-responses` models, the compat field supports Responses-specific flags.
|
|
@@ -1455,6 +1462,7 @@ interface OpenAICompletionsCompat {
|
|
|
1455
1462
|
maxTokensField?: 'max_completion_tokens' | 'max_tokens'; // Which field name to use (default: max_completion_tokens)
|
|
1456
1463
|
requiresToolResultName?: boolean; // Whether tool results require the `name` field (default: false)
|
|
1457
1464
|
requiresAssistantAfterToolResult?: boolean; // Whether tool results must be followed by an assistant message (default: false)
|
|
1465
|
+
requiresNonNullAssistantContent?: boolean; // Whether replayed assistant messages with no text must send "" instead of null content (default: false)
|
|
1458
1466
|
requiresThinkingAsText?: boolean; // Whether thinking blocks must be converted to text (default: false)
|
|
1459
1467
|
requiresReasoningContentOnAssistantMessages?: boolean; // Whether all replayed assistant messages must include empty reasoning_content when reasoning is enabled (default: auto-detected for DeepSeek)
|
|
1460
1468
|
thinkingFormat?: 'openai' | 'openrouter' | 'deepseek' | 'together' | 'baseten' | 'zai' | 'qwen' | 'chat-template' | 'qwen-chat-template' | 'string-thinking' | 'ant-ling'; // Format for reasoning param: 'openai' uses reasoning_effort, 'openrouter' uses reasoning: { effort }, 'deepseek' uses thinking: { type } plus reasoning_effort when supported, 'together' uses reasoning: { enabled } plus reasoning_effort when supported, 'baseten' uses configurable chat_template_args plus reasoning_effort when supported, 'zai' uses thinking: { type }, 'qwen' uses enable_thinking, 'chat-template' uses configurable chat_template_kwargs, 'qwen-chat-template' uses chat_template_kwargs.enable_thinking and preserve_thinking, 'string-thinking' uses top-level thinking, 'ant-ling' uses reasoning: { effort } only for mapped efforts (default: openai)
|
|
@@ -1722,8 +1730,8 @@ models.setProvider(openaiProvider());
|
|
|
1722
1730
|
|
|
1723
1731
|
Rules:
|
|
1724
1732
|
|
|
1725
|
-
- `@earendil-works/pi-ai/models` exports the model runtime (`createModels`, `createProvider`, model helpers, and their types) without
|
|
1726
|
-
- `@earendil-works/pi-ai` is the core entrypoint and does not import built-in catalogs, real provider factories, or SDK implementations, but it eagerly imports
|
|
1733
|
+
- `@earendil-works/pi-ai/models` exports the model runtime (`createModels`, `createProvider`, model helpers, and their types) without schema validation, built-in catalogs, or SDK implementations. Other types can still use `import type` from the root.
|
|
1734
|
+
- `@earendil-works/pi-ai` is the core entrypoint and does not import built-in catalogs, real provider factories, or SDK implementations, but it eagerly imports schema validation (pi-schema). Unbundled Node scripts do not tree-shake its unused exports; prefer `./models`, `./providers/faux`, and specific `./utils/*` subpaths when those are all you need.
|
|
1727
1735
|
- `@earendil-works/pi-ai/providers/<provider>` imports that provider's catalog and lazy API wrapper only.
|
|
1728
1736
|
- `@earendil-works/pi-ai/providers/all` imports every built-in provider factory and all catalogs. Use it only when you want the full built-in set.
|
|
1729
1737
|
- With code splitting, provider SDKs stay in lazy chunks and load on first request.
|
|
@@ -1763,6 +1771,18 @@ setBedrockProviderModule(bedrockProviderModule);
|
|
|
1763
1771
|
|
|
1764
1772
|
That explicit override bundles the AWS SDK. Without it, Bedrock's opaque runtime import expects the package's Bedrock implementation file to be available at runtime.
|
|
1765
1773
|
|
|
1774
|
+
Node bundles that split at dynamic imports (esbuild `splitting: true`) can keep Bedrock and the OAuth login flows inside the bundle but lazy: register loaders with literal dynamic imports, which the bundler turns into chunks that load on first use:
|
|
1775
|
+
|
|
1776
|
+
```typescript
|
|
1777
|
+
import { registerLazyBedrockProvider } from '@earendil-works/pi-ai/lazy-bedrock-provider';
|
|
1778
|
+
import { registerLazyOAuthFlows } from '@earendil-works/pi-ai/lazy-oauth';
|
|
1779
|
+
|
|
1780
|
+
registerLazyBedrockProvider();
|
|
1781
|
+
registerLazyOAuthFlows();
|
|
1782
|
+
```
|
|
1783
|
+
|
|
1784
|
+
Both modules are Node-only; never import them into a browser bundle.
|
|
1785
|
+
|
|
1766
1786
|
### Provider-Scoped Environment Overrides
|
|
1767
1787
|
|
|
1768
1788
|
Pass `env` in stream options to scope provider configuration to a request. Values in `env` are used before process environment variables for provider auth and configuration such as Cloudflare account IDs, Azure OpenAI settings, Vertex project/location, Bedrock settings, `PI_CACHE_RETENTION`, and `HTTP_PROXY`/`HTTPS_PROXY`.
|
|
@@ -1788,7 +1808,7 @@ Several providers support OAuth authentication instead of static API keys:
|
|
|
1788
1808
|
|
|
1789
1809
|
- **Anthropic** (Claude Pro/Max subscription)
|
|
1790
1810
|
- **OpenAI** (Sign in with ChatGPT: uses the ChatGPT subscription with the OpenAI API)
|
|
1791
|
-
- **OpenAI Codex
|
|
1811
|
+
- **OpenAI Codex** (ChatGPT Plus/Pro subscription, access to GPT-5.x Codex models)
|
|
1792
1812
|
- **GitHub Copilot** (Copilot subscription)
|
|
1793
1813
|
- **OpenRouter** (OAuth PKCE that mints a user-controlled API key)
|
|
1794
1814
|
|
|
@@ -1868,7 +1888,7 @@ Built-in login and refresh flows are private provider implementations. Use provi
|
|
|
1868
1888
|
|
|
1869
1889
|
Provider notes:
|
|
1870
1890
|
|
|
1871
|
-
**OpenAI Codex
|
|
1891
|
+
**OpenAI Codex**: Superseded by Sign in with ChatGPT on the OpenAI provider. Requires a ChatGPT Plus or Pro subscription. Provides access to GPT-5.x Codex models with extended context windows and reasoning capabilities. The library automatically handles session-based prompt caching when `sessionId` is provided in stream options unless `cacheRetention` is `"none"`. You can set `transport` in stream options to `"sse"`, `"websocket"`, or `"auto"` for Codex Responses transport selection. When using WebSocket with a `sessionId` and cache retention enabled, connections are reused per session and expire after 5 minutes of inactivity. Call `cleanupSessionResources(sessionId)` when finished so the pooled connection does not keep the process alive.
|
|
1872
1892
|
|
|
1873
1893
|
**Azure OpenAI (Responses)**: Uses the Responses API only. Set `AZURE_OPENAI_API_KEY` and either `AZURE_OPENAI_BASE_URL` or `AZURE_OPENAI_RESOURCE_NAME`. `AZURE_OPENAI_BASE_URL` supports both `https://<resource>.openai.azure.com` and `https://<resource>.cognitiveservices.azure.com`; root endpoints are normalized to `.../openai/v1` automatically. Use `AZURE_OPENAI_API_VERSION` (defaults to `v1`) to override the API version if needed. Deployment names are treated as model IDs by default, override with `azureDeploymentName` or `AZURE_OPENAI_DEPLOYMENT_NAME_MAP` using comma-separated `model-id=deployment` pairs (for example `gpt-4o-mini=my-deployment,gpt-4o=prod`). Legacy deployment-based URLs are intentionally unsupported.
|
|
1874
1894
|
|
|
@@ -1924,19 +1944,19 @@ Create a new API implementation file (for example `bedrock-converse-stream.ts`)
|
|
|
1924
1944
|
|
|
1925
1945
|
Add a lazy wrapper `src/api/<api-id>.lazy.ts` (`<name>Api()` via `lazyApi()`) so providers can reference the implementation without importing its SDK. Add any root-level `export type` re-exports in `src/index.ts` that should remain available from `@earendil-works/pi-ai`.
|
|
1926
1946
|
|
|
1927
|
-
#### 3. Model
|
|
1947
|
+
#### 3. Model Catalog (`catalog/providers/<id>.ts`)
|
|
1928
1948
|
|
|
1929
|
-
- Add
|
|
1949
|
+
- Add a provider definition and register it in `catalog/providers/index.ts`; see `catalog/README.md` for the build order and helpers
|
|
1930
1950
|
- Map chat/tool-capable provider data to `Model`, image-generation data to `ImageModel`, and models.dev `type: "decision"` entries to `ClassifierModel`; hydration groups the ignored `src/providers/data/<id>.json` values by API while stable `src/providers/<id>.models.ts` wrappers derive exact model/API types directly from those JSON keys
|
|
1931
1951
|
- Keep model ids unique within each provider and model type; emit separate entries when an upstream model supports multiple operations
|
|
1932
|
-
- Handle provider-specific quirks (pricing format, capability flags, model ID transformations)
|
|
1952
|
+
- Handle provider-specific quirks (pricing format, capability flags, model ID transformations) in the provider definition
|
|
1933
1953
|
|
|
1934
1954
|
#### 4. Provider Factory (`src/providers/<id>.ts`)
|
|
1935
1955
|
|
|
1936
1956
|
- `createProvider()` wiring catalog + auth + the lazy API wrapper
|
|
1937
1957
|
- Auth: `envApiKeyAuth` for standard key providers, a custom `ApiKeyAuth` for ambient auth (AWS profiles, ADC), `lazyOAuth` where an OAuth flow exists
|
|
1938
1958
|
- Register the factory in `src/providers/all.ts`
|
|
1939
|
-
- If it is a new API: register it in the builtin list in `src/compat.ts
|
|
1959
|
+
- If it is a new API: register it in the builtin list in `src/compat.ts`; the `./api/*` subpath export in `package.json` already covers the new module
|
|
1940
1960
|
|
|
1941
1961
|
#### 5. Tests (`test/`)
|
|
1942
1962
|
|
|
@@ -1947,7 +1967,6 @@ Create or update test files to cover the new provider:
|
|
|
1947
1967
|
- `abort.test.ts` - Request cancellation
|
|
1948
1968
|
- `empty.test.ts` - Empty message handling
|
|
1949
1969
|
- `context-overflow.test.ts` - Context limit errors
|
|
1950
|
-
- `image-limits.test.ts` - Image support (if applicable)
|
|
1951
1970
|
- `unicode-surrogate.test.ts` - Unicode handling
|
|
1952
1971
|
- `tool-call-without-result.test.ts` - Orphaned tool calls
|
|
1953
1972
|
- `image-tool-result.test.ts` - Images in tool results
|
|
@@ -1963,15 +1982,15 @@ For providers with non-standard auth (AWS, Google Vertex), create a utility like
|
|
|
1963
1982
|
|
|
1964
1983
|
Update `src/core/model-resolver.ts`:
|
|
1965
1984
|
|
|
1966
|
-
- Add a default model ID for the provider in `
|
|
1985
|
+
- Add a default model ID for the provider in `defaultModelPerProvider`
|
|
1967
1986
|
|
|
1968
1987
|
Update `src/cli/args.ts`:
|
|
1969
1988
|
|
|
1970
1989
|
- Add environment variable documentation in the help text
|
|
1971
1990
|
|
|
1972
|
-
Update `
|
|
1991
|
+
Update `docs/providers.md`:
|
|
1973
1992
|
|
|
1974
|
-
- Add
|
|
1993
|
+
- Add setup instructions, the environment variable, and the `auth.json` key
|
|
1975
1994
|
|
|
1976
1995
|
#### 7. Documentation
|
|
1977
1996
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAiC,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAiC,MAAM,mBAAmB,CAAC;AAqBlE,OAAO,KAAK,EASX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAIb,MAAM,aAAa,CAAC;AAqKrB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AA6QhE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AAoRD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CAiXzE,CAAC;AA2BF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAgDlF,CAAC"}
|