@openclaw/ai 2026.8.1-beta.3 → 2026.8.2

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 (91) hide show
  1. package/dist/{anthropic-B8KwTtlb.mjs → anthropic-DTGZ4VMY.mjs} +25 -23
  2. package/dist/{anthropic-compaction-replay-4Zx7-aCr.mjs → anthropic-compaction-replay-CKCDrZJv.mjs} +34 -35
  3. package/dist/{anthropic-payload-policy-CSx7MoKH.d.mts → anthropic-payload-policy-BTzmNC14.d.mts} +3 -2
  4. package/dist/{api-registry-DFxSnFqG.d.mts → api-registry-BbUHEKER.d.mts} +2 -1
  5. package/dist/{azure-openai-responses-Aa4mVcYG.mjs → azure-openai-responses-BmqaDXM1.mjs} +6 -5
  6. package/dist/{number-coercion-H9qHik3g.mjs → base64-CEFBpSkN.mjs} +73 -1
  7. package/dist/diagnostics.d.mts +2 -3
  8. package/dist/diagnostics.mjs +1 -1
  9. package/dist/{env-api-keys-DrgeBuva.mjs → env-api-keys-bktO00EJ.mjs} +2 -15
  10. package/dist/{event-stream-D91-ohD_.d.mts → event-stream-DcvAPSBe.d.mts} +1 -2
  11. package/dist/event-stream-pXT3FI6X.d.mts +1 -0
  12. package/dist/event-stream.d.mts +2 -1
  13. package/dist/{google-yDRnipeq.mjs → google-CqjVZMwo.mjs} +8 -6
  14. package/dist/{google-shared-M1dl64nz.mjs → google-shared-Bnqni5j3.mjs} +34 -25
  15. package/dist/{google-vertex-DCJHM_a5.mjs → google-vertex-D_WREEJi.mjs} +8 -6
  16. package/dist/{host-DF_yxOsA.mjs → host-BIaiBURL.mjs} +4 -8
  17. package/dist/{host-DJq_FGcz.d.mts → host-DKFUAmCn.d.mts} +3 -3
  18. package/dist/index-CefaUGSS.d.mts +111 -0
  19. package/dist/index.d.mts +9 -10
  20. package/dist/index.mjs +4 -5
  21. package/dist/internal/anthropic.d.mts +51 -49
  22. package/dist/internal/anthropic.mjs +5 -5
  23. package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
  24. package/dist/internal/openai-responses-payload-policy.mjs +2 -3
  25. package/dist/internal/openai.d.mts +65 -63
  26. package/dist/internal/openai.mjs +10 -9
  27. package/dist/internal/retry-after.d.mts +2 -3
  28. package/dist/internal/runtime.d.mts +51 -40
  29. package/dist/internal/runtime.mjs +9 -9
  30. package/dist/internal/shared.d.mts +25 -25
  31. package/dist/internal/shared.mjs +3 -3
  32. package/dist/{json-parse-CDnesDM_.mjs → json-parse-BuAJEbdW.mjs} +18 -2
  33. package/dist/{mistral-D6hRXI7A.mjs → mistral-C24jVd6f.mjs} +34 -32
  34. package/dist/{openai-chatgpt-responses-C339VIfT.mjs → openai-chatgpt-responses-Czum0oXz.mjs} +38 -20
  35. package/dist/openai-completions-BfFwac6f.mjs +404 -0
  36. package/dist/{openai-completions-compat-B0KTleXp.d.mts → openai-completions-compat-SZhi0Lf4.d.mts} +3 -3
  37. package/dist/openai-completions-stream-DGOvau4J.mjs +1625 -0
  38. package/dist/{openai-responses-BXEcr-Tp.mjs → openai-responses-BAryVEJM.mjs} +11 -7
  39. package/dist/openai-responses-compaction-window-DO7yV7az.mjs +686 -0
  40. package/dist/{openai-responses-contracts-CD75pQ0m.d.mts → openai-responses-contracts-BthRXano.d.mts} +14 -5
  41. package/dist/{openai-responses-payload-policy-CNGFT9zr.d.mts → openai-responses-payload-policy-rLRPsSmB.d.mts} +1 -0
  42. package/dist/{openai-responses-prompt-observer-internal-BG-1AsBI.mjs → openai-responses-prompt-observer-internal--R0kZLOZ.mjs} +3 -2
  43. package/dist/{openai-responses-shared-Cvt5MgEm.mjs → openai-responses-shared-CxgdGBvm.mjs} +332 -1484
  44. package/dist/openai-stop-reason-Drnn_6Qj.mjs +28 -0
  45. package/dist/openai-tool-schema-CSMh5e9O.mjs +1697 -0
  46. package/dist/{provider-error-C8mBRJDl.mjs → provider-error-BI8kIViN.mjs} +14 -88
  47. package/dist/{provider-options-Cc5ZQ6Aa.d.mts → provider-options-DJd_9euj.d.mts} +13 -4
  48. package/dist/{provider-transcript-transform--gtf0ZbR.mjs → provider-transcript-transform-WvJmFUAf.mjs} +1 -1
  49. package/dist/provider-types.d.mts +18 -17
  50. package/dist/providers.d.mts +5 -6
  51. package/dist/providers.mjs +9 -9
  52. package/dist/{reasoning-tag-text-partitioner-5ygO2rZc.mjs → reasoning-tag-text-partitioner-BsUX44Tq.mjs} +30 -20
  53. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  54. package/dist/{sanitize-unicode-BP7HLLZn.mjs → sanitize-unicode-S6binQG-.mjs} +2 -9
  55. package/dist/simple-options-rdOPzr7Z.mjs +155 -0
  56. package/dist/{anthropic-BQXQudmA.mjs → src-C8U7lkoa.mjs} +75 -1
  57. package/dist/{stream-first-event-timeout-MK28puvq.mjs → stream-first-event-timeout-DcNjoFQE.mjs} +1 -1
  58. package/dist/{streaming-byte-guard-BrbkbwUu.mjs → streaming-byte-guard-CC-HMn_u.mjs} +5 -6
  59. package/dist/string-normalization--fwJ4S2q.mjs +16 -0
  60. package/dist/{tool-schema-json-projection-FEr-jOoZ.mjs → tool-schema-json-projection-BtZiml7r.mjs} +22 -32
  61. package/dist/transport-stream-shared-BbG7PThh.d.mts +138 -0
  62. package/dist/{simple-options-oqsXB6U3.mjs → transport-stream-shared-D8nQWCUo.mjs} +10 -118
  63. package/dist/{transport-utils-Bv0FHkd0.mjs → transport-utils-CtuS1Upe.mjs} +10 -10
  64. package/dist/transports.d.mts +130 -189
  65. package/dist/transports.mjs +227 -1249
  66. package/dist/{types-DTAP49HF.d.mts → types-Beemor2E.d.mts} +58 -24
  67. package/dist/types-COdhCX0U.d.mts +1 -0
  68. package/dist/types.d.mts +6 -5
  69. package/dist/types.mjs +3 -4
  70. package/dist/utf16-slice-qz3nsy87.mjs +84 -0
  71. package/dist/{validation-DYNNrU9u.d.mts → validation-CC6s7Smp.d.mts} +1 -2
  72. package/dist/{validation-B61OhAio.mjs → validation-CJZtym2g.mjs} +7 -5
  73. package/dist/validation.d.mts +1 -1
  74. package/dist/validation.mjs +1 -1
  75. package/package.json +6 -6
  76. package/dist/anthropic-BECQCNdF.d.mts +0 -98
  77. package/dist/event-stream-BVVgDSdq.d.mts +0 -1
  78. package/dist/headers-B_e4-1J0.mjs +0 -9
  79. package/dist/index-BVVgDSdq.d.mts +0 -1
  80. package/dist/openai-completions-D88orSJ9.mjs +0 -632
  81. package/dist/openai-responses-contracts-DvILoqBk.mjs +0 -247
  82. package/dist/openai-responses-payload-policy-BDo8CQsx.mjs +0 -208
  83. package/dist/openai-stop-reason-9OONKyAm.mjs +0 -579
  84. package/dist/openai-tool-projection-CHGLt03m.mjs +0 -426
  85. package/dist/provider-options-AvldWZt8.mjs +0 -21
  86. package/dist/record-coerce-DdXsgUd_.mjs +0 -23
  87. package/dist/src-D2H6yKkH.mjs +0 -2
  88. package/dist/stream-first-event-timeout-DvDeSucC.d.mts +0 -29
  89. package/dist/string-coerce-fsri9iCu.mjs +0 -34
  90. package/dist/types-BVVgDSdq.d.mts +0 -1
  91. package/dist/utf16-slice-CvGodqok.mjs +0 -29
@@ -1,30 +1,27 @@
1
- import { n as getEnvApiKey } from "./env-api-keys-DrgeBuva.mjs";
2
- import { d as resolveClaudeSonnet5ModelIdentity, g as supportsClaudeNativeXhighEffort, p as supportsClaudeAdaptiveThinking, u as resolveClaudeOpus5ModelIdentity } from "./anthropic-BQXQudmA.mjs";
3
- import { n as normalizeLowercaseStringOrEmpty, t as hasNonEmptyString } from "./string-coerce-fsri9iCu.mjs";
4
- import { r as calculateCost } from "./sanitize-unicode-BP7HLLZn.mjs";
5
- import { S as usesClaudeStreamingRefusalContract, _ as prepareClaudeNoPrefillRequestContext, a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, f as ANTHROPIC_CLAUDE_CODE_BILLING_SYSTEM_BLOCK, g as mapAnthropicStopReason, h as defaultsClaudeAdaptiveThinking, m as applyClaudeRequestContract, n as getAiTransportHost, p as ANTHROPIC_CLAUDE_CODE_VERSION, r as resolveAiTransportHeaderSentinels, s as extractToolResultBlockText, v as requiresClaudeAdaptiveThinking, x as usesClaudeFable5MessagesContract, y as resolveAnthropicThinkingEffort } from "./host-DF_yxOsA.mjs";
6
- import { a as isRecord } from "./record-coerce-DdXsgUd_.mjs";
7
- import { i as canonicalizeBase64, o as stableStringify } from "./provider-error-C8mBRJDl.mjs";
8
- import { n as toErrorObject, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-BG-1AsBI.mjs";
9
- import { r as asNonNegativeFiniteNumber } from "./number-coercion-H9qHik3g.mjs";
10
- import { _ as isOpenAIGpt56Model, d as OpenAIResponsesWebSocketSafeRetryError, g as isOpenAIGpt55Model, h as isOpenAIGpt54MiniModel, i as OPENAI_RESPONSES_APIS, l as OpenAIResponsesWebSocketPostDispatchError, p as parseOpenAIResponsesWebSocketServerError, r as OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS, t as AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS, u as OpenAIResponsesWebSocketPreDispatchError, v as normalizeOpenAIReasoningEffort, w as uniqueStrings, y as resolveOpenAIReasoningEffortForModel } from "./openai-responses-contracts-DvILoqBk.mjs";
11
- import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
1
+ import { g as supportsClaudeAdaptiveThinking, m as resolveClaudeSonnet5ModelIdentity, p as resolveClaudeOpus5ModelIdentity, y as supportsClaudeNativeXhighEffort } from "./src-C8U7lkoa.mjs";
2
+ import { c as normalizeLowercaseStringOrEmpty, o as isRecord, s as hasNonEmptyString } from "./utf16-slice-qz3nsy87.mjs";
3
+ import { r as calculateCost } from "./sanitize-unicode-S6binQG-.mjs";
4
+ import { S as usesClaudeStreamingRefusalContract, _ as prepareClaudeNoPrefillRequestContext, a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, f as ANTHROPIC_CLAUDE_CODE_BILLING_SYSTEM_BLOCK, g as mapAnthropicStopReason, h as defaultsClaudeAdaptiveThinking, m as applyClaudeRequestContract, n as getAiTransportHost, p as ANTHROPIC_CLAUDE_CODE_VERSION, r as resolveAiTransportHeaderSentinels, s as extractToolResultBlockText, v as requiresClaudeAdaptiveThinking, x as usesClaudeFable5MessagesContract, y as resolveAnthropicThinkingEffort } from "./host-BIaiBURL.mjs";
5
+ import { i as stableStringify } from "./provider-error-BI8kIViN.mjs";
6
+ import { n as toErrorObject, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal--R0kZLOZ.mjs";
7
+ import { a as asNonNegativeFiniteNumber } from "./base64-CEFBpSkN.mjs";
8
+ import { n as uniqueStrings } from "./string-normalization--fwJ4S2q.mjs";
9
+ import { A as applyAnthropicCacheControlToMessages, C as applyAnthropicFallbackBoundary, D as createAnthropicInlineImageBudget, E as applyAnthropicRefusal, F as resolveAnthropicServerCompactionPlan, I as isAnthropicOAuthApiKey, L as omitFoundryBearerCredentialHeaders, M as applyAnthropicPayloadPolicyToParams, N as resolveAnthropicEphemeralCacheControl, O as normalizeAnthropicInlineContent, P as resolveAnthropicPayloadPolicy, R as usesFoundryBearerAuth, T as resolveAnthropicFallbackServingModelCost, _ as toClaudeCodeToolName, a as suppressAnthropicCompaction, b as ANTHROPIC_SERVER_SIDE_FALLBACKS, f as normalizeAnthropicToolCallId, g as resolveOriginalAnthropicToolName, h as reconcileAnthropicToolChoice, i as resolveNewestAnthropicCompaction, j as applyAnthropicEphemeralCacheControlMarkers, k as resolveAnthropicImageMediaType, m as projectAnthropicTools, n as createCompactionCapture, o as applyAnthropicMessageDeltaUsage, p as normalizeAnthropicToolChoice, r as isAnthropicReplayRejection, s as applyAnthropicMessageStartUsage, t as buildAnthropicReplayPlan, v as ANTHROPIC_OMITTED_REASONING_TEXT, w as readAnthropicFallbackBoundary, x as ANTHROPIC_SERVER_SIDE_FALLBACK_BETA, y as findActiveAnthropicToolTurnAssistantIndex } from "./anthropic-compaction-replay-CKCDrZJv.mjs";
12
10
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
13
- import { C as withProviderResponseHook, E as quoteUnsafeIntegerLiterals, P as sortPromptCacheToolsByName, S as withProviderAcceptanceObserver, T as parseJsonPreservingUnsafeIntegers, _ as notifyProviderStreamOpened, a as assignTransportErrorDetails, b as sanitizeTransportPayloadText, c as createEmptyTransportUsage, d as finalizeTerminalToolCallArguments, f as finalizeTransportStream, g as notifyProviderHttpResponse, h as notifyProviderHttpMetadata, j as stripSystemPromptCacheBoundary, l as createWritableTransportEventStream, m as mergeTransportMetadata, o as coerceTransportToolCallArguments, p as mergeTransportHeaders, s as copyProviderAcceptanceObserver, t as adjustMaxTokensForThinking, u as failTransportStream, v as parseTerminalToolCallArguments, w as parseJsonObjectPreservingUnsafeIntegers, x as transportAbortError, y as sanitizeNonEmptyTransportPayloadText } from "./simple-options-oqsXB6U3.mjs";
14
- import { a as resolveProviderEndpoint, c as transformTransportMessages, i as resolveOpenAIStrictToolSetting, n as buildGuardedModelFetch, r as resolveModelRequestTimeoutMs, s as resolveProviderRequestPolicyConfig } from "./tool-schema-json-projection-FEr-jOoZ.mjs";
15
- import { A as resolveAnthropicImageMediaType, C as readAnthropicFallbackBoundary, D as usesFoundryBearerAuth, E as omitFoundryBearerCredentialHeaders, F as resolveAnthropicPayloadPolicy, I as resolveAnthropicServerCompactionPlan, M as applyAnthropicEphemeralCacheControlMarkers, N as applyAnthropicPayloadPolicyToParams, O as createAnthropicInlineImageBudget, P as resolveAnthropicEphemeralCacheControl, S as applyAnthropicFallbackBoundary, T as applyAnthropicRefusal, _ as ANTHROPIC_OMITTED_REASONING_TEXT, a as applyAnthropicMessageDeltaUsage, b as ANTHROPIC_SERVER_SIDE_FALLBACK_BETA, d as normalizeAnthropicToolCallId, f as normalizeAnthropicToolChoice, g as toClaudeCodeToolName, h as resolveOriginalAnthropicToolName, i as suppressAnthropicCompaction, j as applyAnthropicCacheControlToMessages, k as normalizeAnthropicInlineContent, m as reconcileAnthropicToolChoice, n as createCompactionCapture, o as applyAnthropicMessageStartUsage, p as projectAnthropicTools, r as isAnthropicReplayRejection, t as buildAnthropicReplayPlan, v as findActiveAnthropicToolTurnAssistantIndex, w as resolveAnthropicFallbackServingModelCost, y as ANTHROPIC_SERVER_SIDE_FALLBACKS } from "./anthropic-compaction-replay-4Zx7-aCr.mjs";
16
- import { a as createOpenAICompletionsToolCallDeltaNormalizer, c as resolveOpenAICompletionsCompat, d as clearPendingCommentaryText, f as rememberPendingCommentaryTags, h as tagUnresolvedTextAsCommentary, i as hasToolCallHistory, l as resolveOpenAICompletionsResponseFormat, m as tagPendingCommentaryText, n as resolveOpenAIReasoningEffortMap, o as finalizeOpenAICompletionsToolCalls, p as tagInterruptedTextPhases, r as convertMessages, s as detectOpenAICompletionsCompat, t as mapOpenAIStopReason, u as shouldOmitOllamaCompatResponseFormat } from "./openai-stop-reason-9OONKyAm.mjs";
11
+ import { a as codeModeToolSurfaceObserver, d as stripSystemPromptCacheBoundary, m as sortPromptCacheToolsByName, o as reasoningTagTextPolicy, t as adjustMaxTokensForThinking } from "./simple-options-rdOPzr7Z.mjs";
12
+ import { a as resolveProviderEndpoint, c as transformTransportMessages, i as resolveOpenAIStrictToolSetting, n as buildGuardedModelFetch } from "./tool-schema-json-projection-BtZiml7r.mjs";
13
+ import { a as isGoogleGemini3FlashModel, c as parseRetryAfterSeconds, f as resolveModelHeaderSentinels$1, i as isCodeModeModelVisibleToolName, l as readResponseTextSnippet, m as supportsModelTools, n as createAbortError$1, o as isGoogleGemini3ProModel, p as sha256Hex, r as estimateStringChars, t as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, u as redactIdentifier } from "./transport-utils-CtuS1Upe.mjs";
14
+ import { n as getEnvApiKey } from "./env-api-keys-bktO00EJ.mjs";
15
+ import { S as quoteUnsafeIntegerLiterals, _ as transportAbortError, a as createWritableTransportEventStream, b as parseJsonObjectPreservingUnsafeIntegers, c as finalizeTransportStream, d as notifyProviderHttpMetadata, f as notifyProviderHttpResponse, g as sanitizeTransportPayloadText, h as sanitizeNonEmptyTransportPayloadText, i as createEmptyTransportUsage, l as mergeTransportHeaders, m as parseTerminalToolCallArguments, n as coerceTransportToolCallArguments, o as failTransportStream, p as notifyProviderStreamOpened, r as copyProviderAcceptanceObserver, s as finalizeTerminalToolCallArguments, t as assignTransportErrorDetails, u as mergeTransportMetadata, v as withProviderAcceptanceObserver, x as parseJsonPreservingUnsafeIntegers, y as withProviderResponseHook } from "./transport-stream-shared-D8nQWCUo.mjs";
16
+ import { C as createDeepSeekTextFilter, E as tagUnresolvedTextAsCommentary, S as shouldOmitOllamaCompatResponseFormat, T as tagPendingCommentaryText, _ as hasToolCallHistory, a as buildOpenAISdkClientOptions, b as resolveOpenAICompletionsCompat, c as filterCodeModePayloadTools, d as readCodeModePayloadToolName, f as resolveCodeModeResponsesVisibleToolNames, g as convertMessages, h as resolveOpenAIReasoningEffortMap, i as buildOpenAIClientHeaders, l as getCompat, m as usesNativeOpenAICodexResponsesBackend, n as shouldEmitOpenAICompletionsReasoning, o as buildOpenAISdkRequestOptions, p as resolveOpenAIStrictToolFlagWithDiagnostics, r as assertCodeModeResponsesToolSurface, s as enforceCodeModeResponsesToolSurface, t as processCompletionsStream, u as isOpenAICodexResponsesModel, v as finalizeOpenAICompletionsToolCalls, x as resolveOpenAICompletionsResponseFormat, y as detectOpenAICompletionsCompat } from "./openai-completions-stream-DGOvau4J.mjs";
17
17
  import { t as createDeferredEventBuffer } from "./deferred-event-buffer-DAvyP7qA.mjs";
18
- import { n as parseStreamingJson } from "./json-parse-CDnesDM_.mjs";
18
+ import { r as parseStreamingJson, t as createToolArgumentPreviewSchedule } from "./json-parse-BuAJEbdW.mjs";
19
19
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
20
- import { a as isGoogleGemini3FlashModel, c as readResponseTextSnippet, d as resolveModelHeaderSentinels$1, f as resolveSecretSentinel, i as isCodeModeModelVisibleToolName, l as redactIdentifier, m as supportsModelTools, n as createAbortError$1, o as isGoogleGemini3ProModel, p as sha256Hex, r as estimateStringChars, s as parseRetryAfterSeconds, t as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "./transport-utils-Bv0FHkd0.mjs";
21
20
  import { t as googleFlashSupportsMinimalThinking } from "./google-thinking-level-C-V3tecN.mjs";
22
- import { B as buildResponsesInputMessage, C as summarizeResponsesTools, G as suppressOpenAIResponsesCompaction, H as createOpenAIResponsesAssistantOutput, I as createResponsesStreamWithEncryptedContentRetry, K as resolveReplayableResponsesMessageId, L as isInvalidEncryptedContentError, R as resolveAzureOpenAIApiVersion, S as summarizeResponsesPayload, U as buildOpenAIResponsesReasoningReplayMetadata, V as convertResponsesMessages, W as captureOpenAIResponsesCompaction, Y as normalizeOpenAIStrictToolParameters, Z as resolveOpenAIProjectedToolsStrictToolFlag, _ as safeDebugValue, b as summarizeOpenAITransportError, c as processResponsesStream, dt as resolveModelPayloadDebugMode, f as observeResponsesStream, ft as resolveModelSseDebugMode, g as normalizeResponsesFailedEvent, h as logResponsesFailedNoDetails, m as buildResponsesFailedNoDetailsObservation, n as applyResponsesServiceTierPricing, p as ResponsesStreamFailure, q as findOpenAIStrictToolProjectionDiagnostics, ut as emitModelTransportDebug, v as stringifyRedactedEvent, x as summarizeResponsesFailedNoDetailsObservation, y as stringifyRedactedPayload, z as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-Cvt5MgEm.mjs";
23
- import { t as codeModeToolSurfaceObserver } from "./provider-options-AvldWZt8.mjs";
24
- import { a as createModelStreamCooperativeScheduler, c as isOpenAICompletionsThinkingEnabled, d as parseOpenAICompletionsUsage, f as readOpenAICompletionsContentDeltas, h as throwIfModelStreamAborted, i as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, l as log, m as resolvePromptCacheKey, n as reconcileOpenAICompletionsToolChoice, o as createOpenAIProviderAcceptanceHook, p as readOpenAICompletionsReasoningBatch, r as reconcileOpenAIResponsesToolChoice, s as createOpenAIResponseHook, t as projectOpenAITools, u as measureUtf8AppendBytes } from "./openai-tool-projection-CHGLt03m.mjs";
25
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-MK28puvq.mjs";
26
- import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-5ygO2rZc.mjs";
27
- import { i as resolveOpenAIResponsesServerCompactionPlan, n as resolveOpenAIResponsesCompactEndpointPlan, r as resolveOpenAIResponsesPayloadPolicy, t as applyOpenAIResponsesPayloadPolicy } from "./openai-responses-payload-policy-BDo8CQsx.mjs";
21
+ import { B as buildResponsesInputMessage, C as summarizeResponsesTools, G as captureOpenAIResponsesCompaction, H as createOpenAIResponsesAssistantOutput, I as createResponsesStreamWithEncryptedContentRetry, J as resolveReplayableResponsesMessageId, K as resolveNewestOpenAIResponsesCompactionReplay, L as isInvalidEncryptedContentError, R as resolveAzureOpenAIApiVersion, S as summarizeResponsesPayload, U as CompactionReplayRefreshRequiredError, V as convertResponsesMessages, W as buildOpenAIResponsesReasoningReplayMetadata, X as resolveModelPayloadDebugMode, Y as emitModelTransportDebug, Z as resolveModelSseDebugMode, _ as safeDebugValue, b as summarizeOpenAITransportError, c as processResponsesStream, f as observeResponsesStream, g as normalizeResponsesFailedEvent, h as logResponsesFailedNoDetails, m as buildResponsesFailedNoDetailsObservation, n as applyResponsesServiceTierPricing, p as ResponsesStreamFailure, q as suppressOpenAIResponsesCompaction, v as stringifyRedactedEvent, x as summarizeResponsesFailedNoDetailsObservation, y as stringifyRedactedPayload, z as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-CxgdGBvm.mjs";
22
+ import { A as readOpenAICompletionsReasoningBatch, C as createOpenAIProviderAcceptanceHook, D as measureUtf8AppendBytes, E as log, M as resolvePromptCacheKey, N as throwIfModelStreamAborted, O as parseOpenAICompletionsUsage, S as createModelStreamCooperativeScheduler, T as isOpenAICompletionsThinkingEnabled, b as reconcileOpenAIResponsesToolChoice, j as resolveOpenAIClientBaseUrl, k as readOpenAICompletionsContentDeltas, r as normalizeOpenAIStrictToolParameters, v as projectOpenAITools, w as createOpenAIResponseHook, x as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, y as reconcileOpenAICompletionsToolChoice } from "./openai-tool-schema-CSMh5e9O.mjs";
23
+ import { i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-DcNjoFQE.mjs";
24
+ import { C as isOpenAIGpt54MiniModel, D as resolveOpenAIReasoningEffortForModel, E as normalizeOpenAIReasoningEffort, T as isOpenAIGpt56Model, _ as OpenAIResponsesWebSocketPostDispatchError, a as applyOpenAIResponsesPayloadPolicy, c as resolveOpenAIResponsesServerCompactionPlan, d as OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS, f as OPENAI_RESPONSES_APIS, i as sanitizeResponsesImagePayload, l as AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS, n as isOpenAIResponsesCompactionOutput, o as resolveOpenAIResponsesCompactEndpointPlan, s as resolveOpenAIResponsesPayloadPolicy, t as createBoundedOpenAIResponsesCompactionFetch, v as OpenAIResponsesWebSocketPreDispatchError, w as isOpenAIGpt55Model, x as parseOpenAIResponsesWebSocketServerError, y as OpenAIResponsesWebSocketSafeRetryError } from "./openai-responses-compaction-window-DO7yV7az.mjs";
28
25
  import { i as resolveAzureDeploymentNameFromMap, t as isOpenAICompatibleAzureResponsesBaseUrl } from "./azure-openai-responses-client-compat-C7K7QfUE.mjs";
29
26
  import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
30
27
  import { randomUUID } from "node:crypto";
@@ -36,12 +33,12 @@ import { ResponsesWS } from "openai/resources/responses/ws.js";
36
33
  * Converts OpenClaw contexts/tools into Anthropic payloads, streams SSE events
37
34
  * back into runtime output blocks, and applies provider request policy.
38
35
  */
39
- const ANTHROPIC_MESSAGES_ERROR_BODY_MAX_BYTES = 8 * 1024;
36
+ const ANTHROPIC_MESSAGES_ERROR_BODY_MAX_BYTES = 8192;
40
37
  const ANTHROPIC_MESSAGES_ERROR_BODY_MAX_CHARS = 400;
41
38
  const ANTHROPIC_MESSAGES_ERROR_BODY_READ_IDLE_TIMEOUT_MS = 1e4;
42
39
  const ANTHROPIC_MESSAGES_DEFAULT_MAX_TOKENS = 4096;
43
40
  const ANTHROPIC_MESSAGES_FALLBACK_CONTEXT_DIVISOR = 4;
44
- const ANTHROPIC_MESSAGES_SSE_PENDING_BUFFER_MAX_CHARS = 16 * 1024 * 1024;
41
+ const ANTHROPIC_MESSAGES_SSE_PENDING_BUFFER_MAX_CHARS = 16777216;
45
42
  function resolveAnthropicRequestModelId(model) {
46
43
  if (isDirectAnthropicModel(model) && /^anthropic\//i.test(model.id)) return model.id.replace(/^anthropic\//i, "");
47
44
  return model.id;
@@ -61,9 +58,6 @@ function resolveAnthropicMessagesMaxTokens(params) {
61
58
  const contextWindow = resolvePositiveAnthropicTokenLimit(params.modelContextWindow);
62
59
  return contextWindow === void 0 ? ANTHROPIC_MESSAGES_DEFAULT_MAX_TOKENS : Math.max(1, Math.min(ANTHROPIC_MESSAGES_DEFAULT_MAX_TOKENS, Math.floor(contextWindow / ANTHROPIC_MESSAGES_FALLBACK_CONTEXT_DIVISOR)));
63
60
  }
64
- function isAnthropicOAuthToken(apiKey) {
65
- return (resolveSecretSentinel(apiKey) ?? apiKey).includes("sk-ant-oat");
66
- }
67
61
  function isDirectAnthropicModel(model) {
68
62
  if (normalizeLowercaseStringOrEmpty(model.provider) !== "anthropic") return false;
69
63
  const endpointClass = resolveProviderEndpoint(model).endpointClass;
@@ -483,7 +477,7 @@ function createAnthropicTransportClient(params) {
483
477
  }
484
478
  const betaFeatures = ["fine-grained-tool-streaming-2025-05-14"];
485
479
  if (needsInterleavedBeta) betaFeatures.push("interleaved-thinking-2025-05-14");
486
- if (isAnthropicOAuthToken(apiKey)) {
480
+ if (isAnthropicOAuthApiKey(apiKey)) {
487
481
  const betaHeader = buildAnthropicBetaHeader(model, betaFeatures, { oauth: true });
488
482
  return {
489
483
  client: createAnthropicMessagesClient({
@@ -580,18 +574,19 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
580
574
  if (convertedTools.tools.length > 0) params.tools = convertedTools.tools;
581
575
  }
582
576
  if (mandatoryAdaptiveThinking || model.reasoning || supportsClaudeAdaptiveThinking(model)) {
583
- if (mandatoryAdaptiveThinking || options?.thinkingEnabled) if (supportsClaudeAdaptiveThinking(model)) {
584
- params.thinking = {
585
- type: "adaptive",
586
- display: options?.thinkingDisplay ?? "summarized"
577
+ if (mandatoryAdaptiveThinking || options?.thinkingEnabled) {
578
+ if (supportsClaudeAdaptiveThinking(model)) {
579
+ params.thinking = {
580
+ type: "adaptive",
581
+ display: options?.thinkingDisplay ?? "summarized"
582
+ };
583
+ const effort = options?.effort ?? (mandatoryAdaptiveThinking ? "high" : void 0);
584
+ if (effort) params.output_config = { effort };
585
+ } else params.thinking = {
586
+ type: "enabled",
587
+ budget_tokens: options?.thinkingBudgetTokens ?? 1024
587
588
  };
588
- const effort = options?.effort ?? (mandatoryAdaptiveThinking ? "high" : void 0);
589
- if (effort) params.output_config = { effort };
590
- } else params.thinking = {
591
- type: "enabled",
592
- budget_tokens: options?.thinkingBudgetTokens ?? 1024
593
- };
594
- else if (options?.thinkingEnabled === false) params.thinking = { type: "disabled" };
589
+ } else if (options?.thinkingEnabled === false) params.thinking = { type: "disabled" };
595
590
  }
596
591
  if (options?.metadata && typeof options.metadata.user_id === "string") params.metadata = { user_id: options.metadata.user_id };
597
592
  if (options?.toolChoice) {
@@ -713,6 +708,7 @@ function createAnthropicMessagesTransportStreamFn() {
713
708
  }
714
709
  const blocks = output.content;
715
710
  const blockIndexes = /* @__PURE__ */ new Map();
711
+ const toolArgumentPreviewSchedules = /* @__PURE__ */ new WeakMap();
716
712
  const sealedToolCalls = [];
717
713
  const compactionCapture = createCompactionCapture(output, model, transportOptions);
718
714
  const pendingThinkingSignatures = /* @__PURE__ */ new Map();
@@ -966,6 +962,7 @@ function createAnthropicMessagesTransportStreamFn() {
966
962
  };
967
963
  output.content.push(block);
968
964
  blockIndexes.set(index, output.content.length - 1);
965
+ toolArgumentPreviewSchedules.set(block, createToolArgumentPreviewSchedule());
969
966
  eventSink.push({
970
967
  type: "toolcall_start",
971
968
  contentIndex: output.content.length - 1,
@@ -986,16 +983,18 @@ function createAnthropicMessagesTransportStreamFn() {
986
983
  let appendedContent = false;
987
984
  if (!hasNativeAnthropicDelta && typeof delta?.content === "string" && delta.content.length > 0) {
988
985
  const text = sanitizeTransportPayloadText(delta.content);
989
- if (text.length > 0) if (block?.type === "text" && index !== void 0) {
990
- block.text += text;
991
- eventSink.push({
992
- type: "text_delta",
993
- contentIndex: index,
994
- delta: text,
995
- partial: output
996
- });
997
- appendedContent = true;
998
- } else appendedContent = appendReasoningContentTextDelta(event.index, text);
986
+ if (text.length > 0) {
987
+ if (block?.type === "text" && index !== void 0) {
988
+ block.text += text;
989
+ eventSink.push({
990
+ type: "text_delta",
991
+ contentIndex: index,
992
+ delta: text,
993
+ partial: output
994
+ });
995
+ appendedContent = true;
996
+ } else appendedContent = appendReasoningContentTextDelta(event.index, text);
997
+ }
999
998
  }
1000
999
  if ((appendedThinking || appendedContent) && !hasNativeAnthropicDelta) continue;
1001
1000
  }
@@ -1038,7 +1037,7 @@ function createAnthropicMessagesTransportStreamFn() {
1038
1037
  if (block?.type === "toolCall" && delta?.type === "input_json_delta" && typeof delta.partial_json === "string") {
1039
1038
  const partialJson = `${block.partialJson ?? ""}${delta.partial_json}`;
1040
1039
  block.partialJson = partialJson;
1041
- block.arguments = parseAnthropicToolCallArguments(partialJson);
1040
+ if (toolArgumentPreviewSchedules.get(block)?.(partialJson.length)) block.arguments = parseAnthropicToolCallArguments(partialJson);
1042
1041
  eventSink.push({
1043
1042
  type: "toolcall_delta",
1044
1043
  contentIndex: index,
@@ -1103,8 +1102,10 @@ function createAnthropicMessagesTransportStreamFn() {
1103
1102
  if (event.type === "message_delta") {
1104
1103
  const delta = event.delta;
1105
1104
  const usage = event.usage;
1106
- if (delta?.stop_reason) if (delta.stop_reason === "refusal") applyAnthropicRefusal(output, delta.stop_details, model.provider);
1107
- else output.stopReason = mapAnthropicStopReason(delta.stop_reason);
1105
+ if (delta?.stop_reason) {
1106
+ if (delta.stop_reason === "refusal") applyAnthropicRefusal(output, delta.stop_details, model.provider);
1107
+ else output.stopReason = mapAnthropicStopReason(delta.stop_reason);
1108
+ }
1108
1109
  applyAnthropicMessageDeltaUsage(output.usage, usage, messageStartPromptUsage);
1109
1110
  calculateCost(costModel, output.usage);
1110
1111
  if (output.stopReason === "toolUse" || output.content.some((block) => block.type === "toolCall")) tagPendingCommentaryText(output.content);
@@ -1153,96 +1154,6 @@ function createAnthropicMessagesTransportStreamFn() {
1153
1154
  };
1154
1155
  }
1155
1156
  //#endregion
1156
- //#region packages/ai/src/transports/deepseek-text-filter.ts
1157
- /**
1158
- * DeepSeek DSML streaming text filter.
1159
- * Removes provider-emitted DSML tool markup while buffering split tag prefixes
1160
- * across streamed chunks.
1161
- */
1162
- const DSML_KINDS = [
1163
- "tool_use_error",
1164
- "tool_calls",
1165
- "tool_call",
1166
- "function_calls"
1167
- ];
1168
- const DSML_BARS = ["|", "|"];
1169
- const DSML_OPEN_TOKENS = DSML_BARS.flatMap((bar) => DSML_KINDS.map((kind) => `<${bar}DSML${bar}${kind}>`));
1170
- const DSML_CLOSE_TOKENS = DSML_BARS.flatMap((bar) => DSML_KINDS.map((kind) => `</${bar}DSML${bar}${kind}>`));
1171
- const MAX_OPEN_TOKEN_LEN = Math.max(...DSML_OPEN_TOKENS.map((token) => token.length));
1172
- const MAX_CLOSE_TOKEN_LEN = Math.max(...DSML_CLOSE_TOKENS.map((token) => token.length));
1173
- /** Create an incremental text filter that strips DeepSeek DSML tool blocks. */
1174
- function createDeepSeekTextFilter() {
1175
- let buffer = "";
1176
- let insideDsml = false;
1177
- const consume = (final) => {
1178
- const output = [];
1179
- const emit = (text) => {
1180
- if (text) output.push(text);
1181
- };
1182
- while (buffer) {
1183
- if (insideDsml) {
1184
- const close = findEarliestToken(buffer, DSML_CLOSE_TOKENS);
1185
- if (close) {
1186
- buffer = buffer.slice(close.index + close.token.length);
1187
- insideDsml = false;
1188
- continue;
1189
- }
1190
- const keep = final ? 0 : Math.min(buffer.length, MAX_CLOSE_TOKEN_LEN - 1);
1191
- buffer = buffer.slice(buffer.length - keep);
1192
- if (final) insideDsml = false;
1193
- return output;
1194
- }
1195
- const open = findEarliestToken(buffer, DSML_OPEN_TOKENS);
1196
- if (open) {
1197
- emit(buffer.slice(0, open.index));
1198
- buffer = buffer.slice(open.index + open.token.length);
1199
- insideDsml = true;
1200
- continue;
1201
- }
1202
- if (final) {
1203
- emit(buffer);
1204
- buffer = "";
1205
- return output;
1206
- }
1207
- const keep = longestDsmlOpenPrefixSuffixLength(buffer);
1208
- const emitLength = buffer.length - keep;
1209
- if (emitLength <= 0) return output;
1210
- emit(buffer.slice(0, emitLength));
1211
- buffer = buffer.slice(emitLength);
1212
- return output;
1213
- }
1214
- return output;
1215
- };
1216
- return {
1217
- push(chunk) {
1218
- buffer += chunk;
1219
- return consume(false);
1220
- },
1221
- flush() {
1222
- return consume(true);
1223
- }
1224
- };
1225
- }
1226
- function findEarliestToken(text, tokens) {
1227
- let best = null;
1228
- for (const token of tokens) {
1229
- const index = text.indexOf(token);
1230
- if (index !== -1 && (!best || index < best.index)) best = {
1231
- index,
1232
- token
1233
- };
1234
- }
1235
- return best;
1236
- }
1237
- function longestDsmlOpenPrefixSuffixLength(text) {
1238
- const maxLength = Math.min(text.length, MAX_OPEN_TOKEN_LEN - 1);
1239
- for (let length = maxLength; length > 0; length--) {
1240
- const suffix = text.slice(text.length - length);
1241
- if (DSML_OPEN_TOKENS.some((token) => token.startsWith(suffix))) return length;
1242
- }
1243
- return 0;
1244
- }
1245
- //#endregion
1246
1157
  //#region packages/ai/src/transports/model-max-tokens-params.ts
1247
1158
  /**
1248
1159
  * Max-token parameter normalization across provider/native naming variants.
@@ -1541,230 +1452,6 @@ function applyCompletionsReplay(outgoingMessages, context, model, compat) {
1541
1452
  });
1542
1453
  }
1543
1454
  //#endregion
1544
- //#region packages/ai/src/transports/openai-transport-params.ts
1545
- const MAX_OPENAI_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS = 256;
1546
- const OPENAI_CODEX_RESPONSES_PROVIDERS = /* @__PURE__ */ new Set(["openai"]);
1547
- const loggedOpenAIStrictToolDowngradeDiagnosticKeys = /* @__PURE__ */ new Set();
1548
- function readToolPayloadField(record, field) {
1549
- try {
1550
- return Object.hasOwn(record, field) ? record[field] : void 0;
1551
- } catch {
1552
- return;
1553
- }
1554
- }
1555
- function readCodeModePayloadToolName(tool) {
1556
- if (!isRecord(tool)) return;
1557
- const name = readToolPayloadField(tool, "name");
1558
- if (typeof name === "string") return name;
1559
- const fn = readToolPayloadField(tool, "function");
1560
- if (!isRecord(fn)) return;
1561
- const fnName = readToolPayloadField(fn, "name");
1562
- return typeof fnName === "string" ? fnName : void 0;
1563
- }
1564
- function readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes) {
1565
- if (!isRecord(tool)) return;
1566
- const type = readToolPayloadField(tool, "type");
1567
- if (typeof type === "string" && allowedHostedToolTypes?.has(type)) {
1568
- try {
1569
- if (Object.hasOwn(tool, "name") || Object.hasOwn(tool, "function") || Object.hasOwn(tool, "functionDeclarations") || Object.hasOwn(tool, "function_declarations")) return false;
1570
- } catch {
1571
- return false;
1572
- }
1573
- return `hosted:${type}`;
1574
- }
1575
- const name = readCodeModePayloadToolName(tool);
1576
- return typeof name === "string" && isCodeModeModelVisibleToolName(name, visibleToolNames) ? `client:${name}` : void 0;
1577
- }
1578
- function readCodeModePayloadToolIdentities(payload) {
1579
- if (!isRecord(payload)) return [];
1580
- const tools = readToolPayloadField(payload, "tools");
1581
- if (!Array.isArray(tools)) return [];
1582
- return tools.flatMap((tool) => {
1583
- if (!isRecord(tool)) return [];
1584
- const identities = [];
1585
- const name = readCodeModePayloadToolName(tool);
1586
- if (name) identities.push(`client:${name}`);
1587
- for (const key of ["functionDeclarations", "function_declarations"]) {
1588
- const declarations = readToolPayloadField(tool, key);
1589
- if (!Array.isArray(declarations)) continue;
1590
- for (const declaration of declarations) {
1591
- const declarationName = readCodeModePayloadToolName(declaration);
1592
- if (declarationName) identities.push(`client:${declarationName}`);
1593
- }
1594
- }
1595
- const type = readToolPayloadField(tool, "type");
1596
- if (typeof type === "string" && type !== "function") identities.push(`hosted:${type}`);
1597
- return identities;
1598
- });
1599
- }
1600
- function filterCodeModePayloadTools(payload, visibleToolNames, allowedHostedToolTypes, observer) {
1601
- if (!isRecord(payload)) return;
1602
- const tools = readToolPayloadField(payload, "tools");
1603
- if (!Array.isArray(tools)) return;
1604
- const beforeToolIdentities = observer ? readCodeModePayloadToolIdentities(payload) : void 0;
1605
- payload.tools = tools.flatMap((tool) => {
1606
- const identity = readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes);
1607
- if (identity) return [tool];
1608
- if (identity === false) return [];
1609
- if (!isRecord(tool)) return [];
1610
- const filteredGroups = {};
1611
- for (const key of ["functionDeclarations", "function_declarations"]) {
1612
- const declarations = readToolPayloadField(tool, key);
1613
- if (!Array.isArray(declarations)) continue;
1614
- const filtered = declarations.filter((declaration) => {
1615
- const declarationName = readCodeModePayloadToolName(declaration);
1616
- return typeof declarationName === "string" && isCodeModeModelVisibleToolName(declarationName, visibleToolNames);
1617
- });
1618
- if (filtered.length > 0) filteredGroups[key] = filtered;
1619
- }
1620
- return Object.keys(filteredGroups).length > 0 ? [filteredGroups] : [];
1621
- });
1622
- if (beforeToolIdentities) observer?.({
1623
- beforeToolIdentities,
1624
- afterToolIdentities: readCodeModePayloadToolIdentities(payload)
1625
- });
1626
- }
1627
- function resolveCodeModeResponsesVisibleToolNames(context) {
1628
- return new Set((context.tools ?? []).map(readCodeModePayloadToolName).filter((name) => typeof name === "string"));
1629
- }
1630
- function enforceCodeModeResponsesToolSurface(payload, visibleToolNames, allowedHostedToolTypes, observer) {
1631
- if (!isRecord(payload)) return;
1632
- const tools = readToolPayloadField(payload, "tools");
1633
- if (!Array.isArray(tools)) return;
1634
- const beforeToolIdentities = observer ? readCodeModePayloadToolIdentities(payload) : void 0;
1635
- payload.tools = tools.filter((tool) => Boolean(readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes)));
1636
- if (beforeToolIdentities) observer?.({
1637
- beforeToolIdentities,
1638
- afterToolIdentities: readCodeModePayloadToolIdentities(payload)
1639
- });
1640
- }
1641
- function assertCodeModeResponsesToolSurface(payload, visibleToolNames, allowedHostedToolTypes) {
1642
- const tools = isRecord(payload) ? readToolPayloadField(payload, "tools") : void 0;
1643
- if (!Array.isArray(tools)) throw new Error("Code mode payload tool surface violation: expected exec,wait; got no tools");
1644
- const identities = tools.map((tool) => readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes));
1645
- const names = identities.flatMap((identity) => typeof identity === "string" && identity.startsWith("client:") ? [identity.slice(7)] : []).toSorted((left, right) => left.localeCompare(right));
1646
- if (names.length >= 2 && identities.every((identity) => typeof identity === "string") && new Set(identities).size === identities.length && names.includes("exec") && names.includes("wait")) return;
1647
- throw new Error(`Code mode payload tool surface violation: expected exec,wait plus direct-only tools; got ${names.length > 0 ? names.join(",") : "none"}`);
1648
- }
1649
- function buildOpenAIStrictToolDowngradeDiagnosticKey(diagnostics, context) {
1650
- return sha256Hex(JSON.stringify({
1651
- transport: context.transport,
1652
- provider: context.model.provider ?? null,
1653
- model: context.model.id ?? null,
1654
- diagnostics: diagnostics.map((entry) => ({
1655
- toolIndex: entry.toolIndex,
1656
- toolName: entry.toolName ?? null,
1657
- violations: entry.violations
1658
- }))
1659
- }));
1660
- }
1661
- function shouldLogOpenAIStrictToolDowngradeDiagnostic(diagnostics, context) {
1662
- const key = buildOpenAIStrictToolDowngradeDiagnosticKey(diagnostics, context);
1663
- if (loggedOpenAIStrictToolDowngradeDiagnosticKeys.has(key)) return false;
1664
- if (loggedOpenAIStrictToolDowngradeDiagnosticKeys.size >= MAX_OPENAI_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS) loggedOpenAIStrictToolDowngradeDiagnosticKeys.clear();
1665
- loggedOpenAIStrictToolDowngradeDiagnosticKeys.add(key);
1666
- return true;
1667
- }
1668
- function resolveOpenAIStrictToolFlagWithDiagnostics(projection, strictSetting, context) {
1669
- const strict = resolveOpenAIProjectedToolsStrictToolFlag(projection, strictSetting);
1670
- if (strictSetting === true && strict === false) {
1671
- const diagnostics = findOpenAIStrictToolProjectionDiagnostics(projection);
1672
- getAiTransportHost().logDebug("openai-transport", () => {
1673
- if (!shouldLogOpenAIStrictToolDowngradeDiagnostic(diagnostics, context)) return null;
1674
- const sample = diagnostics.slice(0, 5).map((entry) => ({
1675
- tool: entry.toolName ?? `tool[${entry.toolIndex}]`,
1676
- violations: entry.violations.slice(0, 8)
1677
- }));
1678
- return {
1679
- message: `OpenAI ${context.transport} tool schema strict mode downgraded to strict=false for ${context.model.provider ?? "unknown"}/${context.model.id ?? "unknown"} because ${diagnostics.length} tool schema(s) are not strict-compatible`,
1680
- data: {
1681
- transport: context.transport,
1682
- provider: context.model.provider,
1683
- model: context.model.id,
1684
- incompatibleToolCount: diagnostics.length,
1685
- sample
1686
- }
1687
- };
1688
- });
1689
- }
1690
- return strict;
1691
- }
1692
- function isOpenAICodexResponsesModel(model) {
1693
- return OPENAI_CODEX_RESPONSES_PROVIDERS.has(model.provider) && (model.api === "openai-chatgpt-responses" || model.api === "openclaw-openai-chatgpt-responses-transport");
1694
- }
1695
- function isNativeOpenAICodexResponsesBaseUrl(baseUrl) {
1696
- const trimmed = typeof baseUrl === "string" ? baseUrl.trim() : "";
1697
- if (!trimmed) return false;
1698
- try {
1699
- const url = new URL(trimmed);
1700
- if (url.protocol !== "http:" && url.protocol !== "https:") return false;
1701
- if (url.hostname.toLowerCase() !== "chatgpt.com") return false;
1702
- const pathname = url.pathname.replace(/\/+$/u, "").toLowerCase();
1703
- return [
1704
- "/backend-api",
1705
- "/backend-api/v1",
1706
- "/backend-api/codex",
1707
- "/backend-api/codex/v1"
1708
- ].includes(pathname);
1709
- } catch {
1710
- return false;
1711
- }
1712
- }
1713
- function usesNativeOpenAICodexResponsesBackend(model) {
1714
- return isOpenAICodexResponsesModel(model) && isNativeOpenAICodexResponsesBaseUrl(model.baseUrl);
1715
- }
1716
- function buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders, sessionId) {
1717
- const providerHeaders = { ...model.headers };
1718
- if (model.provider === "github-copilot") Object.assign(providerHeaders, getAiTransportHost().buildCopilotDynamicHeaders(context.messages));
1719
- const callerHeaders = {
1720
- ...optionHeaders,
1721
- ...turnHeaders
1722
- };
1723
- const resolvedHeaders = resolveProviderRequestPolicyConfig(model, {
1724
- provider: model.provider,
1725
- api: model.api,
1726
- baseUrl: model.baseUrl,
1727
- capability: "llm",
1728
- transport: "stream",
1729
- providerHeaders,
1730
- callerHeaders: Object.keys(callerHeaders).length > 0 ? callerHeaders : void 0,
1731
- precedence: "caller-wins"
1732
- }).headers ?? {};
1733
- if (sessionId && !Object.keys(resolvedHeaders).some((key) => normalizeLowercaseStringOrEmpty(key) === "session_id") && usesNativeOpenAICodexResponsesBackend(model)) resolvedHeaders.session_id = clampOpenAIPromptCacheKey(sessionId) ?? sessionId;
1734
- return resolvedHeaders;
1735
- }
1736
- function resolveOpenAISdkTimeoutMs(model, timeoutMs) {
1737
- return resolveModelRequestTimeoutMs(model, timeoutMs);
1738
- }
1739
- function buildOpenAISdkClientOptions(model) {
1740
- const timeout = resolveOpenAISdkTimeoutMs(model);
1741
- return timeout === void 0 ? {} : { timeout };
1742
- }
1743
- function buildOpenAISdkRequestOptions(model, signal, options) {
1744
- const timeout = resolveOpenAISdkTimeoutMs(model, options?.timeoutMs);
1745
- const headers = options?.stream === true && usesNativeOpenAICodexResponsesBackend(model) ? { Accept: "text/event-stream" } : void 0;
1746
- if (timeout === void 0 && options?.maxRetries === void 0 && !signal && !headers) return;
1747
- return {
1748
- ...headers ? { headers } : {},
1749
- ...signal ? { signal } : {},
1750
- ...timeout !== void 0 ? { timeout } : {},
1751
- ...options?.maxRetries !== void 0 ? { maxRetries: options.maxRetries } : {}
1752
- };
1753
- }
1754
- function getCompat(model) {
1755
- const resolved = resolveOpenAICompletionsCompat(model);
1756
- const compat = model.compat ?? {};
1757
- return {
1758
- ...resolved,
1759
- cacheControlFormat: resolved.cacheControlFormat,
1760
- reasoningEffortMap: resolveOpenAIReasoningEffortMap(model, {}),
1761
- openRouterRouting: resolved.openRouterRouting ?? {},
1762
- vercelGatewayRouting: resolved.vercelGatewayRouting,
1763
- requiresStringContent: compat.requiresStringContent ?? false,
1764
- strictMessageKeys: compat.strictMessageKeys === true
1765
- };
1766
- }
1767
- //#endregion
1768
1455
  //#region packages/ai/src/transports/openai-completions-params.ts
1769
1456
  function isKnownOpenAICompletionsEndpoint(model) {
1770
1457
  if (!model.baseUrl.trim()) return true;
@@ -1776,7 +1463,7 @@ function isKnownOpenAICompletionsEndpoint(model) {
1776
1463
  return false;
1777
1464
  }
1778
1465
  }
1779
- function resolveOpenAICompletionsReasoningEffort$1(options) {
1466
+ function resolveOpenAICompletionsReasoningEffort(options) {
1780
1467
  return options?.reasoningEffort ?? options?.reasoning ?? "high";
1781
1468
  }
1782
1469
  function resolveOpenAICompletionsMaxTokens(model, options) {
@@ -1908,10 +1595,11 @@ function convertTools(tools, compat, model) {
1908
1595
  function buildOpenAICompletionsParams(model, context, options) {
1909
1596
  const compat = getCompat(model);
1910
1597
  const compatDetection = detectOpenAICompletionsCompat(model);
1911
- let messages = convertMessages(model, context.systemPrompt ? {
1598
+ const completionsContext = context.systemPrompt ? {
1912
1599
  ...context,
1913
1600
  systemPrompt: stripSystemPromptCacheBoundary(context.systemPrompt)
1914
- } : context, compat);
1601
+ } : context;
1602
+ let messages = convertMessages(model, completionsContext, compat);
1915
1603
  applyCompletionsReplay(messages, context, model, compat);
1916
1604
  if (compat.strictMessageKeys) messages = stripCompletionMessagesToRoleContent(messages);
1917
1605
  const cacheRetention = resolveCacheRetention(options?.cacheRetention);
@@ -1972,10 +1660,12 @@ function buildOpenAICompletionsParams(model, context, options) {
1972
1660
  emitModelTransportDebug(log, `[completions] clamp_max_tokens provider=${model.provider} api=${model.api} model=${model.id} requested=${effectiveMaxTokens} output=${clampedMaxTokens} effectiveContext=${effectiveContextTokens} estimatedInput=${estimatedInputTokens}`);
1973
1661
  }
1974
1662
  }
1975
- if (clampedMaxTokens) if (compat.maxTokensField === "max_tokens") params.max_tokens = clampedMaxTokens;
1976
- else params.max_completion_tokens = clampedMaxTokens;
1663
+ if (clampedMaxTokens) {
1664
+ if (compat.maxTokensField === "max_tokens") params.max_tokens = clampedMaxTokens;
1665
+ else params.max_completion_tokens = clampedMaxTokens;
1666
+ }
1977
1667
  }
1978
- const completionsReasoningEffort = resolveOpenAICompletionsReasoningEffort$1(options);
1668
+ const completionsReasoningEffort = resolveOpenAICompletionsReasoningEffort(options);
1979
1669
  const resolvedCompletionsReasoningEffort = completionsReasoningEffort ? resolveOpenAIReasoningEffortForModel({
1980
1670
  model,
1981
1671
  effort: completionsReasoningEffort,
@@ -2001,692 +1691,6 @@ function buildOpenAICompletionsParams(model, context, options) {
2001
1691
  return params;
2002
1692
  }
2003
1693
  //#endregion
2004
- //#region packages/ai/src/transports/openai-completions-dsml.ts
2005
- const DEEPSEEK_DSML_BARS = ["|", "|"];
2006
- const DEEPSEEK_DSML_TOOL_KINDS = [
2007
- "tool_calls",
2008
- "tool_call",
2009
- "function_calls"
2010
- ];
2011
- const DEEPSEEK_DSML_TOOL_OPEN_TOKENS = DEEPSEEK_DSML_BARS.flatMap((bar) => DEEPSEEK_DSML_TOOL_KINDS.map((kind) => `<${bar}DSML${bar}${kind}>`));
2012
- const DEEPSEEK_DSML_TOOL_CLOSE_TOKENS = DEEPSEEK_DSML_BARS.flatMap((bar) => DEEPSEEK_DSML_TOOL_KINDS.map((kind) => `</${bar}DSML${bar}${kind}>`));
2013
- const DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES = DEEPSEEK_DSML_BARS.map((bar) => `<${bar}DSML${bar}invoke`);
2014
- const DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS = DEEPSEEK_DSML_BARS.map((bar) => `</${bar}DSML${bar}invoke>`);
2015
- const DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPEN_TOKENS.map((token) => token.length));
2016
- const DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPEN_TOKENS.map((token) => token.length), ...DEEPSEEK_DSML_TOOL_CLOSE_TOKENS.map((token) => token.length), ...DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES.map((token) => token.length), ...DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS.map((token) => token.length));
2017
- const MAX_DSML_RECOVERY_BUFFER_BYTES = 256e3;
2018
- const DEEPSEEK_DSML_SCAN_BATCH_CHARS = 64 * 1024;
2019
- function createDsmlRecoverer() {
2020
- let buffer = "";
2021
- let bufferBytes = 0;
2022
- let bufferEndsWithHighSurrogate = false;
2023
- let pendingScanChars = 0;
2024
- let activeOpenToken = null;
2025
- let blockScanState = {
2026
- offset: 0,
2027
- mode: "outer",
2028
- invokeOpenStart: -1
2029
- };
2030
- const resetBlockScan = () => {
2031
- activeOpenToken = null;
2032
- pendingScanChars = 0;
2033
- blockScanState = {
2034
- offset: 0,
2035
- mode: "outer",
2036
- invokeOpenStart: -1
2037
- };
2038
- };
2039
- const consume = (final) => {
2040
- const output = [];
2041
- while (buffer) {
2042
- const open = activeOpenToken ? {
2043
- index: 0,
2044
- token: activeOpenToken
2045
- } : findEarliestStringToken(buffer, DEEPSEEK_DSML_TOOL_OPEN_TOKENS);
2046
- if (!open) {
2047
- resetBlockScan();
2048
- if (final) {
2049
- output.push({
2050
- kind: "text",
2051
- text: buffer
2052
- });
2053
- buffer = "";
2054
- bufferBytes = 0;
2055
- bufferEndsWithHighSurrogate = false;
2056
- return output;
2057
- }
2058
- const keep = longestDeepSeekDsmlToolOpenPrefixSuffixLength(buffer);
2059
- const emitLength = buffer.length - keep;
2060
- if (emitLength > 0) {
2061
- const emitted = buffer.slice(0, emitLength);
2062
- output.push({
2063
- kind: "text",
2064
- text: emitted
2065
- });
2066
- bufferBytes -= Buffer.byteLength(emitted, "utf8");
2067
- buffer = buffer.slice(emitted.length);
2068
- if (!buffer) bufferEndsWithHighSurrogate = false;
2069
- }
2070
- return output;
2071
- }
2072
- if (open.index > 0) {
2073
- const prefix = buffer.slice(0, open.index);
2074
- output.push({
2075
- kind: "text",
2076
- text: prefix
2077
- });
2078
- bufferBytes -= Buffer.byteLength(prefix, "utf8");
2079
- buffer = buffer.slice(prefix.length);
2080
- resetBlockScan();
2081
- }
2082
- activeOpenToken = open.token;
2083
- if (blockScanState.offset === 0) blockScanState.offset = open.token.length;
2084
- const blockScan = scanDeepSeekDsmlToolBlock(buffer, open.token.replace("<", "</"), open.token.length, blockScanState);
2085
- if (blockScan.kind === "nested-open") throw new Error("Nested DeepSeek DSML recovery wrappers are not supported");
2086
- const close = blockScan.kind === "close" ? blockScan : null;
2087
- if (!close) {
2088
- if (final) {
2089
- output.push({
2090
- kind: "text",
2091
- text: buffer
2092
- });
2093
- buffer = "";
2094
- bufferBytes = 0;
2095
- bufferEndsWithHighSurrogate = false;
2096
- return output;
2097
- }
2098
- if (bufferBytes > MAX_DSML_RECOVERY_BUFFER_BYTES) throw new Error("Exceeded DeepSeek DSML recovery buffer limit");
2099
- return output;
2100
- }
2101
- resetBlockScan();
2102
- const body = buffer.slice(open.token.length, close.index);
2103
- const blockText = buffer.slice(0, close.index + close.token.length);
2104
- if (Buffer.byteLength(blockText, "utf8") > MAX_DSML_RECOVERY_BUFFER_BYTES) throw new Error("Exceeded DeepSeek DSML recovery buffer limit");
2105
- const recoveredToolCalls = parseDeepSeekDsmlToolCallBlock(body);
2106
- if (recoveredToolCalls.length > 0) output.push(...recoveredToolCalls);
2107
- else output.push({
2108
- kind: "text",
2109
- text: blockText
2110
- });
2111
- bufferBytes -= Buffer.byteLength(blockText, "utf8");
2112
- buffer = buffer.slice(blockText.length);
2113
- if (!buffer) bufferEndsWithHighSurrogate = false;
2114
- }
2115
- return output;
2116
- };
2117
- return {
2118
- push(chunk) {
2119
- const append = measureUtf8AppendBytes(bufferEndsWithHighSurrogate, chunk);
2120
- bufferBytes += append.bytes;
2121
- bufferEndsWithHighSurrogate = append.endsWithHighSurrogate;
2122
- buffer += chunk;
2123
- pendingScanChars += chunk.length;
2124
- if (activeOpenToken && pendingScanChars < DEEPSEEK_DSML_SCAN_BATCH_CHARS && !chunk.includes("<") && !chunk.includes(">") && bufferBytes <= MAX_DSML_RECOVERY_BUFFER_BYTES) return [];
2125
- pendingScanChars = 0;
2126
- return consume(false);
2127
- },
2128
- flush() {
2129
- return consume(true);
2130
- }
2131
- };
2132
- }
2133
- function parseDeepSeekDsmlToolCallBlock(body) {
2134
- const toolCalls = [];
2135
- const invokeOpenRegex = /<[||]DSML[||]invoke\b([^<>]*)>/g;
2136
- let openMatch;
2137
- while ((openMatch = invokeOpenRegex.exec(body)) !== null) {
2138
- const invokeBodyStart = openMatch.index + openMatch[0].length;
2139
- const invokeClose = findEarliestStringToken(body.slice(invokeBodyStart), ["</|DSML|invoke>", "</|DSML|invoke>"]);
2140
- if (!invokeClose) break;
2141
- const invokeBody = body.slice(invokeBodyStart, invokeBodyStart + invokeClose.index);
2142
- invokeOpenRegex.lastIndex = invokeBodyStart + invokeClose.index + invokeClose.token.length;
2143
- const invokeName = parseXmlAttribute(openMatch[1] ?? "", "name");
2144
- if (!invokeName) continue;
2145
- const parsedArguments = parseDeepSeekDsmlInvokeArguments(invokeBody);
2146
- if (!parsedArguments) continue;
2147
- toolCalls.push({
2148
- kind: "toolCall",
2149
- name: invokeName,
2150
- arguments: parsedArguments,
2151
- partialArgs: JSON.stringify(parsedArguments)
2152
- });
2153
- }
2154
- return toolCalls;
2155
- }
2156
- function parseDeepSeekDsmlInvokeArguments(body) {
2157
- const args = {};
2158
- const parameterRegex = /<[||]DSML[||]parameter\b([^>]*)>([\s\S]*?)<\/[||]DSML[||]parameter>/g;
2159
- let parameterMatch;
2160
- while ((parameterMatch = parameterRegex.exec(body)) !== null) {
2161
- const name = parseXmlAttribute(parameterMatch[1] ?? "", "name");
2162
- if (!name) continue;
2163
- const rawValue = parameterMatch[2] ?? "";
2164
- if (rawValue.length === 0) continue;
2165
- args[name] = decodeDeepSeekDsmlText(rawValue);
2166
- }
2167
- if (Object.keys(args).length > 0) return args;
2168
- const trimmed = body.trim();
2169
- if (!trimmed.startsWith("{")) return null;
2170
- try {
2171
- const parsed = JSON.parse(trimmed);
2172
- if (isRecord(parsed) && Object.keys(parsed).length > 0) return parsed;
2173
- } catch {
2174
- return null;
2175
- }
2176
- return null;
2177
- }
2178
- const xmlAttributeRegexCache = /* @__PURE__ */ new Map();
2179
- function xmlAttributeRegex(name) {
2180
- const cached = xmlAttributeRegexCache.get(name);
2181
- if (cached) return cached;
2182
- const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2183
- const pattern = new RegExp(`\\b${escaped}=("([^"]*)"|'([^']*)'|([^\\s>]+))`);
2184
- xmlAttributeRegexCache.set(name, pattern);
2185
- return pattern;
2186
- }
2187
- function parseXmlAttribute(attributes, name) {
2188
- const match = xmlAttributeRegex(name).exec(attributes);
2189
- const value = match?.[2] ?? match?.[3] ?? match?.[4];
2190
- return value ? decodeDeepSeekDsmlText(value) : null;
2191
- }
2192
- function decodeDeepSeekDsmlText(value) {
2193
- return value.replaceAll("&quot;", "\"").replaceAll("&apos;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
2194
- }
2195
- function findEarliestStringToken(text, tokens, fromIndex = 0) {
2196
- let best = null;
2197
- for (const token of tokens) {
2198
- const index = text.indexOf(token, fromIndex);
2199
- if (index !== -1 && (!best || index < best.index)) best = {
2200
- index,
2201
- token
2202
- };
2203
- }
2204
- return best;
2205
- }
2206
- function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
2207
- while (state.offset < text.length) {
2208
- if (state.mode === "invoke-open") {
2209
- const nextOpen = text.indexOf("<", state.offset);
2210
- const nextClose = text.indexOf(">", state.offset);
2211
- if (nextClose === -1 && nextOpen === -1) {
2212
- state.offset = text.length;
2213
- return { kind: "incomplete" };
2214
- }
2215
- if (nextOpen !== -1 && (nextClose === -1 || nextOpen < nextClose)) {
2216
- state.mode = "outer";
2217
- state.offset = nextOpen;
2218
- state.invokeOpenStart = -1;
2219
- continue;
2220
- }
2221
- const invokeOpenTag = text.slice(state.invokeOpenStart, nextClose + 1);
2222
- if (!/^<[||]DSML[||]invoke\b[^<>]*>$/.test(invokeOpenTag)) {
2223
- state.mode = "outer";
2224
- state.offset = state.invokeOpenStart + 1;
2225
- state.invokeOpenStart = -1;
2226
- continue;
2227
- }
2228
- state.mode = "invoke-body";
2229
- state.offset = nextClose + 1;
2230
- state.invokeOpenStart = -1;
2231
- continue;
2232
- }
2233
- if (state.mode === "invoke-body") {
2234
- const invokeClose = findEarliestStringToken(text, DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS, state.offset);
2235
- if (!invokeClose) {
2236
- state.offset = Math.max(0, text.length - DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN + 1);
2237
- return { kind: "incomplete" };
2238
- }
2239
- state.mode = "outer";
2240
- state.offset = invokeClose.index + invokeClose.token.length;
2241
- continue;
2242
- }
2243
- const toolOpen = findEarliestStringToken(text, DEEPSEEK_DSML_TOOL_OPEN_TOKENS, state.offset);
2244
- const toolCloseIndex = text.indexOf(closeToken, state.offset);
2245
- const invokeOpen = findEarliestStringToken(text, DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES, state.offset);
2246
- const next = [
2247
- toolOpen ? {
2248
- kind: "nested-open",
2249
- ...toolOpen
2250
- } : null,
2251
- toolCloseIndex === -1 ? null : {
2252
- kind: "close",
2253
- index: toolCloseIndex,
2254
- token: closeToken
2255
- },
2256
- invokeOpen ? {
2257
- kind: "invoke-open",
2258
- ...invokeOpen
2259
- } : null
2260
- ].filter((candidate) => candidate !== null).toSorted((left, right) => left.index - right.index)[0];
2261
- if (!next) {
2262
- state.offset = Math.max(contentStartIndex, text.length - DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN + 1);
2263
- return { kind: "incomplete" };
2264
- }
2265
- if (next.kind === "invoke-open") {
2266
- state.mode = "invoke-open";
2267
- state.invokeOpenStart = next.index;
2268
- state.offset = next.index + next.token.length;
2269
- continue;
2270
- }
2271
- return next;
2272
- }
2273
- return { kind: "incomplete" };
2274
- }
2275
- function longestDeepSeekDsmlToolOpenPrefixSuffixLength(text) {
2276
- const maxLength = Math.min(text.length, DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN - 1);
2277
- for (let length = maxLength; length > 0; length -= 1) {
2278
- const suffix = text.slice(text.length - length);
2279
- if (DEEPSEEK_DSML_TOOL_OPEN_TOKENS.some((token) => token.startsWith(suffix))) return length;
2280
- }
2281
- return 0;
2282
- }
2283
- //#endregion
2284
- //#region packages/ai/src/transports/openai-completions-stream.ts
2285
- function extractToolCallThoughtSignature(toolCall) {
2286
- const tc = toolCall;
2287
- if (!tc) return;
2288
- const fromExtra = (tc.extra_content?.google)?.thought_signature;
2289
- if (typeof fromExtra === "string" && fromExtra.length > 0) return fromExtra;
2290
- const fromFunction = tc.function?.thought_signature;
2291
- if (typeof fromFunction === "string" && fromFunction.length > 0) return fromFunction;
2292
- const fromToolCall = tc.thought_signature;
2293
- return typeof fromToolCall === "string" && fromToolCall.length > 0 ? fromToolCall : void 0;
2294
- }
2295
- async function processCompletionsStream(responseStream, output, model, stream, options) {
2296
- const MAX_POST_TOOL_CALL_BUFFER_BYTES = 256e3;
2297
- const emitReasoning = options?.emitReasoning ?? true;
2298
- const compat = getCompat(model);
2299
- const visibleReasoningDetailTypes = new Set(compat.visibleReasoningDetailTypes);
2300
- const shouldFilterDeepSeekDsmlText = compat.thinkingFormat === "deepseek";
2301
- const deepSeekTextFilter = shouldFilterDeepSeekDsmlText ? createDeepSeekTextFilter() : null;
2302
- const deepSeekToolCallRecoverer = shouldFilterDeepSeekDsmlText ? createDsmlRecoverer() : null;
2303
- const reasoningTagTextPartitioner = createReasoningTagTextPartitioner();
2304
- let currentBlock = null;
2305
- let currentTextSource;
2306
- let pendingInterruptedTextBlock = null;
2307
- let confirmedInterruptedTextBlock = null;
2308
- let pendingPostToolCallDeltas = [];
2309
- let pendingPostToolCallBytes = 0;
2310
- let isFlushingPendingPostToolCallDeltas = false;
2311
- const toolCallBlocksByIndex = /* @__PURE__ */ new Map();
2312
- const toolCallBlocksById = /* @__PURE__ */ new Map();
2313
- const provisionalCommentaryTags = /* @__PURE__ */ new Map();
2314
- const toolCallBlockIndices = /* @__PURE__ */ new WeakMap();
2315
- let explicitVisibleTextBlocks;
2316
- const normalizeToolCallDeltas = createOpenAICompletionsToolCallDeltaNormalizer();
2317
- let sawStopFinishReason = false;
2318
- let sawNativeToolCallDelta = false;
2319
- const blockIndex = () => output.content.length - 1;
2320
- const measureUtf8Bytes = (text) => Buffer.byteLength(text, "utf8");
2321
- let chunkPushedEvent = false;
2322
- const pushStreamEvent = (event) => {
2323
- chunkPushedEvent = true;
2324
- stream.push(event);
2325
- };
2326
- const queuePostToolCallDelta = (next) => {
2327
- const nextBytes = measureUtf8Bytes(next.text);
2328
- if (pendingPostToolCallBytes + nextBytes > MAX_POST_TOOL_CALL_BUFFER_BYTES) throw new Error("Exceeded post-tool-call delta buffer limit");
2329
- pendingPostToolCallBytes += nextBytes;
2330
- const previous = pendingPostToolCallDeltas[pendingPostToolCallDeltas.length - 1];
2331
- if (!previous || previous.kind !== next.kind || previous.kind === "text" && next.kind === "text" && previous.source !== next.source) {
2332
- pendingPostToolCallDeltas.push(next);
2333
- return;
2334
- }
2335
- if (next.kind === "thinking" && previous.kind === "thinking") {
2336
- if (previous.signature !== next.signature) {
2337
- pendingPostToolCallDeltas.push(next);
2338
- return;
2339
- }
2340
- previous.text += next.text;
2341
- return;
2342
- }
2343
- previous.text += next.text;
2344
- };
2345
- const appendThinkingDeltaInternal = (reasoningDelta) => {
2346
- if (!currentBlock || currentBlock.type !== "thinking") {
2347
- currentBlock = {
2348
- type: "thinking",
2349
- thinking: "",
2350
- ...reasoningDelta.signature ? { thinkingSignature: reasoningDelta.signature } : {}
2351
- };
2352
- output.content.push(currentBlock);
2353
- pushStreamEvent({
2354
- type: "thinking_start",
2355
- contentIndex: blockIndex(),
2356
- partial: output
2357
- });
2358
- }
2359
- currentBlock.thinking += reasoningDelta.text;
2360
- pushStreamEvent({
2361
- type: "thinking_delta",
2362
- contentIndex: blockIndex(),
2363
- delta: reasoningDelta.text,
2364
- partial: output
2365
- });
2366
- };
2367
- const appendTextDeltaInternal = (text, source) => {
2368
- if (currentBlock?.type === "text" && currentTextSource !== source) currentBlock = null;
2369
- if (!currentBlock || currentBlock.type !== "text") {
2370
- currentBlock = {
2371
- type: "text",
2372
- text: ""
2373
- };
2374
- currentTextSource = source;
2375
- if (source === "reasoning_detail") (explicitVisibleTextBlocks ??= /* @__PURE__ */ new Set()).add(currentBlock);
2376
- output.content.push(currentBlock);
2377
- pushStreamEvent({
2378
- type: "text_start",
2379
- contentIndex: blockIndex(),
2380
- partial: output
2381
- });
2382
- }
2383
- currentBlock.text += text;
2384
- if (pendingInterruptedTextBlock && text.trim()) {
2385
- confirmedInterruptedTextBlock = pendingInterruptedTextBlock;
2386
- pendingInterruptedTextBlock = null;
2387
- }
2388
- pushStreamEvent({
2389
- type: "text_delta",
2390
- contentIndex: blockIndex(),
2391
- delta: text
2392
- });
2393
- };
2394
- const flushPendingPostToolCallDeltas = () => {
2395
- if (isFlushingPendingPostToolCallDeltas || currentBlock?.type === "toolCall" || pendingPostToolCallDeltas.length === 0) return;
2396
- isFlushingPendingPostToolCallDeltas = true;
2397
- const bufferedDeltas = pendingPostToolCallDeltas;
2398
- pendingPostToolCallDeltas = [];
2399
- pendingPostToolCallBytes = 0;
2400
- for (const delta of bufferedDeltas) if (delta.kind === "text") appendTextDeltaInternal(delta.text, delta.source);
2401
- else if (emitReasoning) appendThinkingDeltaInternal(delta);
2402
- isFlushingPendingPostToolCallDeltas = false;
2403
- };
2404
- const appendThinkingDelta = (reasoningDelta) => {
2405
- flushPendingPostToolCallDeltas();
2406
- appendThinkingDeltaInternal(reasoningDelta);
2407
- };
2408
- const appendTextDelta = (text, source) => {
2409
- flushPendingPostToolCallDeltas();
2410
- appendTextDeltaInternal(text, source);
2411
- };
2412
- const appendVisibleTextDelta = (text) => {
2413
- if (!text) return;
2414
- if (currentBlock?.type === "toolCall") queuePostToolCallDelta({
2415
- kind: "text",
2416
- text
2417
- });
2418
- else appendTextDelta(text);
2419
- };
2420
- const appendReasoningDeltas = (reasoningDeltas) => {
2421
- for (const reasoningDelta of reasoningDeltas) {
2422
- if (reasoningDelta.kind === "thinking" && !emitReasoning) continue;
2423
- if (currentBlock?.type === "toolCall") {
2424
- queuePostToolCallDelta({ ...reasoningDelta });
2425
- continue;
2426
- }
2427
- if (reasoningDelta.kind === "text") appendTextDelta(reasoningDelta.text, reasoningDelta.source);
2428
- else if (emitReasoning) appendThinkingDelta(reasoningDelta);
2429
- }
2430
- };
2431
- const appendRecoveredToolCall = (toolCall) => {
2432
- if (currentBlock?.type === "toolCall") {
2433
- currentBlock = null;
2434
- flushPendingPostToolCallDeltas();
2435
- }
2436
- rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
2437
- const block = {
2438
- type: "toolCall",
2439
- id: `call_${randomUUID().replaceAll("-", "").slice(0, 24)}`,
2440
- name: toolCall.name,
2441
- arguments: toolCall.arguments,
2442
- partialArgs: toolCall.partialArgs
2443
- };
2444
- currentBlock = block;
2445
- output.content.push(block);
2446
- toolCallBlockIndices.set(block, output.content.length - 1);
2447
- pushStreamEvent({
2448
- type: "toolcall_start",
2449
- contentIndex: toolCallBlockIndices.get(block) ?? -1,
2450
- partial: output
2451
- });
2452
- pushStreamEvent({
2453
- type: "toolcall_delta",
2454
- contentIndex: toolCallBlockIndices.get(block) ?? -1,
2455
- delta: toolCall.partialArgs,
2456
- partial: output
2457
- });
2458
- };
2459
- const appendFilteredVisibleTextDelta = (text) => {
2460
- const recoveredParts = deepSeekToolCallRecoverer?.push(text) ?? [{
2461
- kind: "text",
2462
- text
2463
- }];
2464
- for (const recoveredPart of recoveredParts) {
2465
- if (recoveredPart.kind === "toolCall") {
2466
- appendRecoveredToolCall(recoveredPart);
2467
- continue;
2468
- }
2469
- const parts = deepSeekTextFilter?.push(recoveredPart.text) ?? [recoveredPart.text];
2470
- for (const part of parts) appendVisibleTextDelta(part);
2471
- }
2472
- };
2473
- const flushDeepSeekToolCallRecovererAtEnd = () => {
2474
- const recoveredParts = deepSeekToolCallRecoverer?.flush();
2475
- if (!recoveredParts) return;
2476
- for (const recoveredPart of recoveredParts) {
2477
- if (recoveredPart.kind === "toolCall") {
2478
- appendRecoveredToolCall(recoveredPart);
2479
- continue;
2480
- }
2481
- const parts = deepSeekTextFilter?.push(recoveredPart.text) ?? [recoveredPart.text];
2482
- for (const part of parts) appendVisibleTextDelta(part);
2483
- }
2484
- };
2485
- const flushDeepSeekTextFilterAtEnd = () => {
2486
- const parts = deepSeekTextFilter?.flush();
2487
- if (!parts) return;
2488
- for (const part of parts) appendVisibleTextDelta(part);
2489
- };
2490
- const appendRoutedContentDelta = (delta) => {
2491
- if (delta.kind === "text") {
2492
- appendFilteredVisibleTextDelta(delta.text);
2493
- return;
2494
- }
2495
- if (!emitReasoning) return;
2496
- if (currentBlock?.type === "toolCall") queuePostToolCallDelta(delta);
2497
- else appendThinkingDelta(delta);
2498
- };
2499
- const appendPartitionedVisibleDelta = (delta) => {
2500
- if (delta.kind === "text") appendFilteredVisibleTextDelta(delta.text);
2501
- };
2502
- const emitReasoningUsageActivity = (hasReasoningUsageActivity) => {
2503
- if (!hasReasoningUsageActivity || chunkPushedEvent || !emitReasoning) return;
2504
- const latestBlock = output.content[output.content.length - 1];
2505
- if (currentBlock?.type === "text" || currentBlock?.type === "toolCall") return;
2506
- if (latestBlock?.type === "text" || latestBlock?.type === "toolCall") return;
2507
- appendThinkingDelta({ text: "" });
2508
- };
2509
- const flushReasoningTagTextPartitioner = () => {
2510
- for (const delta of reasoningTagTextPartitioner.flush()) appendPartitionedVisibleDelta(delta);
2511
- };
2512
- const sealTextBeforeReasoning = () => {
2513
- if (currentBlock?.type !== "text" && !reasoningTagTextPartitioner.hasPending()) return;
2514
- flushReasoningTagTextPartitioner();
2515
- if (currentBlock?.type !== "text") return;
2516
- if (currentTextSource !== "reasoning_detail" && currentBlock.text.trim()) pendingInterruptedTextBlock = currentBlock;
2517
- currentBlock = null;
2518
- currentTextSource = void 0;
2519
- };
2520
- const beginReasoning = (hasFollowingVisibleText, forceStrict = false) => {
2521
- if (!output.openclawDelivery?.textPhaseRequiresTerminal) output.openclawDelivery = {
2522
- ...output.openclawDelivery,
2523
- textPhaseRequiresTerminal: true
2524
- };
2525
- if (forceStrict || reasoningTagTextPartitioner.hasPending()) reasoningTagTextPartitioner.markStrict();
2526
- if (!hasFollowingVisibleText || !reasoningTagTextPartitioner.hasPendingSyntax()) sealTextBeforeReasoning();
2527
- };
2528
- const cooperativeScheduler = createModelStreamCooperativeScheduler(options?.signal);
2529
- const guardedStream = withFirstStreamEventTimeout(responseStream, {
2530
- provider: model.provider,
2531
- api: model.api,
2532
- model: model.id,
2533
- timeoutMs: options?.firstEventTimeoutMs ?? 0,
2534
- stage: "completions",
2535
- abort: options?.abortFirstEventStream,
2536
- onTimeout: options?.onFirstEventTimeout,
2537
- hint: "The provider may be stalled while parsing the tool payload; retry with a smaller tool surface or enable OPENCLAW_DEBUG_MODEL_PAYLOAD=tools to inspect exposed tools."
2538
- });
2539
- for await (const rawChunk of guardedStream) {
2540
- throwIfModelStreamAborted(options?.signal);
2541
- chunkPushedEvent = false;
2542
- if (!rawChunk || typeof rawChunk !== "object") {
2543
- await cooperativeScheduler.afterEvent();
2544
- continue;
2545
- }
2546
- notifyLlmRequestActivity(options?.signal);
2547
- const chunk = rawChunk;
2548
- output.responseId ||= chunk.id;
2549
- let hasReasoningUsageActivity = false;
2550
- if (chunk.usage) {
2551
- output.usage = parseOpenAICompletionsUsage(chunk.usage, model);
2552
- hasReasoningUsageActivity = hasOpenAICompletionsReasoningUsageActivity(chunk.usage);
2553
- }
2554
- const choice = Array.isArray(chunk.choices) ? chunk.choices[0] : void 0;
2555
- if (!choice) {
2556
- emitReasoningUsageActivity(hasReasoningUsageActivity);
2557
- await cooperativeScheduler.afterEvent();
2558
- continue;
2559
- }
2560
- const choiceUsage = choice.usage;
2561
- if (!chunk.usage && choiceUsage) {
2562
- output.usage = parseOpenAICompletionsUsage(choiceUsage, model);
2563
- hasReasoningUsageActivity = hasOpenAICompletionsReasoningUsageActivity(choiceUsage);
2564
- }
2565
- if (choice.finish_reason) {
2566
- const finishReasonResult = mapOpenAIStopReason(choice.finish_reason, { allowSingularToolCall: true });
2567
- output.stopReason = finishReasonResult.stopReason;
2568
- if (finishReasonResult.stopReason === "stop") sawStopFinishReason = true;
2569
- if (finishReasonResult.errorMessage) output.errorMessage = finishReasonResult.errorMessage;
2570
- }
2571
- const rawChoiceDelta = choice.delta ?? choice.message;
2572
- if (!rawChoiceDelta) {
2573
- emitReasoningUsageActivity(hasReasoningUsageActivity);
2574
- await cooperativeScheduler.afterEvent();
2575
- continue;
2576
- }
2577
- for (const normalizedDelta of normalizeToolCallDeltas(rawChoiceDelta, choice.finish_reason)) {
2578
- const choiceDelta = normalizedDelta.delta;
2579
- const reasoningBatch = readOpenAICompletionsReasoningBatch(choiceDelta, visibleReasoningDetailTypes);
2580
- const reasoningDeltas = reasoningBatch.deltas;
2581
- const hasReasoningThinking = reasoningBatch.hasThinking;
2582
- const contentDeltas = readOpenAICompletionsContentDeltas(choiceDelta.content, choiceDelta.refusal, reasoningBatch.mirroredThinking);
2583
- const lastVisibleTextIndex = contentDeltas.findLastIndex((delta) => delta.kind === "text");
2584
- const hasSameChunkVisibleText = reasoningBatch.hasVisibleText || lastVisibleTextIndex !== -1;
2585
- if (hasReasoningThinking) {
2586
- beginReasoning(hasSameChunkVisibleText, true);
2587
- appendReasoningDeltas(reasoningDeltas);
2588
- }
2589
- for (const [contentDeltaIndex, contentDelta] of contentDeltas.entries()) if (contentDelta.kind === "text") {
2590
- const routedDeltas = hasReasoningThinking ? reasoningTagTextPartitioner.push(contentDelta.text) : reasoningTagTextPartitioner.pushVisible(contentDelta.text);
2591
- for (const routedDelta of routedDeltas) appendPartitionedVisibleDelta(routedDelta);
2592
- } else {
2593
- beginReasoning(contentDeltaIndex < lastVisibleTextIndex);
2594
- appendRoutedContentDelta(contentDelta);
2595
- }
2596
- if (!hasReasoningThinking) appendReasoningDeltas(reasoningDeltas);
2597
- const toolCallDeltas = normalizedDelta.toolCalls;
2598
- if (toolCallDeltas.length > 0) {
2599
- sawNativeToolCallDelta = true;
2600
- flushReasoningTagTextPartitioner();
2601
- rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
2602
- for (const toolCall of toolCallDeltas) {
2603
- const streamIndex = typeof toolCall.index === "number" ? toolCall.index : void 0;
2604
- let block = streamIndex !== void 0 ? toolCallBlocksByIndex.get(streamIndex) : void 0;
2605
- if (!block && toolCall.id) block = toolCallBlocksById.get(toolCall.id);
2606
- if (!block) {
2607
- if (currentBlock?.type === "toolCall") {
2608
- currentBlock = null;
2609
- flushPendingPostToolCallDeltas();
2610
- }
2611
- const initialSig = extractToolCallThoughtSignature(toolCall);
2612
- block = {
2613
- type: "toolCall",
2614
- id: toolCall.id || "",
2615
- name: toolCall.function?.name || "",
2616
- arguments: {},
2617
- partialArgs: "",
2618
- ...initialSig ? { thoughtSignature: initialSig } : {}
2619
- };
2620
- output.content.push(block);
2621
- toolCallBlockIndices.set(block, output.content.length - 1);
2622
- pushStreamEvent({
2623
- type: "toolcall_start",
2624
- contentIndex: toolCallBlockIndices.get(block) ?? -1,
2625
- partial: output
2626
- });
2627
- }
2628
- if (streamIndex !== void 0 && !toolCallBlocksByIndex.has(streamIndex)) toolCallBlocksByIndex.set(streamIndex, block);
2629
- if (toolCall.id) {
2630
- block.id = toolCall.id;
2631
- toolCallBlocksById.set(toolCall.id, block);
2632
- }
2633
- currentBlock = block;
2634
- if (toolCall.function?.name) block.name = toolCall.function.name;
2635
- const deltaSig = extractToolCallThoughtSignature(toolCall);
2636
- if (deltaSig) block.thoughtSignature = deltaSig;
2637
- if (toolCall.function?.arguments) {
2638
- block.partialArgs += toolCall.function.arguments;
2639
- block.arguments = parseStreamingJson(block.partialArgs);
2640
- pushStreamEvent({
2641
- type: "toolcall_delta",
2642
- contentIndex: toolCallBlockIndices.get(block) ?? -1,
2643
- delta: toolCall.function.arguments,
2644
- partial: output
2645
- });
2646
- }
2647
- }
2648
- }
2649
- }
2650
- flushPendingPostToolCallDeltas();
2651
- emitReasoningUsageActivity(hasReasoningUsageActivity);
2652
- await cooperativeScheduler.afterEvent();
2653
- }
2654
- flushReasoningTagTextPartitioner();
2655
- flushDeepSeekToolCallRecovererAtEnd();
2656
- flushDeepSeekTextFilterAtEnd();
2657
- currentBlock = null;
2658
- flushPendingPostToolCallDeltas();
2659
- finalizeOpenAICompletionsToolCalls(output, {
2660
- allowSilentToolCallPromotion: sawStopFinishReason || sawNativeToolCallDelta && (options?.sawStreamDONE?.() ?? false),
2661
- onConfirmedToolCall(block, contentIndex) {
2662
- if (block.type !== "toolCall") return;
2663
- pushStreamEvent({
2664
- type: "toolcall_end",
2665
- contentIndex,
2666
- toolCall: block,
2667
- partial: output
2668
- });
2669
- }
2670
- });
2671
- if (confirmedInterruptedTextBlock && output.stopReason !== "toolUse" && output.stopReason !== "error" && output.stopReason !== "aborted") tagInterruptedTextPhases(output.content, confirmedInterruptedTextBlock, explicitVisibleTextBlocks);
2672
- if (output.stopReason !== "toolUse") clearPendingCommentaryText(provisionalCommentaryTags);
2673
- if (output.stopReason === "error" || output.stopReason === "aborted") tagUnresolvedTextAsCommentary(output);
2674
- if (output.stopReason === "toolUse") tagPendingCommentaryText(output.content);
2675
- }
2676
- function resolveOpenAICompletionsReasoningEffort(options) {
2677
- return options?.reasoningEffort ?? options?.reasoning ?? "high";
2678
- }
2679
- function shouldEmitOpenAICompletionsReasoning(model, options) {
2680
- if (!model.reasoning) return false;
2681
- const effort = resolveOpenAICompletionsReasoningEffort(options);
2682
- if (!effort || !isOpenAICompletionsThinkingEnabled(effort)) return false;
2683
- return true;
2684
- }
2685
- function hasOpenAICompletionsReasoningUsageActivity(rawUsage) {
2686
- const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
2687
- return typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) && reasoningTokens > 0;
2688
- }
2689
- //#endregion
2690
1694
  //#region packages/ai/src/transports/openai-completions-transport.ts
2691
1695
  function assertOpenAICompletionsPayloadHasConversationTurn(params, model) {
2692
1696
  const messages = params.messages;
@@ -2762,7 +1766,7 @@ function buildOpenAICompletionsClientConfig(model, context, optionHeaders) {
2762
1766
  }
2763
1767
  }
2764
1768
  return {
2765
- baseURL,
1769
+ baseURL: resolveOpenAIClientBaseUrl(model, baseURL),
2766
1770
  defaultHeaders: headers,
2767
1771
  defaultQuery: Object.keys(defaultQuery).length > 0 ? defaultQuery : void 0
2768
1772
  };
@@ -2834,7 +1838,7 @@ function createOpenAICompletionsTransportStreamFn() {
2834
1838
  timeoutMs: options?.timeoutMs,
2835
1839
  maxRetries: options?.maxRetries
2836
1840
  })).withResponse();
2837
- await processCompletionsStream(withProviderResponseHook({
1841
+ const hookedResponseStream = withProviderResponseHook({
2838
1842
  stream: responseStream,
2839
1843
  signal: firstEventAbort.signal,
2840
1844
  abort: firstEventAbort.abort,
@@ -2843,9 +1847,11 @@ function createOpenAICompletionsTransportStreamFn() {
2843
1847
  type: "start",
2844
1848
  partial: output
2845
1849
  })
2846
- }), output, model, stream, {
1850
+ });
1851
+ await processCompletionsStream(hookedResponseStream, output, model, stream, {
2847
1852
  signal: options?.signal,
2848
1853
  emitReasoning,
1854
+ strictReasoningTags: reasoningTagTextPolicy.isStrict(options),
2849
1855
  firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
2850
1856
  abortFirstEventStream: firstEventAbort.abort,
2851
1857
  onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options),
@@ -2910,7 +1916,7 @@ async function requestPreparedOpenAIResponsesCompaction(streamFn, model, context
2910
1916
  }
2911
1917
  //#endregion
2912
1918
  //#region packages/ai/src/transports/openai-responses-continuation.ts
2913
- const HTTP_CONTINUATION_IDLE_TTL_MS = 300 * 1e3;
1919
+ const HTTP_CONTINUATION_IDLE_TTL_MS = 3e5;
2914
1920
  const TURN_HEADERS = /* @__PURE__ */ new Set([
2915
1921
  "traceparent",
2916
1922
  "x-openclaw-turn-id",
@@ -2920,7 +1926,7 @@ function jsonValuesEqual(left, right) {
2920
1926
  return stableStringify(JSON.parse(JSON.stringify(left))) === stableStringify(JSON.parse(JSON.stringify(right)));
2921
1927
  }
2922
1928
  function requestWithoutInput(request) {
2923
- const { input: _input, previous_response_id: _previousResponseId, ...rest } = request;
1929
+ const { input: _input, previous_response_id: _previousResponseId, instructions: _instructions, ...rest } = request;
2924
1930
  if (!isRecord(rest.metadata)) return rest;
2925
1931
  const metadata = Object.fromEntries(Object.entries(rest.metadata).filter(([key]) => key !== "openclaw_turn_id" && key !== "openclaw_turn_attempt"));
2926
1932
  return {
@@ -3111,18 +2117,28 @@ function sanitizeOpenAICodexResponsesParams(model, params) {
3111
2117
  stripOpenAICodexResponsesUnsupportedTextFields(params);
3112
2118
  return params;
3113
2119
  }
3114
- function buildOpenAICodexResponsesInstructions(context) {
2120
+ function buildOpenAIResponsesInstructionsText(context) {
3115
2121
  if (!context.systemPrompt) return;
3116
2122
  return sanitizeTransportPayloadText(stripSystemPromptCacheBoundary(context.systemPrompt));
3117
2123
  }
3118
- function resolveOpenAICodexResponsesInstructions(model, context) {
3119
- const instructions = buildOpenAICodexResponsesInstructions(context);
2124
+ function resolveOpenAIResponsesInstructions(model, context, usesInstructionsField) {
2125
+ if (!usesInstructionsField) return;
2126
+ const instructions = buildOpenAIResponsesInstructionsText(context);
3120
2127
  if (instructions && instructions.trim().length > 0) return instructions;
3121
2128
  return usesNativeOpenAICodexResponsesBackend(model) ? OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS : void 0;
3122
2129
  }
3123
- function ensureOpenAICodexResponsesInput(messages, context) {
2130
+ function buildOpenAIResponsesCompactSystemMessage(model, instructions) {
2131
+ const compat = getCompat(model);
2132
+ const supportsDeveloperRole = typeof compat.supportsDeveloperRole === "boolean" ? compat.supportsDeveloperRole : void 0;
2133
+ const role = model.reasoning && supportsDeveloperRole !== false ? "developer" : "system";
2134
+ return buildResponsesInputMessage(role, [{
2135
+ type: "input_text",
2136
+ text: instructions
2137
+ }]);
2138
+ }
2139
+ function ensureOpenAIResponsesNonEmptyInput(messages, context) {
3124
2140
  if (messages.length > 0 || !context.systemPrompt) return;
3125
- if (!buildOpenAICodexResponsesInstructions(context)) throw new Error("OpenAI Codex Responses requires non-empty input when only systemPrompt is provided.");
2141
+ if (!buildOpenAIResponsesInstructionsText(context)) throw new Error("OpenAI Responses requires non-empty input when only systemPrompt is provided.");
3126
2142
  messages.push(buildResponsesInputMessage("user", [{
3127
2143
  type: "input_text",
3128
2144
  text: " "
@@ -3136,16 +2152,12 @@ function resolveOpenAIResponsesTextFormat(responseFormat) {
3136
2152
  return responseFormat;
3137
2153
  }
3138
2154
  function convertOpenAIResponsesMessagesForRequest(model, context, options, replayMode) {
3139
- const isCodexResponses = isOpenAICodexResponsesModel(model);
3140
2155
  const isNativeCodexResponses = usesNativeOpenAICodexResponsesBackend(model);
3141
- const compat = getCompat(model);
3142
- const supportsDeveloperRole = typeof compat.supportsDeveloperRole === "boolean" ? compat.supportsDeveloperRole : void 0;
3143
2156
  const payloadPolicy = resolveOpenAIResponsesPayloadPolicy(model, { storeMode: "disable" });
3144
2157
  const policyAllowsReplayIds = payloadPolicy.explicitStore !== false && !payloadPolicy.shouldStripStore;
3145
2158
  const replayResponsesItemIds = !isNativeCodexResponses && (options?.replayResponsesItemIds ?? policyAllowsReplayIds);
3146
2159
  return convertResponsesMessages(model, context, OPENAI_RESPONSES_TOOL_CALL_PROVIDERS, {
3147
- includeSystemPrompt: !isCodexResponses,
3148
- supportsDeveloperRole,
2160
+ includeSystemPrompt: !payloadPolicy.usesInstructionsField,
3149
2161
  replayReasoningItems: true,
3150
2162
  replayResponsesItemIds,
3151
2163
  authProfileId: options?.authProfileId,
@@ -3154,19 +2166,19 @@ function convertOpenAIResponsesMessagesForRequest(model, context, options, repla
3154
2166
  });
3155
2167
  }
3156
2168
  function buildOpenAIResponsesParams(model, context, options, metadata, replayMode = "checkpoint") {
3157
- const isCodexResponses = isOpenAICodexResponsesModel(model);
3158
2169
  const payloadPolicy = resolveOpenAIResponsesPayloadPolicy(model, { storeMode: "disable" });
3159
2170
  const messages = convertOpenAIResponsesMessagesForRequest(model, context, options, replayMode);
3160
- if (isCodexResponses) ensureOpenAICodexResponsesInput(messages, context);
2171
+ ensureOpenAIResponsesNonEmptyInput(messages, context);
3161
2172
  const cacheRetention = resolveCacheRetention(options?.cacheRetention);
3162
2173
  const promptCacheKey = resolvePromptCacheKey(options, cacheRetention);
2174
+ const instructions = resolveOpenAIResponsesInstructions(model, context, payloadPolicy.usesInstructionsField);
3163
2175
  const params = {
3164
2176
  model: model.id,
3165
2177
  input: messages,
3166
2178
  stream: true,
3167
2179
  prompt_cache_key: promptCacheKey,
3168
2180
  prompt_cache_retention: getPromptCacheRetention(model.baseUrl, cacheRetention),
3169
- ...isCodexResponses ? { instructions: resolveOpenAICodexResponsesInstructions(model, context) } : {},
2181
+ ...instructions ? { instructions } : {},
3170
2182
  ...metadata ? { metadata } : {}
3171
2183
  };
3172
2184
  const effectiveMaxTokens = options?.maxTokens || model.maxTokens;
@@ -3188,9 +2200,10 @@ function buildOpenAIResponsesParams(model, context, options, metadata, replayMod
3188
2200
  }
3189
2201
  if (model.reasoning) {
3190
2202
  if (options?.reasoningEffort || options?.reasoning || options?.reasoningSummary) {
2203
+ const requestedReasoningEffort = resolveOpenAIReasoningEffort(options);
3191
2204
  const resolvedReasoningEffort = resolveOpenAIReasoningEffortForModel({
3192
2205
  model,
3193
- effort: resolveOpenAIReasoningEffort(options)
2206
+ effort: requestedReasoningEffort
3194
2207
  });
3195
2208
  const reasoningEffort = resolvedReasoningEffort ? raiseMinimalReasoningForResponsesWebSearch({
3196
2209
  model,
@@ -3217,8 +2230,8 @@ function buildOpenAIResponsesParams(model, context, options, metadata, replayMod
3217
2230
  }
3218
2231
  //#endregion
3219
2232
  //#region packages/ai/src/transports/openai-responses-websocket.ts
3220
- const SESSION_WEBSOCKET_CACHE_TTL_MS = 300 * 1e3;
3221
- const SESSION_WEBSOCKET_MAX_AGE_MS = 3300 * 1e3;
2233
+ const SESSION_WEBSOCKET_CACHE_TTL_MS = 3e5;
2234
+ const SESSION_WEBSOCKET_MAX_AGE_MS = 33e5;
3222
2235
  const WEBSOCKET_OPEN_STATE = 1;
3223
2236
  const websocketSessionCache = /* @__PURE__ */ new Map();
3224
2237
  const degradedWebSocketConnections = /* @__PURE__ */ new Map();
@@ -3471,149 +2484,6 @@ function closeOpenAIResponsesWebSocketSessions(sessionId) {
3471
2484
  }
3472
2485
  registerSessionResourceCleanup(closeOpenAIResponsesWebSocketSessions);
3473
2486
  //#endregion
3474
- //#region packages/media-core/src/inline-image-data-url.ts
3475
- /** Prefix used to distinguish inline data URLs from remote/local image references. */
3476
- const INLINE_IMAGE_DATA_URL_PREFIX = "data:";
3477
- const IMAGE_SIGNATURES = [
3478
- {
3479
- mime: "image/png",
3480
- matches: (buffer) => buffer.length >= 8 && buffer[0] === 137 && buffer[1] === 80 && buffer[2] === 78 && buffer[3] === 71 && buffer[4] === 13 && buffer[5] === 10 && buffer[6] === 26 && buffer[7] === 10
3481
- },
3482
- {
3483
- mime: "image/jpeg",
3484
- matches: (buffer) => buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255
3485
- },
3486
- {
3487
- mime: "image/webp",
3488
- matches: (buffer) => buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP"
3489
- },
3490
- {
3491
- mime: "image/gif",
3492
- matches: (buffer) => buffer.length >= 6 && (buffer.subarray(0, 6).toString("ascii") === "GIF87a" || buffer.subarray(0, 6).toString("ascii") === "GIF89a")
3493
- },
3494
- {
3495
- mime: "image/bmp",
3496
- matches: (buffer) => buffer.length >= 2 && buffer[0] === 66 && buffer[1] === 77
3497
- }
3498
- ];
3499
- const HEIC_BRANDS = /* @__PURE__ */ new Set([
3500
- "heic",
3501
- "heix",
3502
- "hevc",
3503
- "hevx",
3504
- "heis",
3505
- "heim",
3506
- "hevm",
3507
- "hevs"
3508
- ]);
3509
- const HEIF_BRANDS = /* @__PURE__ */ new Set(["mif1", "msf1"]);
3510
- const IMAGE_SIGNATURE_PREFIX_BASE64_CHARS = 128;
3511
- const INLINE_IMAGE_DATA_URL_MIMES = /* @__PURE__ */ new Set([
3512
- "image/png",
3513
- "image/jpeg",
3514
- "image/webp",
3515
- "image/gif"
3516
- ]);
3517
- function startsWithDataUrl(value) {
3518
- return value.slice(0, 5).toLowerCase() === INLINE_IMAGE_DATA_URL_PREFIX;
3519
- }
3520
- function sniffIsoBmffImageMime(buffer) {
3521
- if (buffer.length < 12 || buffer.subarray(4, 8).toString("ascii") !== "ftyp") return;
3522
- const brands = [buffer.subarray(8, 12).toString("ascii")];
3523
- for (let offset = 16; offset + 4 <= buffer.length; offset += 4) brands.push(buffer.subarray(offset, offset + 4).toString("ascii"));
3524
- if (brands.some((brand) => HEIC_BRANDS.has(brand))) return "image/heic";
3525
- if (brands.some((brand) => HEIF_BRANDS.has(brand))) return "image/heif";
3526
- }
3527
- /** Sniffs supported inline image formats from decoded bytes. */
3528
- function sniffInlineImageMime(buffer) {
3529
- return IMAGE_SIGNATURES.find((signature) => signature.matches(buffer))?.mime ?? sniffIsoBmffImageMime(buffer);
3530
- }
3531
- function isImageMimeType(value) {
3532
- return value.trim().toLowerCase().startsWith("image/");
3533
- }
3534
- /** Canonicalizes trusted inline image base64 and rejects malformed or non-image payloads. */
3535
- function sanitizeInlineImageBase64(params) {
3536
- if (!isImageMimeType(params.mimeType)) return;
3537
- const canonicalPayload = canonicalizeBase64(params.base64);
3538
- if (!canonicalPayload) return;
3539
- const sniffedMimeType = sniffInlineImageMime(Buffer.from(canonicalPayload.slice(0, IMAGE_SIGNATURE_PREFIX_BASE64_CHARS), "base64"));
3540
- if (!sniffedMimeType) return;
3541
- return {
3542
- mimeType: sniffedMimeType,
3543
- base64: canonicalPayload
3544
- };
3545
- }
3546
- function parseInlineImageDataUrl(value) {
3547
- if (!startsWithDataUrl(value)) return {
3548
- metadata: [],
3549
- payload: value
3550
- };
3551
- const commaIndex = value.indexOf(",");
3552
- if (commaIndex < 0) return;
3553
- return {
3554
- metadata: value.slice(5, commaIndex).split(";").map((part) => part.trim()),
3555
- payload: value.slice(commaIndex + 1)
3556
- };
3557
- }
3558
- function metadataAllowsImageBase64(metadata) {
3559
- const [mimeType, ...options] = metadata;
3560
- return mimeType !== void 0 && isImageMimeType(mimeType) && options.some((part) => part.toLowerCase() === "base64");
3561
- }
3562
- function sanitizeInlineImageDataUrlWithAllowedMimes(imageUrl, allowedMimes) {
3563
- const parsed = parseInlineImageDataUrl(imageUrl);
3564
- if (!parsed) return;
3565
- if (parsed.metadata.length === 0) return imageUrl;
3566
- if (!metadataAllowsImageBase64(parsed.metadata)) return;
3567
- const [mimeType] = parsed.metadata;
3568
- const sanitized = sanitizeInlineImageBase64({
3569
- mimeType: mimeType ?? "",
3570
- base64: parsed.payload
3571
- });
3572
- if (!sanitized) return;
3573
- if (allowedMimes && !allowedMimes.has(sanitized.mimeType)) return;
3574
- return `data:${sanitized.mimeType};base64,${sanitized.base64}`;
3575
- }
3576
- /** Canonicalizes provider-safe inline image data URLs and rejects unsupported formats. */
3577
- function sanitizeInlineImageDataUrl(imageUrl) {
3578
- return sanitizeInlineImageDataUrlWithAllowedMimes(imageUrl, INLINE_IMAGE_DATA_URL_MIMES);
3579
- }
3580
- //#endregion
3581
- //#region packages/ai/src/transports/responses-image-payload-sanitizer.ts
3582
- /**
3583
- * Sanitizes OpenAI Responses payloads before transport. Invalid inline images
3584
- * are replaced with text placeholders so the request remains valid and
3585
- * auditable.
3586
- */
3587
- const IMAGE_OMITTED_TEXT = "omitted image payload: invalid inline image data";
3588
- function invalidSnakeImage() {
3589
- return {
3590
- type: "input_text",
3591
- text: `[${IMAGE_OMITTED_TEXT}]`
3592
- };
3593
- }
3594
- function sanitizeValue(value) {
3595
- if (Array.isArray(value)) return value.map(sanitizeValue);
3596
- if (!isRecord(value)) return value;
3597
- if (value.type === "input_image" && typeof value.image_url === "string") {
3598
- const imageUrl = sanitizeInlineImageDataUrl(value.image_url);
3599
- return imageUrl ? {
3600
- ...value,
3601
- image_url: imageUrl
3602
- } : invalidSnakeImage();
3603
- }
3604
- const next = {};
3605
- for (const [key, child] of Object.entries(value)) next[key] = sanitizeValue(child);
3606
- return next;
3607
- }
3608
- /** Sanitize inline image fields inside a Responses API payload. */
3609
- function sanitizeResponsesImagePayload(params) {
3610
- if (!Array.isArray(params.input)) return params;
3611
- return {
3612
- ...params,
3613
- input: sanitizeValue(params.input)
3614
- };
3615
- }
3616
- //#endregion
3617
2487
  //#region packages/ai/src/transports/openai-responses-client.ts
3618
2488
  function resolveNativeOpenAIResponsesWebSocketMode(model, transport) {
3619
2489
  if (transport !== "websocket" && transport !== "websocket-cached" && transport !== "auto") return;
@@ -3647,17 +2517,18 @@ function resolveProviderTransportTurnState(model, params) {
3647
2517
  }
3648
2518
  });
3649
2519
  }
3650
- function createOpenAIResponsesClient(model, context, apiKey, optionHeaders, turnHeaders, sessionId) {
2520
+ function createOpenAIResponsesClient(model, context, apiKey, optionHeaders, turnHeaders, sessionId, fetchOverride) {
3651
2521
  return new OpenAI({
3652
2522
  apiKey,
3653
- baseURL: model.baseUrl,
2523
+ baseURL: resolveOpenAIClientBaseUrl(model),
3654
2524
  dangerouslyAllowBrowser: true,
3655
2525
  defaultHeaders: buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders, sessionId),
3656
- fetch: buildGuardedModelFetch(model),
2526
+ fetch: fetchOverride ?? buildGuardedModelFetch(model),
3657
2527
  ...buildOpenAISdkClientOptions(model)
3658
2528
  });
3659
2529
  }
3660
2530
  async function postOpenAIResponsesCompaction(params) {
2531
+ const compactInput = typeof params.request.instructions === "string" && params.request.instructions.length > 0 ? [buildOpenAIResponsesCompactSystemMessage(params.model, params.request.instructions), ...params.request.input ?? []] : params.request.input;
3661
2532
  const response = await params.client.post("/responses/compact", {
3662
2533
  ...buildOpenAISdkRequestOptions(params.model, params.options?.signal, {
3663
2534
  timeoutMs: params.options?.timeoutMs,
@@ -3665,19 +2536,19 @@ async function postOpenAIResponsesCompaction(params) {
3665
2536
  }),
3666
2537
  body: {
3667
2538
  model: params.request.model,
3668
- input: params.request.input
2539
+ input: compactInput
3669
2540
  }
3670
2541
  });
3671
2542
  const output = isRecord(response) && Array.isArray(response.output) ? response.output : [];
3672
2543
  const item = output.at(-1);
3673
2544
  const retainedItems = output.slice(0, -1);
3674
- const retainedMessagesAreValid = retainedItems.every((candidate) => isRecord(candidate) && candidate.type === "message" && (candidate.role === "user" || candidate.role === "developer" || candidate.role === "system") && Array.isArray(candidate.content));
3675
2545
  const retainedUserMessageCount = retainedItems.filter((candidate) => isRecord(candidate) && candidate.type === "message" && candidate.role === "user" && Array.isArray(candidate.content)).length;
3676
2546
  const inputUserMessageCount = Array.isArray(params.request.input) ? params.request.input.filter((candidate) => isRecord(candidate) && candidate.type === "message" && candidate.role === "user").length : 0;
3677
2547
  const retainedMessagePrefixSupported = supportsNativeOpenAIResponsesEndpoint(params.model);
3678
2548
  const usage = isRecord(response) && isRecord(response.usage) ? response.usage : void 0;
3679
- if (!isRecord(response) || response.object !== "response.compaction" || !retainedMessagesAreValid || retainedItems.length > 0 && (!retainedMessagePrefixSupported || retainedUserMessageCount !== inputUserMessageCount) || !isRecord(item) || item.type !== "compaction" || typeof item.encrypted_content !== "string" || item.encrypted_content.length === 0 || !usage || typeof usage.input_tokens !== "number" || typeof usage.output_tokens !== "number") throw new Error("Responses compact endpoint did not return one trailing compaction item");
2549
+ if (!isRecord(response) || response.object !== "response.compaction" || !isOpenAIResponsesCompactionOutput(output, params.model) || retainedItems.length > 0 && (!retainedMessagePrefixSupported || retainedUserMessageCount !== inputUserMessageCount) || !isRecord(item) || item.type !== "compaction" || typeof item.encrypted_content !== "string" || item.encrypted_content.length === 0 || !usage || typeof usage.input_tokens !== "number" || typeof usage.output_tokens !== "number") throw new Error("Responses compact endpoint did not return one trailing compaction item");
3680
2550
  return {
2551
+ output,
3681
2552
  item,
3682
2553
  historyMode: retainedUserMessageCount > 0 ? "retained-users" : "compacted-prefix",
3683
2554
  usage,
@@ -3708,7 +2579,7 @@ function createResponsesTransportExecutor(config) {
3708
2579
  });
3709
2580
  const websocketSessionPolicy = websocketMode ? turnState?.websocket : void 0;
3710
2581
  const websocketHeaders = websocketMode ? buildOpenAIClientHeaders(model, context, options?.headers, websocketSessionPolicy?.headers, options?.sessionId) : void 0;
3711
- const client = config.createClient(model, context, apiKey, options?.headers, turnState?.headers, options?.sessionId);
2582
+ const client = config.createClient(model, context, apiKey, options?.headers, turnState?.headers, options?.sessionId, compactRequest ? createBoundedOpenAIResponsesCompactionFetch(buildGuardedModelFetch(model)) : void 0);
3712
2583
  const buildRequest = async (replayMode) => {
3713
2584
  let params = config.buildRequest(model, context, responsesOptions, turnState?.metadata, replayMode);
3714
2585
  const nextParams = await options?.onPayload?.(params, model);
@@ -3778,7 +2649,7 @@ function createResponsesTransportExecutor(config) {
3778
2649
  emitModelTransportDebug(log, `[responses] start provider=${model.provider} api=${model.api} model=${model.id} requestIdHash=${redactIdentifier(options?.requestId, { len: 64 })} baseUrl=${formatModelTransportDebugBaseUrl(model.baseUrl)} timeoutMs=${safeDebugValue(requestOptions?.timeout)} apiKey=${apiKey ? "present" : "missing"} ${summarizeResponsesPayload(params)}`);
3779
2650
  let continuationBaseline;
3780
2651
  const createSseStream = async (initialRequest = continuationClaim?.request ?? params, initialAttemptKind = "initial", initialRejectedCompaction) => {
3781
- const { stream: rawResponseStream, response, attempt } = await config.createResponseStream({
2652
+ const { stream: responseStream } = await config.createResponseStream({
3782
2653
  client,
3783
2654
  request: initialRequest,
3784
2655
  requestOptions,
@@ -3787,19 +2658,23 @@ function createResponsesTransportExecutor(config) {
3787
2658
  initialAttemptKind,
3788
2659
  initialRejectedCompaction,
3789
2660
  buildFullHistoryRequest: () => buildRequest("full-history"),
3790
- onCompactionRejected: (checkpoint) => suppressOpenAIResponsesCompaction(output, model, responsesOptions, checkpoint)
3791
- });
3792
- if (continuationClaim) continuationBaseline = attempt.request.previous_response_id ? params : attempt.request;
3793
- return withProviderResponseHook({
3794
- stream: observeResponsesStream(rawResponseStream, model, requestStartedAt),
3795
- signal: firstEvent.signal,
3796
- abort: firstEvent.abort,
3797
- hook: createOpenAIProviderAcceptanceHook(options, response, model),
3798
- onReady: () => {
3799
- emitModelTransportDebug(log, `[responses] headers provider=${model.provider} api=${model.api} model=${model.id} transport=sse elapsedMs=${Date.now() - requestStartedAt}`);
3800
- startStream();
2661
+ onCompactionRejected: (checkpoint) => suppressOpenAIResponsesCompaction(output, model, responsesOptions, checkpoint),
2662
+ canRetryStream: () => output.content.length === 0,
2663
+ wrapStream: ({ stream: rawResponseStream, response, attempt }) => {
2664
+ if (continuationClaim) continuationBaseline = attempt.request.previous_response_id ? params : attempt.request;
2665
+ return withProviderResponseHook({
2666
+ stream: observeResponsesStream(rawResponseStream, model, requestStartedAt),
2667
+ signal: firstEvent.signal,
2668
+ abort: firstEvent.abort,
2669
+ hook: createOpenAIProviderAcceptanceHook(options, response, model),
2670
+ onReady: () => {
2671
+ emitModelTransportDebug(log, `[responses] headers provider=${model.provider} api=${model.api} model=${model.id} transport=sse elapsedMs=${Date.now() - requestStartedAt}`);
2672
+ startStream();
2673
+ }
2674
+ });
3801
2675
  }
3802
2676
  });
2677
+ return responseStream;
3803
2678
  };
3804
2679
  let responseStream;
3805
2680
  let finishWebSocket;
@@ -3944,23 +2819,20 @@ function createAzureOpenAIResponsesTransportStreamFn() {
3944
2819
  createResponseStream: createResponsesStreamWithEncryptedContentRetry
3945
2820
  });
3946
2821
  }
3947
- function normalizeAzureBaseUrl(baseUrl) {
3948
- return baseUrl.replace(/\/+$/, "");
3949
- }
3950
2822
  function resolveAzureDeploymentName(model) {
3951
2823
  return resolveAzureDeploymentNameFromMap({
3952
2824
  modelId: model.id,
3953
2825
  deploymentMap: process.env.AZURE_OPENAI_DEPLOYMENT_NAME_MAP
3954
2826
  });
3955
2827
  }
3956
- function createAzureOpenAIClient(model, context, apiKey, optionHeaders, turnHeaders) {
3957
- const baseURL = normalizeAzureBaseUrl(model.baseUrl);
2828
+ function createAzureOpenAIClient(model, context, apiKey, optionHeaders, turnHeaders, _sessionId, fetchOverride) {
2829
+ const baseURL = model.baseUrl.replace(/\/+$/, "");
3958
2830
  const clientOptions = {
3959
2831
  apiKey,
3960
2832
  dangerouslyAllowBrowser: true,
3961
2833
  defaultHeaders: buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders),
3962
2834
  baseURL,
3963
- fetch: buildGuardedModelFetch(model),
2835
+ fetch: fetchOverride ?? buildGuardedModelFetch(model),
3964
2836
  ...buildOpenAISdkClientOptions(model)
3965
2837
  };
3966
2838
  if (isOpenAICompatibleAzureResponsesBaseUrl(baseURL)) return new OpenAI(clientOptions);
@@ -4006,6 +2878,112 @@ const responsesTesting = {
4006
2878
  if (process.env.VITEST || false) globalThis.openclawOpenAIResponsesTransportTestApi = responsesTesting;
4007
2879
  //#endregion
4008
2880
  //#region packages/ai/src/transports/provider-compaction-replay.ts
2881
+ function isAssistantReplayMessage(message) {
2882
+ return message.role === "assistant";
2883
+ }
2884
+ /** Resolve from prepared transport facts; never retain or return credential material. */
2885
+ function resolveCompactionReplayEligibility(model, options) {
2886
+ if (OPENAI_RESPONSES_APIS.has(model.api)) return true;
2887
+ return Boolean(options.apiKey?.trim()) && resolveAnthropicServerCompactionPlan(model, options.extraParams, options.apiKey).enabled;
2888
+ }
2889
+ function resolveCompactionSource(messages, model, identity) {
2890
+ if (identity.enabled === false) return;
2891
+ const assistants = messages.filter(isAssistantReplayMessage);
2892
+ const selected = (() => {
2893
+ if (OPENAI_RESPONSES_APIS.has(model.api)) {
2894
+ const responses = resolveNewestOpenAIResponsesCompactionReplay(assistants, model, identity);
2895
+ return responses ? {
2896
+ family: "responses",
2897
+ ...responses
2898
+ } : void 0;
2899
+ }
2900
+ if (identity.enabled !== true) return;
2901
+ const anthropic = resolveNewestAnthropicCompaction(assistants, model, identity);
2902
+ return anthropic ? {
2903
+ family: "anthropic",
2904
+ ...anthropic
2905
+ } : void 0;
2906
+ })();
2907
+ if (!selected) return;
2908
+ const owner = assistants.find((message) => message === selected.owner);
2909
+ return owner ? {
2910
+ ...selected,
2911
+ owner
2912
+ } : void 0;
2913
+ }
2914
+ /** Manual recovery uses the durable client compactor, never a guessed retained-user prefix. */
2915
+ function requiresCompactionReplayRefresh(messages, model, identity) {
2916
+ const checkpoint = resolveCompactionSource(messages, model, identity);
2917
+ return checkpoint?.family === "responses" && checkpoint.mode === "refresh-required";
2918
+ }
2919
+ /** Carry a checkpoint immediately after reference-preserving history limiting, before repair. */
2920
+ function preserveCompactionReplayWindow(source, windowed, model, identity) {
2921
+ const checkpoint = resolveCompactionSource(source, model, identity);
2922
+ if (!checkpoint || windowed.some((message) => message === checkpoint.owner)) return windowed;
2923
+ const owner = checkpoint.owner;
2924
+ const replay = checkpoint.owner.providerReplay;
2925
+ const providerReplay = replay?.type === "openai-responses-retained-compaction" ? replay : {
2926
+ ...replay,
2927
+ replayIndex: 0
2928
+ };
2929
+ const suffix = new Set(source.slice(source.indexOf(owner) + 1));
2930
+ return [{
2931
+ ...owner,
2932
+ content: [],
2933
+ providerReplay
2934
+ }, ...windowed.filter((message) => suffix.has(message))];
2935
+ }
2936
+ function estimateResponsesWindow(checkpoint, estimate) {
2937
+ return checkpoint.output.reduce((tokens, entry) => {
2938
+ if (entry.type === "compaction") {
2939
+ const { encrypted_content, ...metadata } = entry;
2940
+ return tokens + estimate.text(encrypted_content) + estimate.json(metadata);
2941
+ }
2942
+ const { content, ...metadata } = entry;
2943
+ return tokens + estimate.json(metadata) + content.reduce((sum, block) => {
2944
+ if (block.type === "input_text") {
2945
+ const { text, ...fields } = block;
2946
+ return sum + estimate.text(text) + estimate.json(fields);
2947
+ }
2948
+ if (block.type === "input_image") {
2949
+ const { image_url: _imageUrl, ...fields } = block;
2950
+ return sum + estimate.image() + estimate.json(block.image_url?.startsWith("data:") ? fields : block);
2951
+ }
2952
+ return sum + estimate.json(block);
2953
+ }, 0);
2954
+ }, 0);
2955
+ }
2956
+ /** Estimate the canonical prefix and its tail once, independent of unbound usage snapshots. */
2957
+ function resolveCompactionReplayPressure(messages, model, identity, estimate) {
2958
+ const checkpoint = resolveCompactionSource(messages, model, identity);
2959
+ if (!checkpoint) return;
2960
+ if (checkpoint.family === "responses" && checkpoint.mode === "refresh-required") throw new CompactionReplayRefreshRequiredError();
2961
+ const ownerIndex = messages.findIndex((message) => message === checkpoint.owner);
2962
+ const owner = messages[ownerIndex];
2963
+ if (!owner) return;
2964
+ const prefixTokens = checkpoint.family === "anthropic" ? estimate.text(checkpoint.summary) : checkpoint.mode === "complete-window" ? estimateResponsesWindow(checkpoint, estimate) : estimate.text(checkpoint.item.encrypted_content);
2965
+ const { contextUsage: _staleContextUsage, ...usage } = checkpoint.owner.usage;
2966
+ const tail = [];
2967
+ for (const message of messages.slice(ownerIndex + 1)) {
2968
+ if (!isAssistantReplayMessage(message) || message.usage.contextUsage === void 0) {
2969
+ tail.push(message);
2970
+ continue;
2971
+ }
2972
+ const { contextUsage: _unboundContextUsage, ...billedUsage } = message.usage;
2973
+ tail.push({
2974
+ ...message,
2975
+ usage: billedUsage
2976
+ });
2977
+ }
2978
+ return {
2979
+ messages: [{
2980
+ ...owner,
2981
+ content: checkpoint.owner.content.slice(checkpoint.replayIndex),
2982
+ usage
2983
+ }, ...tail],
2984
+ prefixTokens
2985
+ };
2986
+ }
4009
2987
  /** Whether provider replay state is a prefix-bound server compaction checkpoint. */
4010
2988
  function isCompactionReplayCheckpoint(replay) {
4011
2989
  const type = replay && typeof replay === "object" ? replay.type : void 0;
@@ -4301,4 +3279,4 @@ function prepareModelForSimpleCompletion(params) {
4301
3279
  return applyProviderSimpleCompletionWrapper(apiRegistry, model, cfg);
4302
3280
  }
4303
3281
  //#endregion
4304
- export { GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, applyAnthropicCacheControlToMessages, applyAnthropicEphemeralCacheControlMarkers, applyAnthropicPayloadPolicyToParams, applyOpenAIResponsesPayloadPolicy, assertCodeModeResponsesToolSurface, assignTransportErrorDetails, buildOpenAIClientHeaders, buildOpenAICompletionsParams, buildOpenAISdkClientOptions, buildOpenAISdkRequestOptions, buildTransportAwareSimpleStreamFn, canonicalizeMaxTokensParam, captureOpenAIResponsesCompaction, coerceTransportToolCallArguments, copyProviderAcceptanceObserver, createAnthropicMessagesTransportStreamFn, createAzureOpenAIResponsesTransportStreamFn, createBoundaryAwareStreamFnForModel, createDeepSeekTextFilter, createEmptyTransportUsage, createModelStreamCooperativeScheduler, createOpenAICompletionsTransportStreamFn, createOpenAIProviderAcceptanceHook, createOpenAIResponseHook, createOpenAIResponsesTransportStreamFn, createOpenClawTransportStreamFnForModel, createTransportAwareStreamFnForModel, createWritableTransportEventStream, detectOpenAICompletionsCompat, emitModelTransportDebug, enforceCodeModeResponsesToolSurface, failTransportStream, filterCodeModePayloadTools, finalizeTerminalToolCallArguments, finalizeTransportStream, flattenCompletionMessagesToStringContent, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, getCompat, googleFlashSupportsMinimalThinking, hasOpenAICompatibleConversationTurn, isCodeModeModelVisibleToolName, isCompactionReplayCheckpoint, isOpenAICodexResponsesModel, isOpenAICompletionsThinkingEnabled, log, measureUtf8AppendBytes, mergeTransportHeaders, mergeTransportMetadata, normalizeCodexResponsesBaseUrlForOpenAISdk, notifyProviderHttpMetadata, notifyProviderHttpResponse, notifyProviderStreamOpened, parseJsonObjectPreservingUnsafeIntegers, parseJsonPreservingUnsafeIntegers, parseOpenAICompletionsUsage, parseTerminalToolCallArguments, prepareModelForSimpleCompletion, prepareTransportAwareSimpleModel, quoteUnsafeIntegerLiterals, readCodeModePayloadToolName, readOpenAICompletionsContentDeltas, readOpenAICompletionsReasoningBatch, replaceCompactionReplayOwnerContent, requestPreparedOpenAIResponsesCompaction, resolveAnthropicEphemeralCacheControl, resolveAnthropicMessagesUrl, resolveAnthropicPayloadPolicy, resolveAnthropicServerCompactionPlan, resolveCodeModeResponsesVisibleToolNames, resolveMaxTokensParam, resolveModelPayloadDebugMode, resolveModelSseDebugMode, resolveOpenAICompletionsCompat, resolveOpenAIReasoningEffortMap, resolveOpenAIResponsesCompactEndpointPlan, resolveOpenAIResponsesPayloadPolicy, resolveOpenAIResponsesServerCompactionPlan, resolveOpenAIStrictToolFlagWithDiagnostics, resolvePromptCacheKey, resolveReplayableResponsesMessageId, resolveTransportAwareSimpleApi, sanitizeNonEmptyTransportPayloadText, sanitizeResponsesImagePayload, sanitizeTransportPayloadText, sortPromptCacheToolsByName as sortTransportToolsByName, stripCompactionReplayCheckpoint, stripCompactionReplayCheckpointInPlace, stripCompletionMessagesToRoleContent, throwIfModelStreamAborted, transportAbortError, usesNativeOpenAICodexResponsesBackend, withProviderAcceptanceObserver, withProviderResponseHook };
3282
+ export { CompactionReplayRefreshRequiredError, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, applyAnthropicCacheControlToMessages, applyAnthropicEphemeralCacheControlMarkers, applyAnthropicPayloadPolicyToParams, applyOpenAIResponsesPayloadPolicy, assertCodeModeResponsesToolSurface, assignTransportErrorDetails, buildOpenAIClientHeaders, buildOpenAICompletionsParams, buildOpenAISdkClientOptions, buildOpenAISdkRequestOptions, buildTransportAwareSimpleStreamFn, canonicalizeMaxTokensParam, captureOpenAIResponsesCompaction, coerceTransportToolCallArguments, copyProviderAcceptanceObserver, createAnthropicMessagesTransportStreamFn, createAzureOpenAIResponsesTransportStreamFn, createBoundaryAwareStreamFnForModel, createDeepSeekTextFilter, createEmptyTransportUsage, createModelStreamCooperativeScheduler, createOpenAICompletionsTransportStreamFn, createOpenAIProviderAcceptanceHook, createOpenAIResponseHook, createOpenAIResponsesTransportStreamFn, createOpenClawTransportStreamFnForModel, createTransportAwareStreamFnForModel, createWritableTransportEventStream, detectOpenAICompletionsCompat, emitModelTransportDebug, enforceCodeModeResponsesToolSurface, failTransportStream, filterCodeModePayloadTools, finalizeTerminalToolCallArguments, finalizeTransportStream, flattenCompletionMessagesToStringContent, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, getCompat, googleFlashSupportsMinimalThinking, hasOpenAICompatibleConversationTurn, isCodeModeModelVisibleToolName, isCompactionReplayCheckpoint, isOpenAICodexResponsesModel, isOpenAICompletionsThinkingEnabled, log, measureUtf8AppendBytes, mergeTransportHeaders, mergeTransportMetadata, normalizeCodexResponsesBaseUrlForOpenAISdk, notifyProviderHttpMetadata, notifyProviderHttpResponse, notifyProviderStreamOpened, parseJsonObjectPreservingUnsafeIntegers, parseJsonPreservingUnsafeIntegers, parseOpenAICompletionsUsage, parseTerminalToolCallArguments, prepareModelForSimpleCompletion, prepareTransportAwareSimpleModel, preserveCompactionReplayWindow, quoteUnsafeIntegerLiterals, readCodeModePayloadToolName, readOpenAICompletionsContentDeltas, readOpenAICompletionsReasoningBatch, replaceCompactionReplayOwnerContent, requestPreparedOpenAIResponsesCompaction, requiresCompactionReplayRefresh, resolveAnthropicEphemeralCacheControl, resolveAnthropicMessagesUrl, resolveAnthropicPayloadPolicy, resolveAnthropicServerCompactionPlan, resolveCodeModeResponsesVisibleToolNames, resolveCompactionReplayEligibility, resolveCompactionReplayPressure, resolveMaxTokensParam, resolveModelPayloadDebugMode, resolveModelSseDebugMode, resolveOpenAIClientBaseUrl, resolveOpenAICompletionsCompat, resolveOpenAIReasoningEffortMap, resolveOpenAIResponsesCompactEndpointPlan, resolveOpenAIResponsesPayloadPolicy, resolveOpenAIResponsesServerCompactionPlan, resolveOpenAIStrictToolFlagWithDiagnostics, resolvePromptCacheKey, resolveReplayableResponsesMessageId, resolveTransportAwareSimpleApi, sanitizeNonEmptyTransportPayloadText, sanitizeResponsesImagePayload, sanitizeTransportPayloadText, sortPromptCacheToolsByName as sortTransportToolsByName, stripCompactionReplayCheckpoint, stripCompactionReplayCheckpointInPlace, stripCompletionMessagesToRoleContent, throwIfModelStreamAborted, transportAbortError, usesNativeOpenAICodexResponsesBackend, withProviderAcceptanceObserver, withProviderResponseHook };