@earendil-works/pi-ai 1.3.0 → 1.4.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 +78 -3
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +7 -10
- 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 -4
- 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 +12 -0
- 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/google-generative-ai.js +4 -4
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.js +1 -1
- 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 -9
- 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.js +2 -2
- 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 -11
- 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 +14 -8
- 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 +61 -9
- 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 -9
- 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 +4 -3
- package/dist/api/openrouter-images.js.map +1 -1
- package/dist/api/pi-messages.d.ts.map +1 -1
- package/dist/api/pi-messages.js +3 -3
- 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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- 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.js +19 -6
- package/dist/models.js.map +1 -1
- package/dist/providers/compat-schema.d.ts +168 -0
- package/dist/providers/compat-schema.d.ts.map +1 -1
- package/dist/providers/compat-schema.js +15 -2
- 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/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.json +1 -1
- package/dist/providers/data/groq.json +1 -1
- package/dist/providers/data/huggingface.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/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.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/model-schema.d.ts.map +1 -1
- package/dist/providers/model-schema.js +4 -2
- package/dist/providers/model-schema.js.map +1 -1
- package/dist/telemetry.d.ts +288 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +191 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/types.d.ts +13 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.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/overflow.d.ts +1 -0
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +6 -1
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +16 -7
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/transcript.d.ts +22 -8
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +29 -18
- package/dist/utils/transcript.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 +2 -2
- 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/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)
|
|
@@ -424,6 +426,33 @@ Header names are merged case-insensitively. Explicit headers override auth/model
|
|
|
424
426
|
|
|
425
427
|
`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
428
|
|
|
429
|
+
### Client Identity
|
|
430
|
+
|
|
431
|
+
`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:
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
const models = createModels({
|
|
435
|
+
identity: {
|
|
436
|
+
userAgent: 'detailed',
|
|
437
|
+
version: '2.1.0',
|
|
438
|
+
attribution: { name: 'my-app', url: 'https://my-app.example', categories: ['cloud-agent'] },
|
|
439
|
+
},
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
await models.completeSimple(model, context, { identity: { attribution: null } });
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
- `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.
|
|
446
|
+
- `version`: the version in the detailed `User-Agent`. Default: the pi-ai version.
|
|
447
|
+
- `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:
|
|
448
|
+
- 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).
|
|
449
|
+
- NVIDIA NIM: `X-BILLING-INVOKE-ORIGIN: <name>` with its first letter upper-cased.
|
|
450
|
+
- OpenCode: `x-opencode-client: <name>`.
|
|
451
|
+
|
|
452
|
+
`PI_ATTRIBUTION` is pi's: `{ name: "pi", url: "https://pi.dev", categories: ["cli-agent"] }`.
|
|
453
|
+
|
|
454
|
+
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.
|
|
455
|
+
|
|
427
456
|
### Credential Store
|
|
428
457
|
|
|
429
458
|
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:
|
|
@@ -866,8 +895,8 @@ Classifier models consume structured JSON state, and optionally images, and answ
|
|
|
866
895
|
| Provider | Model IDs | Auth |
|
|
867
896
|
| --- | --- | --- |
|
|
868
897
|
| `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` |
|
|
898
|
+
| `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 |
|
|
899
|
+
| `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
900
|
| `vercel-ai-gateway` | `typesafe-ai/jev` | `AI_GATEWAY_API_KEY` |
|
|
872
901
|
| `opencode` | `jev-1.13`, `jev-1.13-free` | `OPENCODE_API_KEY` |
|
|
873
902
|
| `openai` | `gpt-6-luna` | `OPENAI_API_KEY` |
|
|
@@ -912,6 +941,18 @@ When the service reports token counts, `result.usage` carries them with their co
|
|
|
912
941
|
|
|
913
942
|
`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
943
|
|
|
944
|
+
### System One images
|
|
945
|
+
|
|
946
|
+
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:
|
|
947
|
+
|
|
948
|
+
- **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.
|
|
949
|
+
- **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.
|
|
950
|
+
- **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.
|
|
951
|
+
|
|
952
|
+
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.
|
|
953
|
+
|
|
954
|
+
Vercel AI Gateway and OpenCode list their Jev models with text input only.
|
|
955
|
+
|
|
915
956
|
### OpenAI Decisions
|
|
916
957
|
|
|
917
958
|
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 +1111,40 @@ Every `AssistantMessage` includes a `stopReason` field that indicates how the ge
|
|
|
1070
1111
|
|
|
1071
1112
|
`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
1113
|
|
|
1114
|
+
## Telemetry
|
|
1115
|
+
|
|
1116
|
+
Pass an explicit parent span (`TelemetrySpan`, not an adapter) through `telemetry`; omitting it uses the no-op span:
|
|
1117
|
+
|
|
1118
|
+
```typescript
|
|
1119
|
+
import { InMemoryTelemetryContext } from '@earendil-works/pi-telemetry';
|
|
1120
|
+
|
|
1121
|
+
const telemetry = new InMemoryTelemetryContext();
|
|
1122
|
+
await telemetry.startSpan({ name: 'application.turn' }, async (span) => {
|
|
1123
|
+
await models.completeSimple(model, context, { telemetry: span });
|
|
1124
|
+
});
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
`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.
|
|
1128
|
+
|
|
1129
|
+
`AI_TELEMETRY_SCHEMA`, exported from the root and `@earendil-works/pi-ai/models`, defines the typed Pi-owned vocabulary:
|
|
1130
|
+
|
|
1131
|
+
- Start attributes: `provider`, `api`, `model`, and `reasoning` only when `options.reasoning` is a string. Provider-native reasoning objects are ignored.
|
|
1132
|
+
- 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"`.
|
|
1133
|
+
- `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.
|
|
1134
|
+
|
|
1135
|
+
When `options.telemetry.metrics` is available, the same requests record metrics:
|
|
1136
|
+
|
|
1137
|
+
| Metric | Unit | Attributes |
|
|
1138
|
+
| --- | --- | --- |
|
|
1139
|
+
| `pi.ai.request.duration` | `ms` | `provider`, `model`, `stop` |
|
|
1140
|
+
| `pi.ai.first_chunk.duration` | `ms` | `provider`, `model` |
|
|
1141
|
+
| `pi.ai.tokens` | `token` | `provider`, `model`, `kind` (`input`, `output`, `cache_read`, `cache_write`) |
|
|
1142
|
+
| `pi.ai.cost` | `USD` | `provider`, `model` |
|
|
1143
|
+
|
|
1144
|
+
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.
|
|
1145
|
+
|
|
1146
|
+
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.
|
|
1147
|
+
|
|
1073
1148
|
## Error Handling
|
|
1074
1149
|
|
|
1075
1150
|
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 +1644,7 @@ getCurrentTools(messages); // []
|
|
|
1569
1644
|
|
|
1570
1645
|
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
1646
|
|
|
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
|
|
1647
|
+
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
1648
|
|
|
1574
1649
|
## Context Serialization
|
|
1575
1650
|
|
|
@@ -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,EAMb,MAAM,aAAa,CAAC;AAuJrB,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;
|
|
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,EAMb,MAAM,aAAa,CAAC;AAuJrB,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,CA2WzE,CAAC;AA2BF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAgDlF,CAAC"}
|
|
@@ -4,8 +4,8 @@ import { calculateCost } from "../models.js";
|
|
|
4
4
|
import { appendAssistantMessageDiagnostic } from "../utils/diagnostics.js";
|
|
5
5
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
6
6
|
import { headersToRecord } from "../utils/headers.js";
|
|
7
|
+
import { getIdentityHeaders } from "../utils/identity.js";
|
|
7
8
|
import { parseJsonWithRepair, parseStreamingJson, parseToolCallArguments } from "../utils/json-parse.js";
|
|
8
|
-
import { getPiUserAgent } from "../utils/pi-user-agent.js";
|
|
9
9
|
import { getProviderEnvValue } from "../utils/provider-env.js";
|
|
10
10
|
import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
11
11
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
@@ -160,9 +160,6 @@ function mergeHeaders(...headerSources) {
|
|
|
160
160
|
}
|
|
161
161
|
return merged;
|
|
162
162
|
}
|
|
163
|
-
function mergeClientHeaders(...headerSources) {
|
|
164
|
-
return mergeHeaders({ "User-Agent": getPiUserAgent() }, ...headerSources);
|
|
165
|
-
}
|
|
166
163
|
function hasHeader(headers, name) {
|
|
167
164
|
if (!headers)
|
|
168
165
|
return false;
|
|
@@ -422,7 +419,7 @@ export const stream = (model, context, options) => {
|
|
|
422
419
|
}
|
|
423
420
|
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
424
421
|
const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
|
|
425
|
-
const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation);
|
|
422
|
+
const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation, options?.identity);
|
|
426
423
|
client = created.client;
|
|
427
424
|
isOAuth = created.isOAuthToken;
|
|
428
425
|
}
|
|
@@ -783,7 +780,7 @@ export const streamSimple = (model, context, options) => {
|
|
|
783
780
|
function isOAuthToken(apiKey) {
|
|
784
781
|
return apiKey.includes("sk-ant-oat");
|
|
785
782
|
}
|
|
786
|
-
function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation) {
|
|
783
|
+
function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation, identity) {
|
|
787
784
|
// Copilot: Bearer auth.
|
|
788
785
|
if (model.provider === "github-copilot") {
|
|
789
786
|
const client = new PiAnthropic({
|
|
@@ -792,14 +789,14 @@ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sess
|
|
|
792
789
|
baseURL: model.baseUrl,
|
|
793
790
|
dangerouslyAllowBrowser: true,
|
|
794
791
|
fetch,
|
|
795
|
-
defaultHeaders:
|
|
792
|
+
defaultHeaders: mergeHeaders(getIdentityHeaders(model, identity), {
|
|
796
793
|
accept: "application/json",
|
|
797
794
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
798
795
|
}, model.headers, dynamicHeaders, optionsHeaders),
|
|
799
796
|
});
|
|
800
797
|
return { client, isOAuthToken: false };
|
|
801
798
|
}
|
|
802
|
-
// OAuth: Bearer auth, Claude Code identity headers
|
|
799
|
+
// OAuth: Bearer auth, Claude Code identity headers instead of the client identity.
|
|
803
800
|
if (apiKey && isOAuthToken(apiKey)) {
|
|
804
801
|
const client = new PiAnthropic({
|
|
805
802
|
apiKey: null,
|
|
@@ -807,7 +804,7 @@ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sess
|
|
|
807
804
|
baseURL: model.baseUrl,
|
|
808
805
|
dangerouslyAllowBrowser: true,
|
|
809
806
|
fetch,
|
|
810
|
-
defaultHeaders:
|
|
807
|
+
defaultHeaders: mergeHeaders({
|
|
811
808
|
accept: "application/json",
|
|
812
809
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
813
810
|
"user-agent": `claude-cli/${claudeCodeVersion}`,
|
|
@@ -823,7 +820,7 @@ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sess
|
|
|
823
820
|
const header = compat.sessionAffinityFormat === "openrouter" ? "x-session-id" : "x-session-affinity";
|
|
824
821
|
sessionAffinityHeaders[header] = sessionId;
|
|
825
822
|
}
|
|
826
|
-
const defaultHeaders =
|
|
823
|
+
const defaultHeaders = mergeHeaders(getIdentityHeaders(model, identity), {
|
|
827
824
|
accept: "application/json",
|
|
828
825
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
829
826
|
}, sessionAffinityHeaders, model.headers, optionsHeaders);
|