@openclaw/ai 2026.9.4 → 2026.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{anthropic-C4Qu4H0Z.mjs → anthropic-DZQ_7gD1.mjs} +37 -38
- package/dist/{anthropic-payload-policy-BZ8umAbk.d.mts → anthropic-payload-policy-DyfwikYJ.d.mts} +4 -4
- package/dist/{anthropic-stream-reducer-CILWF7JD.mjs → anthropic-stream-reducer-D6ZI1wwj.mjs} +70 -50
- package/dist/{api-registry-ByUwIR0e.d.mts → api-registry-C2T3lTV7.d.mts} +2 -2
- package/dist/{assistant-output-tLt4H-iQ.mjs → assistant-output-DM1JBNs1.mjs} +1 -1
- package/dist/{azure-openai-responses-BAlqlKKc.mjs → azure-openai-responses-DS86GYzq.mjs} +6 -9
- package/dist/{base64-D-su8YVo.mjs → base64-CPmadnUf.mjs} +12 -12
- package/dist/credential-redaction-BKv49aiv.d.mts +24 -0
- package/dist/{diagnostics-QuErwCIl.mjs → diagnostics-CH8j2wIG.mjs} +139 -7
- package/dist/{diagnostics-CPeq9F7y.mjs → diagnostics-DzrF1h4J.mjs} +18 -1
- package/dist/diagnostics.d.mts +11 -24
- package/dist/diagnostics.mjs +4 -4
- package/dist/event-stream-C0nsgbj2.d.mts +1 -0
- package/dist/{event-stream-Bt5Y4Pav.d.mts → event-stream-CjnIZZst.d.mts} +1 -1
- package/dist/event-stream.d.mts +2 -2
- package/dist/expect-lbe3Hgrh.mjs +8 -0
- package/dist/{google-DPBAOaOW.mjs → google-BZJFjhuC.mjs} +6 -9
- package/dist/{google-messages-6JkpHrhJ.mjs → google-messages-DB7GKkDk.mjs} +3 -3
- package/dist/{google-shared-BvBeW9aq.mjs → google-shared-Bok4I6zB.mjs} +13 -13
- package/dist/{google-vertex-k-TMCAYD.mjs → google-vertex-3eVNR2qW.mjs} +5 -8
- package/dist/{host-4atIX-2V.d.mts → host-DH-Z-LDb.d.mts} +5 -3
- package/dist/{host-policy-Zcg_cNz8.mjs → host-policy-DZO3oPPk.mjs} +1 -1
- package/dist/{host-B8YfDGd4.mjs → host-yTvBrYM2.mjs} +63 -31
- package/dist/{index-DdD3qerf.d.mts → index-C25RT6bP.d.mts} +37 -14
- package/dist/index.d.mts +7 -8
- package/dist/index.mjs +5 -6
- package/dist/internal/anthropic.d.mts +13 -10
- package/dist/internal/anthropic.mjs +5 -5
- package/dist/internal/openai-completions-compat.d.mts +2 -0
- package/dist/internal/openai-completions-compat.mjs +2 -0
- package/dist/internal/openai-responses-payload-policy.d.mts +2 -2
- package/dist/internal/openai-responses-payload-policy.mjs +2 -2
- package/dist/internal/openai.d.mts +24 -53
- package/dist/internal/openai.mjs +12 -9
- package/dist/internal/runtime.d.mts +6 -8
- package/dist/internal/runtime.mjs +6 -10
- package/dist/internal/shared.d.mts +7 -5
- package/dist/internal/shared.mjs +4 -3
- package/dist/internal/tool-schema.d.mts +4 -4
- package/dist/internal/tool-schema.mjs +2 -2
- package/dist/{mistral-CxUZ1jUb.mjs → mistral-C_13dVBn.mjs} +9 -13
- package/dist/{model-transport-url-DKocrEsb.d.mts → model-transport-url-C5f59L3Y.d.mts} +1 -1
- package/dist/{openai-chatgpt-responses-CgO6kZfo.mjs → openai-chatgpt-responses-sTxPl4zM.mjs} +150 -83
- package/dist/{openai-completions-yJuk7eis.mjs → openai-completions-BO6D_hrB.mjs} +11 -12
- package/dist/{openai-prompt-cache-Bds-n_9Q.mjs → openai-completions-compat-CUollwl6.mjs} +5 -50
- package/dist/{openai-completions-compat-eHgh5UPE.d.mts → openai-completions-compat-DfJG1wSO.d.mts} +4 -4
- package/dist/{openai-completions-stream-Da2vvl-S.mjs → openai-completions-stream-BpuJ0ZOA.mjs} +117 -106
- package/dist/{openai-prompt-cache-B4eYo2-I.d.mts → openai-prompt-cache-C4RHdN4n.d.mts} +2 -2
- package/dist/openai-prompt-cache-CjV_2IRI.mjs +46 -0
- package/dist/{openai-provider-client-S2gCrM2Z.mjs → openai-provider-client-BP8J1aeg.mjs} +2 -2
- package/dist/openai-reasoning-effort-ash8dPrd.mjs +243 -0
- package/dist/{openai-responses-DaYwH05E.mjs → openai-responses-BJ_IEoMU.mjs} +8 -12
- package/dist/{openai-responses-compaction-window-CIhBAkkq.mjs → openai-responses-compaction-window-BiNCT0bS.mjs} +20 -62
- package/dist/{openai-responses-contracts-BjBAqAg_.d.mts → openai-responses-contracts-B1ENJFpI.d.mts} +9 -5
- package/dist/openai-responses-contracts-DWrfMODE.mjs +81 -0
- package/dist/{openai-responses-payload-policy-rLRPsSmB.d.mts → openai-responses-payload-policy-C7GsA1y0.d.mts} +5 -3
- package/dist/openai-responses-prompt-observer-internal-DPHWgbBH.mjs +198 -0
- package/dist/openai-responses-request-lifecycle-DFuyO1pQ.mjs +36 -0
- package/dist/{openai-responses-shared-B8RdBPCv.mjs → openai-responses-shared-DvSqtJ6_.mjs} +859 -581
- package/dist/openai-responses-terminal-usage-BNFbvY9f.d.mts +47 -0
- package/dist/{openai-tool-schema-CzjyYXun.mjs → openai-tool-schema-D4BMcj2D.mjs} +262 -162
- package/dist/{openai-transport-params-9aPuV5YY.mjs → openai-transport-params-DZKOTSfH.mjs} +157 -47
- package/dist/{positive-integer-41zhOdcV.mjs → positive-integer-BiUxrd71.mjs} +1 -1
- package/dist/{provider-error-BA-v_tKd.mjs → provider-error-CRhW7lkJ.mjs} +139 -44
- package/dist/{provider-error-CzNw4BWX.d.mts → provider-error-xumb1V3F.d.mts} +3 -1
- package/dist/{provider-options-Ceqv1OKk.d.mts → provider-options-DZYq53lj.d.mts} +12 -7
- package/dist/{provider-replay-context-CJ_YvcEW.mjs → provider-replay-context-DPr3w20a.mjs} +1 -1
- package/dist/{provider-transcript-transform-V5YzU9zh.mjs → provider-transcript-transform-BTocjCRs.mjs} +1 -1
- package/dist/{provider-transport-turn-state-D5EXOFL2.mjs → provider-transport-turn-state-lrXEFkYr.mjs} +1 -1
- package/dist/{provider-types-CVjKjsuq.d.mts → provider-types-w1rEqrGP.d.mts} +3 -3
- package/dist/provider-types.d.mts +6 -7
- package/dist/providers.d.mts +2 -2
- package/dist/providers.mjs +10 -10
- package/dist/{reasoning-tag-text-partitioner-BcR5pztD.mjs → reasoning-tag-text-partitioner-Di38crhI.mjs} +167 -40
- package/dist/{simple-options-BQbb4yQL.mjs → simple-options-np1XPuhm.mjs} +5 -3
- package/dist/{usage-cost-BNWbbXav.mjs → src-DwGYYyZp.mjs} +18 -11
- package/dist/{stream-first-event-timeout-2hfrquuz.mjs → stream-first-event-timeout-BeptfRL6.mjs} +1 -1
- package/dist/{string-normalization-CmLIasuf.mjs → string-normalization-J9ZiLfGO.mjs} +13 -1
- package/dist/tool-schema-json-projection-CD9c_fK8.mjs +134 -0
- package/dist/{transport-stream-shared-zHll9BxO.mjs → transport-stream-shared-B5RioB_Q.mjs} +16 -24
- package/dist/{transport-stream-shared-DNvmoWnv.d.mts → transport-stream-shared-B7Z9oCYg.d.mts} +5 -5
- package/dist/{transport-utils-zrYjICLZ.mjs → transport-utils-03Qi0CN2.mjs} +3 -3
- package/dist/transports.d.mts +27 -13
- package/dist/transports.mjs +168 -462
- package/dist/types-DTvddOfm.d.mts +1 -0
- package/dist/{types-Ntv5z2g2.d.mts → types-qZFbaDbK.d.mts} +49 -3
- package/dist/types.d.mts +6 -7
- package/dist/types.mjs +4 -5
- package/dist/{validation-B0t_G2H6.d.mts → validation-DhQhmt6t.d.mts} +1 -1
- package/dist/{validation-BDzVDnTs.mjs → validation-Dw7cb6BV.mjs} +1 -0
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/package.json +11 -6
- package/dist/diagnostics-DnPnOui6.d.mts +0 -29
- package/dist/event-stream-C3WGFsum.d.mts +0 -1
- package/dist/openai-responses-contracts-DDOHA62Y.mjs +0 -245
- package/dist/openai-responses-prompt-observer-internal-f8J7wpsk.mjs +0 -32
- package/dist/src-DDmEryvj.mjs +0 -2
- package/dist/tool-schema-json-projection-ClptDdAO.mjs +0 -82
- package/dist/types-DlfwzH3T.d.mts +0 -1
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { a as normalizeOptionalString, n as normalizeLowercaseStringOrEmpty } from "./string-coerce-fsri9iCu.mjs";
|
|
2
|
-
import { A as applyProviderReportedUsageCost, j as calculateCost, n as getAiTransportHost } from "./host-B8YfDGd4.mjs";
|
|
3
2
|
import { o as isRecord, r as asOptionalObjectRecord } from "./record-coerce-DwRYMj3t.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { n as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { a as normalizeOpenAIReasoningEffort, c as resolveOpenAIReasoningEffortMapping, f as MODEL_CATALOG_THINKING_LEVELS, m as resolveOpenAIThinkingApi, o as resolveOpenAIModelReasoningEfforts, s as resolveOpenAIReasoningEffortForModel, u as supportsOpenAIReasoningEffort } from "./openai-reasoning-effort-ash8dPrd.mjs";
|
|
4
|
+
import { A as headersToRecord, M as calculateCost, N as clampThinkingLevel, j as applyProviderReportedUsageCost, n as getAiTransportHost } from "./host-yTvBrYM2.mjs";
|
|
5
|
+
import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-CjV_2IRI.mjs";
|
|
6
|
+
import { i as isCodeModeModelVisibleToolName } from "./transport-utils-03Qi0CN2.mjs";
|
|
7
|
+
import { i as resolveOpenAICompletionsCompat, o as usesNativeOpenAICodexResponsesBackend } from "./openai-completions-compat-CUollwl6.mjs";
|
|
8
|
+
import { n as resolveModelRequestTimeoutMs, o as resolveProviderRequestPolicyConfig } from "./host-policy-DZO3oPPk.mjs";
|
|
9
|
+
import { n as projectRuntimeToolInputSchema, t as prepareRuntimeToolInputSchema } from "./tool-schema-json-projection-CD9c_fK8.mjs";
|
|
10
|
+
import { p as notifyProviderHttpResponse, v as transportAbortError } from "./transport-stream-shared-B5RioB_Q.mjs";
|
|
9
11
|
import { n as resolveOpencodeSessionHeaders } from "./session-affinity-Bcunsn4I.mjs";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
12
|
+
import { a as resolveOpenAIProjectedToolsStrictToolFlag, t as findOpenAIStrictToolProjectionDiagnostics } from "./openai-tool-schema-D4BMcj2D.mjs";
|
|
13
|
+
import { i as OPENAI_RESPONSES_APIS } from "./openai-responses-contracts-DWrfMODE.mjs";
|
|
14
|
+
import { hash } from "node:crypto";
|
|
13
15
|
//#region packages/normalization-core/src/node-crypto.ts
|
|
14
16
|
function sha256Hex(input) {
|
|
15
|
-
return
|
|
17
|
+
return hash("sha256", input, "hex");
|
|
16
18
|
}
|
|
17
19
|
function sha256HexPrefixCore(input, length) {
|
|
18
20
|
return sha256Hex(input).slice(0, length);
|
|
@@ -29,6 +31,16 @@ function redactIdentifier(value, opts) {
|
|
|
29
31
|
/** Shared options, usage shape, cache identity, ordering, and stream scheduling for OpenAI APIs. */
|
|
30
32
|
const MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS = 12;
|
|
31
33
|
const MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS = 64;
|
|
34
|
+
const OPENAI_RESPONSE_MODEL_HEADER_NAMES = /* @__PURE__ */ new Set(["openai-model", "x-openai-model"]);
|
|
35
|
+
const OPENAI_RESPONSE_MODEL_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
36
|
+
"response.created",
|
|
37
|
+
"response.in_progress",
|
|
38
|
+
"response.completed",
|
|
39
|
+
"response.done",
|
|
40
|
+
"response.incomplete",
|
|
41
|
+
"response.failed"
|
|
42
|
+
]);
|
|
43
|
+
const OPENAI_DATED_MODEL_SUFFIX = /-(?:\d{8}|\d{4}-\d{2}-\d{2})$/;
|
|
32
44
|
const GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP = "skip_thought_signature_validator";
|
|
33
45
|
const log = {
|
|
34
46
|
debug(message, data) {
|
|
@@ -44,6 +56,69 @@ const log = {
|
|
|
44
56
|
getAiTransportHost().logWarn("openai-transport", message, data);
|
|
45
57
|
}
|
|
46
58
|
};
|
|
59
|
+
const OPENAI_RESPONSE_MODEL_CONFLICT = "Conflicting OpenAI response model attestations";
|
|
60
|
+
function splitOpenAIResponseModelHeader(value) {
|
|
61
|
+
return value ? value.split(",").map((part) => part.trim()).filter(Boolean) : [];
|
|
62
|
+
}
|
|
63
|
+
function readOpenAIResponseModelHeaders(headers) {
|
|
64
|
+
return [...OPENAI_RESPONSE_MODEL_HEADER_NAMES].flatMap((name) => splitOpenAIResponseModelHeader(headers.get(name)));
|
|
65
|
+
}
|
|
66
|
+
function readOpenAIResponseModelHeaderRecord(headers) {
|
|
67
|
+
if (!isRecord(headers)) return [];
|
|
68
|
+
return Object.entries(headers).filter(([name]) => OPENAI_RESPONSE_MODEL_HEADER_NAMES.has(name.toLowerCase())).flatMap(([, value]) => typeof value === "string" ? splitOpenAIResponseModelHeader(value) : []);
|
|
69
|
+
}
|
|
70
|
+
function readOpenAIResponseModelEvent(event) {
|
|
71
|
+
if (!isRecord(event)) return [];
|
|
72
|
+
const response = isRecord(event.response) ? event.response : void 0;
|
|
73
|
+
return [
|
|
74
|
+
...OPENAI_RESPONSE_MODEL_EVENT_TYPES.has(String(event.type)) && typeof response?.model === "string" && response.model.trim() ? [response.model.trim()] : [],
|
|
75
|
+
...readOpenAIResponseModelHeaderRecord(response?.headers),
|
|
76
|
+
...readOpenAIResponseModelHeaderRecord(event.headers)
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
function reconcileOpenAIResponseModels(current, observed) {
|
|
80
|
+
if (!current || current === observed) return observed;
|
|
81
|
+
const currentBase = current.replace(OPENAI_DATED_MODEL_SUFFIX, "");
|
|
82
|
+
const observedBase = observed.replace(OPENAI_DATED_MODEL_SUFFIX, "");
|
|
83
|
+
if (currentBase !== observedBase) return;
|
|
84
|
+
if (currentBase === current && observedBase !== observed) return observed;
|
|
85
|
+
if (observedBase === observed && currentBase !== current) return current;
|
|
86
|
+
}
|
|
87
|
+
function createResponseModelTracker(enabled = true) {
|
|
88
|
+
let responseModel;
|
|
89
|
+
const observe = (models) => {
|
|
90
|
+
for (const model of models) {
|
|
91
|
+
const reconciled = reconcileOpenAIResponseModels(responseModel, model);
|
|
92
|
+
if (!reconciled) throw new Error(OPENAI_RESPONSE_MODEL_CONFLICT);
|
|
93
|
+
responseModel = reconciled;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const begin = (headers) => {
|
|
97
|
+
responseModel = void 0;
|
|
98
|
+
if (enabled && headers) observe(readOpenAIResponseModelHeaders(headers));
|
|
99
|
+
};
|
|
100
|
+
const observeEvent = (event) => {
|
|
101
|
+
if (enabled) observe(readOpenAIResponseModelEvent(event));
|
|
102
|
+
return responseModel;
|
|
103
|
+
};
|
|
104
|
+
const resolve = () => responseModel;
|
|
105
|
+
return {
|
|
106
|
+
begin,
|
|
107
|
+
observeEvent,
|
|
108
|
+
resolve,
|
|
109
|
+
track(response, stream) {
|
|
110
|
+
if (!enabled) return stream;
|
|
111
|
+
return (async function* () {
|
|
112
|
+
begin(response?.headers);
|
|
113
|
+
for await (const event of stream) {
|
|
114
|
+
observeEvent(event);
|
|
115
|
+
yield event;
|
|
116
|
+
}
|
|
117
|
+
})();
|
|
118
|
+
},
|
|
119
|
+
terminalOptions: enabled ? { resolveResponseModel: resolve } : {}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
47
122
|
function resolveOpenAIClientBaseUrl(model, baseUrl = model.baseUrl) {
|
|
48
123
|
if (baseUrl?.trim()) return baseUrl;
|
|
49
124
|
if (model.provider.trim().toLowerCase() === "openai") return;
|
|
@@ -192,14 +267,13 @@ function createModelStreamCooperativeScheduler(signal) {
|
|
|
192
267
|
return { async afterEvent() {
|
|
193
268
|
throwIfModelStreamAborted(signal);
|
|
194
269
|
eventsSinceYield += 1;
|
|
195
|
-
|
|
196
|
-
if (eventsSinceYield < MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS && now - lastYieldedAt < MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS) return;
|
|
270
|
+
if (eventsSinceYield < MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS && Date.now() - lastYieldedAt < MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS) return;
|
|
197
271
|
eventsSinceYield = 0;
|
|
198
|
-
lastYieldedAt = now;
|
|
199
272
|
await new Promise((resolve) => {
|
|
200
273
|
setTimeout(resolve, 0);
|
|
201
274
|
});
|
|
202
275
|
throwIfModelStreamAborted(signal);
|
|
276
|
+
lastYieldedAt = Date.now();
|
|
203
277
|
} };
|
|
204
278
|
}
|
|
205
279
|
function resolvePromptCacheKey(options, cacheRetention) {
|
|
@@ -262,6 +336,45 @@ function readOpenAICompletionsContentPartDeltas(content) {
|
|
|
262
336
|
return [];
|
|
263
337
|
}
|
|
264
338
|
//#endregion
|
|
339
|
+
//#region packages/ai/src/transports/openai-reasoning-compat.ts
|
|
340
|
+
/** Explicit model reasoning-effort compatibility metadata. */
|
|
341
|
+
function readCompatReasoningEffortMap(compat) {
|
|
342
|
+
const rawMap = asOptionalObjectRecord(asOptionalObjectRecord(compat)?.reasoningEffortMap);
|
|
343
|
+
if (!rawMap) return {};
|
|
344
|
+
return Object.fromEntries(Object.entries(rawMap).filter((entry) => typeof entry[1] === "string"));
|
|
345
|
+
}
|
|
346
|
+
/** Resolves the reasoning effort remap for an OpenAI-compatible model. */
|
|
347
|
+
function resolveOpenAIReasoningEffortMap(model, fallbackMap = {}) {
|
|
348
|
+
return {
|
|
349
|
+
...fallbackMap,
|
|
350
|
+
...readCompatReasoningEffortMap(model.compat)
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
//#endregion
|
|
354
|
+
//#region packages/ai/src/providers/openai-request-reasoning.ts
|
|
355
|
+
/** Preserve explicit off until the selected route maps it to its native value. */
|
|
356
|
+
function resolveOpenAISimpleReasoningEffort(model, reasoning) {
|
|
357
|
+
return reasoning === void 0 ? void 0 : clampThinkingLevel(model, reasoning);
|
|
358
|
+
}
|
|
359
|
+
function resolveOpenAIRequestReasoning(model, reasoning) {
|
|
360
|
+
const requested = normalizeOpenAIReasoningEffort(reasoning ?? "off");
|
|
361
|
+
const modelLevel = MODEL_CATALOG_THINKING_LEVELS.find((candidate) => candidate === requested);
|
|
362
|
+
const modelMapped = modelLevel ? model.thinkingLevelMap?.[modelLevel] : void 0;
|
|
363
|
+
const mapped = modelMapped === null ? null : resolveOpenAIReasoningEffortMapping(requested, resolveOpenAIReasoningEffortMap(model)) ?? modelMapped;
|
|
364
|
+
const intent = mapped !== void 0 ? mapped?.trim() : reasoning === void 0 ? void 0 : requested;
|
|
365
|
+
const normalizedIntent = normalizeOpenAIReasoningEffort(intent ?? "off");
|
|
366
|
+
const supported = resolveOpenAIModelReasoningEfforts(model);
|
|
367
|
+
const effort = !model.reasoning || supported?.length === 0 || intent === void 0 ? void 0 : supported === void 0 ? mapped !== void 0 ? intent : requested === "off" ? "none" : requested : resolveOpenAIReasoningEffortForModel({
|
|
368
|
+
model,
|
|
369
|
+
effort: requested,
|
|
370
|
+
fallbackMap: { [requested]: intent }
|
|
371
|
+
});
|
|
372
|
+
return {
|
|
373
|
+
effort: effort === "none" && resolveOpenAIThinkingApi(model.api) === "openai-chatgpt-responses" && !supportsOpenAIReasoningEffort(model.id === "gpt-6-sol" || model.id === "gpt-6-luna" ? model : { compat: model.compat }, "none") ? void 0 : effort,
|
|
374
|
+
thinkingEnabled: intent === void 0 ? void 0 : model.reasoning && normalizedIntent !== "off" && normalizedIntent !== "none"
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
//#endregion
|
|
265
378
|
//#region packages/ai/src/providers/openai-tool-projection.ts
|
|
266
379
|
function unreadableToolDiagnostic(toolIndex) {
|
|
267
380
|
return {
|
|
@@ -271,6 +384,17 @@ function unreadableToolDiagnostic(toolIndex) {
|
|
|
271
384
|
}
|
|
272
385
|
/** Snapshots direct/custom tool descriptors before OpenAI payload construction. */
|
|
273
386
|
function projectOpenAITools(tools) {
|
|
387
|
+
return projectOpenAIToolDescriptors(tools);
|
|
388
|
+
}
|
|
389
|
+
/** Package-private facts are consumed before the projection or payload can escape. */
|
|
390
|
+
function prepareOpenAITools(tools) {
|
|
391
|
+
const schemas = /* @__PURE__ */ new Map();
|
|
392
|
+
return {
|
|
393
|
+
projection: projectOpenAIToolDescriptors(tools, schemas),
|
|
394
|
+
schemas
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
function projectOpenAIToolDescriptors(tools, schemas) {
|
|
274
398
|
let inputToolCount;
|
|
275
399
|
try {
|
|
276
400
|
inputToolCount = tools.length;
|
|
@@ -324,7 +448,8 @@ function projectOpenAITools(tools) {
|
|
|
324
448
|
});
|
|
325
449
|
continue;
|
|
326
450
|
}
|
|
327
|
-
const
|
|
451
|
+
const prepared = schemas ? prepareRuntimeToolInputSchema(parameters ?? {}, `${name}.parameters`) : void 0;
|
|
452
|
+
const schemaProjection = prepared?.projection ?? projectRuntimeToolInputSchema(parameters ?? {}, `${name}.parameters`);
|
|
328
453
|
if (!isRecord(schemaProjection.schema) || schemaProjection.violations.length > 0) {
|
|
329
454
|
diagnostics.push({
|
|
330
455
|
toolIndex,
|
|
@@ -333,6 +458,7 @@ function projectOpenAITools(tools) {
|
|
|
333
458
|
});
|
|
334
459
|
continue;
|
|
335
460
|
}
|
|
461
|
+
if (prepared?.normalization) schemas?.set(schemaProjection.schema, prepared.normalization);
|
|
336
462
|
let descriptionValue;
|
|
337
463
|
try {
|
|
338
464
|
descriptionValue = tool.description;
|
|
@@ -448,36 +574,10 @@ function reconcileOpenAICompletionsToolChoice(choice, projection) {
|
|
|
448
574
|
};
|
|
449
575
|
}
|
|
450
576
|
//#endregion
|
|
451
|
-
//#region packages/ai/src/transports/openai-reasoning-compat.ts
|
|
452
|
-
/**
|
|
453
|
-
* OpenAI reasoning-effort compatibility helpers.
|
|
454
|
-
*
|
|
455
|
-
* Keeps provider metadata and built-in model exceptions on one path before request payloads are built.
|
|
456
|
-
*/
|
|
457
|
-
const OPENAI_MEDIUM_ONLY_REASONING_MODEL_IDS = /* @__PURE__ */ new Set(["gpt-5.1-codex-mini"]);
|
|
458
|
-
function readCompatReasoningEffortMap(compat) {
|
|
459
|
-
const rawMap = asOptionalObjectRecord(asOptionalObjectRecord(compat)?.reasoningEffortMap);
|
|
460
|
-
if (!rawMap) return {};
|
|
461
|
-
return Object.fromEntries(Object.entries(rawMap).filter((entry) => typeof entry[0] === "string" && typeof entry[1] === "string"));
|
|
462
|
-
}
|
|
463
|
-
/** Resolves the reasoning effort remap for an OpenAI-compatible model. */
|
|
464
|
-
function resolveOpenAIReasoningEffortMap(model, fallbackMap = {}) {
|
|
465
|
-
const provider = normalizeLowercaseStringOrEmpty(model.provider ?? "");
|
|
466
|
-
const id = normalizeLowercaseStringOrEmpty(model.id ?? "");
|
|
467
|
-
const builtinMap = provider === "openai" && OPENAI_MEDIUM_ONLY_REASONING_MODEL_IDS.has(id) ? {
|
|
468
|
-
minimal: "medium",
|
|
469
|
-
low: "medium"
|
|
470
|
-
} : {};
|
|
471
|
-
return {
|
|
472
|
-
...fallbackMap,
|
|
473
|
-
...builtinMap,
|
|
474
|
-
...readCompatReasoningEffortMap(model.compat)
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
//#endregion
|
|
478
577
|
//#region packages/ai/src/transports/openai-transport-params.ts
|
|
479
578
|
const MAX_OPENAI_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS = 256;
|
|
480
579
|
const loggedOpenAIStrictToolDowngradeDiagnosticKeys = /* @__PURE__ */ new Set();
|
|
580
|
+
const OPENAI_COMPLETIONS_APIS = /* @__PURE__ */ new Set(["openai-completions", "openclaw-openai-completions-transport"]);
|
|
481
581
|
function readToolPayloadField(record, field) {
|
|
482
582
|
try {
|
|
483
583
|
return Object.hasOwn(record, field) ? record[field] : void 0;
|
|
@@ -616,6 +716,19 @@ function resolveOpenAIStrictToolFlagWithDiagnostics(projection, strictSetting, c
|
|
|
616
716
|
function buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders, sessionId, cacheRetention) {
|
|
617
717
|
const providerHeaders = { ...model.headers };
|
|
618
718
|
if (model.provider === "github-copilot") Object.assign(providerHeaders, getAiTransportHost().buildCopilotDynamicHeaders(context.messages));
|
|
719
|
+
if (OPENAI_COMPLETIONS_APIS.has(model.api) && sessionId && cacheRetention !== "none") {
|
|
720
|
+
const { sessionAffinity } = resolveOpenAICompletionsCompat(model);
|
|
721
|
+
if (sessionAffinity !== "none") {
|
|
722
|
+
const affinityValue = clampOpenAIPromptCacheKey(sessionId) ?? sessionId;
|
|
723
|
+
const affinityHeaders = sessionAffinity === "openrouter" ? ["x-session-id"] : [
|
|
724
|
+
"session_id",
|
|
725
|
+
"x-client-request-id",
|
|
726
|
+
"x-session-affinity"
|
|
727
|
+
];
|
|
728
|
+
const configuredHeaders = new Set(Object.keys(providerHeaders).map((key) => key.toLowerCase()));
|
|
729
|
+
for (const name of affinityHeaders) if (!configuredHeaders.has(name)) providerHeaders[name] = affinityValue;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
619
732
|
const callerHeaders = {
|
|
620
733
|
...optionHeaders,
|
|
621
734
|
...turnHeaders
|
|
@@ -637,18 +750,15 @@ function buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders, se
|
|
|
637
750
|
headers: resolvedHeaders
|
|
638
751
|
}) ?? resolvedHeaders;
|
|
639
752
|
}
|
|
640
|
-
function resolveOpenAISdkTimeoutMs(model, timeoutMs) {
|
|
641
|
-
return resolveModelRequestTimeoutMs(model, timeoutMs);
|
|
642
|
-
}
|
|
643
753
|
function buildOpenAISdkClientOptions(model) {
|
|
644
|
-
const timeout =
|
|
754
|
+
const timeout = resolveModelRequestTimeoutMs(model);
|
|
645
755
|
return {
|
|
646
756
|
...timeout === void 0 ? {} : { timeout },
|
|
647
757
|
maxRetries: 0
|
|
648
758
|
};
|
|
649
759
|
}
|
|
650
760
|
function buildOpenAISdkRequestOptions(model, signal, options) {
|
|
651
|
-
const timeout =
|
|
761
|
+
const timeout = resolveModelRequestTimeoutMs(model, options?.timeoutMs);
|
|
652
762
|
const headers = options?.stream === true && usesNativeOpenAICodexResponsesBackend(model) ? { Accept: "text/event-stream" } : void 0;
|
|
653
763
|
if (timeout === void 0 && !signal && !headers) return;
|
|
654
764
|
return {
|
|
@@ -672,4 +782,4 @@ function getCompat(model) {
|
|
|
672
782
|
};
|
|
673
783
|
}
|
|
674
784
|
//#endregion
|
|
675
|
-
export {
|
|
785
|
+
export { resolvePromptCacheKey as A, isOpenAICompletionsThinkingEnabled as C, readOpenAICompletionsContentDeltas as D, parseOpenAICompletionsUsage as E, redactIdentifier as M, sha256Hex as N, readOpenAICompletionsReasoningBatch as O, createResponseModelTracker as S, measureUtf8AppendBytes as T, resolveOpenAIReasoningEffortMap as _, enforceCodeModeResponsesToolSurface as a, createOpenAIProviderAcceptanceHook as b, readCodeModePayloadToolName as c, prepareOpenAITools as d, projectOpenAITools as f, resolveOpenAISimpleReasoningEffort as g, resolveOpenAIRequestReasoning as h, buildOpenAISdkRequestOptions as i, throwIfModelStreamAborted as j, resolveOpenAIClientBaseUrl as k, resolveCodeModeResponsesVisibleToolNames as l, reconcileOpenAIResponsesToolChoice as m, buildOpenAIClientHeaders as n, filterCodeModePayloadTools as o, reconcileOpenAICompletionsToolChoice as p, buildOpenAISdkClientOptions as r, getCompat as s, assertCodeModeResponsesToolSurface as t, resolveOpenAIStrictToolFlagWithDiagnostics as u, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as v, log as w, createOpenAIResponseHook as x, createModelStreamCooperativeScheduler as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as parseStrictPositiveInteger } from "./base64-
|
|
1
|
+
import { o as parseStrictPositiveInteger } from "./base64-CPmadnUf.mjs";
|
|
2
2
|
//#region packages/ai/src/transports/positive-integer.ts
|
|
3
3
|
function parsePositiveInteger(value) {
|
|
4
4
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return Math.floor(value);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { o as normalizeStringifiedOptionalString } from "./string-coerce-fsri9iCu.mjs";
|
|
2
2
|
import { i as asOptionalRecord } from "./record-coerce-DwRYMj3t.mjs";
|
|
3
3
|
import { t as truncateUtf16Safe } from "./utf16-slice-CvGodqok.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { t as expectDefined } from "./expect-lbe3Hgrh.mjs";
|
|
5
|
+
import { n as estimateBase64DecodedBytes } from "./base64-CPmadnUf.mjs";
|
|
5
6
|
import { parseRetryAfterErrorSeconds, parseRetryAfterHeadersSeconds } from "./internal/retry-after.mjs";
|
|
6
7
|
//#region packages/normalization-core/src/balanced-json.ts
|
|
7
8
|
function isJsonOpeningDelimiter(char, openers) {
|
|
@@ -47,12 +48,54 @@ function extractBalancedJsonFragments(raw, opts = {}) {
|
|
|
47
48
|
return fragments;
|
|
48
49
|
}
|
|
49
50
|
//#endregion
|
|
50
|
-
//#region packages/normalization-core/src/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
//#region packages/normalization-core/src/cjk-chars.ts
|
|
52
|
+
const WEIGHTED_CJK_RANGES = [
|
|
53
|
+
[
|
|
54
|
+
[183, 183],
|
|
55
|
+
[12288, 12703],
|
|
56
|
+
[19968, 40869],
|
|
57
|
+
[44032, 55215],
|
|
58
|
+
[65281, 65376]
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
[4352, 4607],
|
|
62
|
+
[11904, 12287],
|
|
63
|
+
[12704, 19967],
|
|
64
|
+
[40870, 40959],
|
|
65
|
+
[40960, 42239],
|
|
66
|
+
[42752, 42759],
|
|
67
|
+
[43360, 43391],
|
|
68
|
+
[55216, 55295],
|
|
69
|
+
[63744, 64255]
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
[711, 711],
|
|
73
|
+
[713, 715],
|
|
74
|
+
[729, 729],
|
|
75
|
+
[746, 747],
|
|
76
|
+
[773, 773],
|
|
77
|
+
[803, 803],
|
|
78
|
+
[65040, 65103],
|
|
79
|
+
[65377, 65500],
|
|
80
|
+
[65504, 65510]
|
|
81
|
+
],
|
|
82
|
+
[[119648, 119665]],
|
|
83
|
+
[
|
|
84
|
+
[94176, 94207],
|
|
85
|
+
[110576, 110591],
|
|
86
|
+
[110592, 110959],
|
|
87
|
+
[127488, 127743],
|
|
88
|
+
[131072, 195103],
|
|
89
|
+
[196608, 210047]
|
|
90
|
+
]
|
|
91
|
+
];
|
|
92
|
+
new RegExp(`[${WEIGHTED_CJK_RANGES.flatMap((ranges) => ranges.map(([start, end]) => `\\u{${start.toString(16)}}-\\u{${end.toString(16)}}`)).join("")}]`, "u");
|
|
93
|
+
(() => {
|
|
94
|
+
const maxCodePoint = Math.max(...WEIGHTED_CJK_RANGES.flatMap((ranges) => ranges.map(([, end]) => end)));
|
|
95
|
+
const categories = new Uint8Array(maxCodePoint + 1);
|
|
96
|
+
for (const [bucket, ranges] of WEIGHTED_CJK_RANGES.entries()) for (const [start, end] of ranges) categories.fill(bucket + 1, start, end + 1);
|
|
97
|
+
return categories;
|
|
98
|
+
})();
|
|
56
99
|
//#endregion
|
|
57
100
|
//#region packages/normalization-core/src/stable-stringify.ts
|
|
58
101
|
const preserveString = (value) => value;
|
|
@@ -60,7 +103,7 @@ const preserveString = (value) => value;
|
|
|
60
103
|
function stableStringify(value, normalizeString = preserveString) {
|
|
61
104
|
return stringifyStableValue(value, /* @__PURE__ */ new WeakSet(), normalizeString);
|
|
62
105
|
}
|
|
63
|
-
function stringifyStableValue(value, stack, normalizeString) {
|
|
106
|
+
function stringifyStableValue(value, stack, normalizeString, write) {
|
|
64
107
|
if (value === null || value === void 0) return String(value);
|
|
65
108
|
if (typeof value === "number" && !Number.isFinite(value)) return JSON.stringify(String(value));
|
|
66
109
|
if (typeof value === "bigint") return JSON.stringify(value.toString());
|
|
@@ -69,39 +112,73 @@ function stringifyStableValue(value, stack, normalizeString) {
|
|
|
69
112
|
if (stack.has(value)) return JSON.stringify("[Circular]");
|
|
70
113
|
stack.add(value);
|
|
71
114
|
try {
|
|
72
|
-
return stringifyObjectValue(value, stack, normalizeString);
|
|
115
|
+
return stringifyObjectValue(value, stack, normalizeString, write);
|
|
73
116
|
} finally {
|
|
74
117
|
stack.delete(value);
|
|
75
118
|
}
|
|
76
119
|
}
|
|
77
|
-
function stringifyObjectValue(value, stack, normalizeString) {
|
|
120
|
+
function stringifyObjectValue(value, stack, normalizeString, write) {
|
|
78
121
|
if (value instanceof Error) return stringifyStableValue({
|
|
79
122
|
name: value.name,
|
|
80
123
|
message: value.message,
|
|
81
124
|
stack: value.stack
|
|
82
|
-
}, stack, normalizeString);
|
|
125
|
+
}, stack, normalizeString, write);
|
|
83
126
|
if (value instanceof Uint8Array) return stringifyStableValue({
|
|
84
127
|
type: "Uint8Array",
|
|
85
128
|
data: encodeBase64(value)
|
|
86
|
-
}, stack, normalizeString);
|
|
129
|
+
}, stack, normalizeString, write);
|
|
87
130
|
if (Array.isArray(value)) {
|
|
131
|
+
if (write) {
|
|
132
|
+
write("[");
|
|
133
|
+
let separator = "";
|
|
134
|
+
for (const entry of value) {
|
|
135
|
+
write(separator);
|
|
136
|
+
write(stringifyStableValue(entry, stack, normalizeString, write));
|
|
137
|
+
separator = ",";
|
|
138
|
+
}
|
|
139
|
+
write("]");
|
|
140
|
+
return "";
|
|
141
|
+
}
|
|
88
142
|
const serializedEntries = [];
|
|
89
143
|
for (const entry of value) serializedEntries.push(stringifyStableValue(entry, stack, normalizeString));
|
|
90
144
|
return `[${serializedEntries.join(",")}]`;
|
|
91
145
|
}
|
|
92
146
|
const record = value;
|
|
93
147
|
if (normalizeString === preserveString) {
|
|
94
|
-
const fields =
|
|
95
|
-
|
|
148
|
+
const fields = Object.keys(record).sort();
|
|
149
|
+
if (write) {
|
|
150
|
+
write("{");
|
|
151
|
+
let separator = "";
|
|
152
|
+
for (const key of fields) {
|
|
153
|
+
write(`${separator}${JSON.stringify(key)}:`);
|
|
154
|
+
write(stringifyStableValue(record[key], stack, normalizeString, write));
|
|
155
|
+
separator = ",";
|
|
156
|
+
}
|
|
157
|
+
write("}");
|
|
158
|
+
return "";
|
|
159
|
+
}
|
|
160
|
+
let fieldIndex = 0;
|
|
161
|
+
for (const key of fields) fields[fieldIndex++] = `${JSON.stringify(key)}:${stringifyStableValue(record[key], stack, normalizeString)}`;
|
|
96
162
|
return `{${fields.join(",")}}`;
|
|
97
163
|
}
|
|
98
164
|
const entries = Object.keys(record).map((key) => ({
|
|
99
165
|
key,
|
|
100
166
|
normalizedKey: normalizeString(key)
|
|
101
|
-
})).
|
|
167
|
+
})).sort((left, right) => {
|
|
102
168
|
return compareStableStrings(left.normalizedKey, right.normalizedKey) || compareStableStrings(left.key, right.key);
|
|
103
169
|
});
|
|
104
170
|
const serializedFields = [];
|
|
171
|
+
if (write) {
|
|
172
|
+
write("{");
|
|
173
|
+
let separator = "";
|
|
174
|
+
for (const { key, normalizedKey } of entries) {
|
|
175
|
+
write(`${separator}${JSON.stringify(normalizedKey)}:`);
|
|
176
|
+
write(stringifyStableValue(record[key], stack, normalizeString, write));
|
|
177
|
+
separator = ",";
|
|
178
|
+
}
|
|
179
|
+
write("}");
|
|
180
|
+
return "";
|
|
181
|
+
}
|
|
105
182
|
for (const { key, normalizedKey } of entries) serializedFields.push(`${JSON.stringify(normalizedKey)}:${stringifyStableValue(record[key], stack, normalizeString)}`);
|
|
106
183
|
return `{${serializedFields.join(",")}}`;
|
|
107
184
|
}
|
|
@@ -128,6 +205,19 @@ const MEDIA_PAYLOAD_SUFFIXES = "base64|blob|buffer|bytes|data|delta|frames?|outp
|
|
|
128
205
|
const MEDIA_FIELD_NAME_RE = new RegExp(`^(?:input|output)?(?:audio|image|video)s?(?:${MEDIA_PAYLOAD_SUFFIXES})*$`, "u");
|
|
129
206
|
const MEDIA_PAYLOAD_SUFFIX_RE = new RegExp(`^(?:${MEDIA_PAYLOAD_SUFFIXES})$`, "u");
|
|
130
207
|
const MEDIA_WRAPPER_NAME_RE = /^(?:input_|output_)?(?:audio|image|video)s?(?:_|$)/iu;
|
|
208
|
+
const DIAGNOSTIC_FIELD_SEPARATOR_RE = /[^a-z0-9]/g;
|
|
209
|
+
const MEDIA_TYPE_RE = /^(?:input|output)?(?:audio|image|video)/u;
|
|
210
|
+
const MEDIA_MIME_RE = /^(?:audio|image|video)\//iu;
|
|
211
|
+
const MEDIA_ARRAY_INDEX_RE = /^(?:0|[1-9]\d*)$/u;
|
|
212
|
+
const MEDIA_URL_SUFFIX_RE = /(?:uri|url)$/u;
|
|
213
|
+
const MEDIA_MIME_FIELDS = [
|
|
214
|
+
"mimeType",
|
|
215
|
+
"mime_type",
|
|
216
|
+
"mediaType",
|
|
217
|
+
"media_type",
|
|
218
|
+
"contentType",
|
|
219
|
+
"content_type"
|
|
220
|
+
];
|
|
131
221
|
const AUTHORIZATION_VALUE_RE = /\b(Bearer|Basic)\s+[A-Za-z0-9+/._~=-]{8,}/giu;
|
|
132
222
|
const JWT_VALUE_RE = /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/gu;
|
|
133
223
|
const COOKIE_HEADER_RE = /\b((?:set-)?cookie\s*:\s*)([^\r\n]+)/giu;
|
|
@@ -170,7 +260,7 @@ function hasSensitiveProseContent(value) {
|
|
|
170
260
|
return false;
|
|
171
261
|
}
|
|
172
262
|
function normalizeDiagnosticFieldName(value) {
|
|
173
|
-
return value.toLowerCase().replaceAll(
|
|
263
|
+
return value.toLowerCase().replaceAll(DIAGNOSTIC_FIELD_SEPARATOR_RE, "");
|
|
174
264
|
}
|
|
175
265
|
function isCredentialFieldName(normalized) {
|
|
176
266
|
if (!normalized || NON_CREDENTIAL_FIELD_NAMES.has(normalized)) return false;
|
|
@@ -184,27 +274,19 @@ function diagnosticBytes(value, numericArrays = false) {
|
|
|
184
274
|
}
|
|
185
275
|
function isDiagnosticMediaPayload(descriptors) {
|
|
186
276
|
const type = descriptors.type?.value;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
"mime_type",
|
|
190
|
-
"mediaType",
|
|
191
|
-
"media_type",
|
|
192
|
-
"contentType",
|
|
193
|
-
"content_type"
|
|
194
|
-
].some((key) => {
|
|
277
|
+
if (typeof type === "string" && MEDIA_TYPE_RE.test(normalizeDiagnosticFieldName(type))) return true;
|
|
278
|
+
for (const key of MEDIA_MIME_FIELDS) {
|
|
195
279
|
const mime = descriptors[key]?.value;
|
|
196
|
-
|
|
197
|
-
}
|
|
280
|
+
if (typeof mime === "string" && MEDIA_MIME_RE.test(mime)) return true;
|
|
281
|
+
}
|
|
282
|
+
return false;
|
|
198
283
|
}
|
|
199
284
|
function extractDiagnosticMediaField(key, normalized, value, parentMedia) {
|
|
200
285
|
const privateField = normalized === "b64json";
|
|
201
286
|
const mediaField = MEDIA_FIELD_NAME_RE.test(normalized) || MEDIA_WRAPPER_NAME_RE.test(key);
|
|
202
287
|
const contextualPayload = parentMedia && MEDIA_PAYLOAD_SUFFIX_RE.test(normalized);
|
|
203
|
-
if (!privateField && !mediaField && !contextualPayload) {
|
|
204
|
-
|
|
205
|
-
return parentMedia && nestedMedia ? { kind: "context" } : void 0;
|
|
206
|
-
}
|
|
207
|
-
if (/(?:uri|url)$/u.test(normalized)) return { kind: "redacted" };
|
|
288
|
+
if (!privateField && !mediaField && !contextualPayload) return parentMedia && value !== null && (typeof value === "object" || MEDIA_ARRAY_INDEX_RE.test(key)) ? { kind: "context" } : void 0;
|
|
289
|
+
if (MEDIA_URL_SUFFIX_RE.test(normalized)) return { kind: "redacted" };
|
|
208
290
|
const encoded = diagnosticBytes(value, true) ?? (typeof value === "string" ? value : void 0);
|
|
209
291
|
if (encoded === void 0) return { kind: privateField || Array.isArray(value) ? "redacted" : "context" };
|
|
210
292
|
return {
|
|
@@ -213,6 +295,13 @@ function extractDiagnosticMediaField(key, normalized, value, parentMedia) {
|
|
|
213
295
|
source: encoded
|
|
214
296
|
};
|
|
215
297
|
}
|
|
298
|
+
const diagnosticRecords = /* @__PURE__ */ new WeakSet();
|
|
299
|
+
/** Fresh records need no native-object probe while their prototype stays ordinary. */
|
|
300
|
+
function createDiagnosticRecord() {
|
|
301
|
+
const record = {};
|
|
302
|
+
diagnosticRecords.add(record);
|
|
303
|
+
return record;
|
|
304
|
+
}
|
|
216
305
|
function projectDiagnosticValue(value, policy = {}, seen = /* @__PURE__ */ new WeakSet(), mediaPayload = false, state = {
|
|
217
306
|
changed: false,
|
|
218
307
|
nodesRemaining: 64
|
|
@@ -237,24 +326,28 @@ function projectDiagnosticValue(value, policy = {}, seen = /* @__PURE__ */ new W
|
|
|
237
326
|
state.changed = true;
|
|
238
327
|
return "[Truncated]";
|
|
239
328
|
}
|
|
240
|
-
try {
|
|
329
|
+
if (!diagnosticRecords.has(value) || Object.getPrototypeOf(value) !== Object.prototype) try {
|
|
241
330
|
Headers.prototype.has.call(value, "retry-after");
|
|
242
331
|
const seconds = parseRetryAfterHeadersSeconds(value);
|
|
243
332
|
state.changed = true;
|
|
244
333
|
return seconds === void 0 ? {} : { "retry-after-ms": seconds * 1e3 };
|
|
245
334
|
} catch {}
|
|
246
|
-
const keys = Reflect.ownKeys(value)
|
|
247
|
-
const descriptors = Object.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
335
|
+
const keys = Reflect.ownKeys(value);
|
|
336
|
+
const descriptors = Object.create(null);
|
|
337
|
+
for (let index = 0; index < Math.min(keys.length, 64); index += 1) {
|
|
338
|
+
const key = keys[index];
|
|
339
|
+
if (typeof key !== "string") continue;
|
|
340
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
341
|
+
if (descriptor) descriptors[key] = descriptor;
|
|
342
|
+
}
|
|
251
343
|
state.changed ||= keys.length > 64;
|
|
252
344
|
seen.add(value);
|
|
253
345
|
const out = Array.isArray(value) ? [] : {};
|
|
254
346
|
const rawName = typeof descriptors.name?.value === "string" ? descriptors.name.value : descriptors.key?.value;
|
|
255
347
|
const redactValueField = keys.length > 64 || typeof rawName === "string" && isCredentialFieldName(normalizeDiagnosticFieldName(rawName));
|
|
256
348
|
const redactMedia = mediaPayload || keys.length > 64 || isDiagnosticMediaPayload(descriptors);
|
|
257
|
-
for (const
|
|
349
|
+
for (const key in descriptors) {
|
|
350
|
+
const descriptor = expectDefined(descriptors[key], "diagnostic descriptor");
|
|
258
351
|
if (!("value" in descriptor) || !descriptor.enumerable && (policy.propertyScope === "enumerable" || ![
|
|
259
352
|
"cause",
|
|
260
353
|
"errors",
|
|
@@ -349,11 +442,14 @@ function readCauseCode(error) {
|
|
|
349
442
|
if (code) return code;
|
|
350
443
|
}
|
|
351
444
|
}
|
|
445
|
+
function truncateField(text, maxLength) {
|
|
446
|
+
return text.length <= maxLength ? text : `${truncateUtf16Safe(text, maxLength)}... [truncated]`;
|
|
447
|
+
}
|
|
352
448
|
function stringifyField(value, maxLength) {
|
|
353
449
|
if (value === void 0 || value === null) return;
|
|
354
450
|
const text = redactDiagnosticText((typeof value === "string" ? value : stableStringify(value)).trim());
|
|
355
451
|
if (!text) return;
|
|
356
|
-
return
|
|
452
|
+
return maxLength === void 0 ? text : truncateField(text, maxLength);
|
|
357
453
|
}
|
|
358
454
|
function buildProjection(snapshot, signal) {
|
|
359
455
|
const error = asOptionalRecord(snapshot);
|
|
@@ -365,12 +461,11 @@ function buildProjection(snapshot, signal) {
|
|
|
365
461
|
response?.status,
|
|
366
462
|
response?.statusCode
|
|
367
463
|
].find((value) => typeof value === "number" && Number.isFinite(value));
|
|
368
|
-
const
|
|
369
|
-
const body = stringifyField(bodyValue, MAX_ERROR_BODY_LENGTH);
|
|
464
|
+
const body = stringifyField(error?.errorBody ?? error?.body ?? response?.body ?? response?.data ?? nestedError);
|
|
370
465
|
const originalMessage = (typeof snapshot === "string" ? snapshot : void 0) ?? readProviderErrorField(error, "message") ?? readProviderErrorField(nestedError, "message");
|
|
371
466
|
const genericMessage = originalMessage === `${status} status code (no body)`;
|
|
372
467
|
let errorMessage = status !== void 0 && body && (!originalMessage || genericMessage) ? `${status}: ${body}` : originalMessage ?? body ?? stringifyField(snapshot, MAX_ERROR_BODY_LENGTH) ?? "Unknown provider error";
|
|
373
|
-
if (status !== void 0 &&
|
|
468
|
+
if (status !== void 0 && originalMessage && !originalMessage.startsWith(String(status))) errorMessage = `${status}: ${errorMessage}`;
|
|
374
469
|
const rawMetadata = stringifyField(asOptionalRecord(nestedError?.metadata)?.raw, MAX_ERROR_BODY_LENGTH);
|
|
375
470
|
if (rawMetadata && !errorMessage.includes(rawMetadata)) errorMessage += `\n${rawMetadata}`;
|
|
376
471
|
const errorCode = readProviderErrorField(error, "errorCode") ?? readProviderErrorField(error, "code") ?? readProviderErrorField(nestedError, "code") ?? (error ? readCauseCode(error) : void 0) ?? (status === void 0 ? void 0 : String(status));
|
|
@@ -380,7 +475,7 @@ function buildProjection(snapshot, signal) {
|
|
|
380
475
|
errorMessage: stringifyField(errorMessage, 4096) ?? "Unknown provider error",
|
|
381
476
|
...errorCode ? { errorCode: truncateUtf16Safe(errorCode, 256) } : {},
|
|
382
477
|
...errorType ? { errorType: truncateUtf16Safe(errorType, 256) } : {},
|
|
383
|
-
...body ? { errorBody:
|
|
478
|
+
...body ? { errorBody: truncateField(body, 500) } : {}
|
|
384
479
|
};
|
|
385
480
|
}
|
|
386
481
|
/** Projects one hostile provider throw into final, bounded assistant terminal fields. */
|
|
@@ -406,4 +501,4 @@ function projectProviderError(error, signal) {
|
|
|
406
501
|
}
|
|
407
502
|
}
|
|
408
503
|
//#endregion
|
|
409
|
-
export {
|
|
504
|
+
export { redactDiagnosticText as a, projectDiagnosticValue as i, projectProviderError as n, stableStringify as o, createDiagnosticRecord as r, configureProviderErrorRedactor as t };
|
|
@@ -8,5 +8,7 @@ type ProviderErrorProjection = {
|
|
|
8
8
|
};
|
|
9
9
|
type ProviderErrorRedactor = (value: unknown) => unknown;
|
|
10
10
|
declare function configureProviderErrorRedactor(redactor: ProviderErrorRedactor | undefined): ProviderErrorRedactor | undefined;
|
|
11
|
+
/** Projects one hostile provider throw into final, bounded assistant terminal fields. */
|
|
12
|
+
declare function projectProviderError(error: unknown, signal?: AbortSignal): ProviderErrorProjection;
|
|
11
13
|
//#endregion
|
|
12
|
-
export { ProviderErrorRedactor as n, configureProviderErrorRedactor as r, ProviderErrorProjection as t };
|
|
14
|
+
export { projectProviderError as i, ProviderErrorRedactor as n, configureProviderErrorRedactor as r, ProviderErrorProjection as t };
|