@openclaw/ai 2026.9.6 → 2026.9.7
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-DZQ_7gD1.mjs → anthropic-Cw2pgccz.mjs} +37 -66
- package/dist/{anthropic-payload-policy-DyfwikYJ.d.mts → anthropic-payload-policy-NIPVYXPq.d.mts} +7 -5
- package/dist/{anthropic-stream-reducer-D6ZI1wwj.mjs → anthropic-stream-reducer-D9MCkl8Z.mjs} +192 -261
- package/dist/{api-registry-C2T3lTV7.d.mts → api-registry-D-nbmSqr.d.mts} +2 -2
- package/dist/{azure-openai-responses-DS86GYzq.mjs → azure-openai-responses-BwT3-X8P.mjs} +22 -33
- package/dist/{base64-CPmadnUf.mjs → base64-C1PsYcRQ.mjs} +15 -9
- package/dist/{diagnostics-CH8j2wIG.mjs → diagnostics-CJaB6g8J.mjs} +3 -3
- package/dist/diagnostics.d.mts +4 -4
- package/dist/diagnostics.mjs +2 -2
- package/dist/{env-api-keys-bktO00EJ.mjs → env-api-keys-CyX4VKGO.mjs} +7 -5
- package/dist/event-stream-CMQfX_yr.d.mts +1 -0
- package/dist/{event-stream-CjnIZZst.d.mts → event-stream-DOPFYVqs.d.mts} +2 -2
- package/dist/{event-stream-D8PARQfL.mjs → event-stream-vd9UnCAU.mjs} +10 -0
- package/dist/event-stream.d.mts +2 -2
- package/dist/event-stream.mjs +1 -1
- package/dist/{google-BZJFjhuC.mjs → google-BfapkS_K.mjs} +8 -11
- package/dist/google-interactions-DW3iXzjc.mjs +574 -0
- package/dist/{google-messages-DB7GKkDk.mjs → google-messages-CtjVtVot.mjs} +35 -71
- package/dist/{google-shared-Bok4I6zB.mjs → google-shared-Y2YfotEu.mjs} +43 -47
- package/dist/{google-vertex-3eVNR2qW.mjs → google-vertex-Dov4kBWu.mjs} +16 -30
- package/dist/{host-yTvBrYM2.mjs → host-CHi3X87F.mjs} +29 -188
- package/dist/{host-policy-DZO3oPPk.mjs → host-policy-BOAwRg_M.mjs} +2 -14
- package/dist/{host-DH-Z-LDb.d.mts → host-rxlNaBwm.d.mts} +9 -3
- package/dist/{index-C25RT6bP.d.mts → index-D6KsSE74.d.mts} +28 -8
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +6 -6
- package/dist/internal/anthropic.d.mts +8 -7
- package/dist/internal/anthropic.mjs +5 -5
- package/dist/internal/openai-completions-compat.d.mts +1 -1
- package/dist/internal/openai-completions-compat.mjs +1 -1
- package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
- package/dist/internal/openai-responses-payload-policy.mjs +2 -2
- package/dist/internal/openai.d.mts +31 -8
- package/dist/internal/openai.mjs +13 -13
- package/dist/internal/runtime.d.mts +31 -70
- package/dist/internal/runtime.mjs +10 -65
- package/dist/internal/shared.d.mts +14 -12
- package/dist/internal/shared.mjs +5 -4
- package/dist/internal/tool-schema.d.mts +1 -1
- package/dist/internal/tool-schema.mjs +2 -2
- package/dist/{mistral-C_13dVBn.mjs → mistral-RS6mboC-.mjs} +46 -93
- package/dist/{openai-chatgpt-responses-sTxPl4zM.mjs → openai-chatgpt-responses-CYbidtrn.mjs} +26 -30
- package/dist/{openai-completions-BO6D_hrB.mjs → openai-completions-D14ihPYk.mjs} +14 -12
- package/dist/{openai-completions-compat-CUollwl6.mjs → openai-completions-compat-BOVWBZDn.mjs} +3 -5
- package/dist/{openai-completions-compat-DfJG1wSO.d.mts → openai-completions-compat-qJjmqQ71.d.mts} +3 -3
- package/dist/{openai-completions-stream-BpuJ0ZOA.mjs → openai-completions-stream-CDCuw3DP.mjs} +101 -173
- package/dist/{openai-prompt-cache-C4RHdN4n.d.mts → openai-prompt-cache-CouErLh7.d.mts} +2 -2
- package/dist/{openai-prompt-cache-CjV_2IRI.mjs → openai-prompt-cache-D2V7MqR7.mjs} +1 -1
- package/dist/{openai-provider-client-BP8J1aeg.mjs → openai-provider-client-CwfsGBbA.mjs} +2 -2
- package/dist/{openai-reasoning-effort-ash8dPrd.mjs → openai-reasoning-effort-ConhwkeX.mjs} +2 -1
- package/dist/{openai-responses-BJ_IEoMU.mjs → openai-responses-CKCBEc2W.mjs} +12 -11
- package/dist/openai-responses-compaction-replay-DiYn-gFM.d.mts +12 -0
- package/dist/{openai-responses-compaction-window-BiNCT0bS.mjs → openai-responses-compaction-window-UNK1GDpy.mjs} +5 -5
- package/dist/{openai-responses-contracts-DWrfMODE.mjs → openai-responses-contracts-CLxnqS9p.mjs} +1 -1
- package/dist/{openai-responses-contracts-B1ENJFpI.d.mts → openai-responses-contracts-D1iZ0njF.d.mts} +4 -4
- package/dist/{openai-responses-prompt-observer-internal-DPHWgbBH.mjs → openai-responses-prompt-observer-internal-iAqLb4tk.mjs} +12 -12
- package/dist/{openai-responses-request-lifecycle-DFuyO1pQ.mjs → openai-responses-request-lifecycle-Fsag-IGZ.mjs} +1 -1
- package/dist/{openai-responses-shared-DvSqtJ6_.mjs → openai-responses-shared-DL4ulQn7.mjs} +312 -122
- package/dist/{openai-responses-terminal-usage-BNFbvY9f.d.mts → openai-responses-terminal-usage-BE7lf7nW.d.mts} +2 -2
- package/dist/{openai-stop-reason-Drnn_6Qj.mjs → openai-stop-reason-8s70vDXj.mjs} +2 -12
- package/dist/{openai-tool-schema-ynZBgqW-.d.mts → openai-tool-schema-a5ysBBga.d.mts} +0 -6
- package/dist/{openai-tool-schema-D4BMcj2D.mjs → openai-tool-schema-vsl-cE-n.mjs} +243 -383
- package/dist/{openai-transport-params-DZKOTSfH.mjs → openai-transport-params-BwlpzX-2.mjs} +60 -105
- package/dist/{positive-integer-BiUxrd71.mjs → positive-integer-CjN5OJbH.mjs} +1 -1
- package/dist/{provider-error-CRhW7lkJ.mjs → provider-error-CwT_j2v0.mjs} +43 -4
- package/dist/{provider-options-DZYq53lj.d.mts → provider-options-Df7ov0K1.d.mts} +2 -2
- package/dist/{provider-replay-context-DPr3w20a.mjs → provider-replay-context-DsyI5jOP.mjs} +1 -1
- package/dist/{provider-transcript-transform-BTocjCRs.mjs → provider-transcript-transform-JbFbHV8h.mjs} +17 -2
- package/dist/{provider-transport-turn-state-lrXEFkYr.mjs → provider-transport-turn-state-BheUi_hl.mjs} +1 -1
- package/dist/{provider-types-w1rEqrGP.d.mts → provider-types-d4XnoZMd.d.mts} +3 -3
- package/dist/provider-types.d.mts +6 -6
- package/dist/providers.d.mts +2 -2
- package/dist/providers.mjs +15 -11
- package/dist/{reasoning-tag-text-partitioner-Di38crhI.mjs → reasoning-tag-text-partitioner-B6FIIBt6.mjs} +47 -71
- package/dist/{record-coerce-DwRYMj3t.mjs → record-coerce-CNDovvft.mjs} +1 -1
- package/dist/simple-options-CGAkCwtM.mjs +349 -0
- package/dist/{src-DwGYYyZp.mjs → src-H4aXcFuX.mjs} +43 -25
- package/dist/{stream-CREqxHgU.mjs → stream-DDsCBgd-.mjs} +1 -7
- package/dist/{stream-first-event-timeout-BeptfRL6.mjs → stream-first-event-timeout-B9o0S4SZ.mjs} +1 -1
- package/dist/{tool-schema-json-projection-CD9c_fK8.mjs → tool-schema-json-projection-Ct8SeBeJ.mjs} +63 -23
- package/dist/{transport-stream-shared-B5RioB_Q.mjs → transport-stream-shared-Dh5qKJ8e.mjs} +62 -28
- package/dist/{transport-stream-shared-B7Z9oCYg.d.mts → transport-stream-shared-yYhXa4kX.d.mts} +12 -6
- package/dist/{transport-utils-03Qi0CN2.mjs → transport-utils-C-4bf2Ok.mjs} +3 -4
- package/dist/transports.d.mts +36 -32
- package/dist/transports.mjs +160 -216
- package/dist/types-CB-_vNyI.d.mts +1 -0
- package/dist/{types-qZFbaDbK.d.mts → types-CLLR3eB4.d.mts} +3 -1
- package/dist/types.d.mts +6 -6
- package/dist/types.mjs +4 -4
- package/dist/{validation-Dw7cb6BV.mjs → validation-BFZc40Ig.mjs} +80 -54
- package/dist/{validation-DhQhmt6t.d.mts → validation-Cat2wQsc.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/package.json +5 -5
- package/dist/assistant-output-DM1JBNs1.mjs +0 -16
- package/dist/event-stream-C0nsgbj2.d.mts +0 -1
- package/dist/simple-options-np1XPuhm.mjs +0 -175
- package/dist/types-DTvddOfm.d.mts +0 -1
- package/dist/utf16-slice-CvGodqok.mjs +0 -29
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import { o as readProviderRefusalReview, t as appendAssistantMessageDiagnostic } from "./diagnostics-DzrF1h4J.mjs";
|
|
2
|
-
import { r as appendAssistantThinking } from "./event-stream-
|
|
2
|
+
import { r as appendAssistantThinking } from "./event-stream-vd9UnCAU.mjs";
|
|
3
|
+
import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
|
|
4
|
+
import { k as isImageWithMediaPayload, n as getAiTransportHost, r as resolveAiTransportHeaderSentinels, w as calculateCost } from "./host-CHi3X87F.mjs";
|
|
3
5
|
import { a as normalizeOptionalString, o as normalizeStringifiedOptionalString, s as readStringValue } from "./string-coerce-fsri9iCu.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { m as stripSystemPromptCacheBoundary, v as sortPromptCacheToolsByName } from "./simple-options-np1XPuhm.mjs";
|
|
14
|
-
import { M as redactIdentifier, N as sha256Hex, b as createOpenAIProviderAcceptanceHook, d as prepareOpenAITools, h as resolveOpenAIRequestReasoning, u as resolveOpenAIStrictToolFlagWithDiagnostics, w as log, y as createModelStreamCooperativeScheduler } from "./openai-transport-params-DZKOTSfH.mjs";
|
|
15
|
-
import { E as parseStreamingJson, O as shortHash, _ as sanitizeTransportPayloadText, b as withProviderResponseHook, g as sanitizeNonEmptyTransportPayloadText, h as parseTerminalToolCallArguments, l as finalizeTransportStream, s as failTransportStream, t as IncompleteToolCallError, v as transportAbortError, w as createToolArgumentPreviewSchedule, x as parseJsonObjectPreservingUnsafeIntegers } from "./transport-stream-shared-B5RioB_Q.mjs";
|
|
16
|
-
import { n as providerReplayContextMatches, t as buildProviderReplayContext } from "./provider-replay-context-DPr3w20a.mjs";
|
|
6
|
+
import { d as supportsOpenAITemperature } from "./openai-reasoning-effort-ConhwkeX.mjs";
|
|
7
|
+
import { o as truncateUtf16Safe, s as stableStringify } from "./provider-error-CwT_j2v0.mjs";
|
|
8
|
+
import { a as resolveModelSseDebugMode, d as isResponsesProviderTool, g as resolveResponsesTerminalStopReason, h as readResponsesReasoningTokens, i as resolveModelPayloadDebugMode, l as ResponsesOutputIdentityError, m as mapResponsesTerminalUsage, r as emitModelTransportDebug, u as hasOnlyResponsesFunctionTools } from "./diagnostics-CJaB6g8J.mjs";
|
|
9
|
+
import { o as redactSensitiveText } from "./transport-utils-C-4bf2Ok.mjs";
|
|
10
|
+
import { i as resolveOpenAICompletionsCompat } from "./openai-completions-compat-BOVWBZDn.mjs";
|
|
11
|
+
import { A as shortHash, C as parseJsonObjectPreservingUnsafeIntegers, E as createToolArgumentPreviewSchedule, O as parseStreamingJson, S as withProviderResponseHook, _ as sanitizeNonEmptyTransportPayloadText, b as transportAbortError, c as failTransportStream, d as iterateModelStream, g as parseTerminalToolCallArguments, t as IncompleteToolCallError, u as finalizeTransportStream, v as sanitizeTransportPayloadText } from "./transport-stream-shared-Dh5qKJ8e.mjs";
|
|
12
|
+
import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, d as describeToolResultMediaPlaceholder, m as extractToolResultText, s as prepareModelRequestBody } from "./simple-options-CGAkCwtM.mjs";
|
|
13
|
+
import { A as redactIdentifier, C as log, d as prepareOpenAITools, h as resolveOpenAIRequestReasoning, j as sha256Hex, u as resolveOpenAIStrictToolFlagWithDiagnostics, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-BwlpzX-2.mjs";
|
|
14
|
+
import { n as providerReplayContextMatches, t as buildProviderReplayContext } from "./provider-replay-context-DsyI5jOP.mjs";
|
|
17
15
|
import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
|
|
18
|
-
import {
|
|
19
|
-
import { t as
|
|
20
|
-
import { a as resolveOpenAIProjectedToolsStrictToolFlag, f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-
|
|
21
|
-
import { a as OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE, c as OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE, f as RESPONSE_FAILED_NO_DETAILS_MESSAGE, o as OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY, p as isPreviousResponseRejection, s as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY } from "./openai-responses-contracts-
|
|
22
|
-
import { n as isOpenAIResponsesCompactionOutput, r as readOpenAIResponsesCompactionWindow } from "./openai-responses-compaction-window-
|
|
16
|
+
import { t as transformProviderMessages } from "./provider-transcript-transform-JbFbHV8h.mjs";
|
|
17
|
+
import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-B9o0S4SZ.mjs";
|
|
18
|
+
import { a as resolveOpenAIProjectedToolsStrictToolFlag, f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-vsl-cE-n.mjs";
|
|
19
|
+
import { a as OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE, c as OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE, f as RESPONSE_FAILED_NO_DETAILS_MESSAGE, o as OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY, p as isPreviousResponseRejection, s as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY } from "./openai-responses-contracts-CLxnqS9p.mjs";
|
|
20
|
+
import { n as isOpenAIResponsesCompactionOutput, r as readOpenAIResponsesCompactionWindow } from "./openai-responses-compaction-window-UNK1GDpy.mjs";
|
|
23
21
|
import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
|
|
24
|
-
import {
|
|
22
|
+
import { randomUUID } from "node:crypto";
|
|
25
23
|
//#region packages/ai/src/transports/openai-responses-replay.ts
|
|
26
24
|
/** Resolves the assistant message id that can be replayed to OpenAI Responses. */
|
|
27
25
|
function resolveReplayableResponsesMessageId(params) {
|
|
@@ -30,12 +28,68 @@ function resolveReplayableResponsesMessageId(params) {
|
|
|
30
28
|
return params.previousReplayItemWasReasoning ? params.textSignatureId : void 0;
|
|
31
29
|
}
|
|
32
30
|
//#endregion
|
|
31
|
+
//#region packages/ai/src/transports/openai-responses-tool-call-id-shape.ts
|
|
32
|
+
/**
|
|
33
|
+
* Pure OpenAI Responses `call_*`/`fc_*` tool-call-id shape helpers.
|
|
34
|
+
*
|
|
35
|
+
* Moved out of embedded-agent-helpers/openai.ts (the AgentMessage[]-walking
|
|
36
|
+
* caller lives in src/agents and imports from packages/ai, so the reverse
|
|
37
|
+
* import direction is not available) so the continuation transport can
|
|
38
|
+
* recognize its own cached raw ids after this same reshaping and restore
|
|
39
|
+
* them on a replayed wire request -- see openai-responses-continuation.ts.
|
|
40
|
+
*/
|
|
41
|
+
const OPENAI_RESPONSES_ID_MAX_LENGTH = 64;
|
|
42
|
+
const OPENAI_RESPONSES_CALL_ID_RE = /^call_[A-Za-z0-9_-]{1,59}$/;
|
|
43
|
+
const OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE = /^fc_[A-Za-z0-9_-]{1,61}$/;
|
|
44
|
+
function splitOpenAIFunctionCallPairing(id) {
|
|
45
|
+
const separator = id.indexOf("|");
|
|
46
|
+
if (separator <= 0 || separator >= id.length - 1) return { callId: id };
|
|
47
|
+
return {
|
|
48
|
+
callId: id.slice(0, separator),
|
|
49
|
+
itemId: id.slice(separator + 1)
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function shortOpenAIResponsesIdHash(id) {
|
|
53
|
+
return sha256Hex(id).slice(0, 10);
|
|
54
|
+
}
|
|
55
|
+
function sanitizeOpenAIResponsesIdTail(value) {
|
|
56
|
+
return value.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
|
|
57
|
+
}
|
|
58
|
+
function normalizeOpenAIResponsesIdPart(params) {
|
|
59
|
+
const trimmed = params.value.trim();
|
|
60
|
+
if (params.isValid(trimmed)) return trimmed;
|
|
61
|
+
const rawTail = trimmed.startsWith(params.prefix) ? trimmed.slice(params.prefix.length) : trimmed;
|
|
62
|
+
const hash = shortOpenAIResponsesIdHash(trimmed || params.prefix);
|
|
63
|
+
const maxTailLength = 64 - params.prefix.length;
|
|
64
|
+
const hashSuffix = `_${hash}`;
|
|
65
|
+
const tail = `${sanitizeOpenAIResponsesIdTail(rawTail).slice(0, Math.max(1, maxTailLength - hashSuffix.length)) || "id"}${hashSuffix}`.slice(0, maxTailLength);
|
|
66
|
+
return `${params.prefix}${tail}`;
|
|
67
|
+
}
|
|
68
|
+
/** Same shaping `normalizeOpenAIResponsesToolCallIds` applies to a replayed `call_id`/`call_id|fc_id` pair. */
|
|
69
|
+
function normalizeOpenAIResponsesFunctionCallId(id) {
|
|
70
|
+
const { callId, itemId } = splitOpenAIFunctionCallPairing(id);
|
|
71
|
+
const normalizedCallId = normalizeOpenAIResponsesIdPart({
|
|
72
|
+
value: itemId ? `${callId}|${itemId}` : callId,
|
|
73
|
+
prefix: "call_",
|
|
74
|
+
isValid: (value) => OPENAI_RESPONSES_CALL_ID_RE.test(value)
|
|
75
|
+
});
|
|
76
|
+
if (!itemId) return normalizedCallId;
|
|
77
|
+
return `${normalizedCallId}|${normalizeOpenAIResponsesIdPart({
|
|
78
|
+
value: itemId,
|
|
79
|
+
prefix: "fc_",
|
|
80
|
+
isValid: (value) => OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE.test(value)
|
|
81
|
+
})}`;
|
|
82
|
+
}
|
|
83
|
+
function shouldNormalizeOpenAIResponsesToolCallId(id) {
|
|
84
|
+
const pairing = splitOpenAIFunctionCallPairing(id);
|
|
85
|
+
if (!OPENAI_RESPONSES_CALL_ID_RE.test(pairing.callId)) return true;
|
|
86
|
+
if (pairing.itemId === void 0) return false;
|
|
87
|
+
return !OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE.test(pairing.itemId);
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
33
90
|
//#region packages/ai/src/transports/openai-responses-compaction-replay.ts
|
|
34
91
|
const OPENAI_RESPONSES_COMPACTION_SUPPRESSION_TYPE = "openai-responses-compaction-suppression";
|
|
35
92
|
const OPENAI_RESPONSES_COMPACTION_SUPPRESSION_DATA = "rejected";
|
|
36
|
-
function buildOpenAIResponsesReplayContext(model, options) {
|
|
37
|
-
return buildProviderReplayContext(model, options);
|
|
38
|
-
}
|
|
39
93
|
function isOpenAIResponsesReplayContext(value) {
|
|
40
94
|
if (!isRecord(value)) return false;
|
|
41
95
|
return typeof value.provider === "string" && typeof value.api === "string" && typeof value.model === "string" && (value.baseUrlHash === void 0 || typeof value.baseUrlHash === "string") && (value.sessionHash === void 0 || typeof value.sessionHash === "string") && (value.authProfileHash === void 0 || typeof value.authProfileHash === "string");
|
|
@@ -82,7 +136,7 @@ function captureOpenAIResponsesCompaction(output, item, boundary, model, capture
|
|
|
82
136
|
output.providerReplay = replay;
|
|
83
137
|
}
|
|
84
138
|
function suppressOpenAIResponsesCompaction(output, model, options, rejectedCheckpoint) {
|
|
85
|
-
const context =
|
|
139
|
+
const context = buildProviderReplayContext(model, options);
|
|
86
140
|
if (!context.baseUrlHash) return;
|
|
87
141
|
output.providerReplay = {
|
|
88
142
|
v: 1,
|
|
@@ -114,7 +168,7 @@ function isSafeResponsesReplayItemId(id) {
|
|
|
114
168
|
return typeof id === "string" && id.length > 0 && id.length <= 64;
|
|
115
169
|
}
|
|
116
170
|
function resolveNewestOpenAIResponsesCompactionReplay(messages, model, options) {
|
|
117
|
-
const context =
|
|
171
|
+
const context = buildProviderReplayContext(model, options);
|
|
118
172
|
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
119
173
|
const message = messages[index];
|
|
120
174
|
if (message?.role !== "assistant") continue;
|
|
@@ -186,7 +240,7 @@ function buildOpenAIResponsesReasoningReplayMetadata(model, options) {
|
|
|
186
240
|
return {
|
|
187
241
|
v: 1,
|
|
188
242
|
source: "openai-responses",
|
|
189
|
-
...
|
|
243
|
+
...buildProviderReplayContext(model, options)
|
|
190
244
|
};
|
|
191
245
|
}
|
|
192
246
|
//#endregion
|
|
@@ -260,12 +314,87 @@ function requestWithoutInput(request) {
|
|
|
260
314
|
metadata
|
|
261
315
|
};
|
|
262
316
|
}
|
|
263
|
-
function
|
|
317
|
+
function canonicalizeToolCallId(callId, itemId) {
|
|
318
|
+
if (typeof callId !== "string") return callId;
|
|
319
|
+
const paired = typeof itemId === "string" && itemId ? `${callId}|${itemId}` : callId;
|
|
320
|
+
if (!shouldNormalizeOpenAIResponsesToolCallId(paired)) return callId;
|
|
321
|
+
return splitOpenAIFunctionCallPairing(normalizeOpenAIResponsesFunctionCallId(paired)).callId;
|
|
322
|
+
}
|
|
323
|
+
function responseToolCalls(items) {
|
|
324
|
+
return items.flatMap((item) => {
|
|
325
|
+
if (!isRecord(item) || item.type !== "function_call" || typeof item.call_id !== "string") return [];
|
|
326
|
+
return [{
|
|
327
|
+
callId: item.call_id,
|
|
328
|
+
...typeof item.id === "string" ? { itemId: item.id } : {}
|
|
329
|
+
}];
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
function toolCallReplayShapes(call) {
|
|
333
|
+
return new Set([
|
|
334
|
+
call.callId,
|
|
335
|
+
canonicalizeToolCallId(call.callId, call.itemId),
|
|
336
|
+
canonicalizeToolCallId(call.callId, void 0)
|
|
337
|
+
].filter((shape) => typeof shape === "string"));
|
|
338
|
+
}
|
|
339
|
+
function toolCallOwnerByReplayShape(calls) {
|
|
340
|
+
const ownerByReplayShape = /* @__PURE__ */ new Map();
|
|
341
|
+
for (const [index, call] of calls.entries()) for (const replayShape of toolCallReplayShapes(call)) {
|
|
342
|
+
const owner = ownerByReplayShape.get(replayShape);
|
|
343
|
+
ownerByReplayShape.set(replayShape, owner === void 0 || owner === index ? index : null);
|
|
344
|
+
}
|
|
345
|
+
return ownerByReplayShape;
|
|
346
|
+
}
|
|
347
|
+
function pendingResponsesToolCalls(calls, input) {
|
|
348
|
+
const ownerByReplayShape = toolCallOwnerByReplayShape(calls);
|
|
349
|
+
const replayedCallIds = /* @__PURE__ */ new Set();
|
|
350
|
+
const lastCallPosition = /* @__PURE__ */ new Map();
|
|
351
|
+
const lastOutputPosition = /* @__PURE__ */ new Map();
|
|
352
|
+
for (const [inputIndex, item] of input.entries()) {
|
|
353
|
+
if (!isRecord(item) || typeof item.call_id !== "string") continue;
|
|
354
|
+
const owner = ownerByReplayShape.get(item.call_id);
|
|
355
|
+
if (item.type === "function_call") {
|
|
356
|
+
replayedCallIds.add(item.call_id);
|
|
357
|
+
if (owner !== void 0 && owner !== null) lastCallPosition.set(owner, inputIndex);
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (item.type !== "function_call_output") continue;
|
|
361
|
+
if (owner !== void 0 && owner !== null) lastOutputPosition.set(owner, inputIndex);
|
|
362
|
+
}
|
|
363
|
+
return calls.filter((_call, index) => {
|
|
364
|
+
const callPosition = lastCallPosition.get(index);
|
|
365
|
+
return [...toolCallReplayShapes(_call)].some((shape) => replayedCallIds.has(shape)) && (callPosition === void 0 || (lastOutputPosition.get(index) ?? -1) < callPosition);
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
function recordResponsesContinuationState(previous, lastRequest, response, continued = false) {
|
|
369
|
+
const calls = previous && continued ? [...previous.pendingToolCalls ?? [], ...responseToolCalls(previous.lastResponseItems)] : responseToolCalls(lastRequest.input ?? []);
|
|
370
|
+
const seenCalls = /* @__PURE__ */ new Set();
|
|
371
|
+
const pendingToolCalls = pendingResponsesToolCalls(calls.filter((call) => {
|
|
372
|
+
const key = JSON.stringify([call.callId, call.itemId]);
|
|
373
|
+
if (seenCalls.has(key)) return false;
|
|
374
|
+
seenCalls.add(key);
|
|
375
|
+
return true;
|
|
376
|
+
}), lastRequest.input ?? []);
|
|
377
|
+
return {
|
|
378
|
+
lastRequest,
|
|
379
|
+
lastResponseId: response.id,
|
|
380
|
+
lastResponseItems: response.output,
|
|
381
|
+
pendingToolCalls
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
function normalizeAssistantReplayInput(input, fromResponse = false, ignoreCachedItemIds = false) {
|
|
264
385
|
return input.map((item) => {
|
|
265
386
|
if (!isRecord(item)) return item;
|
|
266
387
|
if (item.type === "reasoning") return { type: "reasoning" };
|
|
267
|
-
if (item.type !== "function_call" && !(item.type === "message" && item.role === "assistant")) return item;
|
|
268
|
-
const { id:
|
|
388
|
+
if (item.type !== "function_call" && item.type !== "function_call_output" && !(item.type === "message" && item.role === "assistant")) return item;
|
|
389
|
+
const { id: rawId, status: _status, ...stableItem } = item;
|
|
390
|
+
if (item.type === "function_call_output") {
|
|
391
|
+
if ("id" in item) stableItem.id = item.id;
|
|
392
|
+
if ("status" in item) stableItem.status = item.status;
|
|
393
|
+
}
|
|
394
|
+
if ("call_id" in stableItem) {
|
|
395
|
+
const itemId = item.type === "function_call" && !(fromResponse && ignoreCachedItemIds) ? rawId : void 0;
|
|
396
|
+
stableItem.call_id = canonicalizeToolCallId(stableItem.call_id, itemId);
|
|
397
|
+
}
|
|
269
398
|
if (fromResponse && item.type === "function_call") {
|
|
270
399
|
const args = parseJsonObjectPreservingUnsafeIntegers(stableItem.arguments);
|
|
271
400
|
stableItem.arguments = args ? JSON.stringify(args) : stableItem.arguments;
|
|
@@ -278,6 +407,53 @@ function normalizeAssistantReplayInput(input, fromResponse = false) {
|
|
|
278
407
|
return stableItem;
|
|
279
408
|
});
|
|
280
409
|
}
|
|
410
|
+
function normalizeContinuationHistory(input) {
|
|
411
|
+
const normalized = normalizeAssistantReplayInput(input);
|
|
412
|
+
const ownerByReplayShape = toolCallOwnerByReplayShape(responseToolCalls(input));
|
|
413
|
+
let callIndex = 0;
|
|
414
|
+
for (const [index, item] of input.entries()) {
|
|
415
|
+
const normalizedItem = normalized[index];
|
|
416
|
+
if (!isRecord(item) || !isRecord(normalizedItem)) continue;
|
|
417
|
+
if (item.type === "function_call") {
|
|
418
|
+
if (typeof normalizedItem.call_id !== "string") return;
|
|
419
|
+
const callOwner = ownerByReplayShape.get(normalizedItem.call_id);
|
|
420
|
+
if (callOwner !== callIndex) return;
|
|
421
|
+
normalizedItem.call_id = { callOwner };
|
|
422
|
+
callIndex += 1;
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
if (item.type !== "function_call_output" || typeof item.call_id !== "string") continue;
|
|
426
|
+
const owner = ownerByReplayShape.get(item.call_id);
|
|
427
|
+
if (owner === null) return;
|
|
428
|
+
normalizedItem.call_id = owner === void 0 ? { unknownCallId: canonicalizeToolCallId(item.call_id, void 0) } : { callOwner: owner };
|
|
429
|
+
}
|
|
430
|
+
return normalized;
|
|
431
|
+
}
|
|
432
|
+
function continuationHistoryMatches(previousInput, currentInput) {
|
|
433
|
+
for (const [index, previousItem] of previousInput.entries()) {
|
|
434
|
+
const currentItem = currentInput[index];
|
|
435
|
+
if (!isRecord(previousItem) || !isRecord(currentItem)) continue;
|
|
436
|
+
if (previousItem.type === "function_call" && currentItem.type === "function_call") {
|
|
437
|
+
if (typeof previousItem.call_id === "string" && typeof currentItem.call_id === "string" && !toolCallReplayShapes({
|
|
438
|
+
callId: previousItem.call_id,
|
|
439
|
+
...typeof previousItem.id === "string" ? { itemId: previousItem.id } : {}
|
|
440
|
+
}).has(currentItem.call_id)) return false;
|
|
441
|
+
}
|
|
442
|
+
if (previousItem.type === "function_call_output" && currentItem.type === "function_call_output" && typeof previousItem.call_id === "string" && typeof currentItem.call_id === "string" && currentItem.call_id !== previousItem.call_id && currentItem.call_id !== canonicalizeToolCallId(previousItem.call_id, void 0)) return false;
|
|
443
|
+
}
|
|
444
|
+
const previousCalls = responseToolCalls(previousInput);
|
|
445
|
+
const currentCalls = responseToolCalls(currentInput);
|
|
446
|
+
if (previousCalls.length !== currentCalls.length) return false;
|
|
447
|
+
for (const [index, previousCall] of previousCalls.entries()) {
|
|
448
|
+
const currentCall = currentCalls[index];
|
|
449
|
+
if (!currentCall) return false;
|
|
450
|
+
const previousShapes = toolCallReplayShapes(previousCall);
|
|
451
|
+
if (![...toolCallReplayShapes(currentCall)].some((shape) => previousShapes.has(shape))) return false;
|
|
452
|
+
}
|
|
453
|
+
const normalizedPrevious = normalizeContinuationHistory(previousInput);
|
|
454
|
+
const normalizedCurrent = normalizeContinuationHistory(currentInput);
|
|
455
|
+
return normalizedPrevious !== void 0 && normalizedCurrent !== void 0 && jsonValuesEqual(normalizedCurrent, normalizedPrevious);
|
|
456
|
+
}
|
|
281
457
|
function responsesContinuationRequestFingerprint(request) {
|
|
282
458
|
const serialized = JSON.stringify(requestWithoutInput(request));
|
|
283
459
|
return sha256Hex(stableStringify(JSON.parse(serialized)));
|
|
@@ -286,6 +462,34 @@ function responsesContinuationPrefixFingerprint(input, output = []) {
|
|
|
286
462
|
const serialized = JSON.stringify([...normalizeAssistantReplayInput(input), ...normalizeAssistantReplayInput(output, true)]);
|
|
287
463
|
return sha256Hex(stableStringify(JSON.parse(serialized)));
|
|
288
464
|
}
|
|
465
|
+
function restoreRawCallIdsInDelta(delta, cachedResponseItems, replayedToolRound, pendingToolCalls) {
|
|
466
|
+
const currentResponseCalls = responseToolCalls(cachedResponseItems);
|
|
467
|
+
const replayedCalls = replayedToolRound.filter((item) => isRecord(item) && item.type === "function_call");
|
|
468
|
+
if (currentResponseCalls.length !== replayedCalls.length) return;
|
|
469
|
+
const cachedCalls = [...pendingToolCalls, ...currentResponseCalls];
|
|
470
|
+
const currentCallOffset = pendingToolCalls.length;
|
|
471
|
+
const ownerByReplayShape = toolCallOwnerByReplayShape(cachedCalls);
|
|
472
|
+
for (const index of currentResponseCalls.keys()) {
|
|
473
|
+
const replayedCallId = replayedCalls[index]?.call_id;
|
|
474
|
+
if (typeof replayedCallId !== "string" || ownerByReplayShape.get(replayedCallId) !== currentCallOffset + index) return;
|
|
475
|
+
}
|
|
476
|
+
const restoredDelta = [];
|
|
477
|
+
for (const item of delta) {
|
|
478
|
+
if (!isRecord(item) || item.type !== "function_call_output" || typeof item.call_id !== "string") {
|
|
479
|
+
restoredDelta.push(item);
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
const owner = ownerByReplayShape.get(item.call_id);
|
|
483
|
+
if (owner === void 0 || owner === null) return;
|
|
484
|
+
const rawCallId = cachedCalls[owner]?.callId;
|
|
485
|
+
if (!rawCallId) return;
|
|
486
|
+
restoredDelta.push(rawCallId === item.call_id ? item : {
|
|
487
|
+
...item,
|
|
488
|
+
call_id: rawCallId
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
return restoredDelta;
|
|
492
|
+
}
|
|
289
493
|
function resolveResponsesContinuationRequest(continuation, request, steering) {
|
|
290
494
|
if (!continuation) return {
|
|
291
495
|
request,
|
|
@@ -311,15 +515,24 @@ function resolveResponsesContinuationRequest(continuation, request, steering) {
|
|
|
311
515
|
request,
|
|
312
516
|
continuationStatus: "history_shorter"
|
|
313
517
|
};
|
|
314
|
-
|
|
518
|
+
const replayedToolRoundInput = currentInput.slice(previousInput.length, baselineLength);
|
|
519
|
+
const replayedToolRound = normalizeAssistantReplayInput(replayedToolRoundInput);
|
|
520
|
+
const historyToolRoundUnchanged = jsonValuesEqual(replayedToolRound, normalizeAssistantReplayInput(continuation.lastResponseItems, true)) || jsonValuesEqual(replayedToolRound, normalizeAssistantReplayInput(continuation.lastResponseItems, true, true));
|
|
521
|
+
if (!continuationHistoryMatches(previousInput, currentInput.slice(0, previousInput.length)) || !historyToolRoundUnchanged) return {
|
|
315
522
|
request,
|
|
316
523
|
continuationStatus: "history_changed"
|
|
317
524
|
};
|
|
525
|
+
const restoredInput = restoreRawCallIdsInDelta(currentInput.slice(baselineLength), continuation.lastResponseItems, replayedToolRoundInput, continuation.pendingToolCalls ?? []);
|
|
526
|
+
if (!restoredInput) return {
|
|
527
|
+
request,
|
|
528
|
+
continuationStatus: "history_changed"
|
|
529
|
+
};
|
|
530
|
+
const restoredResponseInput = restoredInput;
|
|
318
531
|
return {
|
|
319
532
|
request: {
|
|
320
533
|
...prepared,
|
|
321
534
|
previous_response_id: continuation.lastResponseId,
|
|
322
|
-
input:
|
|
535
|
+
input: restoredResponseInput
|
|
323
536
|
},
|
|
324
537
|
...prepared !== request ? { fullRequest: prepared } : {},
|
|
325
538
|
continuationStatus: "continued"
|
|
@@ -354,16 +567,12 @@ function claimOpenAIResponsesHttpContinuation(params) {
|
|
|
354
567
|
return {
|
|
355
568
|
request: params.request.store === false ? fullRequest : resolved.request,
|
|
356
569
|
fullRequest,
|
|
357
|
-
commit: (effectiveRequest, response) => {
|
|
570
|
+
commit: (effectiveRequest, response, dispatchedPreviousResponseId) => {
|
|
358
571
|
if (httpContinuationEntries.get(key) !== claimed) return;
|
|
359
572
|
const ready = {
|
|
360
573
|
...claimed,
|
|
361
574
|
kind: "ready",
|
|
362
|
-
state:
|
|
363
|
-
lastRequest: effectiveRequest,
|
|
364
|
-
lastResponseId: response.id,
|
|
365
|
-
lastResponseItems: response.output
|
|
366
|
-
},
|
|
575
|
+
state: recordResponsesContinuationState(previous?.kind === "ready" ? previous.state : void 0, effectiveRequest, response, previous?.kind === "ready" && dispatchedPreviousResponseId === previous.state.lastResponseId),
|
|
367
576
|
idleTimer: setTimeout(() => deleteHttpContinuationIfOwned(key, ready), HTTP_CONTINUATION_IDLE_TTL_MS)
|
|
368
577
|
};
|
|
369
578
|
ready.idleTimer.unref?.();
|
|
@@ -575,36 +784,23 @@ function parseOpenAIResponsesTextSignature(signature) {
|
|
|
575
784
|
} catch {}
|
|
576
785
|
return { id: signature };
|
|
577
786
|
}
|
|
578
|
-
|
|
787
|
+
const responsesInputSource = Symbol("openclaw.responsesInputSource");
|
|
788
|
+
/** Source identity survives payload spreads but never enters serialized provider input. */
|
|
789
|
+
function bindResponsesInputMessage(source) {
|
|
790
|
+
const identity = {};
|
|
791
|
+
Object.defineProperty(source, responsesInputSource, {
|
|
792
|
+
value: identity,
|
|
793
|
+
enumerable: true
|
|
794
|
+
});
|
|
795
|
+
return (input) => typeof input === "object" && input !== null && Reflect.get(input, responsesInputSource) === identity;
|
|
796
|
+
}
|
|
797
|
+
function buildResponsesInputMessage(role, content, source) {
|
|
798
|
+
const identity = source && Reflect.get(source, responsesInputSource);
|
|
579
799
|
return {
|
|
580
800
|
type: "message",
|
|
581
801
|
role,
|
|
582
|
-
content
|
|
583
|
-
|
|
584
|
-
}
|
|
585
|
-
function createOpenAIResponsesAssistantOutput(model, api = model.api) {
|
|
586
|
-
return {
|
|
587
|
-
role: "assistant",
|
|
588
|
-
content: [],
|
|
589
|
-
api,
|
|
590
|
-
provider: model.provider,
|
|
591
|
-
model: model.id,
|
|
592
|
-
usage: {
|
|
593
|
-
input: 0,
|
|
594
|
-
output: 0,
|
|
595
|
-
cacheRead: 0,
|
|
596
|
-
cacheWrite: 0,
|
|
597
|
-
totalTokens: 0,
|
|
598
|
-
cost: {
|
|
599
|
-
input: 0,
|
|
600
|
-
output: 0,
|
|
601
|
-
cacheRead: 0,
|
|
602
|
-
cacheWrite: 0,
|
|
603
|
-
total: 0
|
|
604
|
-
}
|
|
605
|
-
},
|
|
606
|
-
stopReason: "stop",
|
|
607
|
-
timestamp: Date.now()
|
|
802
|
+
content,
|
|
803
|
+
...identity ? { [responsesInputSource]: identity } : {}
|
|
608
804
|
};
|
|
609
805
|
}
|
|
610
806
|
function convertResponsesMessagesWithStyle(model, context, allowedToolCallProviders, options, conversionStyle) {
|
|
@@ -612,7 +808,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
|
|
|
612
808
|
const providerStyle = conversionStyle === "provider";
|
|
613
809
|
const shouldReplayReasoningItems = options?.replayReasoningItems ?? true;
|
|
614
810
|
const shouldReplayResponsesItemIds = options?.replayResponsesItemIds ?? true;
|
|
615
|
-
const replayContext =
|
|
811
|
+
const replayContext = buildProviderReplayContext(model, {
|
|
616
812
|
sessionId: options?.sessionId,
|
|
617
813
|
authProfileId: options?.authProfileId
|
|
618
814
|
});
|
|
@@ -650,7 +846,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
|
|
|
650
846
|
authProfileId: options?.authProfileId,
|
|
651
847
|
mode: options?.replayMode
|
|
652
848
|
});
|
|
653
|
-
const transformMessages = (source) => providerStyle ? transformProviderMessages(source, model, normalizeToolCallId) : transformTransportMessages(source, model, normalizeToolCallId, {
|
|
849
|
+
const transformMessages = (source) => providerStyle ? transformProviderMessages(source, model, normalizeToolCallId) : getAiTransportHost().transformTransportMessages(source, model, normalizeToolCallId, {
|
|
654
850
|
normalizeSameModelToolCallIds: shouldNormalizeSameModelToolCallIds,
|
|
655
851
|
preserveUnframedToolResults: replayPlan.preserveUnframedToolResults
|
|
656
852
|
});
|
|
@@ -686,7 +882,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
|
|
|
686
882
|
if (typeof msg.content === "string") messages.push(buildResponsesInputMessage("user", [{
|
|
687
883
|
type: "input_text",
|
|
688
884
|
text: sanitizeTransportPayloadText(msg.content)
|
|
689
|
-
}]));
|
|
885
|
+
}], msg));
|
|
690
886
|
else {
|
|
691
887
|
const content = msg.content.map((item) => item.type === "text" ? {
|
|
692
888
|
type: "input_text",
|
|
@@ -696,7 +892,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
|
|
|
696
892
|
detail: "auto",
|
|
697
893
|
image_url: `data:${item.mimeType};base64,${item.data}`
|
|
698
894
|
}).filter((item) => providerStyle || model.input.includes("image") || item.type !== "input_image");
|
|
699
|
-
if (content.length > 0) messages.push(buildResponsesInputMessage("user", content));
|
|
895
|
+
if (content.length > 0) messages.push(buildResponsesInputMessage("user", content, msg));
|
|
700
896
|
else if (providerStyle) continue;
|
|
701
897
|
}
|
|
702
898
|
} else if (msg.role === "assistant") {
|
|
@@ -794,7 +990,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
|
|
|
794
990
|
}
|
|
795
991
|
return messages;
|
|
796
992
|
}
|
|
797
|
-
function convertResponsesMessages
|
|
993
|
+
function convertResponsesMessages(model, context, allowedToolCallProviders, options) {
|
|
798
994
|
return convertResponsesMessagesWithStyle(model, context, allowedToolCallProviders, options, "transport");
|
|
799
995
|
}
|
|
800
996
|
function convertProviderResponsesMessages(model, context, allowedToolCallProviders, options) {
|
|
@@ -827,7 +1023,7 @@ function contextFingerprint(input, output = []) {
|
|
|
827
1023
|
function recordResponsesContextUsage(message, model, identity, request, output, projection) {
|
|
828
1024
|
const usage = message.usage.contextUsage;
|
|
829
1025
|
if (usage?.state !== "available" || !Number.isSafeInteger(usage.totalTokens) || usage.totalTokens <= 0 || message.stopReason === "error" || message.stopReason === "aborted" || message.providerReplay || request.previous_response_id || !Array.isArray(request.input) || !request.input.some((item) => isRecord(item) && item.type === "compaction") || !Array.isArray(output) || output.some((item) => isRecord(item) && item.type === "compaction")) return;
|
|
830
|
-
const replayOutput = (projection === "transport" ? convertResponsesMessages
|
|
1026
|
+
const replayOutput = (projection === "transport" ? convertResponsesMessages : convertProviderResponsesMessages)(model, { messages: [message] }, TOOL_CALL_PROVIDERS, {
|
|
831
1027
|
...identity,
|
|
832
1028
|
includeSystemPrompt: false
|
|
833
1029
|
}).filter((item) => item.type !== "function_call_output");
|
|
@@ -856,7 +1052,7 @@ function resolveResponsesContextUsageBoundary(messages, model, identity, systemP
|
|
|
856
1052
|
if (!isRecord(state) || usage?.state !== "available") continue;
|
|
857
1053
|
const { projection, prefixHash, prefixLength, promptTokens, totalTokens, includeSystemPrompt } = state;
|
|
858
1054
|
if (!isOpenAIResponsesReplayContext(state) || !providerReplayContextMatches(state, buildProviderReplayContext(model, identity)) || message.provider !== model.provider || message.api !== model.api || message.model !== model.id || projection !== "transport" && projection !== "provider" || typeof prefixHash !== "string" || typeof prefixLength !== "number" || !Number.isSafeInteger(prefixLength) || prefixLength <= 0 || promptTokens !== usage.promptTokens || totalTokens !== usage.totalTokens || !Number.isSafeInteger(usage.totalTokens) || usage.totalTokens <= 0) return;
|
|
859
|
-
const input = (projection === "transport" ? convertResponsesMessages
|
|
1055
|
+
const input = (projection === "transport" ? convertResponsesMessages : convertProviderResponsesMessages)(model, {
|
|
860
1056
|
messages: messages.filter(isProviderMessage),
|
|
861
1057
|
systemPrompt
|
|
862
1058
|
}, TOOL_CALL_PROVIDERS, {
|
|
@@ -919,9 +1115,6 @@ function responseInputItemShape(input) {
|
|
|
919
1115
|
return item.type;
|
|
920
1116
|
}).join(",") || "none";
|
|
921
1117
|
}
|
|
922
|
-
function hashOpaqueResponsesValue(value) {
|
|
923
|
-
return createHash("sha256").update(value).digest("hex");
|
|
924
|
-
}
|
|
925
1118
|
function summarizeResponsesCompactionItems(input) {
|
|
926
1119
|
if (!Array.isArray(input)) return [
|
|
927
1120
|
"compactionItems=0",
|
|
@@ -932,9 +1125,9 @@ function summarizeResponsesCompactionItems(input) {
|
|
|
932
1125
|
const compactions = input.flatMap((item, inputIndex) => {
|
|
933
1126
|
if (!isRecord(item) || item.type !== "compaction") return [];
|
|
934
1127
|
return [{
|
|
935
|
-
idHash: typeof item.id === "string" ?
|
|
1128
|
+
idHash: typeof item.id === "string" ? sha256Hex(item.id) : void 0,
|
|
936
1129
|
inputIndex,
|
|
937
|
-
payloadHash: typeof item.encrypted_content === "string" ?
|
|
1130
|
+
payloadHash: typeof item.encrypted_content === "string" ? sha256Hex(item.encrypted_content) : void 0
|
|
938
1131
|
}];
|
|
939
1132
|
});
|
|
940
1133
|
return [
|
|
@@ -1248,6 +1441,7 @@ async function resolveNextResponsesEncryptedContentAttempt(attempt, error, optio
|
|
|
1248
1441
|
};
|
|
1249
1442
|
}
|
|
1250
1443
|
async function createResponsesStreamWithEncryptedContentRetry(params) {
|
|
1444
|
+
const encodeBody = params.encodeBody ?? prepareModelRequestBody(void 0);
|
|
1251
1445
|
const send = async (initialAttempt) => {
|
|
1252
1446
|
let attempt = initialAttempt;
|
|
1253
1447
|
for (;;) {
|
|
@@ -1255,8 +1449,16 @@ async function createResponsesStreamWithEncryptedContentRetry(params) {
|
|
|
1255
1449
|
egress: "responses-sdk",
|
|
1256
1450
|
payloadVariant: attempt.kind
|
|
1257
1451
|
});
|
|
1452
|
+
const bodyOptions = await encodeBody(attempt.request);
|
|
1258
1453
|
try {
|
|
1259
|
-
const { data, response } = await params.client.responses.create(attempt.request,
|
|
1454
|
+
const { data, response } = await params.client.responses.create(attempt.request, {
|
|
1455
|
+
...params.requestOptions,
|
|
1456
|
+
...bodyOptions,
|
|
1457
|
+
headers: {
|
|
1458
|
+
...bodyOptions.headers,
|
|
1459
|
+
...params.requestOptions?.headers
|
|
1460
|
+
}
|
|
1461
|
+
}).withResponse();
|
|
1260
1462
|
commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => {
|
|
1261
1463
|
if (checkpoint) params.onCompactionRejected?.(checkpoint);
|
|
1262
1464
|
});
|
|
@@ -1443,15 +1645,12 @@ const STRING_DELTA_EVENTS = /* @__PURE__ */ new Set([
|
|
|
1443
1645
|
"response.text.delta"
|
|
1444
1646
|
]);
|
|
1445
1647
|
async function* adaptResponsesStream(stream, signal) {
|
|
1446
|
-
const
|
|
1447
|
-
for await (const event of stream) {
|
|
1448
|
-
if (signal?.aborted) throw transportAbortError(signal);
|
|
1648
|
+
for await (const event of iterateModelStream(stream, signal)) {
|
|
1449
1649
|
if (!isRecord(event) || typeof event.type !== "string") throw new Error("Responses stream delivered a malformed event without a string type");
|
|
1450
1650
|
if (STRING_DELTA_EVENTS.has(event.type) && typeof event.delta !== "string") throw new Error(`Responses stream delivered malformed ${event.type} delta`);
|
|
1451
1651
|
if ((event.type === "response.output_item.added" || event.type === "response.output_item.done") && !isRecord(event.item)) throw new Error(`Responses stream delivered malformed ${event.type} item`);
|
|
1452
1652
|
if ((event.type === "response.created" || event.type === "response.completed" || event.type === "response.incomplete" || event.type === "response.failed") && !isRecord(event.response)) throw new Error(`Responses stream delivered malformed ${event.type} response`);
|
|
1453
1653
|
yield event;
|
|
1454
|
-
await scheduler.afterEvent();
|
|
1455
1654
|
}
|
|
1456
1655
|
}
|
|
1457
1656
|
async function* observeResponsesStream(stream, model, requestStartedAt) {
|
|
@@ -1543,9 +1742,10 @@ function createResponsesOutputTracker(params) {
|
|
|
1543
1742
|
};
|
|
1544
1743
|
}
|
|
1545
1744
|
function appendResponsesPendingTextDelta(slot, delta, materialize) {
|
|
1745
|
+
const offset = slot.pendingText?.length ?? 0;
|
|
1546
1746
|
slot.pendingText = `${slot.pendingText ?? ""}${delta}`;
|
|
1547
1747
|
const priorText = slot.collapseCandidate?.block.text ?? "";
|
|
1548
|
-
if (priorText.
|
|
1748
|
+
if (offset >= priorText.length || priorText.startsWith(delta.slice(0, priorText.length - offset), offset)) return;
|
|
1549
1749
|
materialize(slot);
|
|
1550
1750
|
}
|
|
1551
1751
|
function readResponsesOutputIndex(event) {
|
|
@@ -1849,7 +2049,7 @@ async function processResponsesStream(openaiStream, output, sink, model, options
|
|
|
1849
2049
|
});
|
|
1850
2050
|
const stream = outputs.trackStream(sink);
|
|
1851
2051
|
let terminalResponse;
|
|
1852
|
-
let
|
|
2052
|
+
let rejectedToolCall;
|
|
1853
2053
|
let lastTextBlock = null;
|
|
1854
2054
|
const blocks = output.content;
|
|
1855
2055
|
const compactionTracker = createCompactionTracker(output, model, options);
|
|
@@ -2023,8 +2223,12 @@ async function processResponsesStream(openaiStream, output, sink, model, options
|
|
|
2023
2223
|
for await (const event of guardedStream) {
|
|
2024
2224
|
outputs.observeEvent(event);
|
|
2025
2225
|
notifyLlmRequestActivity(options?.signal);
|
|
2026
|
-
if (event.type === "response.output_item.done" && event.item.type === "function_call" && event.item.status
|
|
2027
|
-
|
|
2226
|
+
if (event.type === "response.output_item.done" && event.item.type === "function_call" && event.item.status && event.item.status !== "completed" && !rejectedToolCall) try {
|
|
2227
|
+
resolveCompletedResponsesToolCall(event.item);
|
|
2228
|
+
} catch (error) {
|
|
2229
|
+
rejectedToolCall = { error };
|
|
2230
|
+
}
|
|
2231
|
+
if (rejectedToolCall && event.type !== "response.completed" && event.type !== "response.incomplete" && event.type !== "response.failed" && event.type !== "error") continue;
|
|
2028
2232
|
if (event.type === "response.created") output.responseId = event.response.id;
|
|
2029
2233
|
else if (event.type === "response.output_item.added") {
|
|
2030
2234
|
materializeDeferredTextSlots();
|
|
@@ -2067,22 +2271,15 @@ async function processResponsesStream(openaiStream, output, sink, model, options
|
|
|
2067
2271
|
if (!slot) continue;
|
|
2068
2272
|
slot.item.summary = slot.item.summary || [];
|
|
2069
2273
|
slot.item.summary.push(event.part);
|
|
2070
|
-
} else if (event.type === "response.reasoning_summary_text.delta") {
|
|
2274
|
+
} else if (event.type === "response.reasoning_summary_text.delta" || event.type === "response.reasoning_summary_part.done") {
|
|
2071
2275
|
const slot = outputSlots.resolve(event, "thinking");
|
|
2072
2276
|
if (!slot) continue;
|
|
2073
2277
|
slot.item.summary = slot.item.summary || [];
|
|
2074
2278
|
const lastPart = slot.item.summary[slot.item.summary.length - 1];
|
|
2075
2279
|
if (!lastPart) continue;
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
const slot = outputSlots.resolve(event, "thinking");
|
|
2080
|
-
if (!slot) continue;
|
|
2081
|
-
slot.item.summary = slot.item.summary || [];
|
|
2082
|
-
const lastPart = slot.item.summary[slot.item.summary.length - 1];
|
|
2083
|
-
if (!lastPart) continue;
|
|
2084
|
-
lastPart.text += "\n\n";
|
|
2085
|
-
appendThinkingDelta(slot, "\n\n");
|
|
2280
|
+
const delta = event.type === "response.reasoning_summary_text.delta" ? event.delta : "\n\n";
|
|
2281
|
+
lastPart.text += delta;
|
|
2282
|
+
appendThinkingDelta(slot, delta);
|
|
2086
2283
|
} else if (event.type === "response.reasoning_text.delta") {
|
|
2087
2284
|
const slot = outputSlots.resolve(event, "thinking");
|
|
2088
2285
|
if (!slot) continue;
|
|
@@ -2255,22 +2452,22 @@ async function processResponsesStream(openaiStream, output, sink, model, options
|
|
|
2255
2452
|
if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
|
|
2256
2453
|
const streamedArguments = streamingToolCall?.block.partialJson || "";
|
|
2257
2454
|
const parsedStreamedArguments = streamingToolCall?.argumentStreamReliable && streamingToolCall?.argumentsStreamed && streamedArguments.length > 0 && completedArguments !== void 0 && streamedArguments !== completedArguments ? parseJsonObjectPreservingUnsafeIntegers(streamedArguments) : null;
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2455
|
+
let validated;
|
|
2456
|
+
try {
|
|
2457
|
+
validated = resolveCompletedResponsesToolCall(item, {
|
|
2458
|
+
name: streamingToolCall?.block.name,
|
|
2459
|
+
arguments: parsedStreamedArguments ?? (completedArguments || streamedArguments)
|
|
2460
|
+
});
|
|
2461
|
+
} catch (error) {
|
|
2462
|
+
rejectedToolCall = { error };
|
|
2463
|
+
continue;
|
|
2464
|
+
}
|
|
2262
2465
|
finalizeToolCall(item, readResponsesOutputIndex(event), streamingToolCall, validated);
|
|
2263
2466
|
}
|
|
2264
2467
|
} else if (event.type === "response.completed" || event.type === "response.incomplete") {
|
|
2265
2468
|
terminal.finalizeResponse(event.response, event.type);
|
|
2266
|
-
if (
|
|
2267
|
-
|
|
2268
|
-
resolveCompletedResponsesToolCall(incompleteToolCall);
|
|
2269
|
-
}
|
|
2270
|
-
if (event.type === "response.incomplete" && streamingToolCalls.hasActive()) {
|
|
2271
|
-
if (output.errorMessage) throw new Error(output.errorMessage);
|
|
2272
|
-
throw new IncompleteToolCallError("Responses stream completed with unresolved tool calls");
|
|
2273
|
-
}
|
|
2469
|
+
if (rejectedToolCall) throw output.errorMessage ? new Error(output.errorMessage) : rejectedToolCall.error;
|
|
2470
|
+
if (event.type === "response.incomplete" && streamingToolCalls.hasActive()) throw output.errorMessage ? new Error(output.errorMessage) : new IncompleteToolCallError("Responses stream completed with unresolved tool calls");
|
|
2274
2471
|
if (event.type === "response.completed" || output.stopReason === "length") {
|
|
2275
2472
|
const items = event.response.output ?? [];
|
|
2276
2473
|
const completeToolCall = event.type === "response.completed" ? prepareTerminalToolCalls(items) : void 0;
|
|
@@ -2294,6 +2491,7 @@ async function processResponsesStream(openaiStream, output, sink, model, options
|
|
|
2294
2491
|
}
|
|
2295
2492
|
}
|
|
2296
2493
|
if (options?.signal?.aborted) throw transportAbortError(options.signal);
|
|
2494
|
+
if (rejectedToolCall) throw rejectedToolCall.error;
|
|
2297
2495
|
if (streamingToolCalls.hasActive()) throw new Error("Responses stream ended with unresolved tool calls");
|
|
2298
2496
|
if (terminalResponse === void 0) throw new Error("OpenAI Responses stream ended before a terminal response event");
|
|
2299
2497
|
return terminalResponse ?? void 0;
|
|
@@ -2355,10 +2553,6 @@ function resolveResponsesStrictToolSetting(options) {
|
|
|
2355
2553
|
}
|
|
2356
2554
|
//#endregion
|
|
2357
2555
|
//#region packages/ai/src/providers/openai-responses-shared.ts
|
|
2358
|
-
function convertResponsesMessages(model, context, allowedToolCallProviders, options) {
|
|
2359
|
-
return convertProviderResponsesMessages(model, context, allowedToolCallProviders, options);
|
|
2360
|
-
}
|
|
2361
|
-
const createResponsesAssistantOutput = createOpenAIResponsesAssistantOutput;
|
|
2362
2556
|
function applyResponsesServiceTierPricing(usage, serviceTier, model) {
|
|
2363
2557
|
let multiplier = 1;
|
|
2364
2558
|
if (serviceTier === "flex") multiplier = .5;
|
|
@@ -2387,13 +2581,6 @@ function applyCommonResponsesParams(params, model, context, options, config) {
|
|
|
2387
2581
|
params.include = ["reasoning.encrypted_content"];
|
|
2388
2582
|
}
|
|
2389
2583
|
}
|
|
2390
|
-
function buildResponsesRequestOptions(options) {
|
|
2391
|
-
return {
|
|
2392
|
-
...options?.signal ? { signal: options.signal } : {},
|
|
2393
|
-
...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
|
|
2394
|
-
maxRetries: 0
|
|
2395
|
-
};
|
|
2396
|
-
}
|
|
2397
2584
|
function cleanStreamingScratchBuffers(output) {
|
|
2398
2585
|
for (const block of output.content) {
|
|
2399
2586
|
delete block.index;
|
|
@@ -2406,6 +2593,7 @@ async function runResponsesStreamLifecycle(params) {
|
|
|
2406
2593
|
try {
|
|
2407
2594
|
const model = params.resolveRequestModel?.(params.model) ?? params.model;
|
|
2408
2595
|
const client = params.createClient(model);
|
|
2596
|
+
const encodeBody = prepareModelRequestBody(options);
|
|
2409
2597
|
const buildRequest = async (replayMode) => {
|
|
2410
2598
|
let request = params.buildParams(model, replayMode);
|
|
2411
2599
|
const nextRequest = await options?.onPayload?.(request, model);
|
|
@@ -2421,10 +2609,12 @@ async function runResponsesStreamLifecycle(params) {
|
|
|
2421
2609
|
client,
|
|
2422
2610
|
request: requestParams,
|
|
2423
2611
|
requestOptions: {
|
|
2424
|
-
|
|
2425
|
-
|
|
2612
|
+
signal: firstEvent.signal,
|
|
2613
|
+
...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
|
|
2614
|
+
maxRetries: 0
|
|
2426
2615
|
},
|
|
2427
2616
|
model,
|
|
2617
|
+
encodeBody,
|
|
2428
2618
|
buildFullHistoryRequest: () => buildRequest("full-history"),
|
|
2429
2619
|
onCompactionRejected: (checkpoint) => suppressOpenAIResponsesCompaction(output, model, options, checkpoint),
|
|
2430
2620
|
canRetryStream: () => output.content.length === 0,
|
|
@@ -2496,4 +2686,4 @@ async function runResponsesStreamLifecycle(params) {
|
|
|
2496
2686
|
}
|
|
2497
2687
|
}
|
|
2498
2688
|
//#endregion
|
|
2499
|
-
export {
|
|
2689
|
+
export { OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE as $, recordResponsesContextUsage as A, resolveResponsesContinuationRequest as B, resolveAzureOpenAIApiVersion as C, safeDebugValue as D, logResponsesFailedNoDetails as E, convertResponsesMessages as F, supportsResponsesReasoningUpdate as G, responsesContinuationRequestFingerprint as H, recordResponsesInputReplay as I, captureOpenAIResponsesCompaction as J, CompactionReplayRefreshRequiredError as K, responsesInputFingerprint as L, bindResponsesInputMessage as M, buildResponsesInputMessage as N, summarizeOpenAITransportError as O, convertProviderResponsesMessages as P, OPENAI_RESPONSES_CALL_ID_RE as Q, claimOpenAIResponsesHttpContinuation as R, isInvalidEncryptedContentError as S, ResponsesStreamFailure as T, isConfigurationUpdate as U, responsesContinuationPrefixFingerprint as V, replayResponsesReasoningUpdates as W, resolveNewestOpenAIResponsesCompactionReplay as X, isOpenAIResponsesReplayContext as Y, suppressOpenAIResponsesCompaction as Z, isResponsesTextContentPartType as _, prepareResponsesTools as a, commitResponsesEncryptedContentAttempt as b, observeResponsesStream as c, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as d, OPENAI_RESPONSES_ID_MAX_LENGTH as et, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as f, isAzureResponsesTextDeltaEventType as g, isAzureResponsesTextDeltaEvent as h, convertResponsesToolPayload as i, resolveReplayableResponsesMessageId as it, resolveResponsesContextUsageBoundary as j, summarizeResponsesPayload as k, createResponsesToolCallTracker as l, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as m, applyResponsesServiceTierPricing as n, shouldNormalizeOpenAIResponsesToolCallId as nt, readOpenAIMisalignmentReview as o, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as p, buildOpenAIResponsesReasoningReplayMetadata as q, runResponsesStreamLifecycle as r, splitOpenAIFunctionCallPairing as rt, processResponsesStream as s, applyCommonResponsesParams as t, normalizeOpenAIResponsesFunctionCallId as tt, readResponsesToolCallItemIdentity as u, isResponsesTextDeltaEventType as v, resolveNextResponsesEncryptedContentAttempt as w, createResponsesStreamWithEncryptedContentRetry as x, resolveResponsesMessageSnapshotCollapse as y, recordResponsesContinuationState as z };
|