@openclaw/ai 2026.9.4 → 2026.9.5

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 (97) hide show
  1. package/README.md +1 -1
  2. package/dist/{anthropic-C4Qu4H0Z.mjs → anthropic-COtDvgtt.mjs} +10 -11
  3. package/dist/{anthropic-payload-policy-BZ8umAbk.d.mts → anthropic-payload-policy-5Erq1Nzy.d.mts} +3 -3
  4. package/dist/{anthropic-stream-reducer-CILWF7JD.mjs → anthropic-stream-reducer-BvdYYWL8.mjs} +47 -43
  5. package/dist/{api-registry-ByUwIR0e.d.mts → api-registry-Ba2Cv-ut.d.mts} +2 -2
  6. package/dist/{assistant-output-tLt4H-iQ.mjs → assistant-output-BsEkB-vU.mjs} +1 -1
  7. package/dist/{azure-openai-responses-BAlqlKKc.mjs → azure-openai-responses-YrgnD583.mjs} +6 -9
  8. package/dist/{base64-D-su8YVo.mjs → base64-BQOzsvUH.mjs} +4 -4
  9. package/dist/credential-redaction-BKv49aiv.d.mts +24 -0
  10. package/dist/{diagnostics-QuErwCIl.mjs → diagnostics-Dm4bisWG.mjs} +89 -2
  11. package/dist/diagnostics.d.mts +4 -23
  12. package/dist/diagnostics.mjs +3 -3
  13. package/dist/{event-stream-Bt5Y4Pav.d.mts → event-stream-CCoa-qSI.d.mts} +1 -1
  14. package/dist/event-stream-DmSCpi1T.d.mts +1 -0
  15. package/dist/event-stream.d.mts +2 -2
  16. package/dist/expect-lbe3Hgrh.mjs +8 -0
  17. package/dist/{google-DPBAOaOW.mjs → google-BuhpRO9r.mjs} +6 -9
  18. package/dist/{google-messages-6JkpHrhJ.mjs → google-messages-CyWnYlh0.mjs} +3 -3
  19. package/dist/{google-shared-BvBeW9aq.mjs → google-shared-BT5ZeNer.mjs} +13 -13
  20. package/dist/{google-vertex-k-TMCAYD.mjs → google-vertex-C7EplRvt.mjs} +5 -8
  21. package/dist/{host-B8YfDGd4.mjs → host-B4MeUNBc.mjs} +25 -27
  22. package/dist/{host-4atIX-2V.d.mts → host-FZ1RA_qD.d.mts} +5 -3
  23. package/dist/{host-policy-Zcg_cNz8.mjs → host-policy-DUnXSx0I.mjs} +1 -1
  24. package/dist/{index-DdD3qerf.d.mts → index-DaF2QbwS.d.mts} +4 -9
  25. package/dist/index.d.mts +6 -7
  26. package/dist/index.mjs +3 -4
  27. package/dist/internal/anthropic.d.mts +6 -7
  28. package/dist/internal/anthropic.mjs +4 -4
  29. package/dist/internal/openai-completions-compat.d.mts +2 -0
  30. package/dist/internal/openai-completions-compat.mjs +2 -0
  31. package/dist/internal/openai-responses-payload-policy.d.mts +2 -2
  32. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  33. package/dist/internal/openai.d.mts +10 -53
  34. package/dist/internal/openai.mjs +11 -9
  35. package/dist/internal/runtime.d.mts +6 -8
  36. package/dist/internal/runtime.mjs +5 -9
  37. package/dist/internal/shared.d.mts +6 -5
  38. package/dist/internal/shared.mjs +4 -3
  39. package/dist/internal/tool-schema.d.mts +3 -3
  40. package/dist/internal/tool-schema.mjs +2 -2
  41. package/dist/{mistral-CxUZ1jUb.mjs → mistral-moA-mbwl.mjs} +9 -13
  42. package/dist/{openai-chatgpt-responses-CgO6kZfo.mjs → openai-chatgpt-responses-DWID3EFO.mjs} +73 -29
  43. package/dist/{openai-completions-yJuk7eis.mjs → openai-completions-DJ1Vm-CD.mjs} +11 -12
  44. package/dist/{openai-prompt-cache-Bds-n_9Q.mjs → openai-completions-compat-CkwdxTZx.mjs} +5 -50
  45. package/dist/{openai-completions-compat-eHgh5UPE.d.mts → openai-completions-compat-JE7gqxb9.d.mts} +4 -4
  46. package/dist/{openai-completions-stream-Da2vvl-S.mjs → openai-completions-stream-Bu98b0Hv.mjs} +94 -96
  47. package/dist/openai-prompt-cache-1wfaIszn.mjs +46 -0
  48. package/dist/{openai-prompt-cache-B4eYo2-I.d.mts → openai-prompt-cache-CJ_xEevu.d.mts} +2 -2
  49. package/dist/{openai-provider-client-S2gCrM2Z.mjs → openai-provider-client-DPo0Hmak.mjs} +2 -2
  50. package/dist/openai-reasoning-effort-NlFZmfEu.mjs +235 -0
  51. package/dist/{openai-responses-DaYwH05E.mjs → openai-responses-BejZzQCP.mjs} +8 -12
  52. package/dist/{openai-responses-compaction-window-CIhBAkkq.mjs → openai-responses-compaction-window-D6P5oZP5.mjs} +20 -62
  53. package/dist/openai-responses-contracts-DWrfMODE.mjs +81 -0
  54. package/dist/{openai-responses-contracts-BjBAqAg_.d.mts → openai-responses-contracts-Dflvrfa8.d.mts} +9 -5
  55. package/dist/{openai-responses-payload-policy-rLRPsSmB.d.mts → openai-responses-payload-policy-C7GsA1y0.d.mts} +5 -3
  56. package/dist/openai-responses-prompt-observer-internal-C15_-OwV.mjs +195 -0
  57. package/dist/{openai-responses-shared-B8RdBPCv.mjs → openai-responses-shared-CwsziD_m.mjs} +385 -178
  58. package/dist/openai-responses-terminal-usage-Dl3J6zrf.d.mts +47 -0
  59. package/dist/{openai-tool-schema-CzjyYXun.mjs → openai-tool-schema-BO8rwyAD.mjs} +92 -68
  60. package/dist/{openai-transport-params-9aPuV5YY.mjs → openai-transport-params-DQeuAvBl.mjs} +157 -47
  61. package/dist/{positive-integer-41zhOdcV.mjs → positive-integer-DtjCkbue.mjs} +1 -1
  62. package/dist/{provider-error-BA-v_tKd.mjs → provider-error-DDqw9Qda.mjs} +100 -38
  63. package/dist/{provider-options-Ceqv1OKk.d.mts → provider-options-DprLsWh9.d.mts} +9 -6
  64. package/dist/{provider-replay-context-CJ_YvcEW.mjs → provider-replay-context-CnUSOwhr.mjs} +1 -1
  65. package/dist/{provider-transcript-transform-V5YzU9zh.mjs → provider-transcript-transform-BsRAhuWJ.mjs} +1 -1
  66. package/dist/{provider-transport-turn-state-D5EXOFL2.mjs → provider-transport-turn-state-CkGToCD2.mjs} +1 -1
  67. package/dist/{provider-types-CVjKjsuq.d.mts → provider-types-CAKRC7N5.d.mts} +3 -3
  68. package/dist/provider-types.d.mts +5 -6
  69. package/dist/providers.d.mts +2 -2
  70. package/dist/providers.mjs +10 -10
  71. package/dist/{reasoning-tag-text-partitioner-BcR5pztD.mjs → reasoning-tag-text-partitioner-Dy9IO8Dc.mjs} +15 -7
  72. package/dist/{simple-options-BQbb4yQL.mjs → simple-options-C6cFWj_f.mjs} +5 -3
  73. package/dist/{usage-cost-BNWbbXav.mjs → src-DeKjbE8I.mjs} +3 -5
  74. package/dist/{stream-first-event-timeout-2hfrquuz.mjs → stream-first-event-timeout-C9ZadkJW.mjs} +1 -1
  75. package/dist/{string-normalization-CmLIasuf.mjs → string-normalization-J9ZiLfGO.mjs} +13 -1
  76. package/dist/tool-schema-json-projection-CD9c_fK8.mjs +134 -0
  77. package/dist/{transport-stream-shared-DNvmoWnv.d.mts → transport-stream-shared-BbUkFaHi.d.mts} +4 -4
  78. package/dist/{transport-stream-shared-zHll9BxO.mjs → transport-stream-shared-D-6FQSHm.mjs} +14 -14
  79. package/dist/{transport-utils-zrYjICLZ.mjs → transport-utils-1cyq5Y7x.mjs} +3 -3
  80. package/dist/transports.d.mts +26 -12
  81. package/dist/transports.mjs +130 -449
  82. package/dist/{types-Ntv5z2g2.d.mts → types-4_uVs5WH.d.mts} +47 -3
  83. package/dist/types-DkJfb4W3.d.mts +1 -0
  84. package/dist/types.d.mts +5 -6
  85. package/dist/types.mjs +2 -3
  86. package/dist/{validation-B0t_G2H6.d.mts → validation-Ctzu2DhF.d.mts} +1 -1
  87. package/dist/{validation-BDzVDnTs.mjs → validation-Dw7cb6BV.mjs} +1 -0
  88. package/dist/validation.d.mts +1 -1
  89. package/dist/validation.mjs +1 -1
  90. package/package.json +10 -5
  91. package/dist/diagnostics-DnPnOui6.d.mts +0 -29
  92. package/dist/event-stream-C3WGFsum.d.mts +0 -1
  93. package/dist/openai-responses-contracts-DDOHA62Y.mjs +0 -245
  94. package/dist/openai-responses-prompt-observer-internal-f8J7wpsk.mjs +0 -32
  95. package/dist/src-DDmEryvj.mjs +0 -2
  96. package/dist/tool-schema-json-projection-ClptDdAO.mjs +0 -82
  97. package/dist/types-DlfwzH3T.d.mts +0 -1
@@ -1,23 +1,25 @@
1
+ import { t as appendAssistantMessageDiagnostic } from "./diagnostics-CPeq9F7y.mjs";
1
2
  import { r as appendAssistantThinking } from "./event-stream-D8PARQfL.mjs";
2
3
  import { a as normalizeOptionalString } from "./string-coerce-fsri9iCu.mjs";
3
- import { M as clampThinkingLevel, _ as isImageWithMediaPayload, d as describeToolResultMediaPlaceholder, j as calculateCost, m as extractToolResultText, n as getAiTransportHost } from "./host-B8YfDGd4.mjs";
4
4
  import { o as isRecord } from "./record-coerce-DwRYMj3t.mjs";
5
+ import { u as supportsOpenAITemperature } from "./openai-reasoning-effort-NlFZmfEu.mjs";
6
+ import { _ as isImageWithMediaPayload, d as describeToolResultMediaPlaceholder, j as calculateCost, m as extractToolResultText, n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-B4MeUNBc.mjs";
5
7
  import { t as truncateUtf16Safe } from "./utf16-slice-CvGodqok.mjs";
6
- import { i as stableStringify } from "./provider-error-BA-v_tKd.mjs";
7
- import { a as resolveModelSseDebugMode, i as resolveModelPayloadDebugMode, r as emitModelTransportDebug } from "./diagnostics-QuErwCIl.mjs";
8
- import { r as asFiniteNumber } from "./base64-D-su8YVo.mjs";
9
- import { o as redactSensitiveText } from "./transport-utils-zrYjICLZ.mjs";
10
- import { s as transformTransportMessages } from "./host-policy-Zcg_cNz8.mjs";
11
- import { m as stripSystemPromptCacheBoundary, v as sortPromptCacheToolsByName } from "./simple-options-BQbb4yQL.mjs";
12
- import { O as redactIdentifier, _ as createOpenAIProviderAcceptanceHook, b as log, f as projectOpenAITools, g as createModelStreamCooperativeScheduler, k as sha256Hex, u as resolveOpenAIStrictToolFlagWithDiagnostics } from "./openai-transport-params-9aPuV5YY.mjs";
13
- import { E as parseStreamingJson, _ as sanitizeTransportPayloadText, b as withProviderResponseHook, g as sanitizeNonEmptyTransportPayloadText, h as parseTerminalToolCallArguments, k as shortHash, l as finalizeTransportStream, s as failTransportStream, t as IncompleteToolCallError, v as transportAbortError, w as createToolArgumentPreviewSchedule } from "./transport-stream-shared-zHll9BxO.mjs";
14
- import { n as providerReplayContextMatches, t as buildProviderReplayContext } from "./provider-replay-context-CJ_YvcEW.mjs";
8
+ import { o as stableStringify } from "./provider-error-DDqw9Qda.mjs";
9
+ import { a as resolveModelSseDebugMode, d as readResponsesReasoningTokens, f as resolveResponsesTerminalStopReason, i as resolveModelPayloadDebugMode, r as emitModelTransportDebug, u as mapResponsesTerminalUsage } from "./diagnostics-Dm4bisWG.mjs";
10
+ import { o as redactSensitiveText } from "./transport-utils-1cyq5Y7x.mjs";
11
+ import { s as transformTransportMessages } from "./host-policy-DUnXSx0I.mjs";
12
+ import { m as stripSystemPromptCacheBoundary, v as sortPromptCacheToolsByName } from "./simple-options-C6cFWj_f.mjs";
13
+ 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-DQeuAvBl.mjs";
14
+ import { E as parseStreamingJson, _ as sanitizeTransportPayloadText, b as withProviderResponseHook, g as sanitizeNonEmptyTransportPayloadText, h as parseTerminalToolCallArguments, k as shortHash, l as finalizeTransportStream, s as failTransportStream, t as IncompleteToolCallError, v as transportAbortError, w as createToolArgumentPreviewSchedule, x as parseJsonObjectPreservingUnsafeIntegers } from "./transport-stream-shared-D-6FQSHm.mjs";
15
+ import { n as providerReplayContextMatches, t as buildProviderReplayContext } from "./provider-replay-context-CnUSOwhr.mjs";
15
16
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
16
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-2hfrquuz.mjs";
17
- import { t as transformProviderMessages } from "./provider-transcript-transform-V5YzU9zh.mjs";
18
- import { C as supportsOpenAITemperature, a as OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE, b as resolveOpenAIReasoningEffortForModel, c as OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE, f as RESPONSE_FAILED_NO_DETAILS_MESSAGE, o as OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY, s as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY, y as resolveOpenAIModelReasoningEfforts } from "./openai-responses-contracts-DDOHA62Y.mjs";
19
- import { a as resolveOpenAIProjectedToolsStrictToolFlag, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-CzjyYXun.mjs";
20
- import { n as isOpenAIResponsesCompactionOutput, r as readOpenAIResponsesCompactionWindow } from "./openai-responses-compaction-window-CIhBAkkq.mjs";
17
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-C9ZadkJW.mjs";
18
+ import { t as transformProviderMessages } from "./provider-transcript-transform-BsRAhuWJ.mjs";
19
+ import { a as resolveOpenAIProjectedToolsStrictToolFlag, f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-BO8rwyAD.mjs";
20
+ 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-DWrfMODE.mjs";
21
+ import { n as isOpenAIResponsesCompactionOutput, r as readOpenAIResponsesCompactionWindow } from "./openai-responses-compaction-window-D6P5oZP5.mjs";
22
+ import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
21
23
  import { createHash, randomUUID } from "node:crypto";
22
24
  //#region packages/ai/src/transports/openai-responses-replay.ts
23
25
  /** Resolves the assistant message id that can be replayed to OpenAI Responses. */
@@ -187,6 +189,199 @@ function buildOpenAIResponsesReasoningReplayMetadata(model, options) {
187
189
  };
188
190
  }
189
191
  //#endregion
192
+ //#region packages/ai/src/transports/openai-responses-reasoning-update.ts
193
+ function isConfigurationUpdate(value) {
194
+ return isRecord(value) && value.type === "configuration_update" && isRecord(value.reasoning) && typeof value.reasoning.effort === "string";
195
+ }
196
+ function isResponsesReasoningUpdateCompatible(request) {
197
+ const mode = isRecord(request.reasoning) ? request.reasoning.mode : void 0;
198
+ return request.model === "gpt-6-astra" && (mode === void 0 || mode === "standard") && (!isRecord(request.multi_agent) || request.multi_agent.enabled !== true) && request.truncation !== "auto" && (!Array.isArray(request.context_management) || !request.context_management.some((item) => isRecord(item) && item.type === "compaction"));
199
+ }
200
+ function supportsResponsesReasoningUpdate(request) {
201
+ return isResponsesReasoningUpdateCompatible(request) && isRecord(request.reasoning) && typeof request.reasoning.effort === "string";
202
+ }
203
+ function canReferenceResponsesReasoningHistory(previous, request) {
204
+ return !previous.input?.some(isConfigurationUpdate) || isResponsesReasoningUpdateCompatible(request);
205
+ }
206
+ /** Rehydrate input controls only provisionally; continuation must validate the full prefix. */
207
+ function replayResponsesReasoningUpdates(previous, request, previousOutputLength, steering) {
208
+ if (steering !== "required-input" && (!supportsResponsesReasoningUpdate(previous) || !supportsResponsesReasoningUpdate(request)) || !Array.isArray(previous.input) || !Array.isArray(request.input) || request.input.some(isConfigurationUpdate)) return request;
209
+ const input = [...request.input];
210
+ let activeEffort = isRecord(previous.reasoning) ? previous.reasoning.effort : void 0;
211
+ for (const [index, item] of previous.input.entries()) if (isConfigurationUpdate(item)) {
212
+ input.splice(index, 0, item);
213
+ activeEffort = item.reasoning.effort;
214
+ }
215
+ if (steering === "required-input") return input.length === request.input.length ? request : {
216
+ ...request,
217
+ input
218
+ };
219
+ if (!isRecord(previous.reasoning) || !isRecord(request.reasoning) || typeof request.reasoning.effort !== "string") return request;
220
+ if (activeEffort !== request.reasoning.effort && steering !== "automatic") {
221
+ const baselineLength = previous.input.length + previousOutputLength;
222
+ const nextUser = input.findIndex((item, index) => index >= baselineLength && "role" in item && item.role === "user");
223
+ if (nextUser === -1) return request;
224
+ input.splice(nextUser, 0, {
225
+ type: "configuration_update",
226
+ reasoning: { effort: request.reasoning.effort }
227
+ });
228
+ }
229
+ if (input.length === request.input.length && activeEffort === request.reasoning.effort) return request;
230
+ return {
231
+ ...request,
232
+ reasoning: {
233
+ ...request.reasoning,
234
+ effort: previous.reasoning.effort
235
+ },
236
+ input
237
+ };
238
+ }
239
+ //#endregion
240
+ //#region packages/ai/src/transports/openai-responses-continuation.ts
241
+ const HTTP_CONTINUATION_IDLE_TTL_MS = 3e5;
242
+ const TURN_HEADERS = /* @__PURE__ */ new Set([
243
+ "traceparent",
244
+ "x-openclaw-turn-id",
245
+ "x-openclaw-turn-attempt"
246
+ ]);
247
+ function jsonValuesEqual(left, right) {
248
+ const leftJson = JSON.stringify(left);
249
+ const normalizedLeft = stableStringify(JSON.parse(leftJson));
250
+ const rightJson = JSON.stringify(right);
251
+ return leftJson === rightJson || normalizedLeft === stableStringify(JSON.parse(rightJson));
252
+ }
253
+ function requestWithoutInput(request) {
254
+ const { input: _input, previous_response_id: _previousResponseId, instructions: _instructions, tools: _tools, ...rest } = request;
255
+ if (!isRecord(rest.metadata)) return rest;
256
+ const metadata = Object.fromEntries(Object.entries(rest.metadata).filter(([key]) => key !== "openclaw_turn_id" && key !== "openclaw_turn_attempt"));
257
+ return {
258
+ ...rest,
259
+ metadata
260
+ };
261
+ }
262
+ function normalizeAssistantReplayInput(input, fromResponse = false) {
263
+ return input.map((item) => {
264
+ if (!isRecord(item)) return item;
265
+ if (item.type === "reasoning") return { type: "reasoning" };
266
+ if (item.type !== "function_call" && !(item.type === "message" && item.role === "assistant")) return item;
267
+ const { id: _id, status: _status, ...stableItem } = item;
268
+ if (fromResponse && item.type === "function_call") {
269
+ const args = parseJsonObjectPreservingUnsafeIntegers(stableItem.arguments);
270
+ stableItem.arguments = args ? JSON.stringify(args) : stableItem.arguments;
271
+ }
272
+ if (item.type === "message" && Array.isArray(stableItem.content)) stableItem.content = stableItem.content.map((part) => {
273
+ if (!isRecord(part) || part.type !== "output_text") return part;
274
+ const { annotations: _annotations, logprobs: _logprobs, ...stablePart } = part;
275
+ return stablePart;
276
+ });
277
+ return stableItem;
278
+ });
279
+ }
280
+ function responsesContinuationRequestFingerprint(request) {
281
+ const serialized = JSON.stringify(requestWithoutInput(request));
282
+ return sha256Hex(stableStringify(JSON.parse(serialized)));
283
+ }
284
+ function responsesContinuationPrefixFingerprint(input, output = []) {
285
+ const serialized = JSON.stringify([...normalizeAssistantReplayInput(input), ...normalizeAssistantReplayInput(output, true)]);
286
+ return sha256Hex(stableStringify(JSON.parse(serialized)));
287
+ }
288
+ function resolveResponsesContinuationRequest(continuation, request, steering) {
289
+ if (!continuation) return {
290
+ request,
291
+ continuationStatus: "no_previous_response"
292
+ };
293
+ if (request.previous_response_id) return {
294
+ request,
295
+ continuationStatus: "explicit_previous_response_id"
296
+ };
297
+ if (!canReferenceResponsesReasoningHistory(continuation.lastRequest, request)) return {
298
+ request,
299
+ continuationStatus: "request_changed"
300
+ };
301
+ const prepared = replayResponsesReasoningUpdates(continuation.lastRequest, request, continuation.lastResponseItems.length, steering);
302
+ if (steering !== "required-input" && !jsonValuesEqual(requestWithoutInput(prepared), requestWithoutInput(continuation.lastRequest))) return {
303
+ request,
304
+ continuationStatus: "request_changed"
305
+ };
306
+ const currentInput = prepared.input ?? [];
307
+ const previousInput = continuation.lastRequest.input ?? [];
308
+ const baselineLength = previousInput.length + continuation.lastResponseItems.length;
309
+ if (currentInput.length < baselineLength) return {
310
+ request,
311
+ continuationStatus: "history_shorter"
312
+ };
313
+ if (!jsonValuesEqual(normalizeAssistantReplayInput(currentInput.slice(0, previousInput.length)), normalizeAssistantReplayInput(previousInput)) || !jsonValuesEqual(normalizeAssistantReplayInput(currentInput.slice(previousInput.length, baselineLength)), normalizeAssistantReplayInput(continuation.lastResponseItems, true))) return {
314
+ request,
315
+ continuationStatus: "history_changed"
316
+ };
317
+ return {
318
+ request: {
319
+ ...prepared,
320
+ previous_response_id: continuation.lastResponseId,
321
+ input: currentInput.slice(baselineLength)
322
+ },
323
+ ...prepared !== request ? { fullRequest: prepared } : {},
324
+ continuationStatus: "continued"
325
+ };
326
+ }
327
+ const httpContinuationEntries = /* @__PURE__ */ new Map();
328
+ function deleteHttpContinuationIfOwned(key, entry) {
329
+ if (httpContinuationEntries.get(key) === entry) httpContinuationEntries.delete(key);
330
+ }
331
+ function connectionIdentity(params) {
332
+ const headers = Object.entries(resolveAiTransportHeaderSentinels(params.headers) ?? {}).map(([name, value]) => [name.toLowerCase(), value]).filter(([name]) => !TURN_HEADERS.has(name)).toSorted(([a], [b]) => a.localeCompare(b));
333
+ return sha256Hex(JSON.stringify([
334
+ getAiTransportHost().resolveSecretSentinel(params.apiKey),
335
+ params.baseUrl,
336
+ headers
337
+ ]));
338
+ }
339
+ function claimOpenAIResponsesHttpContinuation(params) {
340
+ const key = `${params.sessionId}\0${connectionIdentity(params)}`;
341
+ const previous = httpContinuationEntries.get(key);
342
+ if (previous?.kind === "claimed") return;
343
+ if (previous?.kind === "ready") clearTimeout(previous.idleTimer);
344
+ const claimed = {
345
+ kind: "claimed",
346
+ sessionId: params.sessionId
347
+ };
348
+ httpContinuationEntries.set(key, claimed);
349
+ try {
350
+ const request = previous?.kind === "ready" ? params.request : params.restoreRequest?.() ?? params.request;
351
+ const resolved = resolveResponsesContinuationRequest(previous?.kind === "ready" ? previous.state : void 0, request);
352
+ const fullRequest = resolved.fullRequest ?? request;
353
+ return {
354
+ request: params.request.store === false ? fullRequest : resolved.request,
355
+ fullRequest,
356
+ commit: (effectiveRequest, response) => {
357
+ if (httpContinuationEntries.get(key) !== claimed) return;
358
+ const ready = {
359
+ ...claimed,
360
+ kind: "ready",
361
+ state: {
362
+ lastRequest: effectiveRequest,
363
+ lastResponseId: response.id,
364
+ lastResponseItems: response.output
365
+ },
366
+ idleTimer: setTimeout(() => deleteHttpContinuationIfOwned(key, ready), HTTP_CONTINUATION_IDLE_TTL_MS)
367
+ };
368
+ ready.idleTimer.unref?.();
369
+ httpContinuationEntries.set(key, ready);
370
+ },
371
+ release: () => deleteHttpContinuationIfOwned(key, claimed)
372
+ };
373
+ } catch (error) {
374
+ deleteHttpContinuationIfOwned(key, claimed);
375
+ throw error;
376
+ }
377
+ }
378
+ registerSessionResourceCleanup((sessionId) => {
379
+ for (const [key, entry] of httpContinuationEntries) if (!sessionId || entry.sessionId === sessionId) {
380
+ if (entry.kind === "ready") clearTimeout(entry.idleTimer);
381
+ httpContinuationEntries.delete(key);
382
+ }
383
+ });
384
+ //#endregion
190
385
  //#region packages/ai/src/transports/openai-responses-input-replay.ts
191
386
  function recordResponsesInputReplay(message, replay) {
192
387
  if (replay) Object.assign(message, { openclawResponsesInputReplay: replay });
@@ -605,6 +800,83 @@ function convertProviderResponsesMessages(model, context, allowedToolCallProvide
605
800
  return convertResponsesMessagesWithStyle(model, context, allowedToolCallProviders, options, "provider");
606
801
  }
607
802
  //#endregion
803
+ //#region packages/ai/src/transports/openai-responses-context-usage.ts
804
+ const TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set([
805
+ "openai",
806
+ "opencode",
807
+ "azure-openai-responses",
808
+ "github-copilot"
809
+ ]);
810
+ function inputReplay(message) {
811
+ const value = "openclawResponsesInputReplay" in message ? message.openclawResponsesInputReplay : void 0;
812
+ return isRecord(value) ? value : void 0;
813
+ }
814
+ function contextFingerprint(input, output = []) {
815
+ const reasoning = [...input, ...output].flatMap((item) => {
816
+ if (!isRecord(item) || item.type !== "reasoning") return [];
817
+ const { id: _id, status: _status, ...content } = item;
818
+ return [content];
819
+ });
820
+ return sha256Hex(stableStringify({
821
+ prefix: responsesContinuationPrefixFingerprint(input, output),
822
+ reasoning
823
+ }));
824
+ }
825
+ /** Bind measured usage to the admitted replay prefix, without copying its content. */
826
+ function recordResponsesContextUsage(message, model, identity, request, output, projection) {
827
+ const usage = message.usage.contextUsage;
828
+ 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;
829
+ const replayOutput = (projection === "transport" ? convertResponsesMessages$1 : convertProviderResponsesMessages)(model, { messages: [message] }, TOOL_CALL_PROVIDERS, {
830
+ ...identity,
831
+ includeSystemPrompt: false
832
+ }).filter((item) => item.type !== "function_call_output");
833
+ const firstInput = request.input[0];
834
+ const contextUsage = {
835
+ ...buildProviderReplayContext(model, identity),
836
+ projection,
837
+ includeSystemPrompt: request.instructions === void 0 && firstInput?.type === "message" && (firstInput.role === "developer" || firstInput.role === "system"),
838
+ prefixHash: contextFingerprint(request.input, replayOutput),
839
+ prefixLength: request.input.length + replayOutput.length,
840
+ promptTokens: usage.promptTokens,
841
+ totalTokens: usage.totalTokens
842
+ };
843
+ Object.assign(message, { openclawResponsesInputReplay: {
844
+ ...inputReplay(message),
845
+ contextUsage
846
+ } });
847
+ }
848
+ /** Only matching provider input may replace the conservative local pressure estimate. */
849
+ function resolveResponsesContextUsageBoundary(messages, model, identity, systemPrompt) {
850
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
851
+ const message = messages[index];
852
+ if (!message || !isAssistant(message)) continue;
853
+ const state = inputReplay(message)?.contextUsage;
854
+ const usage = message.usage.contextUsage;
855
+ if (!isRecord(state) || usage?.state !== "available") continue;
856
+ const { projection, prefixHash, prefixLength, promptTokens, totalTokens, includeSystemPrompt } = state;
857
+ 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;
858
+ const input = (projection === "transport" ? convertResponsesMessages$1 : convertProviderResponsesMessages)(model, {
859
+ messages: messages.filter(isProviderMessage),
860
+ systemPrompt
861
+ }, TOOL_CALL_PROVIDERS, {
862
+ ...identity,
863
+ includeSystemPrompt: includeSystemPrompt === true
864
+ });
865
+ if (input.length < prefixLength || contextFingerprint(input.slice(0, prefixLength)) !== prefixHash) return;
866
+ return {
867
+ index,
868
+ totalTokens: usage.totalTokens,
869
+ suffix: input.slice(prefixLength)
870
+ };
871
+ }
872
+ }
873
+ function isAssistant(message) {
874
+ return message.role === "assistant";
875
+ }
876
+ function isProviderMessage(message) {
877
+ return message.role === "user" || message.role === "assistant" || message.role === "toolResult";
878
+ }
879
+ //#endregion
608
880
  //#region packages/ai/src/transports/openai-responses-replay-internal.ts
609
881
  function isAsyncIterable(value) {
610
882
  return (typeof value === "object" && value !== null || typeof value === "function") && Symbol.asyncIterator in value;
@@ -691,7 +963,7 @@ async function createResponsesStreamWithEncryptedContentRetry(params) {
691
963
  };
692
964
  } catch (error) {
693
965
  let nextAttempt = await resolveNextResponsesEncryptedContentAttempt(attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest });
694
- if (!nextAttempt && attempt.request.previous_response_id && error && typeof error === "object" && typeof error.status === "number" && error.code === "previous_response_not_found") {
966
+ if (!nextAttempt && attempt.request.previous_response_id && error && typeof error === "object" && typeof error.status === "number" && isPreviousResponseRejection(error)) {
695
967
  const request = { ...params.buildFullHistoryRequest ? await params.buildFullHistoryRequest() : attempt.request };
696
968
  delete request.previous_response_id;
697
969
  nextAttempt = {
@@ -711,43 +983,40 @@ async function createResponsesStreamWithEncryptedContentRetry(params) {
711
983
  request: params.request,
712
984
  ...params.initialRejectedCompaction ? { rejectedCompaction: params.initialRejectedCompaction } : {}
713
985
  });
714
- return {
715
- ...result,
716
- stream: { async *[Symbol.asyncIterator]() {
717
- let current = result;
718
- for (;;) {
719
- let rejectedEvent;
720
- try {
721
- for await (const event of params.wrapStream?.(current) ?? current.stream) {
722
- if (isRecord(event)) {
723
- const failure = event.type === "response.failed" && isRecord(event.response) ? event.response.error : event.type === "error" ? event.error ?? event : void 0;
724
- if (isRecord(failure) && params.canRetryStream?.() === true && isInvalidEncryptedContentError(failure)) {
725
- rejectedEvent = event;
726
- const message = typeof failure.message === "string" ? failure.message : "";
727
- throw Object.assign(new Error(message), {
728
- code: failure.code,
729
- status: failure.status
730
- });
731
- }
986
+ return { stream: { async *[Symbol.asyncIterator]() {
987
+ let current = result;
988
+ for (;;) {
989
+ let rejectedEvent;
990
+ try {
991
+ for await (const event of params.wrapStream?.(current) ?? current.stream) {
992
+ if (isRecord(event)) {
993
+ const failure = event.type === "response.failed" && isRecord(event.response) ? event.response.error : event.type === "error" ? event.error ?? event : void 0;
994
+ if (isRecord(failure) && params.canRetryStream?.() === true && isInvalidEncryptedContentError(failure)) {
995
+ rejectedEvent = event;
996
+ const message = typeof failure.message === "string" ? failure.message : "";
997
+ throw Object.assign(new Error(message), {
998
+ code: failure.code,
999
+ status: failure.status
1000
+ });
732
1001
  }
733
- yield event;
734
1002
  }
735
- return;
736
- } catch (error) {
737
- const nextAttempt = params.canRetryStream?.() === true && !params.requestOptions?.signal?.aborted ? await resolveNextResponsesEncryptedContentAttempt(current.attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest }) : void 0;
738
- if (!nextAttempt) {
739
- if (rejectedEvent !== void 0) {
740
- yield rejectedEvent;
741
- return;
742
- }
743
- throw error;
1003
+ yield event;
1004
+ }
1005
+ return;
1006
+ } catch (error) {
1007
+ const nextAttempt = params.canRetryStream?.() === true && !params.requestOptions?.signal?.aborted ? await resolveNextResponsesEncryptedContentAttempt(current.attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest }) : void 0;
1008
+ if (!nextAttempt) {
1009
+ if (rejectedEvent !== void 0) {
1010
+ yield rejectedEvent;
1011
+ return;
744
1012
  }
745
- log.warn(`[responses] retrying streamed encrypted content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
746
- current = await send(nextAttempt);
1013
+ throw error;
747
1014
  }
1015
+ log.warn(`[responses] retrying streamed encrypted content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
1016
+ current = await send(nextAttempt);
748
1017
  }
749
- } }
750
- };
1018
+ }
1019
+ } } };
751
1020
  }
752
1021
  function resolveAzureOpenAIApiVersion(env = process.env) {
753
1022
  return env.AZURE_OPENAI_API_VERSION?.trim() || "preview";
@@ -1288,86 +1557,6 @@ function createResponsesOutputSlotTracker() {
1288
1557
  };
1289
1558
  }
1290
1559
  //#endregion
1291
- //#region packages/ai/src/providers/openai-responses-terminal-usage.ts
1292
- /**
1293
- * Canonical mapping for terminal OpenAI Responses events.
1294
- *
1295
- * `response.completed`, `response.incomplete`, and `response.failed` are terminal and can carry
1296
- * usage, so every Responses path finalizes through the helpers here. Keeping one owner prevents
1297
- * package and managed transports from drifting on token buckets, service-tier pricing, or future
1298
- * terminal-event semantics.
1299
- */
1300
- function readReportedCount(value) {
1301
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
1302
- }
1303
- function readCount(value) {
1304
- return readReportedCount(value) ?? 0;
1305
- }
1306
- /**
1307
- * Split a terminal usage payload into the priced buckets.
1308
- *
1309
- * OpenAI includes cache reads and writes in `input_tokens`, so both are subtracted out of the
1310
- * billable input bucket. `total_tokens` comes from the payload, but never below the sum of the
1311
- * split buckets: proxies routinely omit it (reporting 0 would understate the turn), and a payload
1312
- * whose `cached_tokens` exceeds `input_tokens` clamps the input bucket, leaving the reported total
1313
- * short of what the buckets actually price.
1314
- */
1315
- function mapResponsesTerminalUsage(usage) {
1316
- if (!usage) return;
1317
- const cacheRead = readCount(usage.input_tokens_details?.cached_tokens);
1318
- const cacheWrite = readCount(usage.input_tokens_details?.cache_write_tokens);
1319
- const input = Math.max(0, readCount(usage.input_tokens) - cacheRead - cacheWrite);
1320
- const output = readCount(usage.output_tokens);
1321
- const bucketTotal = input + output + cacheRead + cacheWrite;
1322
- const totalTokens = Math.max(bucketTotal, readCount(usage.total_tokens));
1323
- const reportedInput = readReportedCount(usage.input_tokens);
1324
- const reportedOutput = readReportedCount(usage.output_tokens);
1325
- const reportedTotal = readReportedCount(usage.total_tokens);
1326
- return {
1327
- input,
1328
- output,
1329
- cacheRead,
1330
- cacheWrite,
1331
- contextUsage: reportedInput !== void 0 && (reportedOutput !== void 0 || reportedTotal !== void 0 && reportedTotal >= reportedInput) && cacheRead + cacheWrite <= reportedInput ? {
1332
- state: "available",
1333
- promptTokens: reportedInput,
1334
- totalTokens: Math.max(totalTokens, reportedInput + (reportedOutput ?? 0))
1335
- } : { state: "unavailable" },
1336
- totalTokens
1337
- };
1338
- }
1339
- /** Reasoning tokens are reported by the agent path only; the package path does not track them. */
1340
- function readResponsesReasoningTokens(usage) {
1341
- return asFiniteNumber(usage?.output_tokens_details?.reasoning_tokens);
1342
- }
1343
- function mapResponsesTerminalStopReason(status) {
1344
- if (!status) return "stop";
1345
- switch (status) {
1346
- case "completed": return "stop";
1347
- case "incomplete": return "length";
1348
- case "failed":
1349
- case "cancelled": return "error";
1350
- case "in_progress":
1351
- case "queued": return "stop";
1352
- default: throw new Error(`Unhandled stop reason: ${String(status)}`);
1353
- }
1354
- }
1355
- /**
1356
- * Resolve the terminal stop reason, including the two overrides every Responses path shares: a
1357
- * content-filtered turn is a provider error rather than a truncated answer, and a turn that
1358
- * produced tool calls reports `toolUse` instead of a plain stop.
1359
- */
1360
- function resolveResponsesTerminalStopReason(params) {
1361
- const status = params.status ?? (params.terminalEventType === "response.incomplete" ? "incomplete" : void 0);
1362
- if (status === "incomplete" && params.incompleteReason === "content_filter") return {
1363
- stopReason: "error",
1364
- errorMessage: "Provider incomplete_reason: content_filter"
1365
- };
1366
- const stopReason = mapResponsesTerminalStopReason(status);
1367
- if (stopReason === "stop" && params.hasToolCall) return { stopReason: "toolUse" };
1368
- return { stopReason };
1369
- }
1370
- //#endregion
1371
1560
  //#region packages/ai/src/transports/openai-responses-stream-terminal-internal.ts
1372
1561
  function splitToolCallId(id) {
1373
1562
  const separator = id.indexOf("|");
@@ -1561,7 +1750,7 @@ function createResponsesTerminalController(params) {
1561
1750
  };
1562
1751
  const finalizeTerminalFacts = (response, responseId = response.id) => {
1563
1752
  output.responseId = responseId || output.responseId;
1564
- output.responseModel = response.model?.trim() || void 0;
1753
+ output.responseModel = options?.resolveResponseModel ? options.resolveResponseModel()?.trim() || void 0 : response.model?.trim() || void 0;
1565
1754
  const usage = mapResponsesTerminalUsage(response.usage);
1566
1755
  const reasoningTokens = readResponsesReasoningTokens(response.usage);
1567
1756
  if (usage) output.usage = {
@@ -1592,6 +1781,17 @@ function createResponsesTerminalController(params) {
1592
1781
  });
1593
1782
  output.stopReason = terminal.stopReason;
1594
1783
  output.errorMessage = terminal.errorMessage;
1784
+ if (terminalEventType === "response.completed" && typeof response.end_turn === "boolean") output.endTurn = response.end_turn;
1785
+ const incompleteReason = response.incomplete_details?.reason;
1786
+ appendAssistantMessageDiagnostic(output, {
1787
+ type: "openai_responses_terminal",
1788
+ timestamp: Date.now(),
1789
+ details: {
1790
+ eventType: terminalEventType,
1791
+ ...terminalEventType === "response.incomplete" ? { incompleteReason: incompleteReason === "max_output_tokens" || incompleteReason === "max_messages" || incompleteReason === "content_filter" || incompleteReason === "steered" ? incompleteReason : "unknown" } : {},
1792
+ endTurn: typeof response.end_turn === "boolean" ? response.end_turn : response.end_turn === void 0 ? "absent" : "invalid"
1793
+ }
1794
+ });
1595
1795
  };
1596
1796
  return {
1597
1797
  finalizeResponse,
@@ -1807,6 +2007,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1807
2007
  block: toolCallBlock,
1808
2008
  contentIndex,
1809
2009
  argumentStreamReliable: true,
2010
+ argumentsStreamed: false,
1810
2011
  previewSchedule: createToolArgumentPreviewSchedule(),
1811
2012
  ...readResponsesToolCallItemIdentity(item)
1812
2013
  };
@@ -1900,6 +2101,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1900
2101
  const toolCall = streamingToolCalls.resolve(event);
1901
2102
  if (toolCall) {
1902
2103
  toolCall.block.partialJson += event.delta;
2104
+ toolCall.argumentsStreamed = true;
1903
2105
  if (toolCall.previewSchedule(toolCall.block.partialJson.length)) toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
1904
2106
  stream.push({
1905
2107
  type: "toolcall_delta",
@@ -1917,6 +2119,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1917
2119
  toolCall.block.partialJson = doneArguments;
1918
2120
  toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
1919
2121
  toolCall.argumentStreamReliable = true;
2122
+ toolCall.argumentsStreamed = true;
1920
2123
  }
1921
2124
  if (doneArguments?.startsWith(previousPartialJson)) {
1922
2125
  const delta = doneArguments.slice(previousPartialJson.length);
@@ -2012,9 +2215,11 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2012
2215
  if (!streamingToolCall && streamingToolCalls.hasActive()) continue;
2013
2216
  const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
2014
2217
  if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
2218
+ const streamedArguments = streamingToolCall?.block.partialJson || "";
2219
+ const preferredArguments = streamingToolCall?.argumentStreamReliable && streamingToolCall?.argumentsStreamed && streamedArguments.length > 0 && completedArguments !== void 0 && streamedArguments !== completedArguments && parseJsonObjectPreservingUnsafeIntegers(streamedArguments) !== null ? streamedArguments : completedArguments || streamedArguments;
2015
2220
  const validated = resolveCompletedResponsesToolCall(item, {
2016
2221
  name: streamingToolCall?.block.name,
2017
- arguments: completedArguments || streamingToolCall?.block.partialJson || ""
2222
+ arguments: preferredArguments
2018
2223
  });
2019
2224
  finalizeToolCall(item, readResponsesOutputIndex(event), streamingToolCall, validated);
2020
2225
  }
@@ -2055,23 +2260,33 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2055
2260
  //#region packages/ai/src/providers/openai-responses-tools.ts
2056
2261
  /** Projects direct provider descriptors before resolving their strict policy. */
2057
2262
  function convertResponsesToolPayload(tools, options) {
2058
- return convertProjectedResponsesTools(projectOpenAITools(tools), resolveResponsesStrictToolSetting(options), options?.model);
2059
- }
2060
- /** Uses caller-prepared facts without rereading descriptors or resolving host policy again. */
2061
- function convertProjectedResponsesTools(projection, strictSetting, model) {
2062
- const strict = model ? resolveOpenAIStrictToolFlagWithDiagnostics(projection, strictSetting, {
2063
- transport: "responses",
2064
- model
2065
- }) : resolveOpenAIProjectedToolsStrictToolFlag(projection, strictSetting);
2066
- return sortPromptCacheToolsByName(projection.tools).map((tool) => {
2067
- const result = {
2068
- type: "function",
2069
- name: tool.name,
2070
- description: tool.description,
2071
- parameters: normalizeOpenAIStrictToolParameters(tool.parameters, strict === true, model?.compat)
2072
- };
2073
- if (strict !== void 0) result.strict = strict;
2074
- return result;
2263
+ return convertPreparedResponsesTools(prepareOpenAITools(tools), resolveResponsesStrictToolSetting(options), options?.model);
2264
+ }
2265
+ /** The transport has already resolved policy before descriptor projection. */
2266
+ function prepareResponsesTools(tools, strictSetting, model) {
2267
+ const prepared = prepareOpenAITools(tools);
2268
+ return {
2269
+ projection: prepared.projection,
2270
+ tools: convertPreparedResponsesTools(prepared, strictSetting, model)
2271
+ };
2272
+ }
2273
+ function convertPreparedResponsesTools(prepared, strictSetting, model) {
2274
+ const { projection, schemas } = prepared;
2275
+ return withPreparedToolSchemaNormalization(schemas, () => {
2276
+ const strict = model ? resolveOpenAIStrictToolFlagWithDiagnostics(projection, strictSetting, {
2277
+ transport: "responses",
2278
+ model
2279
+ }) : resolveOpenAIProjectedToolsStrictToolFlag(projection, strictSetting);
2280
+ return sortPromptCacheToolsByName(projection.tools).map((tool) => {
2281
+ const result = {
2282
+ type: "function",
2283
+ name: tool.name,
2284
+ description: tool.description,
2285
+ parameters: normalizeOpenAIStrictToolParameters(tool.parameters, strict === true, model?.compat)
2286
+ };
2287
+ if (strict !== void 0) result.strict = strict;
2288
+ return result;
2289
+ });
2075
2290
  });
2076
2291
  }
2077
2292
  function resolveResponsesStrictToolSetting(options) {
@@ -2099,19 +2314,6 @@ function applyResponsesServiceTierPricing(usage, serviceTier, model) {
2099
2314
  usage.cost.cacheWrite *= multiplier;
2100
2315
  usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
2101
2316
  }
2102
- function resolveResponsesReasoningEffort(model, reasoning) {
2103
- if (!reasoning) return;
2104
- const clampedReasoning = model.reasoning && model.thinkingLevelMap?.[reasoning] === void 0 && resolveOpenAIModelReasoningEfforts(model)?.includes(reasoning) ? reasoning : clampThinkingLevel(model, reasoning);
2105
- return clampedReasoning === "off" ? void 0 : clampedReasoning;
2106
- }
2107
- function resolveResponsesRequestReasoningEffort(model, reasoning) {
2108
- const mapped = model.thinkingLevelMap?.[reasoning === "none" ? "off" : reasoning];
2109
- if (mapped !== void 0) return mapped ?? void 0;
2110
- return resolveOpenAIModelReasoningEfforts(model) === void 0 ? reasoning === "off" ? "none" : reasoning : resolveOpenAIReasoningEffortForModel({
2111
- model,
2112
- effort: reasoning
2113
- });
2114
- }
2115
2317
  function applyCommonResponsesParams(params, model, context, options, config) {
2116
2318
  if (options?.maxTokens) params.max_output_tokens = Math.max(options.maxTokens, 16);
2117
2319
  if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) params.temperature = options.temperature;
@@ -2121,10 +2323,10 @@ function applyCommonResponsesParams(params, model, context, options, config) {
2121
2323
  }
2122
2324
  if (!model.reasoning) return;
2123
2325
  const requestedEffort = options?.reasoningEffort ?? (options?.reasoningSummary ? "medium" : config?.setDefaultReasoningOff ?? true ? "off" : void 0);
2124
- const effort = requestedEffort === void 0 ? void 0 : resolveResponsesRequestReasoningEffort(model, requestedEffort);
2326
+ const effort = requestedEffort === void 0 ? void 0 : resolveOpenAIRequestReasoning(model, requestedEffort).effort;
2125
2327
  if (effort === void 0) return;
2126
2328
  params.reasoning = { effort };
2127
- if (options?.reasoningEffort || options?.reasoningSummary) {
2329
+ if (effort !== "none" && (options?.reasoningEffort || options?.reasoningSummary)) {
2128
2330
  params.reasoning.summary = options?.reasoningSummary || "auto";
2129
2331
  params.include = ["reasoning.encrypted_content"];
2130
2332
  }
@@ -2158,6 +2360,7 @@ async function runResponsesStreamLifecycle(params) {
2158
2360
  const firstEvent = createFirstStreamEventAbortController(options?.signal);
2159
2361
  firstEventAbort = firstEvent;
2160
2362
  let started = false;
2363
+ let admittedRequest;
2161
2364
  const { stream: hookedOpenAIStream } = await createResponsesStreamWithEncryptedContentRetry({
2162
2365
  client,
2163
2366
  request: requestParams,
@@ -2169,25 +2372,28 @@ async function runResponsesStreamLifecycle(params) {
2169
2372
  buildFullHistoryRequest: () => buildRequest("full-history"),
2170
2373
  onCompactionRejected: (checkpoint) => suppressOpenAIResponsesCompaction(output, model, options, checkpoint),
2171
2374
  canRetryStream: () => output.content.length === 0,
2172
- wrapStream: ({ stream: openaiStream, response }) => withProviderResponseHook({
2173
- stream: openaiStream,
2174
- signal: firstEvent.signal,
2175
- abort: firstEvent.abort,
2176
- hook: createOpenAIProviderAcceptanceHook(options, response, model),
2177
- onReady: () => {
2178
- if (!started) {
2179
- started = true;
2180
- stream.push({
2181
- type: "start",
2182
- partial: output
2183
- });
2375
+ wrapStream: ({ stream: openaiStream, response, attempt }) => {
2376
+ admittedRequest = attempt.kind === "initial" ? attempt.request : void 0;
2377
+ return withProviderResponseHook({
2378
+ stream: openaiStream,
2379
+ signal: firstEvent.signal,
2380
+ abort: firstEvent.abort,
2381
+ hook: createOpenAIProviderAcceptanceHook(options, response, model),
2382
+ onReady: () => {
2383
+ if (!started) {
2384
+ started = true;
2385
+ stream.push({
2386
+ type: "start",
2387
+ partial: output
2388
+ });
2389
+ }
2184
2390
  }
2185
- }
2186
- })
2391
+ });
2392
+ }
2187
2393
  });
2188
2394
  const firstEventTimeoutMs = getFirstStreamEventTimeoutMs(options);
2189
2395
  const onFirstEventTimeout = getFirstStreamEventTimeoutHandler(options);
2190
- await processResponsesStream(hookedOpenAIStream, output, stream, model, {
2396
+ const terminal = await processResponsesStream(hookedOpenAIStream, output, stream, model, {
2191
2397
  ...params.processStreamOptions || firstEventTimeoutMs !== void 0 || onFirstEventTimeout !== void 0 ? {
2192
2398
  ...params.processStreamOptions,
2193
2399
  firstEventTimeoutMs: params.processStreamOptions?.firstEventTimeoutMs ?? firstEventTimeoutMs,
@@ -2200,6 +2406,7 @@ async function runResponsesStreamLifecycle(params) {
2200
2406
  authProfileId: options?.authProfileId
2201
2407
  })
2202
2408
  });
2409
+ if (terminal && admittedRequest && !options?.signal?.aborted) recordResponsesContextUsage(output, model, options, admittedRequest, terminal.output, "provider");
2203
2410
  finalizeTransportStream({
2204
2411
  stream,
2205
2412
  output,
@@ -2218,4 +2425,4 @@ async function runResponsesStreamLifecycle(params) {
2218
2425
  }
2219
2426
  }
2220
2427
  //#endregion
2221
- export { resolveResponsesMessageSnapshotCollapse as A, responsesInputFingerprint as B, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as C, isAzureResponsesTextDeltaEventType as D, isAzureResponsesTextDeltaEvent as E, resolveNextResponsesEncryptedContentAttempt as F, resolveNewestOpenAIResponsesCompactionReplay as G, buildOpenAIResponsesReasoningReplayMetadata as H, buildResponsesInputMessage as I, suppressOpenAIResponsesCompaction as K, convertResponsesMessages$1 as L, createResponsesStreamWithEncryptedContentRetry as M, isInvalidEncryptedContentError as N, isResponsesTextContentPartType as O, resolveAzureOpenAIApiVersion as P, createOpenAIResponsesAssistantOutput as R, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as S, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as T, captureOpenAIResponsesCompaction as U, CompactionReplayRefreshRequiredError as V, isOpenAIResponsesReplayContext as W, safeDebugValue as _, resolveResponsesReasoningEffort as a, createResponsesToolCallTracker as b, convertProjectedResponsesTools as c, mapResponsesTerminalUsage as d, readResponsesReasoningTokens as f, logResponsesFailedNoDetails as g, ResponsesStreamFailure as h, createResponsesAssistantOutput as i, commitResponsesEncryptedContentAttempt as j, isResponsesTextDeltaEventType as k, convertResponsesToolPayload as l, observeResponsesStream as m, applyResponsesServiceTierPricing as n, resolveResponsesRequestReasoningEffort as o, resolveResponsesTerminalStopReason as p, resolveReplayableResponsesMessageId as q, convertResponsesMessages as r, runResponsesStreamLifecycle as s, applyCommonResponsesParams as t, processResponsesStream as u, summarizeOpenAITransportError as v, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as w, readResponsesToolCallItemIdentity as x, summarizeResponsesPayload as y, recordResponsesInputReplay as z };
2428
+ export { resolveNextResponsesEncryptedContentAttempt as A, responsesContinuationPrefixFingerprint as B, isResponsesTextContentPartType as C, createResponsesStreamWithEncryptedContentRetry as D, commitResponsesEncryptedContentAttempt as E, createOpenAIResponsesAssistantOutput as F, CompactionReplayRefreshRequiredError as G, isConfigurationUpdate as H, recordResponsesInputReplay as I, isOpenAIResponsesReplayContext as J, buildOpenAIResponsesReasoningReplayMetadata as K, responsesInputFingerprint as L, resolveResponsesContextUsageBoundary as M, buildResponsesInputMessage as N, isInvalidEncryptedContentError as O, convertResponsesMessages$1 as P, claimOpenAIResponsesHttpContinuation as R, isAzureResponsesTextDeltaEventType as S, resolveResponsesMessageSnapshotCollapse as T, replayResponsesReasoningUpdates as U, responsesContinuationRequestFingerprint as V, supportsResponsesReasoningUpdate as W, suppressOpenAIResponsesCompaction as X, resolveNewestOpenAIResponsesCompactionReplay as Y, resolveReplayableResponsesMessageId as Z, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as _, runResponsesStreamLifecycle as a, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as b, processResponsesStream as c, logResponsesFailedNoDetails as d, safeDebugValue as f, readResponsesToolCallItemIdentity as g, createResponsesToolCallTracker as h, createResponsesAssistantOutput as i, recordResponsesContextUsage as j, resolveAzureOpenAIApiVersion as k, observeResponsesStream as l, summarizeResponsesPayload as m, applyResponsesServiceTierPricing as n, convertResponsesToolPayload as o, summarizeOpenAITransportError as p, captureOpenAIResponsesCompaction as q, convertResponsesMessages as r, prepareResponsesTools as s, applyCommonResponsesParams as t, ResponsesStreamFailure as u, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as v, isResponsesTextDeltaEventType as w, isAzureResponsesTextDeltaEvent as x, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as y, resolveResponsesContinuationRequest as z };