@earendil-works/pi-ai 1.3.0 → 1.5.0
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 +113 -38
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +66 -81
- 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 +8 -10
- 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 +137 -103
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/classifier-shared.d.ts.map +1 -1
- package/dist/api/classifier-shared.js +4 -3
- package/dist/api/classifier-shared.js.map +1 -1
- package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -1
- package/dist/api/cloudflare-workers-ai-system-one.js +8 -0
- package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -1
- package/dist/api/constrained-sampling.d.ts +15 -1
- package/dist/api/constrained-sampling.d.ts.map +1 -1
- package/dist/api/constrained-sampling.js +51 -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 +4 -10
- 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 +58 -3
- 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 +9 -15
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/lazy.d.ts +7 -2
- package/dist/api/lazy.d.ts.map +1 -1
- package/dist/api/lazy.js +24 -5
- package/dist/api/lazy.js.map +1 -1
- package/dist/api/llama-cpp-classify.d.ts.map +1 -1
- package/dist/api/llama-cpp-classify.js +2 -1
- package/dist/api/llama-cpp-classify.js.map +1 -1
- package/dist/api/mistral-conversations.d.ts.map +1 -1
- package/dist/api/mistral-conversations.js +19 -46
- 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 +17 -16
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +56 -62
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts +16 -0
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +119 -66
- 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 +17 -15
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/openrouter-images.d.ts.map +1 -1
- package/dist/api/openrouter-images.js +5 -3
- 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 +27 -12
- package/dist/api/pi-messages.js.map +1 -1
- package/dist/api/simple-options.d.ts.map +1 -1
- package/dist/api/simple-options.js +2 -1
- package/dist/api/simple-options.js.map +1 -1
- package/dist/api/system-one-shared.d.ts +29 -2
- package/dist/api/system-one-shared.d.ts.map +1 -1
- package/dist/api/system-one-shared.js +55 -3
- package/dist/api/system-one-shared.js.map +1 -1
- package/dist/api/typesafe-system-one.d.ts.map +1 -1
- package/dist/api/typesafe-system-one.js +10 -0
- package/dist/api/typesafe-system-one.js.map +1 -1
- 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/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/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/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +4 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.generated.js +1 -1
- package/dist/models.generated.js.map +1 -1
- package/dist/models.js +20 -6
- package/dist/models.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 -304
- package/dist/providers/compat-schema.d.ts.map +1 -1
- package/dist/providers/compat-schema.js +155 -109
- 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/cerebras.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/groq.json +1 -1
- package/dist/providers/data/huggingface.json +1 -1
- package/dist/providers/data/kimi-coding.json +1 -1
- package/dist/providers/data/minimax-cn.json +1 -1
- package/dist/providers/data/minimax.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.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/typesafe.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.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 +44 -31
- 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.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.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 +288 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +192 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/types.d.ts +25 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/error-body.d.ts.map +1 -1
- package/dist/utils/error-body.js +2 -1
- package/dist/utils/error-body.js.map +1 -1
- package/dist/utils/identity.d.ts +65 -0
- package/dist/utils/identity.d.ts.map +1 -0
- package/dist/utils/identity.js +141 -0
- package/dist/utils/identity.js.map +1 -0
- 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 +1 -0
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +8 -1
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +19 -7
- 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 +23 -9
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +30 -19
- 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 +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +3 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +11 -10
- package/dist/utils/pi-user-agent.d.ts +0 -2
- package/dist/utils/pi-user-agent.d.ts.map +0 -1
- package/dist/utils/pi-user-agent.js +0 -12
- package/dist/utils/pi-user-agent.js.map +0 -1
- package/dist/utils/typebox-helpers.d.ts.map +0 -1
- package/dist/utils/typebox-helpers.js.map +0 -1
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ Unified LLM API with provider collections, automatic auth resolution, token and
|
|
|
18
18
|
- [Auth](#auth)
|
|
19
19
|
- [How Auth Resolves](#how-auth-resolves)
|
|
20
20
|
- [Transforming Request Headers](#transforming-request-headers)
|
|
21
|
+
- [Client Identity](#client-identity)
|
|
21
22
|
- [Credential Store](#credential-store)
|
|
22
23
|
- [Environment Variables](#environment-variables)
|
|
23
24
|
- [Tools](#tools)
|
|
@@ -34,6 +35,7 @@ Unified LLM API with provider collections, automatic auth resolution, token and
|
|
|
34
35
|
- [Provider-Specific Options](#provider-specific-options-streamcomplete)
|
|
35
36
|
- [Streaming Thinking Content](#streaming-thinking-content)
|
|
36
37
|
- [Stop Reasons](#stop-reasons)
|
|
38
|
+
- [Telemetry](#telemetry)
|
|
37
39
|
- [Error Handling](#error-handling)
|
|
38
40
|
- [Aborting Requests](#aborting-requests)
|
|
39
41
|
- [Continuing After Abort](#continuing-after-abort)
|
|
@@ -101,15 +103,16 @@ Unified LLM API with provider collections, automatic auth resolution, token and
|
|
|
101
103
|
npm install @earendil-works/pi-ai
|
|
102
104
|
```
|
|
103
105
|
|
|
104
|
-
|
|
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.
|
|
105
107
|
|
|
106
108
|
## Quick Start
|
|
107
109
|
|
|
108
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)).
|
|
109
111
|
|
|
110
112
|
```typescript
|
|
111
|
-
import {
|
|
113
|
+
import { type Context, type Tool } from '@earendil-works/pi-ai';
|
|
112
114
|
import { builtinModels } from '@earendil-works/pi-ai/providers/all';
|
|
115
|
+
import { obj, opt, str } from '@earendil-works/pi-schema';
|
|
113
116
|
|
|
114
117
|
// A Models collection with every built-in provider registered
|
|
115
118
|
const models = builtinModels();
|
|
@@ -117,12 +120,12 @@ const models = builtinModels();
|
|
|
117
120
|
// Sync lookup against the collection
|
|
118
121
|
const model = models.getModel('openai', 'gpt-4o-mini')!;
|
|
119
122
|
|
|
120
|
-
// Define tools with
|
|
123
|
+
// Define tools with JSON Schema; pi-schema's builders also type the arguments
|
|
121
124
|
const tools: Tool[] = [{
|
|
122
125
|
name: 'get_time',
|
|
123
126
|
description: 'Get the current time',
|
|
124
|
-
parameters:
|
|
125
|
-
timezone:
|
|
127
|
+
parameters: obj({
|
|
128
|
+
timezone: opt(str({ description: 'Optional timezone (e.g., America/New_York)' }))
|
|
126
129
|
})
|
|
127
130
|
}];
|
|
128
131
|
|
|
@@ -231,8 +234,12 @@ for (const block of response.content) {
|
|
|
231
234
|
}
|
|
232
235
|
```
|
|
233
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
|
+
|
|
234
239
|
Snippets in the rest of this README assume a `models` collection set up like this (with the relevant providers registered).
|
|
235
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
|
+
|
|
236
243
|
## Providers and Models
|
|
237
244
|
|
|
238
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.
|
|
@@ -424,6 +431,33 @@ Header names are merged case-insensitively. Explicit headers override auth/model
|
|
|
424
431
|
|
|
425
432
|
`transformHeaders` belongs to `Models`, not `Provider`. A `Models` implementation must consume it and remove it before calling `Provider.stream*()`. Provider implementations continue receiving ordinary `ApiStreamOptions` or `SimpleStreamOptions` and never handle the transform themselves. Use this option instead of calling `getAuth(model)` before `stream*()`, which would resolve request auth twice.
|
|
426
433
|
|
|
434
|
+
### Client Identity
|
|
435
|
+
|
|
436
|
+
`identity` controls how requests identify the calling app to providers. Set it on `createModels()` as a default, or per request; a request's fields override the `Models` default field by field:
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
const models = createModels({
|
|
440
|
+
identity: {
|
|
441
|
+
userAgent: 'detailed',
|
|
442
|
+
version: '2.1.0',
|
|
443
|
+
attribution: { name: 'my-app', url: 'https://my-app.example', categories: ['cloud-agent'] },
|
|
444
|
+
},
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
await models.completeSimple(model, context, { identity: { attribution: null } });
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
- `userAgent`: `"detailed"` (default) sends `pi/<version> (<platform>; <runtime>; <arch>)`, `"short"` sends `pi`, and `{ custom: "..." }` sends the given value. On Bedrock the value is appended to the AWS SDK user agent.
|
|
451
|
+
- `version`: the version in the detailed `User-Agent`. Default: the pi-ai version.
|
|
452
|
+
- `attribution`: provider attribution headers. Absent (default) or `null` sends none; `null` also turns off attribution from a merged identity. `{ name, url, categories? }` maps to each provider's headers:
|
|
453
|
+
- OpenRouter: `HTTP-Referer: <url>` (the app's identity in OpenRouter's rankings, grouped by origin), `X-OpenRouter-Title: <name>`, and `X-OpenRouter-Categories` (comma-separated).
|
|
454
|
+
- NVIDIA NIM: `X-BILLING-INVOKE-ORIGIN: <name>` with its first letter upper-cased.
|
|
455
|
+
- OpenCode: `x-opencode-client: <name>`.
|
|
456
|
+
|
|
457
|
+
`PI_ATTRIBUTION` is pi's: `{ name: "pi", url: "https://pi.dev", categories: ["cli-agent"] }`.
|
|
458
|
+
|
|
459
|
+
Identity headers are defaults below provider, model, and request headers, so configured headers win and a `null` request header removes one. Providers that send a fixed client identity, such as GitHub Copilot and Anthropic OAuth, keep it. `withClientIdentity(models, identity)` returns a wrapper of a `Models` (or `MutableModels`) whose requests use `identity` over the one the `Models` was created with, for libraries that receive a `Models` from their host. `identity` is plain JSON, so it can be persisted with other request options.
|
|
460
|
+
|
|
427
461
|
### Credential Store
|
|
428
462
|
|
|
429
463
|
Stored credentials (API keys entered interactively, OAuth tokens) live in a `CredentialStore` — one type-tagged credential per provider. pi-ai ships an in-memory default; apps inject persistent storage:
|
|
@@ -505,34 +539,35 @@ Amazon Bedrock resolves ambient AWS credentials (`AWS_PROFILE`, access key pairs
|
|
|
505
539
|
|
|
506
540
|
## Tools
|
|
507
541
|
|
|
508
|
-
Tools enable LLMs to interact with external systems.
|
|
542
|
+
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.
|
|
509
543
|
|
|
510
544
|
### Defining Tools
|
|
511
545
|
|
|
512
546
|
```typescript
|
|
513
|
-
import {
|
|
547
|
+
import { type Tool, StringEnum } from '@earendil-works/pi-ai';
|
|
548
|
+
import { arr, obj, str } from '@earendil-works/pi-schema';
|
|
514
549
|
|
|
515
|
-
// Define tool parameters with
|
|
550
|
+
// Define tool parameters with pi-schema's builders
|
|
516
551
|
const weatherTool: Tool = {
|
|
517
552
|
name: 'get_weather',
|
|
518
553
|
description: 'Get current weather for a location',
|
|
519
|
-
parameters:
|
|
520
|
-
location:
|
|
554
|
+
parameters: obj({
|
|
555
|
+
location: str({ description: 'City name or coordinates' }),
|
|
521
556
|
units: StringEnum(['celsius', 'fahrenheit'], { default: 'celsius' })
|
|
522
557
|
})
|
|
523
558
|
};
|
|
524
559
|
|
|
525
|
-
// Note:
|
|
526
|
-
//
|
|
560
|
+
// Note: StringEnum gives { type: "string", enum: [...] }, which every provider accepts,
|
|
561
|
+
// including Google's, which rejects anyOf/const patterns
|
|
527
562
|
|
|
528
563
|
const bookMeetingTool: Tool = {
|
|
529
564
|
name: 'book_meeting',
|
|
530
565
|
description: 'Schedule a meeting',
|
|
531
|
-
parameters:
|
|
532
|
-
title:
|
|
533
|
-
startTime:
|
|
534
|
-
endTime:
|
|
535
|
-
attendees:
|
|
566
|
+
parameters: obj({
|
|
567
|
+
title: str({ minLength: 1 }),
|
|
568
|
+
startTime: str({ format: 'date-time' }),
|
|
569
|
+
endTime: str({ format: 'date-time' }),
|
|
570
|
+
attendees: arr(str({ format: 'email' }), { minItems: 1 })
|
|
536
571
|
})
|
|
537
572
|
};
|
|
538
573
|
```
|
|
@@ -545,10 +580,7 @@ Tools can opt in to provider-side constrained sampling. For JSON-schema tools, `
|
|
|
545
580
|
const strictTool: Tool = {
|
|
546
581
|
name: 'edit_file',
|
|
547
582
|
description: 'Edit a file',
|
|
548
|
-
parameters:
|
|
549
|
-
path: Type.String(),
|
|
550
|
-
content: Type.String()
|
|
551
|
-
}, { additionalProperties: false }),
|
|
583
|
+
parameters: obj({ path: str(), content: str() }), // obj() is closed: additionalProperties: false
|
|
552
584
|
constrainedSampling: { type: 'json_schema', strict: 'prefer' }
|
|
553
585
|
};
|
|
554
586
|
```
|
|
@@ -559,9 +591,7 @@ Strict JSON-schema constrained sampling is supported for OpenAI, Anthropic, supp
|
|
|
559
591
|
const patchTool: Tool = {
|
|
560
592
|
name: 'apply_patch',
|
|
561
593
|
description: 'Apply a patch',
|
|
562
|
-
parameters:
|
|
563
|
-
input: Type.String()
|
|
564
|
-
}, { additionalProperties: false }),
|
|
594
|
+
parameters: obj({ input: str() }),
|
|
565
595
|
constrainedSampling: {
|
|
566
596
|
type: 'grammar',
|
|
567
597
|
variants: {
|
|
@@ -665,7 +695,7 @@ for await (const event of s) {
|
|
|
665
695
|
|
|
666
696
|
### Validating Tool Arguments
|
|
667
697
|
|
|
668
|
-
When implementing your own tool execution loop, use `validateToolCall` to validate arguments before passing them to your tools:
|
|
698
|
+
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:
|
|
669
699
|
|
|
670
700
|
```typescript
|
|
671
701
|
import { validateToolCall, type Tool } from '@earendil-works/pi-ai';
|
|
@@ -866,8 +896,8 @@ Classifier models consume structured JSON state, and optionally images, and answ
|
|
|
866
896
|
| Provider | Model IDs | Auth |
|
|
867
897
|
| --- | --- | --- |
|
|
868
898
|
| `typesafe` | `jev-latest` | `TYPESAFE_API_KEY` |
|
|
869
|
-
| `openrouter` | `typesafe/jev-1.13`, `~typesafe/jev-latest` | `OPENROUTER_API_KEY` or OpenRouter OAuth |
|
|
870
|
-
| `cloudflare-workers-ai` | `typesafe/jev`, `@cf/cloudflare/clef`, `@cf/cloudflare/clef-flash` | `CLOUDFLARE_API_KEY` and `CLOUDFLARE_ACCOUNT_ID` |
|
|
899
|
+
| `openrouter` | `typesafe/jev-1.13`, `typesafe/jev-1.14`, `~typesafe/jev-latest`, `cloudflare/clef`, `cloudflare/clef-flash`, `cloudflare/clef-omni` | `OPENROUTER_API_KEY` or OpenRouter OAuth |
|
|
900
|
+
| `cloudflare-workers-ai` | `typesafe/jev`, `typesafe/jev-1.14.0`, `@cf/cloudflare/clef`, `@cf/cloudflare/clef-flash`, `@cf/cloudflare/clef-omni` | `CLOUDFLARE_API_KEY` and `CLOUDFLARE_ACCOUNT_ID` |
|
|
871
901
|
| `vercel-ai-gateway` | `typesafe-ai/jev` | `AI_GATEWAY_API_KEY` |
|
|
872
902
|
| `opencode` | `jev-1.13`, `jev-1.13-free` | `OPENCODE_API_KEY` |
|
|
873
903
|
| `openai` | `gpt-6-luna` | `OPENAI_API_KEY` |
|
|
@@ -912,6 +942,18 @@ When the service reports token counts, `result.usage` carries them with their co
|
|
|
912
942
|
|
|
913
943
|
`ClassifierContext.images` holds image blocks (`{ type: "image", data, mimeType }`) judged together with the state. Only models whose `input` includes `"image"` accept them; `classify()` returns an error result for other models.
|
|
914
944
|
|
|
945
|
+
### System One images
|
|
946
|
+
|
|
947
|
+
System One services take images in three forms. The model's `compat.imageInput` chooses the form (`"assets"`, `"images"`, or `"state-image-urls"`), and `compat.sendImageOptInHeader` controls TypeSafe's opt-in header:
|
|
948
|
+
|
|
949
|
+
- **TypeSafe** (`typesafe`, and Jev on Workers AI) takes PNG and JPEG images as `assets`, `{ "<image-1>": { type: "image", format: "png", data_base64 } }`. Every asset must be referenced from the request, so the state is sent as `["<image-1>", ..., state]`. Images are experimental on TypeSafe's own API and need the `TypeSafe-Danger-Zone-Images: true` header, which the API sends with requests that carry images.
|
|
950
|
+
- **Clef on Workers AI** takes up to four PNG, JPEG, or WebP images as an `images` list of data URLs, next to the unchanged state.
|
|
951
|
+
- **OpenRouter** takes images as `{ type: "image_url", image_url: { url } }` parts before the state: `[part, ..., state]`. It answers requests with `assets` but drops the images, without an error.
|
|
952
|
+
|
|
953
|
+
Built-in catalog entries set `compat` explicitly, so they keep their form when `baseUrl` points at a proxy. For models without it, the APIs detect the form: OpenRouter by provider `openrouter` or a `baseUrl` containing `openrouter.ai`, Clef by a model ID starting with `@cf/cloudflare/clef`, and TypeSafe's form with the opt-in header otherwise. A custom provider that reaches OpenRouter through a proxy matches neither check and must set `compat.imageInput: "state-image-urls"` and `compat.sendImageOptInHeader: false`; otherwise OpenRouter drops its images.
|
|
954
|
+
|
|
955
|
+
Vercel AI Gateway and OpenCode list their Jev models with text input only.
|
|
956
|
+
|
|
915
957
|
### OpenAI Decisions
|
|
916
958
|
|
|
917
959
|
The `openai-decisions` API calls OpenAI's [Decisions API](https://developers.openai.com/api/docs/guides/decisions) (`POST /v1/decisions`). GPT-6 Luna is its only model. The state is sent as JSON text; with images, the input is one user message with the state followed by the images as data URLs (at most 128). `choice` and `score` questions map to the Decisions types of the same name. `bool` questions become `predicate` questions; predicates have no criteria field, so the meanings of true and false are appended to the instructions. If OpenAI refuses to answer a question, the whole result is an error. Usage reports input tokens only, priced at the catalog input rate with OpenAI's long-context multiplier.
|
|
@@ -1070,6 +1112,40 @@ Every `AssistantMessage` includes a `stopReason` field that indicates how the ge
|
|
|
1070
1112
|
|
|
1071
1113
|
`AssistantMessage` may also include `responseId`, a provider-specific upstream response or message identifier when the underlying API exposes one. Do not assume it is always present across providers.
|
|
1072
1114
|
|
|
1115
|
+
## Telemetry
|
|
1116
|
+
|
|
1117
|
+
Pass an explicit parent span (`TelemetrySpan`, not an adapter) through `telemetry`; omitting it uses the no-op span:
|
|
1118
|
+
|
|
1119
|
+
```typescript
|
|
1120
|
+
import { InMemoryTelemetryContext } from '@earendil-works/pi-telemetry';
|
|
1121
|
+
|
|
1122
|
+
const telemetry = new InMemoryTelemetryContext();
|
|
1123
|
+
await telemetry.startSpan({ name: 'application.turn' }, async (span) => {
|
|
1124
|
+
await models.completeSimple(model, context, { telemetry: span });
|
|
1125
|
+
});
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
`Models.stream()` and `streamSimple()` create `pi.ai.request`; `streamDeferred()` creates one `pi.ai.poll` per poll. Their completion helpers use the same spans. These spans include auth/setup, end at the terminal result, and do not require the caller to consume events. Direct provider/API calls are not instrumented.
|
|
1129
|
+
|
|
1130
|
+
`AI_TELEMETRY_SCHEMA`, exported from the root and `@earendil-works/pi-ai/models`, defines the typed Pi-owned vocabulary:
|
|
1131
|
+
|
|
1132
|
+
- Start attributes: `provider`, `api`, `model`, and `reasoning` only when `options.reasoning` is a string. Provider-native reasoning objects are ignored.
|
|
1133
|
+
- End attributes: `stop`, `usage.input`, `usage.output`, `usage.cache_read`, `usage.cache_write`, `cost.total`, and optional `response.id`. `stop: "error"` sets error status with the fixed category `provider_error` and `AssistantMessage.errorMessage` truncated to 500 characters (empty when absent). Cancellation keeps status `ok` with `stop: "aborted"`.
|
|
1134
|
+
- `pi.ai.first_chunk` marks the first normalized event, including setup errors. Each completed text, thinking, or tool-call block emits `pi.ai.block` with `type`, `index`, and `chars`; only tool calls include `tool`. Character counts use JavaScript string length; tool counts sum argument delta lengths without serializing arguments.
|
|
1135
|
+
|
|
1136
|
+
When `options.telemetry.metrics` is available, the same requests record metrics:
|
|
1137
|
+
|
|
1138
|
+
| Metric | Unit | Attributes |
|
|
1139
|
+
| --- | --- | --- |
|
|
1140
|
+
| `pi.ai.request.duration` | `ms` | `provider`, `model`, `stop` |
|
|
1141
|
+
| `pi.ai.first_chunk.duration` | `ms` | `provider`, `model` |
|
|
1142
|
+
| `pi.ai.tokens` | `token` | `provider`, `model`, `kind` (`input`, `output`, `cache_read`, `cache_write`) |
|
|
1143
|
+
| `pi.ai.cost` | `USD` | `provider`, `model` |
|
|
1144
|
+
|
|
1145
|
+
Durations use `performance.now()`. Pending/deferred polls do not add tokens or cost; final completed/error polls do. A parent span without metric capabilities remains valid and simply records no metrics. Adapter-created spans carry the same optional metric and propagation capabilities as their root.
|
|
1146
|
+
|
|
1147
|
+
Telemetry does not record prompts, generated text, reasoning content, or arguments in attributes/events. Error status includes up to 500 characters of provider error text, which may contain sensitive data; apply your export policy accordingly. Telemetry observes the existing forwarding path without another stream consumer or per-delta events. Response identifiers and error messages never become metric attributes.
|
|
1148
|
+
|
|
1073
1149
|
## Error Handling
|
|
1074
1150
|
|
|
1075
1151
|
Request failures after a stream is returned never throw: when a request ends with an error (including aborts and tool call validation errors), the streaming API emits an error event and the final message carries the details. Setup failures may emit `error` without `start`; failures after generation begins emit `start`, any observed updates, then `error`. Direct API `streamSimple()` calls throw synchronously when request auth is missing:
|
|
@@ -1569,7 +1645,7 @@ getCurrentTools(messages); // []
|
|
|
1569
1645
|
|
|
1570
1646
|
A custom `Provider` or `ProviderStreams` implementation reads the prompt and tools the same way from `context.messages`; `context.systemPrompt` and `context.tools` do not exist at that layer.
|
|
1571
1647
|
|
|
1572
|
-
Models that accept system messages mid-conversation (`supportsMidConvoSystemMessages` in the model's compat settings, set by the generated catalog for verified models) receive each later system message in place, so the cached prefix stays intact; section changes are framed by name for the model. Every other model receives `collapseSystemMessages(transcript)`: the replayed prompt and current tools as the leading system message, with later system messages dropped. Anthropic models that also set `supportsMidConvoToolChanges` send tool changes as native blocks (`inline-tools-2026-09-15` beta): the top-level tool list holds the initial tools plus a stable deferred placeholder and never changes, later tools are defined by value in `tool_addition` blocks (a new definition under an existing name replaces the old one), and removals are `tool_removal` references, so tool changes do not invalidate the prompt cache. That needs at least one initial tool; otherwise the current tool list is sent at the top level with the system text only. OpenAI Responses models with `supportsAdditionalTools` or `supportsToolSearch` anchor
|
|
1648
|
+
Models that accept system messages mid-conversation (`supportsMidConvoSystemMessages` in the model's compat settings, set by the generated catalog for verified models) receive each later system message in place, so the cached prefix stays intact; section changes are framed by name for the model. Every other model receives `collapseSystemMessages(transcript)`: the replayed prompt and current tools as the leading system message, with later system messages dropped. Anthropic models that also set `supportsMidConvoToolChanges` send tool changes as native blocks (`inline-tools-2026-09-15` beta): the top-level tool list holds the initial tools plus a stable deferred placeholder and never changes, later tools are defined by value in `tool_addition` blocks (a new definition under an existing name replaces the old one), and removals are `tool_removal` references, so tool changes do not invalidate the prompt cache. That needs at least one initial tool; otherwise the current tool list is sent at the top level with the system text only. OpenAI Responses models with `supportsAdditionalTools` declare every tool in `additional_tools` items, like Codex: the initial tools in one at the head of the input and later additions and redefinitions at their message, with no top-level tool list. A later item replaces same-name definitions from earlier items but cannot replace a top-level tool or remove any tool, so removals are announced as text, later updates restate the tools that are still unavailable, and calls to removed tools fail at execution. OpenAI Responses models with only `supportsToolSearch`, and Kimi models with `supportsMidConvoToolAdditions`, anchor new tools at their message; a removal or a redeclared name moves the tool state up to that point into the top-level list once. Everything else sends the current tool list at the top level.
|
|
1573
1649
|
|
|
1574
1650
|
## Context Serialization
|
|
1575
1651
|
|
|
@@ -1647,8 +1723,8 @@ models.setProvider(openaiProvider());
|
|
|
1647
1723
|
|
|
1648
1724
|
Rules:
|
|
1649
1725
|
|
|
1650
|
-
- `@earendil-works/pi-ai/models` exports the model runtime (`createModels`, `createProvider`, model helpers, and their types) without
|
|
1651
|
-
- `@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
|
|
1726
|
+
- `@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.
|
|
1727
|
+
- `@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.
|
|
1652
1728
|
- `@earendil-works/pi-ai/providers/<provider>` imports that provider's catalog and lazy API wrapper only.
|
|
1653
1729
|
- `@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.
|
|
1654
1730
|
- With code splitting, provider SDKs stay in lazy chunks and load on first request.
|
|
@@ -1849,19 +1925,19 @@ Create a new API implementation file (for example `bedrock-converse-stream.ts`)
|
|
|
1849
1925
|
|
|
1850
1926
|
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`.
|
|
1851
1927
|
|
|
1852
|
-
#### 3. Model
|
|
1928
|
+
#### 3. Model Catalog (`catalog/providers/<id>.ts`)
|
|
1853
1929
|
|
|
1854
|
-
- Add
|
|
1930
|
+
- Add a provider definition and register it in `catalog/providers/index.ts`; see `catalog/README.md` for the build order and helpers
|
|
1855
1931
|
- 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
|
|
1856
1932
|
- Keep model ids unique within each provider and model type; emit separate entries when an upstream model supports multiple operations
|
|
1857
|
-
- Handle provider-specific quirks (pricing format, capability flags, model ID transformations)
|
|
1933
|
+
- Handle provider-specific quirks (pricing format, capability flags, model ID transformations) in the provider definition
|
|
1858
1934
|
|
|
1859
1935
|
#### 4. Provider Factory (`src/providers/<id>.ts`)
|
|
1860
1936
|
|
|
1861
1937
|
- `createProvider()` wiring catalog + auth + the lazy API wrapper
|
|
1862
1938
|
- Auth: `envApiKeyAuth` for standard key providers, a custom `ApiKeyAuth` for ambient auth (AWS profiles, ADC), `lazyOAuth` where an OAuth flow exists
|
|
1863
1939
|
- Register the factory in `src/providers/all.ts`
|
|
1864
|
-
- If it is a new API: register it in the builtin list in `src/compat.ts
|
|
1940
|
+
- 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
|
|
1865
1941
|
|
|
1866
1942
|
#### 5. Tests (`test/`)
|
|
1867
1943
|
|
|
@@ -1872,7 +1948,6 @@ Create or update test files to cover the new provider:
|
|
|
1872
1948
|
- `abort.test.ts` - Request cancellation
|
|
1873
1949
|
- `empty.test.ts` - Empty message handling
|
|
1874
1950
|
- `context-overflow.test.ts` - Context limit errors
|
|
1875
|
-
- `image-limits.test.ts` - Image support (if applicable)
|
|
1876
1951
|
- `unicode-surrogate.test.ts` - Unicode handling
|
|
1877
1952
|
- `tool-call-without-result.test.ts` - Orphaned tool calls
|
|
1878
1953
|
- `image-tool-result.test.ts` - Images in tool results
|
|
@@ -1888,15 +1963,15 @@ For providers with non-standard auth (AWS, Google Vertex), create a utility like
|
|
|
1888
1963
|
|
|
1889
1964
|
Update `src/core/model-resolver.ts`:
|
|
1890
1965
|
|
|
1891
|
-
- Add a default model ID for the provider in `
|
|
1966
|
+
- Add a default model ID for the provider in `defaultModelPerProvider`
|
|
1892
1967
|
|
|
1893
1968
|
Update `src/cli/args.ts`:
|
|
1894
1969
|
|
|
1895
1970
|
- Add environment variable documentation in the help text
|
|
1896
1971
|
|
|
1897
|
-
Update `
|
|
1972
|
+
Update `docs/providers.md`:
|
|
1898
1973
|
|
|
1899
|
-
- Add
|
|
1974
|
+
- Add setup instructions, the environment variable, and the `auth.json` key
|
|
1900
1975
|
|
|
1901
1976
|
#### 7. Documentation
|
|
1902
1977
|
|
|
@@ -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;AAoBlE,OAAO,KAAK,EASX,mBAAmB,EAEnB,cAAc,EACd,aAAa,
|
|
1
|
+
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAiC,MAAM,mBAAmB,CAAC;AAoBlE,OAAO,KAAK,EASX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAIb,MAAM,aAAa,CAAC;AA+JrB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AA2ChE,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,CA8VzE,CAAC;AA2BF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAgDlF,CAAC"}
|