@earendil-works/pi-ai 1.4.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -39
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +282 -87
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/dist/api/azure-openai-responses.js +1 -7
- package/dist/api/azure-openai-responses.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +127 -103
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/bedrock-converse-stream.lazy.d.ts +7 -0
- package/dist/api/bedrock-converse-stream.lazy.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.lazy.js +18 -5
- package/dist/api/bedrock-converse-stream.lazy.js.map +1 -1
- package/dist/api/constrained-sampling.d.ts +13 -1
- package/dist/api/constrained-sampling.d.ts.map +1 -1
- package/dist/api/constrained-sampling.js +38 -18
- package/dist/api/constrained-sampling.js.map +1 -1
- package/dist/api/google-generative-ai.d.ts.map +1 -1
- package/dist/api/google-generative-ai.js +0 -6
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts +2 -1
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +57 -2
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/google-vertex.d.ts.map +1 -1
- package/dist/api/google-vertex.js +0 -6
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/lazy.d.ts +1 -1
- package/dist/api/lazy.d.ts.map +1 -1
- package/dist/api/lazy.js +9 -8
- package/dist/api/lazy.js.map +1 -1
- package/dist/api/mistral-conversations.d.ts.map +1 -1
- package/dist/api/mistral-conversations.js +17 -44
- package/dist/api/mistral-conversations.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +7 -8
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts +2 -1
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +55 -59
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +58 -57
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +4 -8
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/openrouter-images.js +1 -0
- package/dist/api/openrouter-images.js.map +1 -1
- package/dist/api/pi-messages.d.ts +2 -0
- package/dist/api/pi-messages.d.ts.map +1 -1
- package/dist/api/pi-messages.js +24 -9
- package/dist/api/pi-messages.js.map +1 -1
- package/dist/api/simple-options.d.ts +1 -0
- package/dist/api/simple-options.d.ts.map +1 -1
- package/dist/api/simple-options.js +16 -2
- package/dist/api/simple-options.js.map +1 -1
- package/dist/api/strict-tool-limits.d.ts +13 -0
- package/dist/api/strict-tool-limits.d.ts.map +1 -0
- package/dist/api/strict-tool-limits.js +50 -0
- package/dist/api/strict-tool-limits.js.map +1 -0
- package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
- package/dist/auth/oauth/github-copilot.js +4 -11
- package/dist/auth/oauth/github-copilot.js.map +1 -1
- package/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
- package/dist/auth/oauth/kimi-coding.js +4 -22
- package/dist/auth/oauth/kimi-coding.js.map +1 -1
- package/dist/auth/oauth/load.d.ts.map +1 -1
- package/dist/auth/oauth/load.js +5 -2
- package/dist/auth/oauth/load.js.map +1 -1
- package/dist/auth/oauth/meta.d.ts.map +1 -1
- package/dist/auth/oauth/meta.js +1 -14
- package/dist/auth/oauth/meta.js.map +1 -1
- package/dist/auth/oauth/radius.d.ts.map +1 -1
- package/dist/auth/oauth/radius.js +9 -3
- package/dist/auth/oauth/radius.js.map +1 -1
- package/dist/auth/oauth/trusted-url.d.ts +7 -0
- package/dist/auth/oauth/trusted-url.d.ts.map +1 -0
- package/dist/auth/oauth/trusted-url.js +12 -0
- package/dist/auth/oauth/trusted-url.js.map +1 -0
- package/dist/auth/types.d.ts +4 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/types.js.map +1 -1
- package/dist/cache-warming.d.ts +53 -0
- package/dist/cache-warming.d.ts.map +1 -0
- package/dist/cache-warming.js +82 -0
- package/dist/cache-warming.js.map +1 -0
- package/dist/cli.js +6 -2
- package/dist/cli.js.map +1 -1
- package/dist/compat/extension-oauth-types.d.ts +4 -0
- package/dist/compat/extension-oauth-types.d.ts.map +1 -1
- package/dist/compat/extension-oauth-types.js.map +1 -1
- package/dist/env-api-keys.d.ts.map +1 -1
- package/dist/env-api-keys.js +1 -0
- package/dist/env-api-keys.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/lazy-bedrock-provider.d.ts +10 -0
- package/dist/lazy-bedrock-provider.d.ts.map +1 -0
- package/dist/lazy-bedrock-provider.js +13 -0
- package/dist/lazy-bedrock-provider.js.map +1 -0
- package/dist/lazy-oauth.d.ts +10 -0
- package/dist/lazy-oauth.d.ts.map +1 -0
- package/dist/lazy-oauth.js +23 -0
- package/dist/lazy-oauth.js.map +1 -0
- package/dist/models.d.ts +7 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.generated.d.ts +4 -0
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +5 -1
- package/dist/models.generated.js.map +1 -1
- package/dist/models.js +20 -11
- package/dist/models.js.map +1 -1
- package/dist/providers/all.d.ts.map +1 -1
- package/dist/providers/all.js +2 -0
- package/dist/providers/all.js.map +1 -1
- package/dist/providers/amazon-bedrock.models.js +1 -1
- package/dist/providers/amazon-bedrock.models.js.map +1 -1
- package/dist/providers/ant-ling.models.js +1 -1
- package/dist/providers/ant-ling.models.js.map +1 -1
- package/dist/providers/anthropic.models.js +1 -1
- package/dist/providers/anthropic.models.js.map +1 -1
- package/dist/providers/azure.models.js +1 -1
- package/dist/providers/azure.models.js.map +1 -1
- package/dist/providers/baseten.models.js +1 -1
- package/dist/providers/baseten.models.js.map +1 -1
- package/dist/providers/cerebras.models.js +1 -1
- package/dist/providers/cerebras.models.js.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.js +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
- package/dist/providers/cloudflare-workers-ai.models.js +1 -1
- package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
- package/dist/providers/compat-schema.d.ts +444 -456
- package/dist/providers/compat-schema.d.ts.map +1 -1
- package/dist/providers/compat-schema.js +166 -112
- package/dist/providers/compat-schema.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/amazon-bedrock.json +1 -1
- package/dist/providers/data/anthropic.json +1 -1
- package/dist/providers/data/azure.json +1 -1
- package/dist/providers/data/baseten.json +1 -1
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/dist/providers/data/fireworks.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/google-vertex.json +1 -1
- package/dist/providers/data/google.json +1 -1
- package/dist/providers/data/huggingface.json +1 -1
- package/dist/providers/data/kimi-coding.json +1 -1
- package/dist/providers/data/mistral.json +1 -1
- package/dist/providers/data/moonshotai-cn.json +1 -1
- package/dist/providers/data/moonshotai.json +1 -1
- package/dist/providers/data/nvidia.json +1 -1
- package/dist/providers/data/openai-codex.json +1 -1
- package/dist/providers/data/openai.json +1 -1
- package/dist/providers/data/opencode-go.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/dist/providers/data/qwen-token-plan-individual-cn.json +1 -0
- package/dist/providers/data/qwen-token-plan-individual.json +1 -1
- package/dist/providers/data/qwen-token-plan.json +1 -1
- package/dist/providers/data/radius.json +1 -1
- package/dist/providers/data/together.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/data/xai.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
- package/dist/providers/data/xiaomi.json +1 -1
- package/dist/providers/data/zai-coding-cn.json +1 -1
- package/dist/providers/data/zai.json +1 -1
- package/dist/providers/deepseek.models.js +1 -1
- package/dist/providers/deepseek.models.js.map +1 -1
- package/dist/providers/faux.d.ts.map +1 -1
- package/dist/providers/faux.js +7 -2
- package/dist/providers/faux.js.map +1 -1
- package/dist/providers/fireworks.models.js +1 -1
- package/dist/providers/fireworks.models.js.map +1 -1
- package/dist/providers/github-copilot.d.ts +3 -1
- package/dist/providers/github-copilot.d.ts.map +1 -1
- package/dist/providers/github-copilot.js +13 -2
- package/dist/providers/github-copilot.js.map +1 -1
- package/dist/providers/github-copilot.models.js +1 -1
- package/dist/providers/github-copilot.models.js.map +1 -1
- package/dist/providers/google-vertex.models.js +1 -1
- package/dist/providers/google-vertex.models.js.map +1 -1
- package/dist/providers/google.models.js +1 -1
- package/dist/providers/google.models.js.map +1 -1
- package/dist/providers/groq.models.js +1 -1
- package/dist/providers/groq.models.js.map +1 -1
- package/dist/providers/huggingface.models.js +1 -1
- package/dist/providers/huggingface.models.js.map +1 -1
- package/dist/providers/kimi-coding.models.js +1 -1
- package/dist/providers/kimi-coding.models.js.map +1 -1
- package/dist/providers/meta.models.js +1 -1
- package/dist/providers/meta.models.js.map +1 -1
- package/dist/providers/minimax-cn.models.js +1 -1
- package/dist/providers/minimax-cn.models.js.map +1 -1
- package/dist/providers/minimax.models.js +1 -1
- package/dist/providers/minimax.models.js.map +1 -1
- package/dist/providers/mistral.models.js +1 -1
- package/dist/providers/mistral.models.js.map +1 -1
- package/dist/providers/model-schema.d.ts +65 -65
- package/dist/providers/model-schema.d.ts.map +1 -1
- package/dist/providers/model-schema.js +41 -30
- package/dist/providers/model-schema.js.map +1 -1
- package/dist/providers/moonshotai-cn.models.js +1 -1
- package/dist/providers/moonshotai-cn.models.js.map +1 -1
- package/dist/providers/moonshotai.models.js +1 -1
- package/dist/providers/moonshotai.models.js.map +1 -1
- package/dist/providers/nvidia.models.js +1 -1
- package/dist/providers/nvidia.models.js.map +1 -1
- package/dist/providers/openai-codex.js +1 -1
- package/dist/providers/openai-codex.js.map +1 -1
- package/dist/providers/openai-codex.models.js +1 -1
- package/dist/providers/openai-codex.models.js.map +1 -1
- package/dist/providers/openai.models.js +1 -1
- package/dist/providers/openai.models.js.map +1 -1
- package/dist/providers/opencode-go.models.js +1 -1
- package/dist/providers/opencode-go.models.js.map +1 -1
- package/dist/providers/opencode.js +1 -1
- package/dist/providers/opencode.js.map +1 -1
- package/dist/providers/opencode.models.js +1 -1
- package/dist/providers/opencode.models.js.map +1 -1
- package/dist/providers/openrouter.models.js +1 -1
- package/dist/providers/openrouter.models.js.map +1 -1
- package/dist/providers/qwen-token-plan-cn.models.js +1 -1
- package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
- package/dist/providers/qwen-token-plan-individual-cn.d.ts +3 -0
- package/dist/providers/qwen-token-plan-individual-cn.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-individual-cn.js +15 -0
- package/dist/providers/qwen-token-plan-individual-cn.js.map +1 -0
- package/dist/providers/qwen-token-plan-individual-cn.models.d.ts +6 -0
- package/dist/providers/qwen-token-plan-individual-cn.models.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-individual-cn.models.js +8 -0
- package/dist/providers/qwen-token-plan-individual-cn.models.js.map +1 -0
- package/dist/providers/qwen-token-plan-individual.models.js +1 -1
- package/dist/providers/qwen-token-plan-individual.models.js.map +1 -1
- package/dist/providers/qwen-token-plan.models.js +1 -1
- package/dist/providers/qwen-token-plan.models.js.map +1 -1
- package/dist/providers/radius-config.d.ts.map +1 -1
- package/dist/providers/radius-config.js +2 -1
- package/dist/providers/radius-config.js.map +1 -1
- package/dist/providers/radius.models.js +1 -1
- package/dist/providers/radius.models.js.map +1 -1
- package/dist/providers/schema-builders.d.ts +10 -0
- package/dist/providers/schema-builders.d.ts.map +1 -0
- package/dist/providers/schema-builders.js +18 -0
- package/dist/providers/schema-builders.js.map +1 -0
- package/dist/providers/together.models.js +1 -1
- package/dist/providers/together.models.js.map +1 -1
- package/dist/providers/typesafe.models.js +1 -1
- package/dist/providers/typesafe.models.js.map +1 -1
- package/dist/providers/vercel-ai-gateway.models.js +1 -1
- package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
- package/dist/providers/xai.models.js +1 -1
- package/dist/providers/xai.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-ams.models.js +1 -1
- package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-cn.models.js +1 -1
- package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
- package/dist/providers/xiaomi-token-plan-sgp.models.js +1 -1
- package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
- package/dist/providers/xiaomi.models.js +1 -1
- package/dist/providers/xiaomi.models.js.map +1 -1
- package/dist/providers/zai-coding-cn.models.js +1 -1
- package/dist/providers/zai-coding-cn.models.js.map +1 -1
- package/dist/providers/zai.models.js +1 -1
- package/dist/providers/zai.models.js.map +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +2 -1
- package/dist/telemetry.js.map +1 -1
- package/dist/types.d.ts +20 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/error-body.d.ts +8 -0
- package/dist/utils/error-body.d.ts.map +1 -1
- package/dist/utils/error-body.js +30 -2
- package/dist/utils/error-body.js.map +1 -1
- package/dist/utils/openrouter-cost.d.ts +24 -0
- package/dist/utils/openrouter-cost.d.ts.map +1 -0
- package/dist/utils/openrouter-cost.js +34 -0
- package/dist/utils/openrouter-cost.js.map +1 -0
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +2 -0
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +6 -0
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/streaming-json.d.ts +84 -0
- package/dist/utils/streaming-json.d.ts.map +1 -0
- package/dist/utils/streaming-json.js +513 -0
- package/dist/utils/streaming-json.js.map +1 -0
- package/dist/utils/{typebox-helpers.d.ts → string-enum.d.ts} +5 -5
- package/dist/utils/string-enum.d.ts.map +1 -0
- package/dist/utils/{typebox-helpers.js → string-enum.js} +5 -6
- package/dist/utils/string-enum.js.map +1 -0
- package/dist/utils/text.d.ts +7 -0
- package/dist/utils/text.d.ts.map +1 -1
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/transcript.d.ts +1 -1
- package/dist/utils/transcript.js +1 -1
- package/dist/utils/transcript.js.map +1 -1
- package/dist/utils/validation.d.ts +5 -3
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +27 -277
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/version.js +1 -1
- package/dist/utils/version.js.map +1 -1
- package/package.json +19 -10
- package/dist/utils/typebox-helpers.d.ts.map +0 -1
- package/dist/utils/typebox-helpers.js.map +0 -1
|
@@ -5,13 +5,14 @@ import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
|
5
5
|
import { shortHash } from "../utils/hash.js";
|
|
6
6
|
import { headersToRecord } from "../utils/headers.js";
|
|
7
7
|
import { getIdentityHeaders } from "../utils/identity.js";
|
|
8
|
-
import {
|
|
8
|
+
import { applyOpenRouterReportedCost, isOpenRouterModel, } from "../utils/openrouter-cost.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";
|
|
12
|
+
import { ToolCallArgumentsStream } from "../utils/streaming-json.js";
|
|
12
13
|
import { getSystemMessageText, renderSystemMessageUpdate } from "../utils/text.js";
|
|
13
14
|
import { getDeclaredTools, resolveTranscript, resolveTranscriptTools, } from "../utils/transcript.js";
|
|
14
|
-
import { appendGrammarToolInputJsonDelta, createGrammarToolInputProperties, getGrammarToolInput, getJsonSchemaToolParameters, resolveGrammarConstrainedSampling, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
|
|
15
|
+
import { appendGrammarToolInputJsonDelta, closeGrammarToolInputJson, createGrammarToolInputProperties, getGrammarToolInput, getJsonSchemaToolParameters, resolveGrammarConstrainedSampling, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
|
|
15
16
|
import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
|
|
16
17
|
import { clampOpenAIPromptCacheKey } from "./openai-prompt-cache.js";
|
|
17
18
|
import { buildBaseOptions, clampThinkingBudgetToAnswerRoom, resolveSamplingParams, thinkingBudgetForLevel, } from "./simple-options.js";
|
|
@@ -206,23 +207,14 @@ export const stream = (model, context, options) => {
|
|
|
206
207
|
let hasFinishReason = false;
|
|
207
208
|
const toolCallBlocksByIndex = new Map();
|
|
208
209
|
const toolCallBlocksById = new Map();
|
|
210
|
+
const toolCallStates = new Map();
|
|
209
211
|
const blocks = output.content;
|
|
210
212
|
const getContentIndex = (block) => blocks.indexOf(block);
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return typeof value === "string" ? value : "";
|
|
217
|
-
};
|
|
218
|
-
const appendCustomToolCallInput = (block, nextInput, close) => {
|
|
219
|
-
const customInput = block.customInput;
|
|
220
|
-
if (!customInput)
|
|
221
|
-
return undefined;
|
|
222
|
-
const delta = appendGrammarToolInputJsonDelta(customInput.jsonBuffer, customInput.property, nextInput, close);
|
|
223
|
-
block.arguments = { [customInput.property]: nextInput };
|
|
224
|
-
return delta;
|
|
225
|
-
};
|
|
213
|
+
const customInput = (property) => ({
|
|
214
|
+
kind: "custom",
|
|
215
|
+
property,
|
|
216
|
+
buffer: { input: "", started: false, closed: false },
|
|
217
|
+
});
|
|
226
218
|
const finishBlock = (block) => {
|
|
227
219
|
const contentIndex = getContentIndex(block);
|
|
228
220
|
if (contentIndex === -1) {
|
|
@@ -246,8 +238,10 @@ export const stream = (model, context, options) => {
|
|
|
246
238
|
});
|
|
247
239
|
}
|
|
248
240
|
else if (block.type === "toolCall") {
|
|
249
|
-
|
|
250
|
-
|
|
241
|
+
const input = toolCallStates.get(block).input;
|
|
242
|
+
toolCallStates.delete(block);
|
|
243
|
+
if (input.kind === "custom") {
|
|
244
|
+
const delta = closeGrammarToolInputJson(input.buffer, input.property, undefined);
|
|
251
245
|
if (delta !== undefined) {
|
|
252
246
|
stream.push({
|
|
253
247
|
type: "toolcall_delta",
|
|
@@ -258,13 +252,8 @@ export const stream = (model, context, options) => {
|
|
|
258
252
|
}
|
|
259
253
|
}
|
|
260
254
|
else {
|
|
261
|
-
Object.assign(block,
|
|
255
|
+
Object.assign(block, input.arguments.finish());
|
|
262
256
|
}
|
|
263
|
-
// Finalize in-place and strip the scratch buffers so replay only
|
|
264
|
-
// carries parsed arguments.
|
|
265
|
-
delete block.partialArgs;
|
|
266
|
-
delete block.customInput;
|
|
267
|
-
delete block.streamIndex;
|
|
268
257
|
stream.push({
|
|
269
258
|
type: "toolcall_end",
|
|
270
259
|
contentIndex,
|
|
@@ -304,18 +293,18 @@ export const stream = (model, context, options) => {
|
|
|
304
293
|
// Note: the "input" fallback here should/must not be taken. in case the LLM makes up
|
|
305
294
|
// a tool we don't knwo about, we at least have a place to stash our stuff.
|
|
306
295
|
const customInputProperty = toolCall.custom && !toolCall.function ? (grammarToolInputProperties.get(name) ?? "input") : undefined;
|
|
307
|
-
const hasCustomInput = customInputProperty !== undefined;
|
|
308
296
|
block = {
|
|
309
297
|
type: "toolCall",
|
|
310
298
|
id: toolCall.id || "",
|
|
311
299
|
name,
|
|
312
|
-
arguments:
|
|
313
|
-
partialArgs: hasCustomInput ? undefined : "",
|
|
314
|
-
customInput: hasCustomInput
|
|
315
|
-
? { property: customInputProperty, jsonBuffer: { input: "", started: false, closed: false } }
|
|
316
|
-
: undefined,
|
|
317
|
-
streamIndex,
|
|
300
|
+
arguments: customInputProperty !== undefined ? { [customInputProperty]: "" } : {},
|
|
318
301
|
};
|
|
302
|
+
toolCallStates.set(block, {
|
|
303
|
+
streamIndex,
|
|
304
|
+
input: customInputProperty !== undefined
|
|
305
|
+
? customInput(customInputProperty)
|
|
306
|
+
: { kind: "json", arguments: new ToolCallArgumentsStream() },
|
|
307
|
+
});
|
|
319
308
|
if (streamIndex !== undefined) {
|
|
320
309
|
toolCallBlocksByIndex.set(streamIndex, block);
|
|
321
310
|
}
|
|
@@ -329,8 +318,9 @@ export const stream = (model, context, options) => {
|
|
|
329
318
|
partial: output,
|
|
330
319
|
});
|
|
331
320
|
}
|
|
332
|
-
|
|
333
|
-
|
|
321
|
+
const state = toolCallStates.get(block);
|
|
322
|
+
if (streamIndex !== undefined && state.streamIndex === undefined) {
|
|
323
|
+
state.streamIndex = streamIndex;
|
|
334
324
|
toolCallBlocksByIndex.set(streamIndex, block);
|
|
335
325
|
}
|
|
336
326
|
if (toolCall.id) {
|
|
@@ -339,16 +329,12 @@ export const stream = (model, context, options) => {
|
|
|
339
329
|
if (!block.name && name) {
|
|
340
330
|
block.name = name;
|
|
341
331
|
}
|
|
342
|
-
if (toolCall.custom && !toolCall.function &&
|
|
332
|
+
if (toolCall.custom && !toolCall.function && state.input.kind !== "custom") {
|
|
343
333
|
const customInputProperty = grammarToolInputProperties.get(block.name) ?? "input";
|
|
344
334
|
block.arguments = { [customInputProperty]: "" };
|
|
345
|
-
|
|
346
|
-
property: customInputProperty,
|
|
347
|
-
jsonBuffer: { input: "", started: false, closed: false },
|
|
348
|
-
};
|
|
349
|
-
delete block.partialArgs;
|
|
335
|
+
state.input = customInput(customInputProperty);
|
|
350
336
|
}
|
|
351
|
-
return block;
|
|
337
|
+
return { block, state };
|
|
352
338
|
};
|
|
353
339
|
for await (const chunk of openaiStream) {
|
|
354
340
|
await options?.onProviderStreamEvent?.(chunk, model);
|
|
@@ -440,7 +426,7 @@ export const stream = (model, context, options) => {
|
|
|
440
426
|
}
|
|
441
427
|
if (choice?.delta?.tool_calls) {
|
|
442
428
|
for (const toolCall of choice.delta.tool_calls) {
|
|
443
|
-
const block = ensureToolCallBlock(toolCall);
|
|
429
|
+
const { block, state } = ensureToolCallBlock(toolCall);
|
|
444
430
|
if (!block.id && toolCall.id) {
|
|
445
431
|
block.id = toolCall.id;
|
|
446
432
|
toolCallBlocksById.set(toolCall.id, block);
|
|
@@ -450,14 +436,15 @@ export const stream = (model, context, options) => {
|
|
|
450
436
|
block.name = name;
|
|
451
437
|
}
|
|
452
438
|
let delta = "";
|
|
453
|
-
|
|
439
|
+
const input = state.input;
|
|
440
|
+
if (toolCall.function?.arguments && input.kind === "json") {
|
|
454
441
|
delta = toolCall.function.arguments;
|
|
455
|
-
block.
|
|
456
|
-
block.arguments = parseStreamingJson(block.partialArgs);
|
|
442
|
+
block.arguments = input.arguments.append(delta);
|
|
457
443
|
}
|
|
458
|
-
else if (toolCall.custom?.input) {
|
|
459
|
-
|
|
460
|
-
|
|
444
|
+
else if (toolCall.custom?.input && input.kind === "custom") {
|
|
445
|
+
delta =
|
|
446
|
+
appendGrammarToolInputJsonDelta(input.buffer, input.property, toolCall.custom.input) ?? "";
|
|
447
|
+
block.arguments = { [input.property]: input.buffer.input };
|
|
461
448
|
}
|
|
462
449
|
stream.push({
|
|
463
450
|
type: "toolcall_delta",
|
|
@@ -495,11 +482,6 @@ export const stream = (model, context, options) => {
|
|
|
495
482
|
if (block.type === "thinking") {
|
|
496
483
|
applyStreamedReasoningDetails(block);
|
|
497
484
|
}
|
|
498
|
-
delete block.index;
|
|
499
|
-
// Streaming scratch buffers are only used during parsing; never persist them.
|
|
500
|
-
delete block.partialArgs;
|
|
501
|
-
delete block.customInput;
|
|
502
|
-
delete block.streamIndex;
|
|
503
485
|
}
|
|
504
486
|
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
505
487
|
output.errorMessage = formatProviderError(normalizeProviderError(error));
|
|
@@ -573,12 +555,16 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
|
|
|
573
555
|
grammarToolInputProperties,
|
|
574
556
|
});
|
|
575
557
|
const cacheControl = getCompatCacheControl(compat, cacheRetention);
|
|
558
|
+
const promptCacheKeyMode = compat.promptCacheKeyMode ?? "auto";
|
|
559
|
+
const supportsPromptCacheKey = promptCacheKeyMode === "enabled" ||
|
|
560
|
+
(promptCacheKeyMode === "auto" &&
|
|
561
|
+
(model.baseUrl.includes("api.openai.com") ||
|
|
562
|
+
(cacheRetention === "long" && compat.supportsLongCacheRetention)));
|
|
576
563
|
const params = {
|
|
577
564
|
model: model.id,
|
|
578
565
|
messages,
|
|
579
566
|
stream: true,
|
|
580
|
-
prompt_cache_key:
|
|
581
|
-
(cacheRetention === "long" && compat.supportsLongCacheRetention)
|
|
567
|
+
prompt_cache_key: cacheRetention !== "none" && supportsPromptCacheKey
|
|
582
568
|
? clampOpenAIPromptCacheKey(options?.sessionId)
|
|
583
569
|
: undefined,
|
|
584
570
|
prompt_cache_retention: cacheRetention === "long" && compat.supportsLongCacheRetention ? "24h" : undefined,
|
|
@@ -607,8 +593,7 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
|
|
|
607
593
|
params.tool_stream = true;
|
|
608
594
|
}
|
|
609
595
|
}
|
|
610
|
-
else if (hasToolHistory(context.messages)) {
|
|
611
|
-
// Anthropic (via LiteLLM/proxy) requires tools param when conversation has tool_calls/tool_results
|
|
596
|
+
else if (compat.requiresToolsWithToolHistory && hasToolHistory(context.messages)) {
|
|
612
597
|
params.tools = [];
|
|
613
598
|
}
|
|
614
599
|
if (cacheControl) {
|
|
@@ -968,7 +953,7 @@ export function convertMessages(model, context, compat, options) {
|
|
|
968
953
|
// Some providers don't accept null content, use empty string instead
|
|
969
954
|
const assistantMsg = {
|
|
970
955
|
role: "assistant",
|
|
971
|
-
content: compat.requiresAssistantAfterToolResult ? "" : null,
|
|
956
|
+
content: compat.requiresAssistantAfterToolResult || compat.requiresNonNullAssistantContent ? "" : null,
|
|
972
957
|
};
|
|
973
958
|
const assistantTextParts = msg.content
|
|
974
959
|
.filter(isTextContentBlock)
|
|
@@ -1168,7 +1153,10 @@ function convertTools(tools, compat) {
|
|
|
1168
1153
|
};
|
|
1169
1154
|
});
|
|
1170
1155
|
}
|
|
1171
|
-
function parseChunkUsage(
|
|
1156
|
+
function parseChunkUsage(
|
|
1157
|
+
// OpenRouter adds billing fields to streamed usage at runtime,
|
|
1158
|
+
// although the OpenAI SDK does not type those fields.
|
|
1159
|
+
rawUsage, model) {
|
|
1172
1160
|
const promptTokens = rawUsage.prompt_tokens || 0;
|
|
1173
1161
|
const cacheReadTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? rawUsage.prompt_cache_hit_tokens ?? rawUsage.cached_tokens ?? 0;
|
|
1174
1162
|
const cacheWriteTokens = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
|
|
@@ -1196,6 +1184,9 @@ function parseChunkUsage(rawUsage, model) {
|
|
|
1196
1184
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
1197
1185
|
};
|
|
1198
1186
|
calculateCost(model, usage);
|
|
1187
|
+
if (isOpenRouterModel(model)) {
|
|
1188
|
+
applyOpenRouterReportedCost(usage, rawUsage);
|
|
1189
|
+
}
|
|
1199
1190
|
return usage;
|
|
1200
1191
|
}
|
|
1201
1192
|
function mapStopReason(reason) {
|
|
@@ -1276,6 +1267,8 @@ function detectCompat(model) {
|
|
|
1276
1267
|
maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
|
|
1277
1268
|
requiresToolResultName: false,
|
|
1278
1269
|
requiresAssistantAfterToolResult: false,
|
|
1270
|
+
requiresNonNullAssistantContent: false,
|
|
1271
|
+
requiresToolsWithToolHistory: false,
|
|
1279
1272
|
requiresThinkingAsText: false,
|
|
1280
1273
|
requiresReasoningContentOnAssistantMessages: isDeepSeek,
|
|
1281
1274
|
thinkingFormat: isDeepSeek
|
|
@@ -1328,6 +1321,8 @@ function getCompat(model) {
|
|
|
1328
1321
|
maxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,
|
|
1329
1322
|
requiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,
|
|
1330
1323
|
requiresAssistantAfterToolResult: model.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
|
|
1324
|
+
requiresNonNullAssistantContent: model.compat.requiresNonNullAssistantContent ?? detected.requiresNonNullAssistantContent,
|
|
1325
|
+
requiresToolsWithToolHistory: model.compat.requiresToolsWithToolHistory ?? detected.requiresToolsWithToolHistory,
|
|
1331
1326
|
requiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,
|
|
1332
1327
|
requiresReasoningContentOnAssistantMessages: model.compat.requiresReasoningContentOnAssistantMessages ??
|
|
1333
1328
|
detected.requiresReasoningContentOnAssistantMessages,
|
|
@@ -1347,6 +1342,7 @@ function getCompat(model) {
|
|
|
1347
1342
|
sendSessionAffinityHeaders: model.compat.sendSessionAffinityHeaders ?? detected.sendSessionAffinityHeaders,
|
|
1348
1343
|
sessionAffinityFormat: model.compat.sessionAffinityFormat ?? detected.sessionAffinityFormat,
|
|
1349
1344
|
supportsLongCacheRetention: model.compat.supportsLongCacheRetention ?? detected.supportsLongCacheRetention,
|
|
1345
|
+
promptCacheKeyMode: model.compat.promptCacheKeyMode,
|
|
1350
1346
|
vllmPriority: model.compat.vllmPriority,
|
|
1351
1347
|
};
|
|
1352
1348
|
}
|