@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
|
@@ -4,14 +4,16 @@ 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 {
|
|
8
|
-
import {
|
|
7
|
+
import { getIdentityHeaders } from "../utils/identity.js";
|
|
8
|
+
import { parseJsonWithRepair } from "../utils/json-parse.js";
|
|
9
|
+
import { applyOpenRouterReportedCost, isOpenRouterModel, } from "../utils/openrouter-cost.js";
|
|
9
10
|
import { getProviderEnvValue } from "../utils/provider-env.js";
|
|
10
11
|
import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
11
12
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
13
|
+
import { ToolCallArgumentsStream } from "../utils/streaming-json.js";
|
|
12
14
|
import { getSystemMessageText, renderSystemMessageUpdate } from "../utils/text.js";
|
|
13
15
|
import { getCurrentTools, getInitialSystemMessage, resolveTranscript, } from "../utils/transcript.js";
|
|
14
|
-
import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
|
|
16
|
+
import { getJsonSchemaToolParameters, isStrictToolLimitErrorMessage, prefersJsonSchemaStrictSampling, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
|
|
15
17
|
import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
|
|
16
18
|
import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext } from "./simple-options.js";
|
|
17
19
|
import { splitErrorToolResultImages, transformMessages } from "./transform-messages.js";
|
|
@@ -160,9 +162,6 @@ function mergeHeaders(...headerSources) {
|
|
|
160
162
|
}
|
|
161
163
|
return merged;
|
|
162
164
|
}
|
|
163
|
-
function mergeClientHeaders(...headerSources) {
|
|
164
|
-
return mergeHeaders({ "User-Agent": getPiUserAgent() }, ...headerSources);
|
|
165
|
-
}
|
|
166
165
|
function hasHeader(headers, name) {
|
|
167
166
|
if (!headers)
|
|
168
167
|
return false;
|
|
@@ -422,7 +421,7 @@ export const stream = (model, context, options) => {
|
|
|
422
421
|
}
|
|
423
422
|
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
424
423
|
const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
|
|
425
|
-
const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation);
|
|
424
|
+
const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation, options?.identity);
|
|
426
425
|
client = created.client;
|
|
427
426
|
isOAuth = created.isOAuthToken;
|
|
428
427
|
}
|
|
@@ -459,11 +458,7 @@ export const stream = (model, context, options) => {
|
|
|
459
458
|
!(error instanceof Anthropic.APIError) ||
|
|
460
459
|
error.status !== 400 ||
|
|
461
460
|
error.type !== "invalid_request_error" ||
|
|
462
|
-
!
|
|
463
|
-
"The compiled grammar is too large",
|
|
464
|
-
"Too many strict tools (",
|
|
465
|
-
"Schemas contains too many parameters with union types (",
|
|
466
|
-
].some((message) => error.message.includes(message))) {
|
|
461
|
+
!isStrictToolLimitErrorMessage(error.message)) {
|
|
467
462
|
throw error;
|
|
468
463
|
}
|
|
469
464
|
disablePreferredStrictTools = true;
|
|
@@ -477,7 +472,12 @@ export const stream = (model, context, options) => {
|
|
|
477
472
|
}
|
|
478
473
|
await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
|
|
479
474
|
stream.push({ type: "start", partial: output });
|
|
480
|
-
|
|
475
|
+
// Stream state per Anthropic block index, kept off the content blocks so it never reaches partials.
|
|
476
|
+
const openBlocks = new Map();
|
|
477
|
+
const openBlock = (anthropicIndex) => {
|
|
478
|
+
const open = openBlocks.get(anthropicIndex);
|
|
479
|
+
return open === undefined ? undefined : { ...open, block: output.content[open.contentIndex] };
|
|
480
|
+
};
|
|
481
481
|
for await (const event of iterateAnthropicEvents(response, options?.signal)) {
|
|
482
482
|
await options?.onProviderStreamEvent?.(event, model);
|
|
483
483
|
if (event.type === "message_start") {
|
|
@@ -512,105 +512,92 @@ export const stream = (model, context, options) => {
|
|
|
512
512
|
continue;
|
|
513
513
|
}
|
|
514
514
|
if (event.content_block.type === "text") {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
text: event.content_block.text ?? "",
|
|
518
|
-
index: event.index,
|
|
519
|
-
};
|
|
520
|
-
output.content.push(block);
|
|
515
|
+
output.content.push({ type: "text", text: event.content_block.text ?? "" });
|
|
516
|
+
openBlocks.set(event.index, { contentIndex: output.content.length - 1 });
|
|
521
517
|
stream.push({ type: "text_start", contentIndex: output.content.length - 1, partial: output });
|
|
522
518
|
}
|
|
523
519
|
else if (event.content_block.type === "thinking") {
|
|
524
|
-
|
|
520
|
+
output.content.push({
|
|
525
521
|
type: "thinking",
|
|
526
522
|
thinking: event.content_block.thinking ?? "",
|
|
527
523
|
thinkingSignature: event.content_block.signature ?? "",
|
|
528
|
-
|
|
529
|
-
};
|
|
530
|
-
output.content.push(block);
|
|
524
|
+
});
|
|
525
|
+
openBlocks.set(event.index, { contentIndex: output.content.length - 1 });
|
|
531
526
|
stream.push({ type: "thinking_start", contentIndex: output.content.length - 1, partial: output });
|
|
532
527
|
}
|
|
533
528
|
else if (event.content_block.type === "redacted_thinking") {
|
|
534
|
-
|
|
529
|
+
output.content.push({
|
|
535
530
|
type: "thinking",
|
|
536
531
|
thinking: "[Reasoning redacted]",
|
|
537
532
|
thinkingSignature: event.content_block.data,
|
|
538
533
|
redacted: true,
|
|
539
|
-
|
|
540
|
-
};
|
|
541
|
-
output.content.push(block);
|
|
534
|
+
});
|
|
535
|
+
openBlocks.set(event.index, { contentIndex: output.content.length - 1 });
|
|
542
536
|
stream.push({ type: "thinking_start", contentIndex: output.content.length - 1, partial: output });
|
|
543
537
|
}
|
|
544
538
|
else if (event.content_block.type === "tool_use") {
|
|
545
|
-
|
|
539
|
+
output.content.push({
|
|
546
540
|
type: "toolCall",
|
|
547
541
|
id: event.content_block.id,
|
|
548
542
|
name: isOAuth
|
|
549
543
|
? fromClaudeCodeName(event.content_block.name, currentTools)
|
|
550
544
|
: event.content_block.name,
|
|
551
545
|
arguments: event.content_block.input ?? {},
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
546
|
+
});
|
|
547
|
+
openBlocks.set(event.index, {
|
|
548
|
+
contentIndex: output.content.length - 1,
|
|
549
|
+
arguments: new ToolCallArgumentsStream(),
|
|
550
|
+
});
|
|
556
551
|
stream.push({ type: "toolcall_start", contentIndex: output.content.length - 1, partial: output });
|
|
557
552
|
}
|
|
558
553
|
}
|
|
559
554
|
else if (event.type === "content_block_delta") {
|
|
555
|
+
const open = openBlock(event.index);
|
|
560
556
|
if (event.delta.type === "text_delta") {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
if (block && block.type === "text") {
|
|
564
|
-
block.text += event.delta.text;
|
|
557
|
+
if (open?.block.type === "text") {
|
|
558
|
+
open.block.text += event.delta.text;
|
|
565
559
|
stream.push({
|
|
566
560
|
type: "text_delta",
|
|
567
|
-
contentIndex:
|
|
561
|
+
contentIndex: open.contentIndex,
|
|
568
562
|
delta: event.delta.text,
|
|
569
563
|
partial: output,
|
|
570
564
|
});
|
|
571
565
|
}
|
|
572
566
|
}
|
|
573
567
|
else if (event.delta.type === "thinking_delta") {
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
if (block && block.type === "thinking") {
|
|
577
|
-
block.thinking += event.delta.thinking;
|
|
568
|
+
if (open?.block.type === "thinking") {
|
|
569
|
+
open.block.thinking += event.delta.thinking;
|
|
578
570
|
stream.push({
|
|
579
571
|
type: "thinking_delta",
|
|
580
|
-
contentIndex:
|
|
572
|
+
contentIndex: open.contentIndex,
|
|
581
573
|
delta: event.delta.thinking,
|
|
582
574
|
partial: output,
|
|
583
575
|
});
|
|
584
576
|
}
|
|
585
577
|
}
|
|
586
578
|
else if (event.delta.type === "input_json_delta") {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
if (block && block.type === "toolCall") {
|
|
590
|
-
block.partialJson += event.delta.partial_json;
|
|
591
|
-
block.arguments = parseStreamingJson(block.partialJson);
|
|
579
|
+
if (open?.block.type === "toolCall" && open.arguments !== undefined) {
|
|
580
|
+
open.block.arguments = open.arguments.append(event.delta.partial_json);
|
|
592
581
|
stream.push({
|
|
593
582
|
type: "toolcall_delta",
|
|
594
|
-
contentIndex:
|
|
583
|
+
contentIndex: open.contentIndex,
|
|
595
584
|
delta: event.delta.partial_json,
|
|
596
585
|
partial: output,
|
|
597
586
|
});
|
|
598
587
|
}
|
|
599
588
|
}
|
|
600
589
|
else if (event.delta.type === "signature_delta") {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
block.thinkingSignature = block.thinkingSignature || "";
|
|
605
|
-
block.thinkingSignature += event.delta.signature;
|
|
590
|
+
if (open?.block.type === "thinking") {
|
|
591
|
+
open.block.thinkingSignature = open.block.thinkingSignature || "";
|
|
592
|
+
open.block.thinkingSignature += event.delta.signature;
|
|
606
593
|
}
|
|
607
594
|
}
|
|
608
595
|
}
|
|
609
596
|
else if (event.type === "content_block_stop") {
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
if (
|
|
613
|
-
|
|
597
|
+
const open = openBlock(event.index);
|
|
598
|
+
openBlocks.delete(event.index);
|
|
599
|
+
if (open) {
|
|
600
|
+
const { block, contentIndex: index } = open;
|
|
614
601
|
if (block.type === "text") {
|
|
615
602
|
stream.push({
|
|
616
603
|
type: "text_end",
|
|
@@ -627,11 +614,8 @@ export const stream = (model, context, options) => {
|
|
|
627
614
|
partial: output,
|
|
628
615
|
});
|
|
629
616
|
}
|
|
630
|
-
else if (block.type === "toolCall") {
|
|
631
|
-
Object.assign(block,
|
|
632
|
-
// Finalize in-place and strip the scratch buffer so replay only
|
|
633
|
-
// carries parsed arguments.
|
|
634
|
-
delete block.partialJson;
|
|
617
|
+
else if (block.type === "toolCall" && open.arguments !== undefined) {
|
|
618
|
+
Object.assign(block, open.arguments.finish());
|
|
635
619
|
stream.push({
|
|
636
620
|
type: "toolcall_end",
|
|
637
621
|
contentIndex: index,
|
|
@@ -683,6 +667,11 @@ export const stream = (model, context, options) => {
|
|
|
683
667
|
output.usage.totalTokens =
|
|
684
668
|
output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
685
669
|
calculateCost(usageModel, output.usage);
|
|
670
|
+
if (isOpenRouterModel(model) && event.usage) {
|
|
671
|
+
// OpenRouter adds billing fields to streamed message_delta usage at runtime,
|
|
672
|
+
// although its OpenAPI schema and the Anthropic SDK do not type those fields.
|
|
673
|
+
applyOpenRouterReportedCost(output.usage, event.usage);
|
|
674
|
+
}
|
|
686
675
|
}
|
|
687
676
|
}
|
|
688
677
|
if (options?.signal?.aborted) {
|
|
@@ -711,11 +700,6 @@ export const stream = (model, context, options) => {
|
|
|
711
700
|
stream.end();
|
|
712
701
|
}
|
|
713
702
|
catch (error) {
|
|
714
|
-
for (const block of output.content) {
|
|
715
|
-
delete block.index;
|
|
716
|
-
// partialJson is only a streaming scratch buffer; never persist it.
|
|
717
|
-
delete block.partialJson;
|
|
718
|
-
}
|
|
719
703
|
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
720
704
|
output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
|
721
705
|
stream.push({ type: "error", reason: output.stopReason, error: output });
|
|
@@ -783,7 +767,7 @@ export const streamSimple = (model, context, options) => {
|
|
|
783
767
|
function isOAuthToken(apiKey) {
|
|
784
768
|
return apiKey.includes("sk-ant-oat");
|
|
785
769
|
}
|
|
786
|
-
function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation) {
|
|
770
|
+
function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation, identity) {
|
|
787
771
|
// Copilot: Bearer auth.
|
|
788
772
|
if (model.provider === "github-copilot") {
|
|
789
773
|
const client = new PiAnthropic({
|
|
@@ -792,14 +776,14 @@ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sess
|
|
|
792
776
|
baseURL: model.baseUrl,
|
|
793
777
|
dangerouslyAllowBrowser: true,
|
|
794
778
|
fetch,
|
|
795
|
-
defaultHeaders:
|
|
779
|
+
defaultHeaders: mergeHeaders(getIdentityHeaders(model, identity), {
|
|
796
780
|
accept: "application/json",
|
|
797
781
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
798
782
|
}, model.headers, dynamicHeaders, optionsHeaders),
|
|
799
783
|
});
|
|
800
784
|
return { client, isOAuthToken: false };
|
|
801
785
|
}
|
|
802
|
-
// OAuth: Bearer auth, Claude Code identity headers
|
|
786
|
+
// OAuth: Bearer auth, Claude Code identity headers instead of the client identity.
|
|
803
787
|
if (apiKey && isOAuthToken(apiKey)) {
|
|
804
788
|
const client = new PiAnthropic({
|
|
805
789
|
apiKey: null,
|
|
@@ -807,7 +791,7 @@ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sess
|
|
|
807
791
|
baseURL: model.baseUrl,
|
|
808
792
|
dangerouslyAllowBrowser: true,
|
|
809
793
|
fetch,
|
|
810
|
-
defaultHeaders:
|
|
794
|
+
defaultHeaders: mergeHeaders({
|
|
811
795
|
accept: "application/json",
|
|
812
796
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
813
797
|
"user-agent": `claude-cli/${claudeCodeVersion}`,
|
|
@@ -823,7 +807,7 @@ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sess
|
|
|
823
807
|
const header = compat.sessionAffinityFormat === "openrouter" ? "x-session-id" : "x-session-affinity";
|
|
824
808
|
sessionAffinityHeaders[header] = sessionId;
|
|
825
809
|
}
|
|
826
|
-
const defaultHeaders =
|
|
810
|
+
const defaultHeaders = mergeHeaders(getIdentityHeaders(model, identity), {
|
|
827
811
|
accept: "application/json",
|
|
828
812
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
829
813
|
}, sessionAffinityHeaders, model.headers, optionsHeaders);
|
|
@@ -904,10 +888,7 @@ function buildParams(model, context, isOAuthToken, options, disablePreferredStri
|
|
|
904
888
|
let hasPreferredStrictTools = false;
|
|
905
889
|
const convertToolDefinitions = (tools, toolCacheControl) => {
|
|
906
890
|
const definitions = convertTools(tools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl, disablePreferredStrictTools);
|
|
907
|
-
if (definitions.some((definition, index) => {
|
|
908
|
-
const config = tools[index].constrainedSampling;
|
|
909
|
-
return definition.strict === true && config && config.type === "json_schema" && config.strict === "prefer";
|
|
910
|
-
})) {
|
|
891
|
+
if (definitions.some((definition, index) => definition.strict === true && prefersJsonSchemaStrictSampling(tools[index]))) {
|
|
911
892
|
hasPreferredStrictTools = true;
|
|
912
893
|
}
|
|
913
894
|
return definitions;
|
|
@@ -988,7 +969,10 @@ function buildParams(model, context, isOAuthToken, options, disablePreferredStri
|
|
|
988
969
|
display: options?.thinkingDisplay ?? "summarized",
|
|
989
970
|
block_binding: { prefix_mismatch_behavior: "drop_block" },
|
|
990
971
|
};
|
|
991
|
-
|
|
972
|
+
// Effort markers set the level for every reply. The top-level effort is part of the cached
|
|
973
|
+
// prompt, so it stays fixed. It is "low" because organizations can cap effort and reject
|
|
974
|
+
// requests containing any level above the cap.
|
|
975
|
+
params.output_config = { effort: "low" };
|
|
992
976
|
}
|
|
993
977
|
else if (model.reasoning && options?.thinkingEnabled) {
|
|
994
978
|
// Default to "summarized" so Opus 4.7 and Mythos Preview behave like
|
|
@@ -1048,7 +1032,9 @@ convertToolDefinitions) {
|
|
|
1048
1032
|
const params = [];
|
|
1049
1033
|
const assistantLevels = new Map();
|
|
1050
1034
|
// Later system messages are held back and emitted directly before the next assistant
|
|
1051
|
-
// message (or at the end of the transcript).
|
|
1035
|
+
// message that is sent (or at the end of the transcript). Assistant messages that convert to
|
|
1036
|
+
// no blocks are dropped, so holding past them keeps an update from landing before a user
|
|
1037
|
+
// message (#11091). Anthropic requires `tool_result` blocks to
|
|
1052
1038
|
// immediately follow their `tool_use`, so a system message between them is rejected; this
|
|
1053
1039
|
// also mirrors where the managed-effort system messages are inserted. As a result an
|
|
1054
1040
|
// update placed before a user message in the transcript lands after it on the wire.
|
|
@@ -1121,7 +1107,6 @@ convertToolDefinitions) {
|
|
|
1121
1107
|
}
|
|
1122
1108
|
}
|
|
1123
1109
|
else if (msg.role === "assistant") {
|
|
1124
|
-
flushPendingSystemMessages();
|
|
1125
1110
|
const blocks = [];
|
|
1126
1111
|
for (const block of msg.content) {
|
|
1127
1112
|
if (block.type === "text") {
|
|
@@ -1179,6 +1164,7 @@ convertToolDefinitions) {
|
|
|
1179
1164
|
}
|
|
1180
1165
|
if (blocks.length === 0)
|
|
1181
1166
|
continue;
|
|
1167
|
+
flushPendingSystemMessages();
|
|
1182
1168
|
const messageIndex = params.length;
|
|
1183
1169
|
params.push({
|
|
1184
1170
|
role: "assistant",
|
|
@@ -1302,8 +1288,7 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
|
|
|
1302
1288
|
if (!tools)
|
|
1303
1289
|
return [];
|
|
1304
1290
|
return tools.map((tool, index) => {
|
|
1305
|
-
const
|
|
1306
|
-
const strict = disablePreferredStrictTools && config && config.type === "json_schema" && config.strict === "prefer"
|
|
1291
|
+
const strict = disablePreferredStrictTools && prefersJsonSchemaStrictSampling(tool)
|
|
1307
1292
|
? undefined
|
|
1308
1293
|
: resolveJsonSchemaStrictSampling(tool, supportsStrictTools, isAnthropicStrictUnsupportedKeyword);
|
|
1309
1294
|
const parameters = getJsonSchemaToolParameters(tool, strict);
|