@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.
Files changed (101) hide show
  1. package/README.md +1 -1
  2. package/dist/{anthropic-C4Qu4H0Z.mjs → anthropic-DZQ_7gD1.mjs} +37 -38
  3. package/dist/{anthropic-payload-policy-BZ8umAbk.d.mts → anthropic-payload-policy-DyfwikYJ.d.mts} +4 -4
  4. package/dist/{anthropic-stream-reducer-CILWF7JD.mjs → anthropic-stream-reducer-D6ZI1wwj.mjs} +70 -50
  5. package/dist/{api-registry-ByUwIR0e.d.mts → api-registry-C2T3lTV7.d.mts} +2 -2
  6. package/dist/{assistant-output-tLt4H-iQ.mjs → assistant-output-DM1JBNs1.mjs} +1 -1
  7. package/dist/{azure-openai-responses-BAlqlKKc.mjs → azure-openai-responses-DS86GYzq.mjs} +6 -9
  8. package/dist/{base64-D-su8YVo.mjs → base64-CPmadnUf.mjs} +12 -12
  9. package/dist/credential-redaction-BKv49aiv.d.mts +24 -0
  10. package/dist/{diagnostics-QuErwCIl.mjs → diagnostics-CH8j2wIG.mjs} +139 -7
  11. package/dist/{diagnostics-CPeq9F7y.mjs → diagnostics-DzrF1h4J.mjs} +18 -1
  12. package/dist/diagnostics.d.mts +11 -24
  13. package/dist/diagnostics.mjs +4 -4
  14. package/dist/event-stream-C0nsgbj2.d.mts +1 -0
  15. package/dist/{event-stream-Bt5Y4Pav.d.mts → event-stream-CjnIZZst.d.mts} +1 -1
  16. package/dist/event-stream.d.mts +2 -2
  17. package/dist/expect-lbe3Hgrh.mjs +8 -0
  18. package/dist/{google-DPBAOaOW.mjs → google-BZJFjhuC.mjs} +6 -9
  19. package/dist/{google-messages-6JkpHrhJ.mjs → google-messages-DB7GKkDk.mjs} +3 -3
  20. package/dist/{google-shared-BvBeW9aq.mjs → google-shared-Bok4I6zB.mjs} +13 -13
  21. package/dist/{google-vertex-k-TMCAYD.mjs → google-vertex-3eVNR2qW.mjs} +5 -8
  22. package/dist/{host-4atIX-2V.d.mts → host-DH-Z-LDb.d.mts} +5 -3
  23. package/dist/{host-policy-Zcg_cNz8.mjs → host-policy-DZO3oPPk.mjs} +1 -1
  24. package/dist/{host-B8YfDGd4.mjs → host-yTvBrYM2.mjs} +63 -31
  25. package/dist/{index-DdD3qerf.d.mts → index-C25RT6bP.d.mts} +37 -14
  26. package/dist/index.d.mts +7 -8
  27. package/dist/index.mjs +5 -6
  28. package/dist/internal/anthropic.d.mts +13 -10
  29. package/dist/internal/anthropic.mjs +5 -5
  30. package/dist/internal/openai-completions-compat.d.mts +2 -0
  31. package/dist/internal/openai-completions-compat.mjs +2 -0
  32. package/dist/internal/openai-responses-payload-policy.d.mts +2 -2
  33. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  34. package/dist/internal/openai.d.mts +24 -53
  35. package/dist/internal/openai.mjs +12 -9
  36. package/dist/internal/runtime.d.mts +6 -8
  37. package/dist/internal/runtime.mjs +6 -10
  38. package/dist/internal/shared.d.mts +7 -5
  39. package/dist/internal/shared.mjs +4 -3
  40. package/dist/internal/tool-schema.d.mts +4 -4
  41. package/dist/internal/tool-schema.mjs +2 -2
  42. package/dist/{mistral-CxUZ1jUb.mjs → mistral-C_13dVBn.mjs} +9 -13
  43. package/dist/{model-transport-url-DKocrEsb.d.mts → model-transport-url-C5f59L3Y.d.mts} +1 -1
  44. package/dist/{openai-chatgpt-responses-CgO6kZfo.mjs → openai-chatgpt-responses-sTxPl4zM.mjs} +150 -83
  45. package/dist/{openai-completions-yJuk7eis.mjs → openai-completions-BO6D_hrB.mjs} +11 -12
  46. package/dist/{openai-prompt-cache-Bds-n_9Q.mjs → openai-completions-compat-CUollwl6.mjs} +5 -50
  47. package/dist/{openai-completions-compat-eHgh5UPE.d.mts → openai-completions-compat-DfJG1wSO.d.mts} +4 -4
  48. package/dist/{openai-completions-stream-Da2vvl-S.mjs → openai-completions-stream-BpuJ0ZOA.mjs} +117 -106
  49. package/dist/{openai-prompt-cache-B4eYo2-I.d.mts → openai-prompt-cache-C4RHdN4n.d.mts} +2 -2
  50. package/dist/openai-prompt-cache-CjV_2IRI.mjs +46 -0
  51. package/dist/{openai-provider-client-S2gCrM2Z.mjs → openai-provider-client-BP8J1aeg.mjs} +2 -2
  52. package/dist/openai-reasoning-effort-ash8dPrd.mjs +243 -0
  53. package/dist/{openai-responses-DaYwH05E.mjs → openai-responses-BJ_IEoMU.mjs} +8 -12
  54. package/dist/{openai-responses-compaction-window-CIhBAkkq.mjs → openai-responses-compaction-window-BiNCT0bS.mjs} +20 -62
  55. package/dist/{openai-responses-contracts-BjBAqAg_.d.mts → openai-responses-contracts-B1ENJFpI.d.mts} +9 -5
  56. package/dist/openai-responses-contracts-DWrfMODE.mjs +81 -0
  57. package/dist/{openai-responses-payload-policy-rLRPsSmB.d.mts → openai-responses-payload-policy-C7GsA1y0.d.mts} +5 -3
  58. package/dist/openai-responses-prompt-observer-internal-DPHWgbBH.mjs +198 -0
  59. package/dist/openai-responses-request-lifecycle-DFuyO1pQ.mjs +36 -0
  60. package/dist/{openai-responses-shared-B8RdBPCv.mjs → openai-responses-shared-DvSqtJ6_.mjs} +859 -581
  61. package/dist/openai-responses-terminal-usage-BNFbvY9f.d.mts +47 -0
  62. package/dist/{openai-tool-schema-CzjyYXun.mjs → openai-tool-schema-D4BMcj2D.mjs} +262 -162
  63. package/dist/{openai-transport-params-9aPuV5YY.mjs → openai-transport-params-DZKOTSfH.mjs} +157 -47
  64. package/dist/{positive-integer-41zhOdcV.mjs → positive-integer-BiUxrd71.mjs} +1 -1
  65. package/dist/{provider-error-BA-v_tKd.mjs → provider-error-CRhW7lkJ.mjs} +139 -44
  66. package/dist/{provider-error-CzNw4BWX.d.mts → provider-error-xumb1V3F.d.mts} +3 -1
  67. package/dist/{provider-options-Ceqv1OKk.d.mts → provider-options-DZYq53lj.d.mts} +12 -7
  68. package/dist/{provider-replay-context-CJ_YvcEW.mjs → provider-replay-context-DPr3w20a.mjs} +1 -1
  69. package/dist/{provider-transcript-transform-V5YzU9zh.mjs → provider-transcript-transform-BTocjCRs.mjs} +1 -1
  70. package/dist/{provider-transport-turn-state-D5EXOFL2.mjs → provider-transport-turn-state-lrXEFkYr.mjs} +1 -1
  71. package/dist/{provider-types-CVjKjsuq.d.mts → provider-types-w1rEqrGP.d.mts} +3 -3
  72. package/dist/provider-types.d.mts +6 -7
  73. package/dist/providers.d.mts +2 -2
  74. package/dist/providers.mjs +10 -10
  75. package/dist/{reasoning-tag-text-partitioner-BcR5pztD.mjs → reasoning-tag-text-partitioner-Di38crhI.mjs} +167 -40
  76. package/dist/{simple-options-BQbb4yQL.mjs → simple-options-np1XPuhm.mjs} +5 -3
  77. package/dist/{usage-cost-BNWbbXav.mjs → src-DwGYYyZp.mjs} +18 -11
  78. package/dist/{stream-first-event-timeout-2hfrquuz.mjs → stream-first-event-timeout-BeptfRL6.mjs} +1 -1
  79. package/dist/{string-normalization-CmLIasuf.mjs → string-normalization-J9ZiLfGO.mjs} +13 -1
  80. package/dist/tool-schema-json-projection-CD9c_fK8.mjs +134 -0
  81. package/dist/{transport-stream-shared-zHll9BxO.mjs → transport-stream-shared-B5RioB_Q.mjs} +16 -24
  82. package/dist/{transport-stream-shared-DNvmoWnv.d.mts → transport-stream-shared-B7Z9oCYg.d.mts} +5 -5
  83. package/dist/{transport-utils-zrYjICLZ.mjs → transport-utils-03Qi0CN2.mjs} +3 -3
  84. package/dist/transports.d.mts +27 -13
  85. package/dist/transports.mjs +168 -462
  86. package/dist/types-DTvddOfm.d.mts +1 -0
  87. package/dist/{types-Ntv5z2g2.d.mts → types-qZFbaDbK.d.mts} +49 -3
  88. package/dist/types.d.mts +6 -7
  89. package/dist/types.mjs +4 -5
  90. package/dist/{validation-B0t_G2H6.d.mts → validation-DhQhmt6t.d.mts} +1 -1
  91. package/dist/{validation-BDzVDnTs.mjs → validation-Dw7cb6BV.mjs} +1 -0
  92. package/dist/validation.d.mts +1 -1
  93. package/dist/validation.mjs +1 -1
  94. package/package.json +11 -6
  95. package/dist/diagnostics-DnPnOui6.d.mts +0 -29
  96. package/dist/event-stream-C3WGFsum.d.mts +0 -1
  97. package/dist/openai-responses-contracts-DDOHA62Y.mjs +0 -245
  98. package/dist/openai-responses-prompt-observer-internal-f8J7wpsk.mjs +0 -32
  99. package/dist/src-DDmEryvj.mjs +0 -2
  100. package/dist/tool-schema-json-projection-ClptDdAO.mjs +0 -82
  101. 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 { l as usesNativeOpenAICodexResponsesBackend, n as clampOpenAIPromptCacheKey, s as resolveOpenAICompletionsCompat } from "./openai-prompt-cache-Bds-n_9Q.mjs";
5
- import { i as isCodeModeModelVisibleToolName } from "./transport-utils-zrYjICLZ.mjs";
6
- import { n as resolveModelRequestTimeoutMs, o as resolveProviderRequestPolicyConfig } from "./host-policy-Zcg_cNz8.mjs";
7
- import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-ClptDdAO.mjs";
8
- import { O as headersToRecord, p as notifyProviderHttpResponse, v as transportAbortError } from "./transport-stream-shared-zHll9BxO.mjs";
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 { i as OPENAI_RESPONSES_APIS } from "./openai-responses-contracts-DDOHA62Y.mjs";
11
- import { a as resolveOpenAIProjectedToolsStrictToolFlag, t as findOpenAIStrictToolProjectionDiagnostics } from "./openai-tool-schema-CzjyYXun.mjs";
12
- import { createHash } from "node:crypto";
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 createHash("sha256").update(input).digest("hex");
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
- const now = Date.now();
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 schemaProjection = projectRuntimeToolInputSchema(parameters ?? {}, `${name}.parameters`);
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 = resolveOpenAISdkTimeoutMs(model);
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 = resolveOpenAISdkTimeoutMs(model, options?.timeoutMs);
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 { readOpenAICompletionsContentDeltas as C, throwIfModelStreamAborted as D, resolvePromptCacheKey as E, redactIdentifier as O, parseOpenAICompletionsUsage as S, resolveOpenAIClientBaseUrl as T, createOpenAIProviderAcceptanceHook as _, enforceCodeModeResponsesToolSurface as a, log as b, readCodeModePayloadToolName as c, resolveOpenAIReasoningEffortMap as d, projectOpenAITools as f, createModelStreamCooperativeScheduler as g, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as h, buildOpenAISdkRequestOptions as i, sha256Hex 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, createOpenAIResponseHook as v, readOpenAICompletionsReasoningBatch as w, measureUtf8AppendBytes as x, isOpenAICompletionsThinkingEnabled as y };
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-D-su8YVo.mjs";
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 { n as estimateBase64DecodedBytes } from "./base64-D-su8YVo.mjs";
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/expect.ts
51
- /** Returns the value or throws with the named context; use for genuine invariants only. */
52
- function expectDefined(value, context) {
53
- if (value === null || value === void 0) throw new Error("expected " + context + " to be defined");
54
- return value;
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
- for (const key of Object.keys(record).toSorted()) fields.push(`${JSON.stringify(key)}:${stringifyStableValue(record[key], stack, normalizeString)}`);
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
- })).toSorted((left, right) => {
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(/[^a-z0-9]/g, "");
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
- return typeof type === "string" && /^(?:input|output)?(?:audio|image|video)/u.test(normalizeDiagnosticFieldName(type)) || [
188
- "mimeType",
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
- return typeof mime === "string" && /^(?:audio|image|video)\//iu.test(mime);
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
- const nestedMedia = value !== null && (typeof value === "object" || /^(?:0|[1-9]\d*)$/u.test(key));
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).slice(0, 65);
247
- const descriptors = Object.fromEntries(keys.slice(0, 64).flatMap((key) => {
248
- const descriptor = typeof key === "string" && Object.getOwnPropertyDescriptor(value, key);
249
- return descriptor ? [[key, descriptor]] : [];
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 [key, descriptor] of Object.entries(descriptors)) {
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 text.length <= maxLength ? text : `${truncateUtf16Safe(text, maxLength)}... [truncated]`;
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 bodyValue = error?.errorBody ?? error?.body ?? response?.body ?? response?.data ?? nestedError;
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 && !body && originalMessage && !originalMessage.startsWith(String(status))) errorMessage = `${status}: ${errorMessage}`;
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: stringifyField(bodyValue, 500) } : {}
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 { expectDefined as a, stableStringify as i, projectProviderError as n, projectDiagnosticValue as r, configureProviderErrorRedactor as t };
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 };