@openclaw/ai 2026.7.2-beta.7 → 2026.8.1-beta.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/dist/{anthropic-CH4UUnZr.mjs → anthropic-CE-7SkF6.mjs} +28 -191
- package/dist/{anthropic-usage-DWU-x8MI.mjs → anthropic-usage-Ma4iX6uG.mjs} +262 -4
- package/dist/{api-registry-DlMgPR39.d.mts → api-registry-EpJoVwM1.d.mts} +1 -1
- package/dist/{azure-openai-responses-CImcwB83.mjs → azure-openai-responses-Cc_kasye.mjs} +4 -4
- package/dist/{event-stream-D8n2uFee.mjs → event-stream-CEV9t6da.mjs} +10 -2
- package/dist/{event-stream-YjaPW20U.d.mts → event-stream-DRmDMRHH.d.mts} +2 -1
- package/dist/event-stream.d.mts +1 -1
- package/dist/event-stream.mjs +1 -1
- package/dist/{google-CtSg0iTS.mjs → google-CGQu21aw.mjs} +5 -5
- package/dist/{google-shared-DNBz5rcD.mjs → google-shared-Cq2UKx1l.mjs} +151 -85
- package/dist/{google-vertex-31f1uS9L.mjs → google-vertex-CusxWzvE.mjs} +10 -7
- package/dist/{host-Dog2WQiR.mjs → host-Bl7Kgddo.mjs} +40 -2
- package/dist/{host-B9GUmcra.d.mts → host-Dn4_SZI2.d.mts} +2 -2
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +2 -2
- package/dist/internal/anthropic.d.mts +19 -3
- package/dist/internal/anthropic.mjs +4 -4
- package/dist/internal/openai.d.mts +4 -4
- package/dist/internal/openai.mjs +7 -7
- package/dist/internal/runtime.d.mts +2 -2
- package/dist/internal/runtime.mjs +3 -3
- package/dist/internal/shared.d.mts +1 -1
- package/dist/internal/shared.mjs +3 -4
- package/dist/{mistral-CWmpvWYh.mjs → mistral-Dx6VzNjf.mjs} +25 -9
- package/dist/model-utils-Dau5dlgm.mjs +64 -0
- package/dist/number-coercion-1Miyb5MO.mjs +66 -0
- package/dist/{openai-chatgpt-responses-B84Ibtrd.mjs → openai-chatgpt-responses-SC9m0FSf.mjs} +94 -131
- package/dist/{openai-completions-DsOxhOD1.mjs → openai-completions-BaIpl93j.mjs} +47 -66
- package/dist/{openai-reasoning-compat-YgeLncHw.mjs → openai-reasoning-compat-DKebnIBL.mjs} +147 -6
- package/dist/{openai-responses-BT7A3sLu.mjs → openai-responses-Bdx3V_Yu.mjs} +6 -22
- package/dist/openai-responses-contracts-BBKBfAqR.d.mts +116 -0
- package/dist/openai-responses-prompt-observer-internal-DDZPxRfr.mjs +46 -0
- package/dist/{openai-responses-shared-pXl6Wd8S.mjs → openai-responses-shared-CCyMvg7M.mjs} +21 -10
- package/dist/{openai-responses-stream-internal-Cw5txaGW.mjs → openai-responses-stream-internal-Bl8YyVtF.mjs} +244 -81
- package/dist/{openai-tool-projection-OhX64DoP.mjs → openai-transport-shared-Cipt7egQ.mjs} +129 -29
- package/dist/{provider-error-CAEvRjry.mjs → provider-error-DI0Ts28U.mjs} +1 -1
- package/dist/{provider-options-D8bB3z9b.d.mts → provider-options-C5kYML7i.d.mts} +1 -1
- package/dist/providers.d.mts +1 -1
- package/dist/providers.mjs +9 -9
- package/dist/{stream-first-event-timeout-BBys9hSb.mjs → stream-first-event-timeout-BIBomOGq.mjs} +1 -1
- package/dist/{tool-result-text-CTpIRbYd.mjs → tool-result-text-Dvkp2Dus.mjs} +51 -2
- package/dist/{tool-schema-json-projection-BwNu3nDi.mjs → tool-schema-json-projection-B1b-XCn5.mjs} +28 -1
- package/dist/transform-messages-DfjpNXNQ.mjs +2 -0
- package/dist/{transport-stream-shared-D81p90xq.mjs → transport-stream-shared-CPNv7A3r.mjs} +4 -4
- package/dist/transports.d.mts +41 -73
- package/dist/transports.mjs +317 -601
- package/dist/{types-bzp5k29J.d.mts → types-CH7ReIcU.d.mts} +4 -0
- package/dist/types.d.mts +3 -3
- package/dist/types.mjs +1 -1
- package/dist/{validation-B-j7cOYp.d.mts → validation-CcPcuEbR.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/package.json +1 -1
- package/dist/error-coercion-DgxlWC0n.mjs +0 -15
- package/dist/number-coercion-DvG7SNMg.mjs +0 -129
- package/dist/openai-completions-compat-DBWjXoMZ.d.mts +0 -43
- package/dist/simple-options-9lhRrN73.mjs +0 -50
- package/dist/transform-messages-C8mBqZxF.mjs +0 -2
|
@@ -1,13 +1,110 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as
|
|
3
|
-
import { a as isImageWithMediaPayload,
|
|
4
|
-
import {
|
|
5
|
-
import { c as calculateCost } from "./number-coercion-DvG7SNMg.mjs";
|
|
1
|
+
import { _ as normalizeLowercaseStringOrEmpty, b as isRecord, v as normalizeOptionalString } from "./host-Bl7Kgddo.mjs";
|
|
2
|
+
import { n as calculateCost } from "./model-utils-Dau5dlgm.mjs";
|
|
3
|
+
import { a as isImageWithMediaPayload, h as stripSystemPromptCacheBoundary, o as truncateUtf16Safe, r as extractToolResultText, t as describeToolResultMediaPlaceholder } from "./tool-result-text-Dvkp2Dus.mjs";
|
|
4
|
+
import { c as transformTransportMessages } from "./tool-schema-json-projection-B1b-XCn5.mjs";
|
|
6
5
|
import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
|
|
7
|
-
import { b as redactIdentifier, d as transportAbortError, l as sanitizeNonEmptyTransportPayloadText, u as sanitizeTransportPayloadText, x as redactSensitiveText } from "./transport-stream-shared-
|
|
8
|
-
import {
|
|
6
|
+
import { b as redactIdentifier, d as transportAbortError, l as sanitizeNonEmptyTransportPayloadText, u as sanitizeTransportPayloadText, x as redactSensitiveText } from "./transport-stream-shared-CPNv7A3r.mjs";
|
|
7
|
+
import { i as log, n as createModelStreamCooperativeScheduler } from "./openai-transport-shared-Cipt7egQ.mjs";
|
|
8
|
+
import { a as withFirstStreamEventTimeout } from "./stream-first-event-timeout-BIBomOGq.mjs";
|
|
9
9
|
import { t as shortHash } from "./hash-CHgqbJmD.mjs";
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
|
+
//#region packages/ai/src/transports/json-unsafe-integers.ts
|
|
12
|
+
/**
|
|
13
|
+
* JSON parsing helpers that preserve integer literals larger than
|
|
14
|
+
* Number.MAX_SAFE_INTEGER as strings before JSON.parse can round them.
|
|
15
|
+
*/
|
|
16
|
+
const MAX_SAFE_INTEGER_ABS_STR = String(Number.MAX_SAFE_INTEGER);
|
|
17
|
+
function isAsciiDigit(ch) {
|
|
18
|
+
return ch !== void 0 && ch >= "0" && ch <= "9";
|
|
19
|
+
}
|
|
20
|
+
function parseJsonNumberToken(input, start) {
|
|
21
|
+
let idx = start;
|
|
22
|
+
if (input[idx] === "-") idx += 1;
|
|
23
|
+
if (idx >= input.length) return null;
|
|
24
|
+
if (input[idx] === "0") idx += 1;
|
|
25
|
+
else if (isAsciiDigit(input[idx]) && input[idx] !== "0") while (isAsciiDigit(input[idx])) idx += 1;
|
|
26
|
+
else return null;
|
|
27
|
+
let isInteger = true;
|
|
28
|
+
if (input[idx] === ".") {
|
|
29
|
+
isInteger = false;
|
|
30
|
+
idx += 1;
|
|
31
|
+
if (!isAsciiDigit(input[idx])) return null;
|
|
32
|
+
while (isAsciiDigit(input[idx])) idx += 1;
|
|
33
|
+
}
|
|
34
|
+
if (input[idx] === "e" || input[idx] === "E") {
|
|
35
|
+
isInteger = false;
|
|
36
|
+
idx += 1;
|
|
37
|
+
if (input[idx] === "+" || input[idx] === "-") idx += 1;
|
|
38
|
+
if (!isAsciiDigit(input[idx])) return null;
|
|
39
|
+
while (isAsciiDigit(input[idx])) idx += 1;
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
token: input.slice(start, idx),
|
|
43
|
+
end: idx,
|
|
44
|
+
isInteger
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function isUnsafeIntegerLiteral(token) {
|
|
48
|
+
const digits = token[0] === "-" ? token.slice(1) : token;
|
|
49
|
+
if (digits.length < MAX_SAFE_INTEGER_ABS_STR.length) return false;
|
|
50
|
+
if (digits.length > MAX_SAFE_INTEGER_ABS_STR.length) return true;
|
|
51
|
+
return digits > MAX_SAFE_INTEGER_ABS_STR;
|
|
52
|
+
}
|
|
53
|
+
/** Quotes integer literals above Number.MAX_SAFE_INTEGER before JSON.parse. */
|
|
54
|
+
function quoteUnsafeIntegerLiterals(input) {
|
|
55
|
+
let out = "";
|
|
56
|
+
let inString = false;
|
|
57
|
+
let escaped = false;
|
|
58
|
+
let idx = 0;
|
|
59
|
+
while (idx < input.length) {
|
|
60
|
+
const ch = input[idx] ?? "";
|
|
61
|
+
if (inString) {
|
|
62
|
+
out += ch;
|
|
63
|
+
if (escaped) escaped = false;
|
|
64
|
+
else if (ch === "\\") escaped = true;
|
|
65
|
+
else if (ch === "\"") inString = false;
|
|
66
|
+
idx += 1;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (ch === "\"") {
|
|
70
|
+
inString = true;
|
|
71
|
+
out += ch;
|
|
72
|
+
idx += 1;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (ch === "-" || isAsciiDigit(ch)) {
|
|
76
|
+
const parsed = parseJsonNumberToken(input, idx);
|
|
77
|
+
if (parsed) {
|
|
78
|
+
if (parsed.isInteger && isUnsafeIntegerLiteral(parsed.token)) out += `"${parsed.token}"`;
|
|
79
|
+
else out += parsed.token;
|
|
80
|
+
idx = parsed.end;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
out += ch;
|
|
85
|
+
idx += 1;
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
/** Parses JSON while preserving unsafe integer literals as strings. */
|
|
90
|
+
function parseJsonPreservingUnsafeIntegers(input) {
|
|
91
|
+
return JSON.parse(quoteUnsafeIntegerLiterals(input));
|
|
92
|
+
}
|
|
93
|
+
/** Parses or accepts an object while preserving unsafe integer literals in string input. */
|
|
94
|
+
function parseJsonObjectPreservingUnsafeIntegers(value) {
|
|
95
|
+
if (typeof value === "string") {
|
|
96
|
+
try {
|
|
97
|
+
const parsed = parseJsonPreservingUnsafeIntegers(value);
|
|
98
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
if (value && typeof value === "object" && !Array.isArray(value)) return value;
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
11
108
|
//#region packages/ai/src/transports/model-transport-debug.ts
|
|
12
109
|
function normalizeEnv(value) {
|
|
13
110
|
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
@@ -1480,49 +1577,6 @@ function resolveOpenAIProjectedToolsStrictToolFlag(projection, strict) {
|
|
|
1480
1577
|
return projection.tools.every((tool) => isStrictOpenAIJsonSchemaCompatible(tool.parameters));
|
|
1481
1578
|
}
|
|
1482
1579
|
//#endregion
|
|
1483
|
-
//#region packages/ai/src/transports/openai-transport-shared.ts
|
|
1484
|
-
/** Shared options, usage shape, cache identity, ordering, and stream scheduling for OpenAI APIs. */
|
|
1485
|
-
const MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS = 12;
|
|
1486
|
-
const MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS = 64;
|
|
1487
|
-
const GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP = "skip_thought_signature_validator";
|
|
1488
|
-
const log = {
|
|
1489
|
-
debug(message, data) {
|
|
1490
|
-
getAiTransportHost().logDebug("openai-transport", () => ({
|
|
1491
|
-
message,
|
|
1492
|
-
data
|
|
1493
|
-
}));
|
|
1494
|
-
},
|
|
1495
|
-
info(message, data) {
|
|
1496
|
-
getAiTransportHost().logInfo("openai-transport", message, data);
|
|
1497
|
-
},
|
|
1498
|
-
warn(message, data) {
|
|
1499
|
-
getAiTransportHost().logWarn("openai-transport", message, data);
|
|
1500
|
-
}
|
|
1501
|
-
};
|
|
1502
|
-
function throwIfModelStreamAborted(signal) {
|
|
1503
|
-
if (signal?.aborted) throw transportAbortError(signal);
|
|
1504
|
-
}
|
|
1505
|
-
function createModelStreamCooperativeScheduler(signal) {
|
|
1506
|
-
let lastYieldedAt = Date.now();
|
|
1507
|
-
let eventsSinceYield = 0;
|
|
1508
|
-
return { async afterEvent() {
|
|
1509
|
-
throwIfModelStreamAborted(signal);
|
|
1510
|
-
eventsSinceYield += 1;
|
|
1511
|
-
const now = Date.now();
|
|
1512
|
-
if (eventsSinceYield < MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS && now - lastYieldedAt < MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS) return;
|
|
1513
|
-
eventsSinceYield = 0;
|
|
1514
|
-
lastYieldedAt = now;
|
|
1515
|
-
await new Promise((resolve) => {
|
|
1516
|
-
setTimeout(resolve, 0);
|
|
1517
|
-
});
|
|
1518
|
-
throwIfModelStreamAborted(signal);
|
|
1519
|
-
} };
|
|
1520
|
-
}
|
|
1521
|
-
function resolvePromptCacheKey(options, cacheRetention) {
|
|
1522
|
-
if (cacheRetention === "none") return;
|
|
1523
|
-
return clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId);
|
|
1524
|
-
}
|
|
1525
|
-
//#endregion
|
|
1526
1580
|
//#region packages/ai/src/transports/openai-responses-replay.ts
|
|
1527
1581
|
/** Resolves the assistant message id that can be replayed to OpenAI Responses. */
|
|
1528
1582
|
function resolveReplayableResponsesMessageId(params) {
|
|
@@ -1535,6 +1589,19 @@ const AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS = 3e4;
|
|
|
1535
1589
|
const RESPONSE_FAILED_NO_DETAILS_MESSAGE = "Unknown error (no error details in response)";
|
|
1536
1590
|
const OPENAI_RESPONSES_REASONING_REPLAY_META_KEY = "__openclaw_replay";
|
|
1537
1591
|
const OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY = "openclawReasoningReplay";
|
|
1592
|
+
const PROMPT_OBSERVER = Symbol("openaiResponsesPromptObserver");
|
|
1593
|
+
const responsesPromptObserver = {
|
|
1594
|
+
set(options, observer) {
|
|
1595
|
+
Reflect.set(options, PROMPT_OBSERVER, observer);
|
|
1596
|
+
},
|
|
1597
|
+
get(options) {
|
|
1598
|
+
return Reflect.get(options, PROMPT_OBSERVER);
|
|
1599
|
+
},
|
|
1600
|
+
copy(source, target) {
|
|
1601
|
+
const observer = source && responsesPromptObserver.get(source);
|
|
1602
|
+
if (observer) responsesPromptObserver.set(target, observer);
|
|
1603
|
+
}
|
|
1604
|
+
};
|
|
1538
1605
|
//#endregion
|
|
1539
1606
|
//#region packages/ai/src/transports/openai-responses-debug.ts
|
|
1540
1607
|
function stringifyUnknown(value, fallback = "") {
|
|
@@ -1922,12 +1989,28 @@ function prepareOpenAIResponsesReasoningItemForReplay(item, context, blockMetada
|
|
|
1922
1989
|
}
|
|
1923
1990
|
async function createResponsesStreamWithEncryptedContentRetry(params) {
|
|
1924
1991
|
try {
|
|
1925
|
-
|
|
1992
|
+
params.observePrompt?.(params.request, {
|
|
1993
|
+
egress: "responses-sdk",
|
|
1994
|
+
payloadVariant: "initial"
|
|
1995
|
+
});
|
|
1996
|
+
const { data, response } = await params.client.responses.create(params.request, params.requestOptions).withResponse();
|
|
1997
|
+
return {
|
|
1998
|
+
stream: data,
|
|
1999
|
+
response
|
|
2000
|
+
};
|
|
1926
2001
|
} catch (error) {
|
|
1927
2002
|
const retryRequest = stripResponsesRequestEncryptedContent(params.request);
|
|
1928
2003
|
if (!isInvalidEncryptedContentError(error) || retryRequest === params.request) throw error;
|
|
1929
2004
|
log.warn(`[responses] retrying without encrypted reasoning content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
|
|
1930
|
-
|
|
2005
|
+
params.observePrompt?.(retryRequest, {
|
|
2006
|
+
egress: "responses-sdk",
|
|
2007
|
+
payloadVariant: "encrypted-content-retry"
|
|
2008
|
+
});
|
|
2009
|
+
const { data, response } = await params.client.responses.create(retryRequest, params.requestOptions).withResponse();
|
|
2010
|
+
return {
|
|
2011
|
+
stream: data,
|
|
2012
|
+
response
|
|
2013
|
+
};
|
|
1931
2014
|
}
|
|
1932
2015
|
}
|
|
1933
2016
|
function resolveAzureOpenAIApiVersion(env = process.env) {
|
|
@@ -2254,6 +2337,12 @@ async function* observeResponsesStream(stream, model) {
|
|
|
2254
2337
|
}
|
|
2255
2338
|
//#endregion
|
|
2256
2339
|
//#region packages/ai/src/transports/openai-responses-stream-slots-internal.ts
|
|
2340
|
+
function appendResponsesPendingTextDelta(slot, delta, materialize) {
|
|
2341
|
+
slot.pendingText = `${slot.pendingText ?? ""}${delta}`;
|
|
2342
|
+
const priorText = slot.collapseCandidate?.block.text ?? "";
|
|
2343
|
+
if (priorText.startsWith(slot.pendingText) || slot.pendingText.startsWith(priorText)) return;
|
|
2344
|
+
materialize(slot);
|
|
2345
|
+
}
|
|
2257
2346
|
function readResponsesOutputIndex(event) {
|
|
2258
2347
|
const outputIndex = event.output_index;
|
|
2259
2348
|
return typeof outputIndex === "number" && Number.isInteger(outputIndex) && outputIndex >= 0 ? outputIndex : void 0;
|
|
@@ -2371,13 +2460,19 @@ function resolveResponsesToolCallId(item, fallbackId) {
|
|
|
2371
2460
|
const generated = `call_${randomUUID().replaceAll("-", "").slice(0, 24)}`;
|
|
2372
2461
|
return resolvedItemId ? `${generated}|${resolvedItemId}` : generated;
|
|
2373
2462
|
}
|
|
2374
|
-
function
|
|
2375
|
-
|
|
2376
|
-
const
|
|
2463
|
+
function resolveCompletedResponsesToolCall(item, streamed) {
|
|
2464
|
+
if (item.status && item.status !== "completed") throw new Error("Responses stream completed with an incomplete terminal tool call");
|
|
2465
|
+
const streamedName = streamed?.name?.trim() || void 0;
|
|
2466
|
+
const completedName = typeof item.name === "string" ? item.name.trim() || void 0 : void 0;
|
|
2377
2467
|
if (streamedName && completedName && streamedName !== completedName) throw new Error(`Responses stream changed tool-call function name from ${streamedName} to ${completedName}`);
|
|
2378
2468
|
const name = completedName ?? streamedName;
|
|
2379
2469
|
if (!name) throw new Error("Responses stream completed tool call without a function name");
|
|
2380
|
-
|
|
2470
|
+
const argumentsValue = parseJsonObjectPreservingUnsafeIntegers(streamed?.arguments ?? item.arguments);
|
|
2471
|
+
if (!argumentsValue) throw new Error("Responses stream completed tool call with invalid JSON arguments");
|
|
2472
|
+
return {
|
|
2473
|
+
name,
|
|
2474
|
+
arguments: argumentsValue
|
|
2475
|
+
};
|
|
2381
2476
|
}
|
|
2382
2477
|
function createResponsesTerminalController(params) {
|
|
2383
2478
|
const { output, stream, model, options } = params;
|
|
@@ -2400,8 +2495,35 @@ function createResponsesTerminalController(params) {
|
|
|
2400
2495
|
const content = part;
|
|
2401
2496
|
return content.type === "output_text" || content.type === "text" ? content.text ?? "" : content.refusal ?? "";
|
|
2402
2497
|
}).join("");
|
|
2403
|
-
|
|
2498
|
+
const started = params.startedTextBlocksByItemId.get(item.id);
|
|
2499
|
+
if (!text && !started) return;
|
|
2404
2500
|
const phase = item.phase ?? void 0;
|
|
2501
|
+
if (started) {
|
|
2502
|
+
const previousText = started.block.text;
|
|
2503
|
+
started.block.text = text;
|
|
2504
|
+
started.block.textSignature = encodeTextSignatureV1(item.id, phase);
|
|
2505
|
+
params.setLastTextBlock({
|
|
2506
|
+
block: started.block,
|
|
2507
|
+
index: started.index,
|
|
2508
|
+
phase
|
|
2509
|
+
});
|
|
2510
|
+
params.startedTextBlocksByItemId.delete(item.id);
|
|
2511
|
+
if (text.startsWith(previousText)) {
|
|
2512
|
+
const delta = text.slice(previousText.length);
|
|
2513
|
+
if (delta) stream.push({
|
|
2514
|
+
type: "text_delta",
|
|
2515
|
+
contentIndex: started.index,
|
|
2516
|
+
delta
|
|
2517
|
+
});
|
|
2518
|
+
}
|
|
2519
|
+
stream.push({
|
|
2520
|
+
type: "text_end",
|
|
2521
|
+
contentIndex: started.index,
|
|
2522
|
+
content: text,
|
|
2523
|
+
partial: output
|
|
2524
|
+
});
|
|
2525
|
+
return;
|
|
2526
|
+
}
|
|
2405
2527
|
const previous = params.getLastTextBlock();
|
|
2406
2528
|
const collapse = resolveResponsesMessageSnapshotCollapse({
|
|
2407
2529
|
prior: previous && {
|
|
@@ -2447,11 +2569,12 @@ function createResponsesTerminalController(params) {
|
|
|
2447
2569
|
});
|
|
2448
2570
|
};
|
|
2449
2571
|
const appendToolCall = (item) => {
|
|
2572
|
+
const validated = resolveCompletedResponsesToolCall(item);
|
|
2450
2573
|
const toolCall = {
|
|
2451
2574
|
type: "toolCall",
|
|
2452
2575
|
id: resolveResponsesToolCallId(item),
|
|
2453
|
-
name:
|
|
2454
|
-
arguments:
|
|
2576
|
+
name: validated.name,
|
|
2577
|
+
arguments: validated.arguments
|
|
2455
2578
|
};
|
|
2456
2579
|
blocks.push(toolCall);
|
|
2457
2580
|
const contentIndex = blocks.length - 1;
|
|
@@ -2468,11 +2591,35 @@ function createResponsesTerminalController(params) {
|
|
|
2468
2591
|
});
|
|
2469
2592
|
};
|
|
2470
2593
|
const recoverTerminalOutput = (items, includeToolCalls) => {
|
|
2471
|
-
|
|
2472
|
-
for (const item of items
|
|
2473
|
-
|
|
2594
|
+
let hasCompletedLaterOutput = false;
|
|
2595
|
+
for (const item of items.toReversed()) {
|
|
2596
|
+
if (item.type === "reasoning") {
|
|
2597
|
+
hasCompletedLaterOutput ||= params.reasoningBlocksById.has(item.id);
|
|
2598
|
+
continue;
|
|
2599
|
+
}
|
|
2600
|
+
if (item.type !== "message" && item.type !== "function_call") continue;
|
|
2601
|
+
const identity = item.type === "message" ? `message:${item.id}` : `function_call:${item.call_id}`;
|
|
2602
|
+
if (params.completedOutputItemIdentities.has(identity) || item.type === "message" && params.startedTextBlocksByItemId.has(item.id)) {
|
|
2603
|
+
hasCompletedLaterOutput = true;
|
|
2604
|
+
continue;
|
|
2605
|
+
}
|
|
2606
|
+
if (item.type === "function_call" && !includeToolCalls) continue;
|
|
2607
|
+
if (hasCompletedLaterOutput) throw new Error("Responses stream omitted an output item before completed output");
|
|
2608
|
+
if (item.type === "function_call") resolveCompletedResponsesToolCall(item);
|
|
2609
|
+
}
|
|
2610
|
+
for (const item of items) if (item.type === "message") {
|
|
2611
|
+
const identity = `message:${item.id}`;
|
|
2612
|
+
if (params.completedOutputItemIdentities.has(identity)) continue;
|
|
2613
|
+
appendText(item);
|
|
2614
|
+
params.completedOutputItemIdentities.add(identity);
|
|
2615
|
+
} else {
|
|
2474
2616
|
params.setLastTextBlock(null);
|
|
2475
|
-
if (includeToolCalls && item.type === "function_call")
|
|
2617
|
+
if (includeToolCalls && item.type === "function_call") {
|
|
2618
|
+
const identity = `function_call:${item.call_id}`;
|
|
2619
|
+
if (params.completedOutputItemIdentities.has(identity)) continue;
|
|
2620
|
+
appendToolCall(item);
|
|
2621
|
+
params.completedOutputItemIdentities.add(identity);
|
|
2622
|
+
}
|
|
2476
2623
|
}
|
|
2477
2624
|
};
|
|
2478
2625
|
const finalizeResponse = (response, terminalEventType) => {
|
|
@@ -2526,6 +2673,8 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2526
2673
|
const streamingToolCalls = createResponsesToolCallTracker();
|
|
2527
2674
|
const outputSlots = createResponsesOutputSlotTracker();
|
|
2528
2675
|
const reasoningBlocksById = /* @__PURE__ */ new Map();
|
|
2676
|
+
const completedOutputItemIdentities = /* @__PURE__ */ new Set();
|
|
2677
|
+
const startedTextBlocksByItemId = /* @__PURE__ */ new Map();
|
|
2529
2678
|
let terminalResponseEvent;
|
|
2530
2679
|
let lastTextBlock = null;
|
|
2531
2680
|
const blocks = output.content;
|
|
@@ -2543,6 +2692,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2543
2692
|
contentIndex: blocks.length
|
|
2544
2693
|
};
|
|
2545
2694
|
blocks.push(block);
|
|
2695
|
+
reasoningBlocksById.set(item.id, block);
|
|
2546
2696
|
outputSlots.register(event, slot);
|
|
2547
2697
|
stream.push({
|
|
2548
2698
|
type: "thinking_start",
|
|
@@ -2567,7 +2717,14 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2567
2717
|
pendingText: collapseCandidate ? "" : null,
|
|
2568
2718
|
collapseCandidate
|
|
2569
2719
|
};
|
|
2570
|
-
if (block)
|
|
2720
|
+
if (block) {
|
|
2721
|
+
blocks.push(block);
|
|
2722
|
+
startedTextBlocksByItemId.set(messageItem.id, {
|
|
2723
|
+
block,
|
|
2724
|
+
index: slot.contentIndex ?? blocks.length - 1,
|
|
2725
|
+
phase: messageItem.phase ?? void 0
|
|
2726
|
+
});
|
|
2727
|
+
}
|
|
2571
2728
|
outputSlots.register(event, slot);
|
|
2572
2729
|
if (slot.contentIndex !== void 0) stream.push({
|
|
2573
2730
|
type: "text_start",
|
|
@@ -2595,6 +2752,11 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2595
2752
|
};
|
|
2596
2753
|
blocks.push(slot.block);
|
|
2597
2754
|
slot.contentIndex = blockIndex();
|
|
2755
|
+
startedTextBlocksByItemId.set(slot.item.id, {
|
|
2756
|
+
block: slot.block,
|
|
2757
|
+
index: slot.contentIndex,
|
|
2758
|
+
phase: slot.item.phase ?? void 0
|
|
2759
|
+
});
|
|
2598
2760
|
stream.push({
|
|
2599
2761
|
type: "text_start",
|
|
2600
2762
|
contentIndex: slot.contentIndex,
|
|
@@ -2612,18 +2774,14 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2612
2774
|
const materializeDeferredTextSlots = (except) => {
|
|
2613
2775
|
for (const slot of outputSlots.values()) if (slot !== except && slot.type === "text") materializeDeferredTextSlot(slot);
|
|
2614
2776
|
};
|
|
2615
|
-
const appendPendingMessageDelta = (slot, delta) => {
|
|
2616
|
-
slot.pendingText = `${slot.pendingText ?? ""}${delta}`;
|
|
2617
|
-
const priorText = slot.collapseCandidate?.block.text ?? "";
|
|
2618
|
-
if (priorText.startsWith(slot.pendingText) || slot.pendingText.startsWith(priorText)) return;
|
|
2619
|
-
materializeDeferredTextSlot(slot);
|
|
2620
|
-
};
|
|
2621
2777
|
const { finalizeResponse, recoverTerminalOutput } = createResponsesTerminalController({
|
|
2622
2778
|
output,
|
|
2623
2779
|
stream,
|
|
2624
2780
|
model,
|
|
2625
2781
|
options,
|
|
2626
2782
|
reasoningBlocksById,
|
|
2783
|
+
completedOutputItemIdentities,
|
|
2784
|
+
startedTextBlocksByItemId,
|
|
2627
2785
|
getLastTextBlock: () => lastTextBlock,
|
|
2628
2786
|
setLastTextBlock: (block) => {
|
|
2629
2787
|
lastTextBlock = block;
|
|
@@ -2738,7 +2896,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2738
2896
|
slot.item.content.push(lastPart);
|
|
2739
2897
|
}
|
|
2740
2898
|
lastPart.text += event.delta;
|
|
2741
|
-
if (slot.pendingText !== null)
|
|
2899
|
+
if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
|
|
2742
2900
|
else if (slot.block && slot.contentIndex !== void 0) {
|
|
2743
2901
|
slot.block.text += event.delta;
|
|
2744
2902
|
stream.push({
|
|
@@ -2760,7 +2918,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2760
2918
|
slot.item.content.push(lastPart);
|
|
2761
2919
|
}
|
|
2762
2920
|
lastPart.text += event.delta;
|
|
2763
|
-
if (slot.pendingText !== null)
|
|
2921
|
+
if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
|
|
2764
2922
|
else if (slot.block && slot.contentIndex !== void 0) {
|
|
2765
2923
|
slot.block.text += event.delta;
|
|
2766
2924
|
stream.push({
|
|
@@ -2782,7 +2940,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2782
2940
|
slot.item.content.push(lastPart);
|
|
2783
2941
|
}
|
|
2784
2942
|
lastPart.refusal += event.delta;
|
|
2785
|
-
if (slot.pendingText !== null)
|
|
2943
|
+
if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
|
|
2786
2944
|
else if (slot.block && slot.contentIndex !== void 0) {
|
|
2787
2945
|
slot.block.text += event.delta;
|
|
2788
2946
|
stream.push({
|
|
@@ -2835,7 +2993,6 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2835
2993
|
outputSlot.block.thinking = summaryText || contentText || outputSlot.block.thinking;
|
|
2836
2994
|
outputSlot.block.thinkingSignature = JSON.stringify(item);
|
|
2837
2995
|
if (item.encrypted_content && options?.reasoningReplayMetadata) outputSlot.block[OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY] = options.reasoningReplayMetadata;
|
|
2838
|
-
if (typeof item.id === "string") reasoningBlocksById.set(item.id, outputSlot.block);
|
|
2839
2996
|
stream.push({
|
|
2840
2997
|
type: "thinking_end",
|
|
2841
2998
|
contentIndex: outputSlot.contentIndex,
|
|
@@ -2898,21 +3055,26 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2898
3055
|
});
|
|
2899
3056
|
}
|
|
2900
3057
|
outputSlots.forget(outputSlot);
|
|
3058
|
+
startedTextBlocksByItemId.delete(item.id);
|
|
3059
|
+
completedOutputItemIdentities.add(`message:${item.id}`);
|
|
2901
3060
|
} else if (item.type === "function_call") {
|
|
2902
3061
|
const streamingToolCall = streamingToolCalls.resolve(event, readResponsesToolCallItemIdentity(item));
|
|
2903
3062
|
if (!streamingToolCall && streamingToolCalls.hasActive()) continue;
|
|
2904
|
-
const completedName = resolveCompletedToolCallName(streamingToolCall, item.name);
|
|
2905
3063
|
const streamedArguments = streamingToolCall?.block.partialJson ?? "";
|
|
2906
3064
|
const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
|
|
2907
3065
|
if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
|
|
2908
|
-
const
|
|
3066
|
+
const finalArguments = completedArguments !== void 0 && (completedArguments.length > 0 || !streamedArguments) ? completedArguments : streamedArguments;
|
|
3067
|
+
const validated = resolveCompletedResponsesToolCall(item, {
|
|
3068
|
+
name: streamingToolCall?.block.name,
|
|
3069
|
+
arguments: finalArguments
|
|
3070
|
+
});
|
|
2909
3071
|
let toolCall;
|
|
2910
3072
|
let contentIndex;
|
|
2911
3073
|
if (streamingToolCall) {
|
|
2912
3074
|
const block = streamingToolCall.block;
|
|
2913
3075
|
block.id = resolveResponsesToolCallId(item, block.id);
|
|
2914
|
-
block.name =
|
|
2915
|
-
block.arguments =
|
|
3076
|
+
block.name = validated.name;
|
|
3077
|
+
block.arguments = validated.arguments;
|
|
2916
3078
|
delete block.partialJson;
|
|
2917
3079
|
toolCall = block;
|
|
2918
3080
|
contentIndex = streamingToolCall.contentIndex;
|
|
@@ -2920,8 +3082,8 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2920
3082
|
toolCall = {
|
|
2921
3083
|
type: "toolCall",
|
|
2922
3084
|
id: resolveResponsesToolCallId(item),
|
|
2923
|
-
name:
|
|
2924
|
-
arguments:
|
|
3085
|
+
name: validated.name,
|
|
3086
|
+
arguments: validated.arguments
|
|
2925
3087
|
};
|
|
2926
3088
|
blocks.push(toolCall);
|
|
2927
3089
|
contentIndex = blockIndex();
|
|
@@ -2941,6 +3103,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2941
3103
|
toolCall,
|
|
2942
3104
|
partial: output
|
|
2943
3105
|
});
|
|
3106
|
+
completedOutputItemIdentities.add(`function_call:${item.call_id}`);
|
|
2944
3107
|
}
|
|
2945
3108
|
} else if (event.type === "response.completed" || event.type === "response.incomplete") {
|
|
2946
3109
|
if (streamingToolCalls.hasActive()) throw new Error("Responses stream completed with unresolved tool calls");
|
|
@@ -2961,4 +3124,4 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2961
3124
|
}
|
|
2962
3125
|
}
|
|
2963
3126
|
//#endregion
|
|
2964
|
-
export {
|
|
3127
|
+
export { shouldOmitEmptyArrayItems as $, normalizeResponsesFailedEvent as A, responsesPromptObserver as B, prepareOpenAIResponsesReasoningItemForReplay as C, applyServiceTierPricing as D, tagOpenAIResponsesReasoningReplayItem as E, summarizeResponsesFailedNoDetailsObservation as F, normalizeOpenAIStrictToolParameters as G, clearOpenAIToolSchemaCacheForTest as H, summarizeResponsesPayload as I, findOpenAIStrictSchemaViolations as J, normalizeStrictOpenAIJsonSchema as K, summarizeResponsesTools as L, stringifyRedactedEvent as M, stringifyRedactedPayload as N, buildResponsesFailedNoDetailsObservation as O, summarizeOpenAITransportError as P, resolveUnsupportedToolSchemaKeywords as Q, AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS as R, isInvalidEncryptedContentError as S, stripResponsesRequestEncryptedContent as T, findOpenAIStrictToolProjectionDiagnostics as U, resolveReplayableResponsesMessageId as V, isStrictOpenAIJsonSchemaCompatible as W, extractToolSchemaModelCompat as X, normalizeOpenAIStrictCompatSchema as Y, normalizeToolParameterSchema as Z, resolveResponsesMessageSnapshotCollapse as _, resolveModelSseDebugMode as _t, resolveResponsesTerminalStopReason as a, cleanSchemaForGemini as at, convertResponsesMessages as b, quoteUnsafeIntegerLiterals as bt, readResponsesToolCallItemIdentity as c, isOpenAIGpt56Model as ct, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as d, resolveOpenAISupportedReasoningEfforts as dt, stripUnsupportedSchemaKeywords as et, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as f, supportsOpenAIReasoningEffort as ft, isResponsesTextDeltaEventType as g, resolveModelPayloadDebugMode as gt, isResponsesTextContentPartType as h, emitModelTransportDebug as ht, readResponsesReasoningTokens as i, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as it, safeDebugValue as j, logResponsesFailedNoDetails as k, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as l, normalizeOpenAIReasoningEffort as lt, isAzureResponsesTextDeltaEventType as m, uniqueStrings as mt, processResponsesStream as n, cleanSchemaForLlamacppGbnf as nt, observeResponsesStream as o, isOpenAIGpt54MiniModel as ot, isAzureResponsesTextDeltaEvent as p, supportsOpenAITemperature as pt, resolveOpenAIProjectedToolsStrictToolFlag as q, mapResponsesTerminalUsage as r, findLlamacppGbnfSchemaViolations as rt, createResponsesToolCallTracker as s, isOpenAIGpt55Model as st, ResponsesStreamFailure as t, LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD as tt, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as u, resolveOpenAIReasoningEffortForModel as ut, buildOpenAIResponsesReasoningReplayMetadata as v, parseJsonObjectPreservingUnsafeIntegers as vt, resolveAzureOpenAIApiVersion as w, createResponsesStreamWithEncryptedContentRetry as x, buildResponsesInputMessage as y, parseJsonPreservingUnsafeIntegers as yt, OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS as z };
|
|
@@ -1,31 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (options !== void 0) return host.buildModelFetch(model, timeoutMs, options) ?? globalThis.fetch;
|
|
7
|
-
if (timeoutMs !== void 0) return host.buildModelFetch(model, timeoutMs) ?? globalThis.fetch;
|
|
8
|
-
return host.buildModelFetch(model) ?? globalThis.fetch;
|
|
9
|
-
}
|
|
10
|
-
function resolveProviderEndpoint(baseUrl) {
|
|
11
|
-
return { endpointClass: getAiTransportHost().resolveProviderEndpointClass(baseUrl) };
|
|
12
|
-
}
|
|
13
|
-
function resolveProviderRequestCapabilities(input) {
|
|
14
|
-
return getAiTransportHost().resolveProviderRequestCapabilities(input);
|
|
15
|
-
}
|
|
16
|
-
function resolveProviderRequestPolicyConfig(input) {
|
|
17
|
-
return { headers: getAiTransportHost().resolveProviderRequestHeaders(input) };
|
|
18
|
-
}
|
|
19
|
-
function resolveModelRequestTimeoutMs(model, timeoutMs) {
|
|
20
|
-
return timeoutMs ?? getAiTransportHost().resolveModelRequestTimeoutMs(model);
|
|
21
|
-
}
|
|
22
|
-
function resolveOpenAIStrictToolSetting(model, options) {
|
|
23
|
-
return getAiTransportHost().resolveOpenAIStrictToolSetting(model, options);
|
|
24
|
-
}
|
|
25
|
-
function transformTransportMessages(messages, model, normalizeToolCallId, options) {
|
|
26
|
-
return getAiTransportHost().transformTransportMessages(messages, model, normalizeToolCallId, options);
|
|
27
|
-
}
|
|
28
|
-
//#endregion
|
|
1
|
+
import { b as isRecord, n as getAiTransportHost } from "./host-Bl7Kgddo.mjs";
|
|
2
|
+
import { n as calculateCost, t as applyProviderReportedUsageCost } from "./model-utils-Dau5dlgm.mjs";
|
|
3
|
+
import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
|
|
4
|
+
import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-B1b-XCn5.mjs";
|
|
5
|
+
import { d as transportAbortError } from "./transport-stream-shared-CPNv7A3r.mjs";
|
|
29
6
|
//#region packages/ai/src/providers/openai-tool-projection.ts
|
|
30
7
|
function unreadableToolDiagnostic(toolIndex) {
|
|
31
8
|
return {
|
|
@@ -212,4 +189,127 @@ function reconcileOpenAICompletionsToolChoice(choice, projection) {
|
|
|
212
189
|
};
|
|
213
190
|
}
|
|
214
191
|
//#endregion
|
|
215
|
-
|
|
192
|
+
//#region packages/ai/src/transports/openai-transport-shared.ts
|
|
193
|
+
/** Shared options, usage shape, cache identity, ordering, and stream scheduling for OpenAI APIs. */
|
|
194
|
+
const MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS = 12;
|
|
195
|
+
const MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS = 64;
|
|
196
|
+
const GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP = "skip_thought_signature_validator";
|
|
197
|
+
const log = {
|
|
198
|
+
debug(message, data) {
|
|
199
|
+
getAiTransportHost().logDebug("openai-transport", () => ({
|
|
200
|
+
message,
|
|
201
|
+
data
|
|
202
|
+
}));
|
|
203
|
+
},
|
|
204
|
+
info(message, data) {
|
|
205
|
+
getAiTransportHost().logInfo("openai-transport", message, data);
|
|
206
|
+
},
|
|
207
|
+
warn(message, data) {
|
|
208
|
+
getAiTransportHost().logWarn("openai-transport", message, data);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
function parseOpenAICompletionsUsage(rawUsage, model, options) {
|
|
212
|
+
const cacheRead = rawUsage.prompt_tokens_details?.cached_tokens ?? rawUsage.prompt_cache_hit_tokens ?? 0;
|
|
213
|
+
const cacheWrite = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
|
|
214
|
+
const input = Math.max(0, (rawUsage.prompt_tokens || 0) - cacheRead - cacheWrite);
|
|
215
|
+
const output = rawUsage.completion_tokens || 0;
|
|
216
|
+
const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
|
|
217
|
+
const usage = {
|
|
218
|
+
input,
|
|
219
|
+
output,
|
|
220
|
+
cacheRead,
|
|
221
|
+
cacheWrite,
|
|
222
|
+
...options?.includeReasoningTokens !== false && typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) ? { reasoningTokens } : {},
|
|
223
|
+
totalTokens: input + output + cacheRead + cacheWrite,
|
|
224
|
+
cost: {
|
|
225
|
+
input: 0,
|
|
226
|
+
output: 0,
|
|
227
|
+
cacheRead: 0,
|
|
228
|
+
cacheWrite: 0,
|
|
229
|
+
total: 0
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
calculateCost(model, usage);
|
|
233
|
+
applyProviderReportedUsageCost(usage, rawUsage.cost);
|
|
234
|
+
return usage;
|
|
235
|
+
}
|
|
236
|
+
function throwIfModelStreamAborted(signal) {
|
|
237
|
+
if (signal?.aborted) throw transportAbortError(signal);
|
|
238
|
+
}
|
|
239
|
+
function createModelStreamCooperativeScheduler(signal) {
|
|
240
|
+
let lastYieldedAt = Date.now();
|
|
241
|
+
let eventsSinceYield = 0;
|
|
242
|
+
return { async afterEvent() {
|
|
243
|
+
throwIfModelStreamAborted(signal);
|
|
244
|
+
eventsSinceYield += 1;
|
|
245
|
+
const now = Date.now();
|
|
246
|
+
if (eventsSinceYield < MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS && now - lastYieldedAt < MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS) return;
|
|
247
|
+
eventsSinceYield = 0;
|
|
248
|
+
lastYieldedAt = now;
|
|
249
|
+
await new Promise((resolve) => {
|
|
250
|
+
setTimeout(resolve, 0);
|
|
251
|
+
});
|
|
252
|
+
throwIfModelStreamAborted(signal);
|
|
253
|
+
} };
|
|
254
|
+
}
|
|
255
|
+
function resolvePromptCacheKey(options, cacheRetention) {
|
|
256
|
+
if (cacheRetention === "none") return;
|
|
257
|
+
return clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId);
|
|
258
|
+
}
|
|
259
|
+
function isOpenAICompletionsThinkingEnabled(effort) {
|
|
260
|
+
const normalized = effort.trim().toLowerCase();
|
|
261
|
+
return normalized !== "off" && normalized !== "none";
|
|
262
|
+
}
|
|
263
|
+
function readOpenAICompletionsContentDeltas(content, topLevelRefusal, mirroredThinking = []) {
|
|
264
|
+
let deltas = readOpenAICompletionsContentPartDeltas(content);
|
|
265
|
+
if (mirroredThinking.length > 0) {
|
|
266
|
+
const structuredThinking = deltas.filter((delta) => delta.kind === "thinking").map((delta) => delta.text);
|
|
267
|
+
const mirrorsCombinedThinking = structuredThinking.length > 1 && mirroredThinking.includes(structuredThinking.join(""));
|
|
268
|
+
deltas = deltas.filter((delta) => delta.kind !== "thinking" || !mirrorsCombinedThinking && !mirroredThinking.includes(delta.text));
|
|
269
|
+
}
|
|
270
|
+
if (typeof topLevelRefusal !== "string" || !topLevelRefusal) return deltas;
|
|
271
|
+
const structuredRefusals = deltas.filter((delta) => delta.kind === "text" && delta.source === "refusal").map((delta) => delta.text);
|
|
272
|
+
if (structuredRefusals.some((refusal) => refusal === topLevelRefusal) || structuredRefusals.length > 1 && structuredRefusals.join("") === topLevelRefusal) return deltas;
|
|
273
|
+
return [...deltas, {
|
|
274
|
+
kind: "text",
|
|
275
|
+
text: topLevelRefusal,
|
|
276
|
+
source: "refusal"
|
|
277
|
+
}];
|
|
278
|
+
}
|
|
279
|
+
function readOpenAICompletionsContentPartDeltas(content) {
|
|
280
|
+
if (typeof content === "string") return content ? [{
|
|
281
|
+
kind: "text",
|
|
282
|
+
text: content
|
|
283
|
+
}] : [];
|
|
284
|
+
if (Array.isArray(content)) return content.flatMap(readOpenAICompletionsContentPartDeltas);
|
|
285
|
+
if (!content || typeof content !== "object") return [];
|
|
286
|
+
const record = content;
|
|
287
|
+
const type = typeof record.type === "string" ? record.type.toLowerCase() : "";
|
|
288
|
+
const extractText = (value) => {
|
|
289
|
+
if (typeof value === "string") return value;
|
|
290
|
+
if (Array.isArray(value)) return value.map(extractText).join("");
|
|
291
|
+
if (value && typeof value === "object") {
|
|
292
|
+
const nested = value;
|
|
293
|
+
return extractText(nested.text ?? nested.content ?? nested.thinking ?? nested.refusal);
|
|
294
|
+
}
|
|
295
|
+
return "";
|
|
296
|
+
};
|
|
297
|
+
const text = extractText(record.text ?? record.content ?? record.thinking ?? record.refusal);
|
|
298
|
+
if (!text) return [];
|
|
299
|
+
if (type.includes("thinking") || type.includes("reasoning")) return [{
|
|
300
|
+
kind: "thinking",
|
|
301
|
+
text
|
|
302
|
+
}];
|
|
303
|
+
if (type === "refusal") return [{
|
|
304
|
+
kind: "text",
|
|
305
|
+
text,
|
|
306
|
+
source: "refusal"
|
|
307
|
+
}];
|
|
308
|
+
if (["text", "output_text"].includes(type) || type.endsWith(".output_text")) return [{
|
|
309
|
+
kind: "text",
|
|
310
|
+
text
|
|
311
|
+
}];
|
|
312
|
+
return [];
|
|
313
|
+
}
|
|
314
|
+
//#endregion
|
|
315
|
+
export { parseOpenAICompletionsUsage as a, throwIfModelStreamAborted as c, reconcileOpenAIResponsesToolChoice as d, log as i, projectOpenAITools as l, createModelStreamCooperativeScheduler as n, readOpenAICompletionsContentDeltas as o, isOpenAICompletionsThinkingEnabled as r, resolvePromptCacheKey as s, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as t, reconcileOpenAICompletionsToolChoice as u };
|