@openclaw/ai 2026.9.1-beta.1 → 2026.9.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 (88) hide show
  1. package/dist/{anthropic-DI4PZKKB.mjs → anthropic-BDdqdVLK.mjs} +222 -216
  2. package/dist/{anthropic-compaction-replay-nhKaCXu6.mjs → anthropic-compaction-replay-DB2FGLQc.mjs} +160 -68
  3. package/dist/{anthropic-payload-policy-B_0n0enE.d.mts → anthropic-payload-policy-d46X2pR0.d.mts} +28 -4
  4. package/dist/{api-registry-CTd8NzcD.d.mts → api-registry-DWtPjzyn.d.mts} +2 -2
  5. package/dist/{azure-openai-responses-D8dI0ekg.mjs → azure-openai-responses-C5bZRfAP.mjs} +12 -9
  6. package/dist/{number-coercion-H9qHik3g.mjs → base64-CEFBpSkN.mjs} +73 -1
  7. package/dist/{diagnostics-COpOtRwq.mjs → diagnostics-CPeq9F7y.mjs} +5 -1
  8. package/dist/diagnostics-DfFyKeX_.mjs +136 -0
  9. package/dist/{diagnostics-BaTA9eVl.d.mts → diagnostics-DnPnOui6.d.mts} +5 -1
  10. package/dist/diagnostics.d.mts +8 -3
  11. package/dist/diagnostics.mjs +4 -3
  12. package/dist/{env-api-keys-DrgeBuva.mjs → env-api-keys-bktO00EJ.mjs} +2 -15
  13. package/dist/{event-stream-uSMZJ3FA.mjs → event-stream-BgDvQeum.mjs} +3 -9
  14. package/dist/{event-stream-LiXePESD.d.mts → event-stream-BhT5T1Ay.d.mts} +1 -1
  15. package/dist/event-stream-zctLx0yr.d.mts +1 -0
  16. package/dist/event-stream.d.mts +2 -2
  17. package/dist/event-stream.mjs +1 -1
  18. package/dist/{google-Od-LLdVK.mjs → google-4qeuE8iX.mjs} +9 -7
  19. package/dist/{google-shared-Bgr9lFPw.mjs → google-shared-CWeG8RIl.mjs} +27 -23
  20. package/dist/{google-vertex-aerRSXc4.mjs → google-vertex-O9BcnB6X.mjs} +8 -6
  21. package/dist/{host-D51fmkH6.mjs → host-CEvLw30U.mjs} +54 -9
  22. package/dist/{host-DsbPMFU6.d.mts → host-DjzGmdZ2.d.mts} +3 -3
  23. package/dist/index-FnHM2FcI.d.mts +117 -0
  24. package/dist/index.d.mts +10 -11
  25. package/dist/index.mjs +6 -6
  26. package/dist/internal/anthropic.d.mts +59 -55
  27. package/dist/internal/anthropic.mjs +5 -5
  28. package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
  29. package/dist/internal/openai-responses-payload-policy.mjs +2 -3
  30. package/dist/internal/openai.d.mts +66 -64
  31. package/dist/internal/openai.mjs +10 -10
  32. package/dist/internal/retry-after.d.mts +2 -3
  33. package/dist/internal/runtime.d.mts +43 -43
  34. package/dist/internal/runtime.mjs +10 -8
  35. package/dist/internal/shared.d.mts +25 -25
  36. package/dist/internal/shared.mjs +95 -4
  37. package/dist/{mistral-EiHdymeb.mjs → mistral-Tb6oalqH.mjs} +30 -23
  38. package/dist/{openai-chatgpt-responses-DHpF9o1e.mjs → openai-chatgpt-responses-yUXjPNfu.mjs} +76 -137
  39. package/dist/{openai-completions-EFPiUGfS.mjs → openai-completions-BIUV3RDT.mjs} +26 -22
  40. package/dist/{openai-completions-compat-BefmHT26.d.mts → openai-completions-compat-CpjYUArk.d.mts} +5 -5
  41. package/dist/{openai-completions-stream-DUlGwRMz.mjs → openai-completions-stream-BsrBe3Gg.mjs} +103 -96
  42. package/dist/openai-prompt-cache-CGnVB74a.mjs +21 -0
  43. package/dist/openai-prompt-cache-CNoIfHYC.d.mts +16 -0
  44. package/dist/{openai-responses-BogP8OjX.mjs → openai-responses-CCL41ALM.mjs} +15 -14
  45. package/dist/openai-responses-compaction-window-BMVHFOtq.mjs +697 -0
  46. package/dist/{openai-responses-contracts-Dvj_UtPy.d.mts → openai-responses-contracts-rF5DDRNS.d.mts} +23 -6
  47. package/dist/{openai-responses-payload-policy-CNGFT9zr.d.mts → openai-responses-payload-policy-rLRPsSmB.d.mts} +1 -0
  48. package/dist/{openai-responses-prompt-observer-internal-Cd4hJG-S.mjs → openai-responses-prompt-observer-internal-D0bhBfgL.mjs} +4 -18
  49. package/dist/{openai-responses-shared-DJThc6jW.mjs → openai-responses-shared-Bmma_3Qc.mjs} +438 -309
  50. package/dist/{openai-tool-schema-ho-hIkQf.mjs → openai-tool-schema-_pTAJqKF.mjs} +30 -40
  51. package/dist/{provider-error-DDOs_Bz0.mjs → provider-error-9TraxGvt.mjs} +20 -92
  52. package/dist/{provider-options-MdMBLzlU.d.mts → provider-options-Bcc_p-TU.d.mts} +26 -6
  53. package/dist/provider-replay-context-BuSUaAk5.mjs +21 -0
  54. package/dist/{provider-transcript-transform-C01bQ5a3.mjs → provider-transcript-transform-BaMbI1hr.mjs} +1 -1
  55. package/dist/provider-types.d.mts +19 -20
  56. package/dist/providers.d.mts +6 -6
  57. package/dist/providers.mjs +11 -11
  58. package/dist/{reasoning-tag-text-partitioner-5ygO2rZc.mjs → reasoning-tag-text-partitioner-DLCNXki6.mjs} +158 -94
  59. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  60. package/dist/{sanitize-unicode-DCkltN94.mjs → sanitize-unicode-D6xUvZaS.mjs} +2 -8
  61. package/dist/{simple-options-CFj7x3J4.mjs → simple-options-BjHCCh4v.mjs} +42 -6
  62. package/dist/{src-Bu3FiFAG.mjs → src-2qBGKg8O.mjs} +83 -2
  63. package/dist/{stream-first-event-timeout-MK28puvq.mjs → stream-first-event-timeout-DcNjoFQE.mjs} +1 -1
  64. package/dist/{tool-schema-json-projection-qvTEs5Am.mjs → tool-schema-json-projection-mJhXDcyz.mjs} +21 -31
  65. package/dist/{transport-stream-shared-ljShVIZB.mjs → transport-stream-shared-CZqMhfIw.mjs} +19 -6
  66. package/dist/{transport-stream-shared-rvaCyFYt.d.mts → transport-stream-shared-xnaqxmbP.d.mts} +5 -5
  67. package/dist/{transport-utils-LJ1_rbi-.mjs → transport-utils-7il795_9.mjs} +5 -8
  68. package/dist/transports.d.mts +121 -85
  69. package/dist/transports.mjs +747 -464
  70. package/dist/types-3Lnm-QSJ.d.mts +1 -0
  71. package/dist/{types-DhLoJbFm.d.mts → types-CJ1-Ht7A.d.mts} +55 -19
  72. package/dist/types.d.mts +7 -7
  73. package/dist/types.mjs +5 -5
  74. package/dist/{validation-Dk7q7NMN.d.mts → validation-AKZBDGQd.d.mts} +1 -1
  75. package/dist/{validation-B61OhAio.mjs → validation-CJZtym2g.mjs} +7 -5
  76. package/dist/validation.d.mts +1 -1
  77. package/dist/validation.mjs +1 -1
  78. package/package.json +5 -5
  79. package/dist/anthropic-BECQCNdF.d.mts +0 -98
  80. package/dist/event-stream-BKp4fOt_.d.mts +0 -1
  81. package/dist/index-Qbej8io0.d.mts +0 -3
  82. package/dist/openai-prompt-cache-2uo_1OR1.d.mts +0 -7
  83. package/dist/openai-prompt-cache-mZTCdRPo.mjs +0 -12
  84. package/dist/openai-responses-contracts-QUY12X0B.mjs +0 -233
  85. package/dist/openai-responses-payload-policy-D8EdimYe.mjs +0 -204
  86. package/dist/provider-options-AvldWZt8.mjs +0 -21
  87. package/dist/tls-certificate-errors-DXSpluKI.mjs +0 -93
  88. package/dist/types-GiAjXatj.d.mts +0 -1
@@ -1,31 +1,31 @@
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 "./src-Bu3FiFAG.mjs";
1
+ import { _ as supportsClaudeAdaptiveThinking, b as supportsClaudeNativeXhighEffort, h as resolveClaudeSonnet5ModelIdentity, m as resolveClaudeOpus5ModelIdentity } from "./src-2qBGKg8O.mjs";
3
2
  import { c as normalizeLowercaseStringOrEmpty, o as isRecord, s as hasNonEmptyString } from "./utf16-slice-qz3nsy87.mjs";
4
- import { r as calculateCost } from "./sanitize-unicode-DCkltN94.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-D51fmkH6.mjs";
6
- import { i as canonicalizeBase64, o as stableStringify } from "./provider-error-DDOs_Bz0.mjs";
7
- import { n as toErrorObject, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-Cd4hJG-S.mjs";
8
- import { r as asNonNegativeFiniteNumber } from "./number-coercion-H9qHik3g.mjs";
3
+ import { r as calculateCost } from "./sanitize-unicode-D6xUvZaS.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-CEvLw30U.mjs";
5
+ import { i as stableStringify } from "./provider-error-9TraxGvt.mjs";
6
+ import { r as toErrorObject } from "./diagnostics-DfFyKeX_.mjs";
7
+ import { a as asNonNegativeFiniteNumber } from "./base64-CEFBpSkN.mjs";
9
8
  import { n as uniqueStrings } from "./string-normalization--fwJ4S2q.mjs";
9
+ import { r as resolveOpenAIResponsesCacheParams } from "./openai-prompt-cache-CGnVB74a.mjs";
10
+ import { A as createAnthropicInlineImageBudget, B as resolveAnthropicContextManagementBetaHeader, C as ANTHROPIC_SERVER_SIDE_FALLBACKS, D as readAnthropicFallbackBoundary, E as applyAnthropicFallbackBoundary, F as applyAnthropicEphemeralCacheControlMarkers, G as omitFoundryBearerCredentialHeaders, H as resolveAnthropicPayloadPolicy, I as applyAnthropicPayloadPolicyToParams, K as usesFoundryBearerAuth, L as isAnthropicServerToolClearingEnabled, M as resolveAnthropicImageMediaType, N as applyAnthropicCacheControlToMessages, O as resolveAnthropicFallbackServingModelCost, P as applyAnthropicContextManagementToRequest, R as isDirectAnthropicModel, S as readAnthropicInputTransformations, U as resolveAnthropicServerCompactionPlan, V as resolveAnthropicEphemeralCacheControl, W as isAnthropicOAuthApiKey, _ as toClaudeCodeToolName, a as suppressAnthropicCompaction, b as findActiveAnthropicToolTurnAssistantIndex, f as normalizeAnthropicToolCallId, g as resolveOriginalAnthropicToolName, h as reconcileAnthropicToolChoice, i as resolveNewestAnthropicCompaction, j as normalizeAnthropicInlineContent, k as applyAnthropicRefusal, 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 ANTHROPIC_SERVER_SIDE_FALLBACK_BETA, x as logAnthropicThinkingDrops, y as applyAnthropicThinkingBindingControls, z as logAnthropicContextEdits } from "./anthropic-compaction-replay-DB2FGLQc.mjs";
10
11
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
11
- import { f as sortPromptCacheToolsByName, l as stripSystemPromptCacheBoundary, t as adjustMaxTokensForThinking } from "./simple-options-CFj7x3J4.mjs";
12
- import { a as resolveProviderEndpoint, c as transformTransportMessages, i as resolveOpenAIStrictToolSetting, n as buildGuardedModelFetch } from "./tool-schema-json-projection-qvTEs5Am.mjs";
13
- import { a as isGoogleGemini3FlashModel, c as parseRetryAfterSeconds, f as resolveModelHeaderSentinels$1, h as supportsModelTools, i as isCodeModeModelVisibleToolName, l as readResponseTextSnippet, m as sha256Hex, n as createAbortError$1, o as isGoogleGemini3ProModel, p as resolveSecretSentinel, r as estimateStringChars, t as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, u as redactIdentifier } from "./transport-utils-LJ1_rbi-.mjs";
14
- 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-nhKaCXu6.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-ljShVIZB.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-DUlGwRMz.mjs";
12
+ import { a as codeModeToolSurfaceObserver, d as stripSystemPromptCacheBoundary, m as sortPromptCacheToolsByName, o as reasoningTagTextPolicy, t as adjustMaxTokensForThinking } from "./simple-options-BjHCCh4v.mjs";
13
+ import { a as resolveProviderEndpoint, c as transformTransportMessages, i as resolveOpenAIStrictToolSetting, n as buildGuardedModelFetch } from "./tool-schema-json-projection-mJhXDcyz.mjs";
14
+ 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-7il795_9.mjs";
15
+ import { n as getEnvApiKey } from "./env-api-keys-bktO00EJ.mjs";
16
+ 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-CZqMhfIw.mjs";
17
+ 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-BsrBe3Gg.mjs";
17
18
  import { t as createDeferredEventBuffer } from "./deferred-event-buffer-DAvyP7qA.mjs";
18
19
  import { r as parseStreamingJson, t as createToolArgumentPreviewSchedule } from "./json-parse-BuAJEbdW.mjs";
19
20
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
20
21
  import { t as googleFlashSupportsMinimalThinking } from "./google-thinking-level-C-V3tecN.mjs";
21
- import { B as buildResponsesInputMessage, C as summarizeResponsesTools, G as suppressOpenAIResponsesCompaction, H as createOpenAIResponsesAssistantOutput, I as createResponsesStreamWithEncryptedContentRetry, J as resolveModelPayloadDebugMode, K as resolveReplayableResponsesMessageId, L as isInvalidEncryptedContentError, R as resolveAzureOpenAIApiVersion, S as summarizeResponsesPayload, U as buildOpenAIResponsesReasoningReplayMetadata, V as convertResponsesMessages, W as captureOpenAIResponsesCompaction, Y 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 emitModelTransportDebug, v as stringifyRedactedEvent, x as summarizeResponsesFailedNoDetailsObservation, y as stringifyRedactedPayload, z as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-DJThc6jW.mjs";
22
- import { t as codeModeToolSurfaceObserver } from "./provider-options-AvldWZt8.mjs";
23
- 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-ho-hIkQf.mjs";
24
- import { i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-MK28puvq.mjs";
25
- 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, y as resolveOpenAIReasoningEffortForModel } from "./openai-responses-contracts-QUY12X0B.mjs";
26
- import { i as resolveOpenAIResponsesServerCompactionPlan, n as resolveOpenAIResponsesCompactEndpointPlan, r as resolveOpenAIResponsesPayloadPolicy, t as applyOpenAIResponsesPayloadPolicy } from "./openai-responses-payload-policy-D8EdimYe.mjs";
22
+ import { $ as resolveModelPayloadDebugMode, B as resolveNextResponsesEncryptedContentAttempt, C as summarizeResponsesPayload, G as responsesInputFingerprint, H as convertResponsesMessages, J as captureOpenAIResponsesCompaction, K as CompactionReplayRefreshRequiredError, L as createResponsesStreamWithEncryptedContentRetry, Q as emitModelTransportDebug, R as isInvalidEncryptedContentError, S as summarizeResponsesFailedNoDetailsObservation, U as createOpenAIResponsesAssistantOutput, V as buildResponsesInputMessage, W as recordResponsesInputReplay, X as suppressOpenAIResponsesCompaction, Y as resolveNewestOpenAIResponsesCompactionReplay, Z as resolveReplayableResponsesMessageId, _ as normalizeResponsesFailedEvent, b as stringifyRedactedPayload, et as resolveModelSseDebugMode, g as logResponsesFailedNoDetails, h as buildResponsesFailedNoDetailsObservation, l as processResponsesStream, m as ResponsesStreamFailure, n as applyResponsesServiceTierPricing, p as observeResponsesStream, q as buildOpenAIResponsesReasoningReplayMetadata, v as safeDebugValue, w as summarizeResponsesTools, x as summarizeOpenAITransportError, y as stringifyRedactedEvent, z as resolveAzureOpenAIApiVersion } from "./openai-responses-shared-Bmma_3Qc.mjs";
23
+ 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-_pTAJqKF.mjs";
24
+ import { i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-DcNjoFQE.mjs";
25
+ import { C as isOpenAIGpt54MiniModel, E as normalizeOpenAIReasoningEffort, O as resolveOpenAIReasoningEffortForModel, 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, j as supportsOpenAITemperature, 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-BMVHFOtq.mjs";
27
26
  import { i as resolveAzureDeploymentNameFromMap, t as isOpenAICompatibleAzureResponsesBaseUrl } from "./azure-openai-responses-client-compat-C7K7QfUE.mjs";
28
27
  import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
28
+ import { t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-D0bhBfgL.mjs";
29
29
  import { randomUUID } from "node:crypto";
30
30
  import OpenAI, { AzureOpenAI } from "openai";
31
31
  import { ResponsesWS } from "openai/resources/responses/ws.js";
@@ -35,12 +35,12 @@ import { ResponsesWS } from "openai/resources/responses/ws.js";
35
35
  * Converts OpenClaw contexts/tools into Anthropic payloads, streams SSE events
36
36
  * back into runtime output blocks, and applies provider request policy.
37
37
  */
38
- const ANTHROPIC_MESSAGES_ERROR_BODY_MAX_BYTES = 8 * 1024;
38
+ const ANTHROPIC_MESSAGES_ERROR_BODY_MAX_BYTES = 8192;
39
39
  const ANTHROPIC_MESSAGES_ERROR_BODY_MAX_CHARS = 400;
40
40
  const ANTHROPIC_MESSAGES_ERROR_BODY_READ_IDLE_TIMEOUT_MS = 1e4;
41
41
  const ANTHROPIC_MESSAGES_DEFAULT_MAX_TOKENS = 4096;
42
42
  const ANTHROPIC_MESSAGES_FALLBACK_CONTEXT_DIVISOR = 4;
43
- const ANTHROPIC_MESSAGES_SSE_PENDING_BUFFER_MAX_CHARS = 16 * 1024 * 1024;
43
+ const ANTHROPIC_MESSAGES_SSE_PENDING_BUFFER_MAX_CHARS = 16777216;
44
44
  function resolveAnthropicRequestModelId(model) {
45
45
  if (isDirectAnthropicModel(model) && /^anthropic\//i.test(model.id)) return model.id.replace(/^anthropic\//i, "");
46
46
  return model.id;
@@ -60,14 +60,6 @@ function resolveAnthropicMessagesMaxTokens(params) {
60
60
  const contextWindow = resolvePositiveAnthropicTokenLimit(params.modelContextWindow);
61
61
  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)));
62
62
  }
63
- function isAnthropicOAuthToken(apiKey) {
64
- return (resolveSecretSentinel(apiKey) ?? apiKey).includes("sk-ant-oat");
65
- }
66
- function isDirectAnthropicModel(model) {
67
- if (normalizeLowercaseStringOrEmpty(model.provider) !== "anthropic") return false;
68
- const endpointClass = resolveProviderEndpoint(model).endpointClass;
69
- return endpointClass === "default" || endpointClass === "anthropic-public";
70
- }
71
63
  function isKimiAnthropicProvider(provider) {
72
64
  return /^kimi(?:-|$)/.test(normalizeLowercaseStringOrEmpty(provider ?? ""));
73
65
  }
@@ -137,14 +129,12 @@ async function convertAnthropicMessages(messages, model, isOAuthToken, options)
137
129
  const msg = transformedMessages[i];
138
130
  if (!msg) continue;
139
131
  if (msg.role === "user") {
140
- const isRuntimeContextCarrier = msg.runtimeContextCarrier === true;
141
132
  if (typeof msg.content === "string") {
142
133
  if (msg.content.trim().length > 0) {
143
134
  const userParam = {
144
135
  role: "user",
145
136
  content: sanitizeTransportPayloadText(msg.content)
146
137
  };
147
- if (isRuntimeContextCarrier) options.cacheBreakpointOptOutMessageIndexes.add(params.length);
148
138
  params.push(userParam);
149
139
  }
150
140
  continue;
@@ -170,7 +160,6 @@ async function convertAnthropicMessages(messages, model, isOAuthToken, options)
170
160
  role: "user",
171
161
  content: filteredBlocks
172
162
  };
173
- if (isRuntimeContextCarrier) options.cacheBreakpointOptOutMessageIndexes.add(params.length);
174
163
  params.push(userParam);
175
164
  continue;
176
165
  }
@@ -406,12 +395,13 @@ async function* parseAnthropicSseBody(body, signal) {
406
395
  function createAnthropicMessagesClient(params) {
407
396
  const url = resolveAnthropicMessagesUrl(params.baseURL);
408
397
  return { messages: { async stream(body, options) {
409
- const headers = mergeTransportHeaders({
398
+ const headers = new Headers(mergeTransportHeaders({
410
399
  "content-type": "application/json",
411
400
  "anthropic-version": "2023-06-01",
412
401
  ...params.apiKey ? { "x-api-key": params.apiKey } : {},
413
402
  ...params.authToken ? { authorization: `Bearer ${params.authToken}` } : {}
414
- }, params.defaultHeaders);
403
+ }, params.defaultHeaders));
404
+ for (const [name, value] of Object.entries(options?.headers ?? {})) headers.set(name, value);
415
405
  const response = await params.fetch(url, {
416
406
  method: "POST",
417
407
  headers,
@@ -482,7 +472,7 @@ function createAnthropicTransportClient(params) {
482
472
  }
483
473
  const betaFeatures = ["fine-grained-tool-streaming-2025-05-14"];
484
474
  if (needsInterleavedBeta) betaFeatures.push("interleaved-thinking-2025-05-14");
485
- if (isAnthropicOAuthToken(apiKey)) {
475
+ if (isAnthropicOAuthApiKey(apiKey)) {
486
476
  const betaHeader = buildAnthropicBetaHeader(model, betaFeatures, { oauth: true });
487
477
  return {
488
478
  client: createAnthropicMessagesClient({
@@ -503,18 +493,20 @@ function createAnthropicTransportClient(params) {
503
493
  }
504
494
  if (useAnthropicServerSideFallback(model)) betaFeatures.push(ANTHROPIC_SERVER_SIDE_FALLBACK_BETA);
505
495
  const betaHeader = buildAnthropicBetaHeader(model, betaFeatures, { oauth: false });
496
+ const defaultHeaders = mergeTransportHeaders({
497
+ accept: "application/json",
498
+ "anthropic-dangerous-direct-browser-access": "true",
499
+ ...betaHeader ? { "anthropic-beta": betaHeader } : {}
500
+ }, model.headers, options?.headers);
506
501
  return {
507
502
  client: createAnthropicMessagesClient({
508
503
  apiKey,
509
504
  baseURL: model.baseUrl,
510
- defaultHeaders: mergeTransportHeaders({
511
- accept: "application/json",
512
- "anthropic-dangerous-direct-browser-access": "true",
513
- ...betaHeader ? { "anthropic-beta": betaHeader } : {}
514
- }, model.headers, options?.headers),
505
+ defaultHeaders,
515
506
  fetch
516
507
  }),
517
- isOAuthToken: false
508
+ isOAuthToken: false,
509
+ directApiKeyBetaHeader: isDirectAnthropicModel(model) ? new Headers(defaultHeaders).get("anthropic-beta") ?? "" : void 0
518
510
  };
519
511
  }
520
512
  async function buildAnthropicParams(model, context, isOAuthToken, options) {
@@ -533,7 +525,6 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
533
525
  cacheRetention: options?.cacheRetention,
534
526
  enableCacheControl: true
535
527
  }, model);
536
- const cacheBreakpointOptOutMessageIndexes = /* @__PURE__ */ new Set();
537
528
  const replayPlan = buildAnthropicReplayPlan(context.messages, model, {
538
529
  enabled: !isOAuthToken && options?.anthropicServerCompaction === true,
539
530
  authProfileId: options?.authProfileId,
@@ -541,7 +532,6 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
541
532
  });
542
533
  const messages = await convertAnthropicMessages(replayPlan.messages, model, isOAuthToken, {
543
534
  allowReasoningContentReplay: supportsReasoningContentReplay(model),
544
- cacheBreakpointOptOutMessageIndexes,
545
535
  compaction: replayPlan.compaction,
546
536
  replayThinkingEnabled
547
537
  });
@@ -579,18 +569,19 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
579
569
  if (convertedTools.tools.length > 0) params.tools = convertedTools.tools;
580
570
  }
581
571
  if (mandatoryAdaptiveThinking || model.reasoning || supportsClaudeAdaptiveThinking(model)) {
582
- if (mandatoryAdaptiveThinking || options?.thinkingEnabled) if (supportsClaudeAdaptiveThinking(model)) {
583
- params.thinking = {
584
- type: "adaptive",
585
- display: options?.thinkingDisplay ?? "summarized"
572
+ if (mandatoryAdaptiveThinking || options?.thinkingEnabled) {
573
+ if (supportsClaudeAdaptiveThinking(model)) {
574
+ params.thinking = {
575
+ type: "adaptive",
576
+ display: options?.thinkingDisplay ?? "summarized"
577
+ };
578
+ const effort = options?.effort ?? (mandatoryAdaptiveThinking ? "high" : void 0);
579
+ if (effort) params.output_config = { effort };
580
+ } else params.thinking = {
581
+ type: "enabled",
582
+ budget_tokens: options?.thinkingBudgetTokens ?? 1024
586
583
  };
587
- const effort = options?.effort ?? (mandatoryAdaptiveThinking ? "high" : void 0);
588
- if (effort) params.output_config = { effort };
589
- } else params.thinking = {
590
- type: "enabled",
591
- budget_tokens: options?.thinkingBudgetTokens ?? 1024
592
- };
593
- else if (options?.thinkingEnabled === false) params.thinking = { type: "disabled" };
584
+ } else if (options?.thinkingEnabled === false) params.thinking = { type: "disabled" };
594
585
  }
595
586
  if (options?.metadata && typeof options.metadata.user_id === "string") params.metadata = { user_id: options.metadata.user_id };
596
587
  if (options?.toolChoice) {
@@ -598,7 +589,7 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
598
589
  const projectedToolChoice = toolProjection ? reconcileAnthropicToolChoice(normalizedToolChoice, toolProjection) : normalizedToolChoice;
599
590
  if (projectedToolChoice) params.tool_choice = projectedToolChoice;
600
591
  }
601
- applyAnthropicPayloadPolicyToParams(params, payloadPolicy, cacheBreakpointOptOutMessageIndexes);
592
+ applyAnthropicPayloadPolicyToParams(params, payloadPolicy, /* @__PURE__ */ new Set());
602
593
  return {
603
594
  params,
604
595
  toolProjection,
@@ -633,7 +624,9 @@ function resolveAnthropicTransportOptions(model, options, apiKey) {
633
624
  toolChoice: options?.toolChoice,
634
625
  thinkingBudgets: options?.thinkingBudgets,
635
626
  reasoning,
636
- ...options?.anthropicServerCompaction === true ? { anthropicServerCompaction: true } : {},
627
+ anthropicServerCompaction: options?.anthropicServerCompaction,
628
+ anthropicCompactThreshold: options?.anthropicCompactThreshold,
629
+ cacheTtlPruning: options?.cacheTtlPruning,
637
630
  ...options?.authProfileId ? { authProfileId: options.authProfileId } : {}
638
631
  });
639
632
  if (reasoning === "off") {
@@ -674,17 +667,18 @@ function createAnthropicMessagesTransportStreamFn() {
674
667
  stopReason: "stop",
675
668
  timestamp: Date.now()
676
669
  };
677
- const refusalBuffer = usesClaudeStreamingRefusalContract(model) ? createDeferredEventBuffer(stream, () => notifyLlmRequestActivity(options?.signal)) : void 0;
670
+ const refusalBuffer = usesClaudeStreamingRefusalContract(model) ? createDeferredEventBuffer(stream) : void 0;
678
671
  const eventSink = refusalBuffer ?? stream;
679
672
  let costModel = model;
680
673
  let messageStartPromptUsage;
681
674
  let usedCompactionReplay = false;
675
+ let inputTransformations;
682
676
  try {
683
677
  const apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? "";
684
678
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
685
679
  const transportOptions = resolveAnthropicTransportOptions(model, options, apiKey);
686
680
  const requestContext = prepareClaudeNoPrefillRequestContext(model, context);
687
- const { client, isOAuthToken } = createAnthropicTransportClient({
681
+ const { client, isOAuthToken, directApiKeyBetaHeader } = createAnthropicTransportClient({
688
682
  model,
689
683
  context: requestContext,
690
684
  apiKey,
@@ -694,13 +688,19 @@ function createAnthropicMessagesTransportStreamFn() {
694
688
  usedCompactionReplay = builtParams.usedCompactionReplay;
695
689
  let params = builtParams.params;
696
690
  const toolProjection = builtParams.toolProjection;
691
+ applyAnthropicContextManagementToRequest(params, model, transportOptions, directApiKeyBetaHeader);
697
692
  const nextParams = await transportOptions.onPayload?.(params, model);
698
693
  if (nextParams !== void 0) params = nextParams;
699
694
  applyClaudeRequestContract(params, model);
695
+ const betaHeader = resolveAnthropicContextManagementBetaHeader(params, directApiKeyBetaHeader);
696
+ const bindingHeaders = applyAnthropicThinkingBindingControls(params, betaHeader) ?? (betaHeader !== void 0 ? { "anthropic-beta": betaHeader } : void 0);
700
697
  const { response, stream: anthropicStream } = await client.messages.stream({
701
698
  ...params,
702
699
  stream: true
703
- }, transportOptions.signal ? { signal: transportOptions.signal } : void 0);
700
+ }, {
701
+ signal: transportOptions.signal,
702
+ headers: bindingHeaders
703
+ });
704
704
  await notifyProviderHttpResponse({
705
705
  options: transportOptions,
706
706
  response,
@@ -815,6 +815,8 @@ function createAnthropicMessagesTransportStreamFn() {
815
815
  });
816
816
  };
817
817
  for await (const event of anthropicStream) {
818
+ inputTransformations = readAnthropicInputTransformations(event) ?? inputTransformations;
819
+ notifyLlmRequestActivity(transportOptions.signal);
818
820
  if (event.type === "error") {
819
821
  const error = event.error;
820
822
  throw new Error(error?.message || "Anthropic Messages stream failed");
@@ -987,16 +989,18 @@ function createAnthropicMessagesTransportStreamFn() {
987
989
  let appendedContent = false;
988
990
  if (!hasNativeAnthropicDelta && typeof delta?.content === "string" && delta.content.length > 0) {
989
991
  const text = sanitizeTransportPayloadText(delta.content);
990
- if (text.length > 0) if (block?.type === "text" && index !== void 0) {
991
- block.text += text;
992
- eventSink.push({
993
- type: "text_delta",
994
- contentIndex: index,
995
- delta: text,
996
- partial: output
997
- });
998
- appendedContent = true;
999
- } else appendedContent = appendReasoningContentTextDelta(event.index, text);
992
+ if (text.length > 0) {
993
+ if (block?.type === "text" && index !== void 0) {
994
+ block.text += text;
995
+ eventSink.push({
996
+ type: "text_delta",
997
+ contentIndex: index,
998
+ delta: text,
999
+ partial: output
1000
+ });
1001
+ appendedContent = true;
1002
+ } else appendedContent = appendReasoningContentTextDelta(event.index, text);
1003
+ }
1000
1004
  }
1001
1005
  if ((appendedThinking || appendedContent) && !hasNativeAnthropicDelta) continue;
1002
1006
  }
@@ -1102,10 +1106,13 @@ function createAnthropicMessagesTransportStreamFn() {
1102
1106
  continue;
1103
1107
  }
1104
1108
  if (event.type === "message_delta") {
1109
+ logAnthropicContextEdits(event);
1105
1110
  const delta = event.delta;
1106
1111
  const usage = event.usage;
1107
- if (delta?.stop_reason) if (delta.stop_reason === "refusal") applyAnthropicRefusal(output, delta.stop_details, model.provider);
1108
- else output.stopReason = mapAnthropicStopReason(delta.stop_reason);
1112
+ if (delta?.stop_reason) {
1113
+ if (delta.stop_reason === "refusal") applyAnthropicRefusal(output, delta.stop_details, model.provider);
1114
+ else output.stopReason = mapAnthropicStopReason(delta.stop_reason);
1115
+ }
1109
1116
  applyAnthropicMessageDeltaUsage(output.usage, usage, messageStartPromptUsage);
1110
1117
  calculateCost(costModel, output.usage);
1111
1118
  if (output.stopReason === "toolUse" || output.content.some((block) => block.type === "toolCall")) tagPendingCommentaryText(output.content);
@@ -1134,20 +1141,22 @@ function createAnthropicMessagesTransportStreamFn() {
1134
1141
  output
1135
1142
  });
1136
1143
  } catch (error) {
1137
- if (refusalBuffer) {
1138
- refusalBuffer.discard();
1139
- output.content = [];
1140
- } else output.content = output.content.filter((block) => block.type !== "toolCall");
1141
- if (usedCompactionReplay && isAnthropicReplayRejection(error)) suppressAnthropicCompaction(output, model, options);
1142
1144
  failTransportStream({
1143
1145
  stream,
1144
1146
  output,
1145
1147
  signal: options?.signal,
1146
1148
  error,
1147
1149
  cleanup: () => {
1150
+ if (refusalBuffer) {
1151
+ refusalBuffer.discard();
1152
+ output.content = [];
1153
+ } else output.content = output.content.filter((block) => block.type !== "toolCall");
1154
+ if (usedCompactionReplay && isAnthropicReplayRejection(error)) suppressAnthropicCompaction(output, model, options);
1148
1155
  for (const block of output.content) delete block.index;
1149
1156
  }
1150
1157
  });
1158
+ } finally {
1159
+ logAnthropicThinkingDrops(inputTransformations);
1151
1160
  }
1152
1161
  })();
1153
1162
  return eventStream;
@@ -1595,10 +1604,11 @@ function convertTools(tools, compat, model) {
1595
1604
  function buildOpenAICompletionsParams(model, context, options) {
1596
1605
  const compat = getCompat(model);
1597
1606
  const compatDetection = detectOpenAICompletionsCompat(model);
1598
- let messages = convertMessages(model, context.systemPrompt ? {
1607
+ const completionsContext = context.systemPrompt ? {
1599
1608
  ...context,
1600
1609
  systemPrompt: stripSystemPromptCacheBoundary(context.systemPrompt)
1601
- } : context, compat);
1610
+ } : context;
1611
+ let messages = convertMessages(model, completionsContext, compat);
1602
1612
  applyCompletionsReplay(messages, context, model, compat);
1603
1613
  if (compat.strictMessageKeys) messages = stripCompletionMessagesToRoleContent(messages);
1604
1614
  const cacheRetention = resolveCacheRetention(options?.cacheRetention);
@@ -1659,8 +1669,10 @@ function buildOpenAICompletionsParams(model, context, options) {
1659
1669
  emitModelTransportDebug(log, `[completions] clamp_max_tokens provider=${model.provider} api=${model.api} model=${model.id} requested=${effectiveMaxTokens} output=${clampedMaxTokens} effectiveContext=${effectiveContextTokens} estimatedInput=${estimatedInputTokens}`);
1660
1670
  }
1661
1671
  }
1662
- if (clampedMaxTokens) if (compat.maxTokensField === "max_tokens") params.max_tokens = clampedMaxTokens;
1663
- else params.max_completion_tokens = clampedMaxTokens;
1672
+ if (clampedMaxTokens) {
1673
+ if (compat.maxTokensField === "max_tokens") params.max_tokens = clampedMaxTokens;
1674
+ else params.max_completion_tokens = clampedMaxTokens;
1675
+ }
1664
1676
  }
1665
1677
  const completionsReasoningEffort = resolveOpenAICompletionsReasoningEffort(options);
1666
1678
  const resolvedCompletionsReasoningEffort = completionsReasoningEffort ? resolveOpenAIReasoningEffortForModel({
@@ -1831,11 +1843,8 @@ function createOpenAICompletionsTransportStreamFn() {
1831
1843
  if (getCompat(model).requiresNonEmptyUserOrAssistantMessage) assertOpenAICompletionsPayloadHasConversationTurn(params, model);
1832
1844
  const emitReasoning = shouldEmitOpenAICompletionsReasoning(model, options);
1833
1845
  firstEventAbort = createFirstStreamEventAbortController(options?.signal);
1834
- const { data: responseStream, response } = await client.chat.completions.create(params, buildOpenAISdkRequestOptions(model, firstEventAbort.signal, {
1835
- timeoutMs: options?.timeoutMs,
1836
- maxRetries: options?.maxRetries
1837
- })).withResponse();
1838
- await processCompletionsStream(withProviderResponseHook({
1846
+ const { data: responseStream, response } = await client.chat.completions.create(params, buildOpenAISdkRequestOptions(model, firstEventAbort.signal, { timeoutMs: options?.timeoutMs })).withResponse();
1847
+ const hookedResponseStream = withProviderResponseHook({
1839
1848
  stream: responseStream,
1840
1849
  signal: firstEventAbort.signal,
1841
1850
  abort: firstEventAbort.abort,
@@ -1844,9 +1853,11 @@ function createOpenAICompletionsTransportStreamFn() {
1844
1853
  type: "start",
1845
1854
  partial: output
1846
1855
  })
1847
- }), output, model, stream, {
1856
+ });
1857
+ await processCompletionsStream(hookedResponseStream, output, model, stream, {
1848
1858
  signal: options?.signal,
1849
1859
  emitReasoning,
1860
+ strictReasoningTags: reasoningTagTextPolicy.isStrict(options),
1850
1861
  firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
1851
1862
  abortFirstEventStream: firstEventAbort.abort,
1852
1863
  onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options),
@@ -1877,160 +1888,6 @@ function createOpenAICompletionsTransportStreamFn() {
1877
1888
  };
1878
1889
  }
1879
1890
  //#endregion
1880
- //#region packages/ai/src/transports/openai-responses-compact-request.ts
1881
- const COMPACT_REQUEST = Symbol("openaiResponsesCompactRequest");
1882
- function claimResponsesCompactRequest(options) {
1883
- const controller = options ? Reflect.get(options, COMPACT_REQUEST) : void 0;
1884
- if (controller?.claimed === false) {
1885
- controller.claimed = true;
1886
- return controller;
1887
- }
1888
- }
1889
- /** Run a compact-endpoint request through the session's prepared stream stack. */
1890
- async function requestPreparedOpenAIResponsesCompaction(streamFn, model, context, options) {
1891
- const preparedOptions = { ...options };
1892
- let resolveResult;
1893
- let rejectResult;
1894
- const result = new Promise((resolve, reject) => {
1895
- resolveResult = resolve;
1896
- rejectResult = reject;
1897
- });
1898
- const controller = {
1899
- claimed: false,
1900
- resolve: resolveResult,
1901
- reject: rejectResult
1902
- };
1903
- Reflect.set(preparedOptions, COMPACT_REQUEST, controller);
1904
- const stream = await Promise.resolve(streamFn(model, context, preparedOptions));
1905
- if (!controller.claimed) throw new Error("Prepared stream did not reach an OpenAI Responses transport");
1906
- try {
1907
- return await result;
1908
- } finally {
1909
- await stream.result().catch(() => void 0);
1910
- }
1911
- }
1912
- //#endregion
1913
- //#region packages/ai/src/transports/openai-responses-continuation.ts
1914
- const HTTP_CONTINUATION_IDLE_TTL_MS = 300 * 1e3;
1915
- const TURN_HEADERS = /* @__PURE__ */ new Set([
1916
- "traceparent",
1917
- "x-openclaw-turn-id",
1918
- "x-openclaw-turn-attempt"
1919
- ]);
1920
- function jsonValuesEqual(left, right) {
1921
- return stableStringify(JSON.parse(JSON.stringify(left))) === stableStringify(JSON.parse(JSON.stringify(right)));
1922
- }
1923
- function requestWithoutInput(request) {
1924
- const { input: _input, previous_response_id: _previousResponseId, ...rest } = request;
1925
- if (!isRecord(rest.metadata)) return rest;
1926
- const metadata = Object.fromEntries(Object.entries(rest.metadata).filter(([key]) => key !== "openclaw_turn_id" && key !== "openclaw_turn_attempt"));
1927
- return {
1928
- ...rest,
1929
- metadata
1930
- };
1931
- }
1932
- function normalizeAssistantReplayInput(input) {
1933
- return input.map((item) => {
1934
- if (!isRecord(item)) return item;
1935
- if (item.type === "reasoning") return { type: "reasoning" };
1936
- if (item.type !== "function_call" && !(item.type === "message" && item.role === "assistant")) return item;
1937
- const { id: _id, status: _status, ...stableItem } = item;
1938
- if (item.type === "message" && Array.isArray(stableItem.content)) stableItem.content = stableItem.content.map((part) => {
1939
- if (!isRecord(part) || part.type !== "output_text") return part;
1940
- const { annotations: _annotations, logprobs: _logprobs, ...stablePart } = part;
1941
- return stablePart;
1942
- });
1943
- return stableItem;
1944
- });
1945
- }
1946
- function resolveResponsesContinuationRequest(continuation, request) {
1947
- if (!continuation) return {
1948
- request,
1949
- continuationStatus: "no_previous_response"
1950
- };
1951
- if (request.previous_response_id) return {
1952
- request,
1953
- continuationStatus: "explicit_previous_response_id"
1954
- };
1955
- if (!jsonValuesEqual(requestWithoutInput(request), requestWithoutInput(continuation.lastRequest))) return {
1956
- request,
1957
- continuationStatus: "request_changed"
1958
- };
1959
- const currentInput = request.input ?? [];
1960
- const previousInput = continuation.lastRequest.input ?? [];
1961
- const baselineLength = previousInput.length + continuation.lastResponseItems.length;
1962
- if (currentInput.length < baselineLength) return {
1963
- request,
1964
- continuationStatus: "history_shorter"
1965
- };
1966
- if (!jsonValuesEqual(normalizeAssistantReplayInput(currentInput.slice(0, previousInput.length)), normalizeAssistantReplayInput(previousInput)) || !jsonValuesEqual(normalizeAssistantReplayInput(currentInput.slice(previousInput.length, baselineLength)), normalizeAssistantReplayInput(continuation.lastResponseItems))) return {
1967
- request,
1968
- continuationStatus: "history_changed"
1969
- };
1970
- return {
1971
- request: {
1972
- ...request,
1973
- previous_response_id: continuation.lastResponseId,
1974
- input: currentInput.slice(baselineLength)
1975
- },
1976
- continuationStatus: "continued"
1977
- };
1978
- }
1979
- const httpContinuationEntries = /* @__PURE__ */ new Map();
1980
- let nextHttpContinuationGeneration = 1;
1981
- function connectionIdentity(params) {
1982
- const headers = Object.entries(resolveAiTransportHeaderSentinels(params.headers) ?? {}).map(([name, value]) => [name.toLowerCase(), value]).filter(([name]) => !TURN_HEADERS.has(name)).toSorted(([a], [b]) => a.localeCompare(b));
1983
- return sha256Hex(JSON.stringify([
1984
- getAiTransportHost().resolveSecretSentinel(params.apiKey),
1985
- params.baseUrl,
1986
- headers
1987
- ]));
1988
- }
1989
- function claimOpenAIResponsesHttpContinuation(params) {
1990
- const key = `${params.sessionId}\0${connectionIdentity(params)}`;
1991
- const previous = httpContinuationEntries.get(key);
1992
- if (previous?.kind === "claimed") return;
1993
- if (previous?.kind === "ready") clearTimeout(previous.idleTimer);
1994
- const generation = nextHttpContinuationGeneration++;
1995
- const claimed = {
1996
- kind: "claimed",
1997
- sessionId: params.sessionId,
1998
- generation
1999
- };
2000
- httpContinuationEntries.set(key, claimed);
2001
- return {
2002
- request: resolveResponsesContinuationRequest(previous?.kind === "ready" ? previous.state : void 0, params.request).request,
2003
- commit: (effectiveRequest, response) => {
2004
- if (httpContinuationEntries.get(key) !== claimed) return;
2005
- const idleTimer = setTimeout(() => {
2006
- const current = httpContinuationEntries.get(key);
2007
- if (current?.kind === "ready" && current.generation === generation) httpContinuationEntries.delete(key);
2008
- }, HTTP_CONTINUATION_IDLE_TTL_MS);
2009
- idleTimer.unref?.();
2010
- const ready = {
2011
- ...claimed,
2012
- kind: "ready",
2013
- state: {
2014
- lastRequest: effectiveRequest,
2015
- lastResponseId: response.id,
2016
- lastResponseItems: response.output
2017
- },
2018
- idleTimer
2019
- };
2020
- httpContinuationEntries.set(key, ready);
2021
- },
2022
- release: () => {
2023
- if (httpContinuationEntries.get(key) === claimed) httpContinuationEntries.delete(key);
2024
- }
2025
- };
2026
- }
2027
- registerSessionResourceCleanup((sessionId) => {
2028
- for (const [key, entry] of httpContinuationEntries) if (!sessionId || entry.sessionId === sessionId) {
2029
- if (entry.kind === "ready") clearTimeout(entry.idleTimer);
2030
- httpContinuationEntries.delete(key);
2031
- }
2032
- });
2033
- //#endregion
2034
1891
  //#region packages/ai/src/transports/openai-responses-params-internal.ts
2035
1892
  const OPENAI_RESPONSES_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set([
2036
1893
  "openai",
@@ -2058,10 +1915,6 @@ function convertResponsesTools(tools, model, options) {
2058
1915
  })
2059
1916
  };
2060
1917
  }
2061
- function getPromptCacheRetention(baseUrl, cacheRetention) {
2062
- if (cacheRetention !== "long") return;
2063
- return baseUrl?.includes("api.openai.com") ? "24h" : void 0;
2064
- }
2065
1918
  function resolveOpenAIReasoningEffort(options) {
2066
1919
  return normalizeOpenAIReasoningEffort(options?.reasoningEffort ?? options?.reasoning ?? "high");
2067
1920
  }
@@ -2112,18 +1965,28 @@ function sanitizeOpenAICodexResponsesParams(model, params) {
2112
1965
  stripOpenAICodexResponsesUnsupportedTextFields(params);
2113
1966
  return params;
2114
1967
  }
2115
- function buildOpenAICodexResponsesInstructions(context) {
1968
+ function buildOpenAIResponsesInstructionsText(context) {
2116
1969
  if (!context.systemPrompt) return;
2117
1970
  return sanitizeTransportPayloadText(stripSystemPromptCacheBoundary(context.systemPrompt));
2118
1971
  }
2119
- function resolveOpenAICodexResponsesInstructions(model, context) {
2120
- const instructions = buildOpenAICodexResponsesInstructions(context);
1972
+ function resolveOpenAIResponsesInstructions(model, context, usesInstructionsField) {
1973
+ if (!usesInstructionsField) return;
1974
+ const instructions = buildOpenAIResponsesInstructionsText(context);
2121
1975
  if (instructions && instructions.trim().length > 0) return instructions;
2122
1976
  return usesNativeOpenAICodexResponsesBackend(model) ? OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS : void 0;
2123
1977
  }
2124
- function ensureOpenAICodexResponsesInput(messages, context) {
1978
+ function buildOpenAIResponsesCompactSystemMessage(model, instructions) {
1979
+ const compat = getCompat(model);
1980
+ const supportsDeveloperRole = typeof compat.supportsDeveloperRole === "boolean" ? compat.supportsDeveloperRole : void 0;
1981
+ const role = model.reasoning && supportsDeveloperRole !== false ? "developer" : "system";
1982
+ return buildResponsesInputMessage(role, [{
1983
+ type: "input_text",
1984
+ text: instructions
1985
+ }]);
1986
+ }
1987
+ function ensureOpenAIResponsesNonEmptyInput(messages, context) {
2125
1988
  if (messages.length > 0 || !context.systemPrompt) return;
2126
- if (!buildOpenAICodexResponsesInstructions(context)) throw new Error("OpenAI Codex Responses requires non-empty input when only systemPrompt is provided.");
1989
+ if (!buildOpenAIResponsesInstructionsText(context)) throw new Error("OpenAI Responses requires non-empty input when only systemPrompt is provided.");
2127
1990
  messages.push(buildResponsesInputMessage("user", [{
2128
1991
  type: "input_text",
2129
1992
  text: " "
@@ -2137,16 +2000,12 @@ function resolveOpenAIResponsesTextFormat(responseFormat) {
2137
2000
  return responseFormat;
2138
2001
  }
2139
2002
  function convertOpenAIResponsesMessagesForRequest(model, context, options, replayMode) {
2140
- const isCodexResponses = isOpenAICodexResponsesModel(model);
2141
2003
  const isNativeCodexResponses = usesNativeOpenAICodexResponsesBackend(model);
2142
- const compat = getCompat(model);
2143
- const supportsDeveloperRole = typeof compat.supportsDeveloperRole === "boolean" ? compat.supportsDeveloperRole : void 0;
2144
2004
  const payloadPolicy = resolveOpenAIResponsesPayloadPolicy(model, { storeMode: "disable" });
2145
2005
  const policyAllowsReplayIds = payloadPolicy.explicitStore !== false && !payloadPolicy.shouldStripStore;
2146
2006
  const replayResponsesItemIds = !isNativeCodexResponses && (options?.replayResponsesItemIds ?? policyAllowsReplayIds);
2147
2007
  return convertResponsesMessages(model, context, OPENAI_RESPONSES_TOOL_CALL_PROVIDERS, {
2148
- includeSystemPrompt: !isCodexResponses,
2149
- supportsDeveloperRole,
2008
+ includeSystemPrompt: !payloadPolicy.usesInstructionsField,
2150
2009
  replayReasoningItems: true,
2151
2010
  replayResponsesItemIds,
2152
2011
  authProfileId: options?.authProfileId,
@@ -2155,25 +2014,25 @@ function convertOpenAIResponsesMessagesForRequest(model, context, options, repla
2155
2014
  });
2156
2015
  }
2157
2016
  function buildOpenAIResponsesParams(model, context, options, metadata, replayMode = "checkpoint") {
2158
- const isCodexResponses = isOpenAICodexResponsesModel(model);
2159
2017
  const payloadPolicy = resolveOpenAIResponsesPayloadPolicy(model, { storeMode: "disable" });
2160
2018
  const messages = convertOpenAIResponsesMessagesForRequest(model, context, options, replayMode);
2161
- if (isCodexResponses) ensureOpenAICodexResponsesInput(messages, context);
2019
+ ensureOpenAIResponsesNonEmptyInput(messages, context);
2162
2020
  const cacheRetention = resolveCacheRetention(options?.cacheRetention);
2163
2021
  const promptCacheKey = resolvePromptCacheKey(options, cacheRetention);
2022
+ const instructions = resolveOpenAIResponsesInstructions(model, context, payloadPolicy.usesInstructionsField);
2164
2023
  const params = {
2165
2024
  model: model.id,
2166
2025
  input: messages,
2167
2026
  stream: true,
2168
2027
  prompt_cache_key: promptCacheKey,
2169
- prompt_cache_retention: getPromptCacheRetention(model.baseUrl, cacheRetention),
2170
- ...isCodexResponses ? { instructions: resolveOpenAICodexResponsesInstructions(model, context) } : {},
2028
+ ...resolveOpenAIResponsesCacheParams(model, cacheRetention, model.baseUrl?.includes("api.openai.com")),
2029
+ ...instructions ? { instructions } : {},
2171
2030
  ...metadata ? { metadata } : {}
2172
2031
  };
2173
2032
  const effectiveMaxTokens = options?.maxTokens || model.maxTokens;
2174
- if (effectiveMaxTokens) params.max_output_tokens = effectiveMaxTokens;
2175
- if (options?.temperature !== void 0) params.temperature = options.temperature;
2176
- if (options?.topP !== void 0) params.top_p = options.topP;
2033
+ if (effectiveMaxTokens) params.max_output_tokens = Math.max(effectiveMaxTokens, 16);
2034
+ if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) params.temperature = options.temperature;
2035
+ if (options?.topP !== void 0 && model.id !== "gpt-6-astra") params.top_p = options.topP;
2177
2036
  if (options?.responseFormat !== void 0) params.text = {
2178
2037
  ...params.text,
2179
2038
  format: resolveOpenAIResponsesTextFormat(options.responseFormat)
@@ -2189,9 +2048,10 @@ function buildOpenAIResponsesParams(model, context, options, metadata, replayMod
2189
2048
  }
2190
2049
  if (model.reasoning) {
2191
2050
  if (options?.reasoningEffort || options?.reasoning || options?.reasoningSummary) {
2051
+ const requestedReasoningEffort = resolveOpenAIReasoningEffort(options);
2192
2052
  const resolvedReasoningEffort = resolveOpenAIReasoningEffortForModel({
2193
2053
  model,
2194
- effort: resolveOpenAIReasoningEffort(options)
2054
+ effort: requestedReasoningEffort
2195
2055
  });
2196
2056
  const reasoningEffort = resolvedReasoningEffort ? raiseMinimalReasoningForResponsesWebSearch({
2197
2057
  model,
@@ -2217,9 +2077,311 @@ function buildOpenAIResponsesParams(model, context, options, metadata, replayMod
2217
2077
  return sanitizeOpenAICodexResponsesParams(model, params);
2218
2078
  }
2219
2079
  //#endregion
2080
+ //#region packages/ai/src/transports/openai-responses-reasoning-update.ts
2081
+ function isConfigurationUpdate(value) {
2082
+ return isRecord(value) && value.type === "configuration_update" && isRecord(value.reasoning) && typeof value.reasoning.effort === "string";
2083
+ }
2084
+ function isResponsesReasoningUpdateCompatible(request) {
2085
+ const mode = isRecord(request.reasoning) ? request.reasoning.mode : void 0;
2086
+ return request.model === "gpt-6-astra" && (mode === void 0 || mode === "standard") && (!isRecord(request.multi_agent) || request.multi_agent.enabled !== true) && request.truncation !== "auto" && (!Array.isArray(request.context_management) || !request.context_management.some((item) => isRecord(item) && item.type === "compaction"));
2087
+ }
2088
+ function supportsResponsesReasoningUpdate(request) {
2089
+ return isResponsesReasoningUpdateCompatible(request) && isRecord(request.reasoning) && typeof request.reasoning.effort === "string";
2090
+ }
2091
+ function canReferenceResponsesReasoningHistory(previous, request) {
2092
+ return !previous.input?.some(isConfigurationUpdate) || isResponsesReasoningUpdateCompatible(request);
2093
+ }
2094
+ /** Rehydrate input controls only provisionally; continuation must validate the full prefix. */
2095
+ function replayResponsesReasoningUpdates(previous, request, previousOutputLength, steering) {
2096
+ if (steering !== "required-input" && (!supportsResponsesReasoningUpdate(previous) || !supportsResponsesReasoningUpdate(request)) || !Array.isArray(previous.input) || !Array.isArray(request.input) || request.input.some(isConfigurationUpdate)) return request;
2097
+ const input = [...request.input];
2098
+ let activeEffort = isRecord(previous.reasoning) ? previous.reasoning.effort : void 0;
2099
+ for (const [index, item] of previous.input.entries()) if (isConfigurationUpdate(item)) {
2100
+ input.splice(index, 0, item);
2101
+ activeEffort = item.reasoning.effort;
2102
+ }
2103
+ if (steering === "required-input") return input.length === request.input.length ? request : {
2104
+ ...request,
2105
+ input
2106
+ };
2107
+ if (!isRecord(previous.reasoning) || !isRecord(request.reasoning) || typeof request.reasoning.effort !== "string") return request;
2108
+ if (activeEffort !== request.reasoning.effort && steering !== "automatic") {
2109
+ const baselineLength = previous.input.length + previousOutputLength;
2110
+ const nextUser = input.findIndex((item, index) => index >= baselineLength && "role" in item && item.role === "user");
2111
+ if (nextUser === -1) return request;
2112
+ input.splice(nextUser, 0, {
2113
+ type: "configuration_update",
2114
+ reasoning: { effort: request.reasoning.effort }
2115
+ });
2116
+ }
2117
+ if (input.length === request.input.length && activeEffort === request.reasoning.effort) return request;
2118
+ return {
2119
+ ...request,
2120
+ reasoning: {
2121
+ ...request.reasoning,
2122
+ effort: previous.reasoning.effort
2123
+ },
2124
+ input
2125
+ };
2126
+ }
2127
+ //#endregion
2128
+ //#region packages/ai/src/transports/openai-responses-continuation.ts
2129
+ const HTTP_CONTINUATION_IDLE_TTL_MS = 3e5;
2130
+ const TURN_HEADERS = /* @__PURE__ */ new Set([
2131
+ "traceparent",
2132
+ "x-openclaw-turn-id",
2133
+ "x-openclaw-turn-attempt"
2134
+ ]);
2135
+ function jsonValuesEqual(left, right) {
2136
+ const leftJson = JSON.stringify(left);
2137
+ const normalizedLeft = stableStringify(JSON.parse(leftJson));
2138
+ const rightJson = JSON.stringify(right);
2139
+ return leftJson === rightJson || normalizedLeft === stableStringify(JSON.parse(rightJson));
2140
+ }
2141
+ function requestWithoutInput(request) {
2142
+ const { input: _input, previous_response_id: _previousResponseId, instructions: _instructions, tools: _tools, ...rest } = request;
2143
+ if (!isRecord(rest.metadata)) return rest;
2144
+ const metadata = Object.fromEntries(Object.entries(rest.metadata).filter(([key]) => key !== "openclaw_turn_id" && key !== "openclaw_turn_attempt"));
2145
+ return {
2146
+ ...rest,
2147
+ metadata
2148
+ };
2149
+ }
2150
+ function normalizeAssistantReplayInput(input, fromResponse = false) {
2151
+ return input.map((item) => {
2152
+ if (!isRecord(item)) return item;
2153
+ if (item.type === "reasoning") return { type: "reasoning" };
2154
+ if (item.type !== "function_call" && !(item.type === "message" && item.role === "assistant")) return item;
2155
+ const { id: _id, status: _status, ...stableItem } = item;
2156
+ if (fromResponse && item.type === "function_call") {
2157
+ const args = parseJsonObjectPreservingUnsafeIntegers(stableItem.arguments);
2158
+ stableItem.arguments = args ? JSON.stringify(args) : stableItem.arguments;
2159
+ }
2160
+ if (item.type === "message" && Array.isArray(stableItem.content)) stableItem.content = stableItem.content.map((part) => {
2161
+ if (!isRecord(part) || part.type !== "output_text") return part;
2162
+ const { annotations: _annotations, logprobs: _logprobs, ...stablePart } = part;
2163
+ return stablePart;
2164
+ });
2165
+ return stableItem;
2166
+ });
2167
+ }
2168
+ function resolveResponsesContinuationRequest(continuation, request, steering) {
2169
+ if (!continuation) return {
2170
+ request,
2171
+ continuationStatus: "no_previous_response"
2172
+ };
2173
+ if (request.previous_response_id) return {
2174
+ request,
2175
+ continuationStatus: "explicit_previous_response_id"
2176
+ };
2177
+ if (!canReferenceResponsesReasoningHistory(continuation.lastRequest, request)) return {
2178
+ request,
2179
+ continuationStatus: "request_changed"
2180
+ };
2181
+ const prepared = replayResponsesReasoningUpdates(continuation.lastRequest, request, continuation.lastResponseItems.length, steering);
2182
+ if (steering !== "required-input" && !jsonValuesEqual(requestWithoutInput(prepared), requestWithoutInput(continuation.lastRequest))) return {
2183
+ request,
2184
+ continuationStatus: "request_changed"
2185
+ };
2186
+ const currentInput = prepared.input ?? [];
2187
+ const previousInput = continuation.lastRequest.input ?? [];
2188
+ const baselineLength = previousInput.length + continuation.lastResponseItems.length;
2189
+ if (currentInput.length < baselineLength) return {
2190
+ request,
2191
+ continuationStatus: "history_shorter"
2192
+ };
2193
+ if (!jsonValuesEqual(normalizeAssistantReplayInput(currentInput.slice(0, previousInput.length)), normalizeAssistantReplayInput(previousInput)) || !jsonValuesEqual(normalizeAssistantReplayInput(currentInput.slice(previousInput.length, baselineLength)), normalizeAssistantReplayInput(continuation.lastResponseItems, true))) return {
2194
+ request,
2195
+ continuationStatus: "history_changed"
2196
+ };
2197
+ return {
2198
+ request: {
2199
+ ...prepared,
2200
+ previous_response_id: continuation.lastResponseId,
2201
+ input: currentInput.slice(baselineLength)
2202
+ },
2203
+ ...prepared !== request ? { fullRequest: prepared } : {},
2204
+ continuationStatus: "continued"
2205
+ };
2206
+ }
2207
+ const httpContinuationEntries = /* @__PURE__ */ new Map();
2208
+ function deleteHttpContinuationIfOwned(key, entry) {
2209
+ if (httpContinuationEntries.get(key) === entry) httpContinuationEntries.delete(key);
2210
+ }
2211
+ function connectionIdentity(params) {
2212
+ const headers = Object.entries(resolveAiTransportHeaderSentinels(params.headers) ?? {}).map(([name, value]) => [name.toLowerCase(), value]).filter(([name]) => !TURN_HEADERS.has(name)).toSorted(([a], [b]) => a.localeCompare(b));
2213
+ return sha256Hex(JSON.stringify([
2214
+ getAiTransportHost().resolveSecretSentinel(params.apiKey),
2215
+ params.baseUrl,
2216
+ headers
2217
+ ]));
2218
+ }
2219
+ function claimOpenAIResponsesHttpContinuation(params) {
2220
+ const key = `${params.sessionId}\0${connectionIdentity(params)}`;
2221
+ const previous = httpContinuationEntries.get(key);
2222
+ if (previous?.kind === "claimed") return;
2223
+ if (previous?.kind === "ready") clearTimeout(previous.idleTimer);
2224
+ const claimed = {
2225
+ kind: "claimed",
2226
+ sessionId: params.sessionId
2227
+ };
2228
+ httpContinuationEntries.set(key, claimed);
2229
+ try {
2230
+ const resolved = resolveResponsesContinuationRequest(previous?.kind === "ready" ? previous.state : void 0, params.request);
2231
+ const fullRequest = resolved.fullRequest ?? params.request;
2232
+ return {
2233
+ request: params.request.store === false ? fullRequest : resolved.request,
2234
+ fullRequest,
2235
+ commit: (effectiveRequest, response) => {
2236
+ if (httpContinuationEntries.get(key) !== claimed) return;
2237
+ const ready = {
2238
+ ...claimed,
2239
+ kind: "ready",
2240
+ state: {
2241
+ lastRequest: effectiveRequest,
2242
+ lastResponseId: response.id,
2243
+ lastResponseItems: response.output
2244
+ },
2245
+ idleTimer: setTimeout(() => deleteHttpContinuationIfOwned(key, ready), HTTP_CONTINUATION_IDLE_TTL_MS)
2246
+ };
2247
+ ready.idleTimer.unref?.();
2248
+ httpContinuationEntries.set(key, ready);
2249
+ },
2250
+ release: () => deleteHttpContinuationIfOwned(key, claimed)
2251
+ };
2252
+ } catch (error) {
2253
+ deleteHttpContinuationIfOwned(key, claimed);
2254
+ throw error;
2255
+ }
2256
+ }
2257
+ registerSessionResourceCleanup((sessionId) => {
2258
+ for (const [key, entry] of httpContinuationEntries) if (!sessionId || entry.sessionId === sessionId) {
2259
+ if (entry.kind === "ready") clearTimeout(entry.idleTimer);
2260
+ httpContinuationEntries.delete(key);
2261
+ }
2262
+ });
2263
+ //#endregion
2264
+ //#region packages/ai/src/transports/openai-responses-steering.ts
2265
+ function cloneWireRequest(request) {
2266
+ const serialized = JSON.stringify(request);
2267
+ return JSON.parse(serialized);
2268
+ }
2269
+ async function projectResponsesSteeringInput(request, project) {
2270
+ const { input: activeInput, ...activeSettings } = cloneWireRequest(request);
2271
+ if (!Array.isArray(activeInput)) return [];
2272
+ const { input, ...settings } = cloneWireRequest(await project());
2273
+ if (!Array.isArray(input) || stableStringify(settings) !== stableStringify(activeSettings) || stableStringify(input.slice(0, activeInput.length)) !== stableStringify(activeInput)) return [];
2274
+ const projected = input.slice(activeInput.length);
2275
+ return projected.every((item) => isRecord(item) && item.role === "user") ? projected : [];
2276
+ }
2277
+ /** One response owns admission; accepted input stays on this connection until continuation. */
2278
+ function createResponsesSteering(params) {
2279
+ let responseId;
2280
+ let sealed = false;
2281
+ let unsubscribe;
2282
+ const pending = [];
2283
+ const accepted = /* @__PURE__ */ new Map();
2284
+ const acknowledged = /* @__PURE__ */ new Set();
2285
+ const seal = () => {
2286
+ sealed = true;
2287
+ const cleanup = unsubscribe;
2288
+ unsubscribe = void 0;
2289
+ cleanup?.();
2290
+ };
2291
+ return {
2292
+ get responseId() {
2293
+ return responseId;
2294
+ },
2295
+ get pending() {
2296
+ return pending.length > 0;
2297
+ },
2298
+ get acceptedInput() {
2299
+ return [...accepted.values()].flat();
2300
+ },
2301
+ seal,
2302
+ close(error) {
2303
+ seal();
2304
+ for (const submission of pending.splice(0)) submission.reject(error);
2305
+ },
2306
+ handle(event) {
2307
+ if (!isRecord(event)) return false;
2308
+ if (event.type === "response.created" && !responseId && !sealed) {
2309
+ const response = isRecord(event.response) ? event.response : void 0;
2310
+ if (typeof response?.id !== "string" || !response.id.trim()) throw new Error("Responses steering requires a response identity");
2311
+ const activeResponseId = response.id;
2312
+ responseId = activeResponseId;
2313
+ const cleanup = params.onActiveResponse({
2314
+ needsContinuation: params.needsContinuation,
2315
+ steer(messages) {
2316
+ if (sealed || messages.length === 0) return Promise.resolve(false);
2317
+ params.assertActive();
2318
+ const converted = params.toInput(messages);
2319
+ const submit = (input) => {
2320
+ if (sealed || input.length === 0) return Promise.resolve(false);
2321
+ params.assertActive();
2322
+ return new Promise((resolve, reject) => {
2323
+ pending.push({
2324
+ input,
2325
+ resolve,
2326
+ reject
2327
+ });
2328
+ params.send({
2329
+ type: "response.steer",
2330
+ previous_response_id: activeResponseId,
2331
+ input
2332
+ });
2333
+ });
2334
+ };
2335
+ return Array.isArray(converted) ? submit(converted) : converted.then(submit);
2336
+ }
2337
+ });
2338
+ if (sealed) cleanup?.();
2339
+ else unsubscribe = cleanup;
2340
+ return false;
2341
+ }
2342
+ if (event.type !== "response.steer.accepted" && event.type !== "response.steer.failed" && event.type !== "response.steer.pending") return false;
2343
+ const steer = isRecord(event.steer) ? event.steer : void 0;
2344
+ if (!responseId || steer?.previous_response_id !== responseId) throw new Error("Responses steering acknowledgement has an unexpected identity");
2345
+ if (event.type === "response.steer.failed" && steer.id === void 0) {
2346
+ const index = pending.findIndex((submission) => stableStringify(submission.input) === stableStringify(steer.input));
2347
+ const submission = pending[index];
2348
+ if (!submission) throw new Error("Responses steering acknowledgement has no pending submission");
2349
+ pending.splice(index, 1);
2350
+ submission.resolve(false);
2351
+ return true;
2352
+ }
2353
+ if (typeof steer.id !== "string" || !steer.id.trim()) throw new Error("Responses steering acknowledgement has an unexpected identity");
2354
+ if (event.type === "response.steer.pending") {
2355
+ if (!accepted.has(steer.id)) throw new Error("Responses steering pending event has no accepted submission");
2356
+ return true;
2357
+ }
2358
+ if (event.type === "response.steer.failed" && accepted.has(steer.id)) throw new Error("OpenAI could not apply accepted steering; the queued message remains in the conversation");
2359
+ if (acknowledged.has(steer.id)) throw new Error("Responses steering acknowledgement was already applied");
2360
+ const submission = pending.shift();
2361
+ if (!submission) throw new Error("Responses steering acknowledgement has no pending submission");
2362
+ acknowledged.add(steer.id);
2363
+ if (event.type === "response.steer.accepted") {
2364
+ accepted.set(steer.id, submission.input);
2365
+ submission.resolve(true);
2366
+ } else submission.resolve(false);
2367
+ return true;
2368
+ }
2369
+ };
2370
+ }
2371
+ /** Accepted steering is prepended by the server, so never repeat it in response.create. */
2372
+ function omitAcceptedSteering(input, accepted) {
2373
+ const remaining = [...input];
2374
+ for (const message of accepted) {
2375
+ const index = remaining.findIndex((item) => stableStringify(item) === stableStringify(message));
2376
+ if (index < 0) throw new Error("Responses steering continuation no longer contains the accepted user input");
2377
+ remaining.splice(index, 1);
2378
+ }
2379
+ return remaining;
2380
+ }
2381
+ //#endregion
2220
2382
  //#region packages/ai/src/transports/openai-responses-websocket.ts
2221
- const SESSION_WEBSOCKET_CACHE_TTL_MS = 300 * 1e3;
2222
- const SESSION_WEBSOCKET_MAX_AGE_MS = 3300 * 1e3;
2383
+ const SESSION_WEBSOCKET_CACHE_TTL_MS = 3e5;
2384
+ const SESSION_WEBSOCKET_MAX_AGE_MS = 33e5;
2223
2385
  const WEBSOCKET_OPEN_STATE = 1;
2224
2386
  const websocketSessionCache = /* @__PURE__ */ new Map();
2225
2387
  const degradedWebSocketConnections = /* @__PURE__ */ new Map();
@@ -2249,6 +2411,9 @@ function invalidateOwnedWebSocketSession(cacheKey, entry, reason = "done") {
2249
2411
  entry.idleTimer = void 0;
2250
2412
  }
2251
2413
  closeWebSocketSilently(entry.socket, reason);
2414
+ entry.steeringContinuation?.steering.close(/* @__PURE__ */ new Error("Responses steering connection closed"));
2415
+ entry.steeringContinuation?.iterator.return?.().catch(() => void 0);
2416
+ entry.steeringContinuation = void 0;
2252
2417
  if (websocketSessionCache.get(cacheKey) === entry) websocketSessionCache.delete(cacheKey);
2253
2418
  }
2254
2419
  function scheduleSessionWebSocketExpiry(cacheKey, entry) {
@@ -2298,11 +2463,14 @@ function createTransientWebSocketLease(connection) {
2298
2463
  }
2299
2464
  function createCachedWebSocketLease(cacheKey, entry, reusedConnection) {
2300
2465
  entry.busy = true;
2466
+ const steeringContinuation = entry.steeringContinuation;
2467
+ entry.steeringContinuation = void 0;
2301
2468
  return {
2302
2469
  socket: entry.socket,
2303
- iterator: entry.socket.stream(),
2470
+ iterator: steeringContinuation?.iterator ?? entry.socket.stream(),
2304
2471
  entry,
2305
2472
  reusedConnection,
2473
+ steeringContinuation,
2306
2474
  release: ({ keep } = {}) => {
2307
2475
  if (!keep || entry.socket.socket.readyState !== WEBSOCKET_OPEN_STATE) {
2308
2476
  invalidateOwnedWebSocketSession(cacheKey, entry);
@@ -2386,11 +2554,13 @@ function createOpenAIResponsesWebSocketStream(params) {
2386
2554
  throw new OpenAIResponsesWebSocketPreDispatchError(error);
2387
2555
  }
2388
2556
  let prepared;
2557
+ const resumedSteering = lease.steeringContinuation;
2558
+ const steeringMode = resumedSteering ? resumedSteering.requiresInput ? "required-input" : "automatic" : void 0;
2389
2559
  try {
2390
2560
  const continuation = lease.entry?.continuation;
2391
2561
  if (continuation && lease.entry) {
2392
2562
  lease.entry.continuation = void 0;
2393
- prepared = resolveResponsesContinuationRequest(continuation, fullRequest);
2563
+ prepared = resolveResponsesContinuationRequest(continuation, fullRequest, steeringMode);
2394
2564
  } else prepared = {
2395
2565
  request: fullRequest,
2396
2566
  continuationStatus: lease.entry ? "no_previous_response" : "socket_not_cached"
@@ -2404,11 +2574,54 @@ function createOpenAIResponsesWebSocketStream(params) {
2404
2574
  let terminalResponse;
2405
2575
  let terminalReceived = false;
2406
2576
  let released = false;
2577
+ let retainIterator = false;
2578
+ let deferredInput = false;
2579
+ let inputReplay;
2580
+ if (resumedSteering) try {
2581
+ if (prepared.continuationStatus !== "continued" || !prepared.request.previous_response_id) throw new Error("Responses steering continuation changed its request or history");
2582
+ const input = omitAcceptedSteering(prepared.request.input ?? [], resumedSteering.acceptedInput);
2583
+ if (!resumedSteering.requiresInput && (stableStringify(fullRequest.instructions) !== stableStringify(resumedSteering.instructions) || stableStringify(fullRequest.tools) !== stableStringify(resumedSteering.tools))) throw new Error("Responses automatic steering continuation cannot change instructions or tools");
2584
+ const baseline = prepared.fullRequest ?? fullRequest;
2585
+ const priorLength = (baseline.input?.length ?? 0) - (prepared.request.input?.length ?? 0);
2586
+ const fingerprints = input.map(responsesInputFingerprint);
2587
+ if (fingerprints.length > 0) inputReplay = {
2588
+ afterResponseId: prepared.request.previous_response_id,
2589
+ before: resumedSteering.requiresInput ? fingerprints : [],
2590
+ after: resumedSteering.requiresInput ? [] : fingerprints
2591
+ };
2592
+ const delivered = resumedSteering.requiresInput ? input : [];
2593
+ prepared.fullRequest = {
2594
+ ...baseline,
2595
+ input: [
2596
+ ...(baseline.input ?? []).slice(0, priorLength),
2597
+ ...resumedSteering.acceptedInput,
2598
+ ...delivered
2599
+ ]
2600
+ };
2601
+ prepared.request = {
2602
+ ...prepared.request,
2603
+ input: delivered
2604
+ };
2605
+ deferredInput = !resumedSteering.requiresInput && input.length > 0;
2606
+ } catch (error) {
2607
+ lease.iterator.return?.().catch(() => void 0);
2608
+ lease.release({ keep: false });
2609
+ throw new OpenAIResponsesWebSocketPostDispatchError(error);
2610
+ }
2611
+ const steering = lease.entry && params.onActiveResponse && params.steeringInput ? createResponsesSteering({
2612
+ onActiveResponse: params.onActiveResponse,
2613
+ toInput: params.steeringInput,
2614
+ send: (event) => lease.socket.sendRaw(JSON.stringify(event)),
2615
+ needsContinuation: () => deferredInput,
2616
+ assertActive: () => {
2617
+ if (released || terminalReceived || params.signal?.aborted) throw new Error("Responses steering is no longer active");
2618
+ }
2619
+ }) : void 0;
2407
2620
  const finish = ({ keep = true } = {}) => {
2408
2621
  if (released) return;
2409
2622
  released = true;
2410
2623
  if (keep && lease.entry && terminalResponse) lease.entry.continuation = {
2411
- lastRequest: fullRequest,
2624
+ lastRequest: prepared.fullRequest ?? fullRequest,
2412
2625
  lastResponseId: terminalResponse.id,
2413
2626
  lastResponseItems: terminalResponse.output
2414
2627
  };
@@ -2422,8 +2635,19 @@ function createOpenAIResponsesWebSocketStream(params) {
2422
2635
  let requestDispatched = false;
2423
2636
  try {
2424
2637
  if (params.signal?.aborted) throw transportAbortError(params.signal);
2638
+ if (resumedSteering) {
2639
+ requestDispatched = true;
2640
+ if (resumedSteering.requiresInput) lease.socket.send({
2641
+ ...prepared.request,
2642
+ type: "response.create"
2643
+ });
2644
+ }
2425
2645
  for (;;) {
2426
- const next = await nextWebSocketMessage(iterator, params.signal);
2646
+ const buffered = resumedSteering?.buffered.shift();
2647
+ const next = buffered ? {
2648
+ value: buffered,
2649
+ done: false
2650
+ } : await nextWebSocketMessage(iterator, params.signal);
2427
2651
  if (next.done) throw new Error("OpenAI Responses WebSocket closed before a terminal response event");
2428
2652
  if (next.value.type === "open") {
2429
2653
  if (!requestDispatched) {
@@ -2437,8 +2661,51 @@ function createOpenAIResponsesWebSocketStream(params) {
2437
2661
  }
2438
2662
  const event = readServerEvent(next.value);
2439
2663
  if (!event) continue;
2664
+ if (isRecord(event) && typeof event.type === "string" && event.type.startsWith("response.steer.")) {
2665
+ if ((isRecord(event.steer) && event.steer.previous_response_id === steering?.responseId ? steering : resumedSteering?.steering ?? steering)?.handle(event)) continue;
2666
+ }
2667
+ steering?.handle(event);
2440
2668
  if (event.type === "response.completed") terminalResponse = event.response;
2441
2669
  terminalReceived = event.type === "response.completed" || event.type === "response.incomplete" || event.type === "response.failed";
2670
+ if (terminalReceived) {
2671
+ steering?.seal();
2672
+ if (event.type === "response.failed") steering?.close(/* @__PURE__ */ new Error("Responses failed before steering could be applied"));
2673
+ const continuationBuffer = [];
2674
+ for (;;) {
2675
+ if (!steering?.pending) break;
2676
+ const acknowledgement = await nextWebSocketMessage(iterator, params.signal);
2677
+ if (acknowledgement.done) throw new Error("Responses closed before acknowledging steering");
2678
+ const acknowledgedEvent = readServerEvent(acknowledgement.value);
2679
+ if (!steering.handle(acknowledgedEvent)) continuationBuffer.push(acknowledgement.value);
2680
+ }
2681
+ const acceptedInput = steering?.acceptedInput ?? [];
2682
+ const isSteered = event.type === "response.incomplete" && isRecord(event.response.incomplete_details) && event.response.incomplete_details.reason === "steered";
2683
+ if (lease.entry && steering && acceptedInput.length > 0 && (event.type === "response.completed" || isSteered)) {
2684
+ if (event.type === "response.incomplete") terminalResponse = event.response;
2685
+ lease.entry.steeringContinuation = {
2686
+ iterator,
2687
+ buffered: continuationBuffer,
2688
+ acceptedInput,
2689
+ requiresInput: (terminalResponse?.output ?? []).some((item) => (item.type === "function_call" || item.type === "custom_tool_call") && !(isRecord(item) && item.async === true) || item.type === "mcp_approval_request"),
2690
+ steering,
2691
+ instructions: fullRequest.instructions,
2692
+ tools: fullRequest.tools
2693
+ };
2694
+ retainIterator = true;
2695
+ if (isSteered) {
2696
+ yield {
2697
+ ...event,
2698
+ type: "response.completed",
2699
+ response: {
2700
+ ...event.response,
2701
+ status: "completed",
2702
+ incomplete_details: null
2703
+ }
2704
+ };
2705
+ return;
2706
+ }
2707
+ }
2708
+ }
2442
2709
  yield event;
2443
2710
  if (terminalReceived) {
2444
2711
  degradedWebSocketConnections.delete(degradationKey);
@@ -2446,20 +2713,27 @@ function createOpenAIResponsesWebSocketStream(params) {
2446
2713
  }
2447
2714
  }
2448
2715
  } catch (error) {
2716
+ const steeringDispatched = Boolean(steering?.pending || steering?.acceptedInput.length || resumedSteering);
2717
+ steering?.close(error instanceof Error ? error : /* @__PURE__ */ new Error("Responses steering failed"));
2449
2718
  if (lease.entry) lease.entry.continuation = void 0;
2450
- const safeRetry = error instanceof OpenAIResponsesWebSocketSafeRetryError;
2719
+ const safeRetry = error instanceof OpenAIResponsesWebSocketSafeRetryError && !steeringDispatched;
2451
2720
  if (!params.callerSignal?.aborted && !safeRetry) markDegraded();
2452
2721
  if (!requestDispatched && !params.signal?.aborted) throw new OpenAIResponsesWebSocketPreDispatchError(error);
2453
2722
  if (!requestDispatched || params.callerSignal?.aborted || safeRetry) throw error;
2454
2723
  throw new OpenAIResponsesWebSocketPostDispatchError(error);
2455
2724
  } finally {
2456
- await iterator.return?.().catch(() => void 0);
2725
+ steering?.seal();
2726
+ if (!retainIterator) {
2727
+ steering?.close(/* @__PURE__ */ new Error("Responses stream ended before steering was confirmed"));
2728
+ await iterator.return?.().catch(() => void 0);
2729
+ }
2457
2730
  if (!terminalReceived) finish({ keep: false });
2458
2731
  }
2459
2732
  } },
2460
2733
  request: prepared.request,
2461
2734
  reusedConnection: lease.reusedConnection,
2462
2735
  continuationStatus: prepared.continuationStatus,
2736
+ inputReplay,
2463
2737
  finish
2464
2738
  };
2465
2739
  }
@@ -2472,147 +2746,68 @@ function closeOpenAIResponsesWebSocketSessions(sessionId) {
2472
2746
  }
2473
2747
  registerSessionResourceCleanup(closeOpenAIResponsesWebSocketSessions);
2474
2748
  //#endregion
2475
- //#region packages/media-core/src/inline-image-data-url.ts
2476
- /** Prefix used to distinguish inline data URLs from remote/local image references. */
2477
- const INLINE_IMAGE_DATA_URL_PREFIX = "data:";
2478
- const IMAGE_SIGNATURES = [
2479
- {
2480
- mime: "image/png",
2481
- 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
2482
- },
2483
- {
2484
- mime: "image/jpeg",
2485
- matches: (buffer) => buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255
2486
- },
2487
- {
2488
- mime: "image/webp",
2489
- matches: (buffer) => buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP"
2490
- },
2491
- {
2492
- mime: "image/gif",
2493
- matches: (buffer) => buffer.length >= 6 && (buffer.subarray(0, 6).toString("ascii") === "GIF87a" || buffer.subarray(0, 6).toString("ascii") === "GIF89a")
2494
- },
2495
- {
2496
- mime: "image/bmp",
2497
- matches: (buffer) => buffer.length >= 2 && buffer[0] === 66 && buffer[1] === 77
2498
- }
2499
- ];
2500
- const HEIC_BRANDS = /* @__PURE__ */ new Set([
2501
- "heic",
2502
- "heix",
2503
- "hevc",
2504
- "hevx",
2505
- "heis",
2506
- "heim",
2507
- "hevm",
2508
- "hevs"
2509
- ]);
2510
- const HEIF_BRANDS = /* @__PURE__ */ new Set(["mif1", "msf1"]);
2511
- const IMAGE_SIGNATURE_PREFIX_BASE64_CHARS = 128;
2512
- const INLINE_IMAGE_DATA_URL_MIMES = /* @__PURE__ */ new Set([
2513
- "image/png",
2514
- "image/jpeg",
2515
- "image/webp",
2516
- "image/gif"
2517
- ]);
2518
- function startsWithDataUrl(value) {
2519
- return value.slice(0, 5).toLowerCase() === INLINE_IMAGE_DATA_URL_PREFIX;
2520
- }
2521
- function sniffIsoBmffImageMime(buffer) {
2522
- if (buffer.length < 12 || buffer.subarray(4, 8).toString("ascii") !== "ftyp") return;
2523
- const brands = [buffer.subarray(8, 12).toString("ascii")];
2524
- for (let offset = 16; offset + 4 <= buffer.length; offset += 4) brands.push(buffer.subarray(offset, offset + 4).toString("ascii"));
2525
- if (brands.some((brand) => HEIC_BRANDS.has(brand))) return "image/heic";
2526
- if (brands.some((brand) => HEIF_BRANDS.has(brand))) return "image/heif";
2527
- }
2528
- /** Sniffs supported inline image formats from decoded bytes. */
2529
- function sniffInlineImageMime(buffer) {
2530
- return IMAGE_SIGNATURES.find((signature) => signature.matches(buffer))?.mime ?? sniffIsoBmffImageMime(buffer);
2531
- }
2532
- function isImageMimeType(value) {
2533
- return value.trim().toLowerCase().startsWith("image/");
2534
- }
2535
- /** Canonicalizes trusted inline image base64 and rejects malformed or non-image payloads. */
2536
- function sanitizeInlineImageBase64(params) {
2537
- if (!isImageMimeType(params.mimeType)) return;
2538
- const canonicalPayload = canonicalizeBase64(params.base64);
2539
- if (!canonicalPayload) return;
2540
- const sniffedMimeType = sniffInlineImageMime(Buffer.from(canonicalPayload.slice(0, IMAGE_SIGNATURE_PREFIX_BASE64_CHARS), "base64"));
2541
- if (!sniffedMimeType) return;
2542
- return {
2543
- mimeType: sniffedMimeType,
2544
- base64: canonicalPayload
2545
- };
2546
- }
2547
- function parseInlineImageDataUrl(value) {
2548
- if (!startsWithDataUrl(value)) return {
2549
- metadata: [],
2550
- payload: value
2551
- };
2552
- const commaIndex = value.indexOf(",");
2553
- if (commaIndex < 0) return;
2554
- return {
2555
- metadata: value.slice(5, commaIndex).split(";").map((part) => part.trim()),
2556
- payload: value.slice(commaIndex + 1)
2557
- };
2558
- }
2559
- function metadataAllowsImageBase64(metadata) {
2560
- const [mimeType, ...options] = metadata;
2561
- return mimeType !== void 0 && isImageMimeType(mimeType) && options.some((part) => part.toLowerCase() === "base64");
2562
- }
2563
- function sanitizeInlineImageDataUrlWithAllowedMimes(imageUrl, allowedMimes) {
2564
- const parsed = parseInlineImageDataUrl(imageUrl);
2565
- if (!parsed) return;
2566
- if (parsed.metadata.length === 0) return imageUrl;
2567
- if (!metadataAllowsImageBase64(parsed.metadata)) return;
2568
- const [mimeType] = parsed.metadata;
2569
- const sanitized = sanitizeInlineImageBase64({
2570
- mimeType: mimeType ?? "",
2571
- base64: parsed.payload
2749
+ //#region packages/ai/src/transports/openai-responses-compact-client.ts
2750
+ async function postOpenAIResponsesCompaction(params) {
2751
+ const compactInput = typeof params.request.instructions === "string" && params.request.instructions.length > 0 ? [buildOpenAIResponsesCompactSystemMessage(params.model, params.request.instructions), ...params.request.input ?? []] : params.request.input;
2752
+ const response = await params.client.post("/responses/compact", {
2753
+ ...buildOpenAISdkRequestOptions(params.model, params.options?.signal, { timeoutMs: params.options?.timeoutMs }),
2754
+ body: {
2755
+ model: params.request.model,
2756
+ input: compactInput
2757
+ }
2572
2758
  });
2573
- if (!sanitized) return;
2574
- if (allowedMimes && !allowedMimes.has(sanitized.mimeType)) return;
2575
- return `data:${sanitized.mimeType};base64,${sanitized.base64}`;
2576
- }
2577
- /** Canonicalizes provider-safe inline image data URLs and rejects unsupported formats. */
2578
- function sanitizeInlineImageDataUrl(imageUrl) {
2579
- return sanitizeInlineImageDataUrlWithAllowedMimes(imageUrl, INLINE_IMAGE_DATA_URL_MIMES);
2580
- }
2581
- //#endregion
2582
- //#region packages/ai/src/transports/responses-image-payload-sanitizer.ts
2583
- /**
2584
- * Sanitizes OpenAI Responses payloads before transport. Invalid inline images
2585
- * are replaced with text placeholders so the request remains valid and
2586
- * auditable.
2587
- */
2588
- const IMAGE_OMITTED_TEXT = "omitted image payload: invalid inline image data";
2589
- function invalidSnakeImage() {
2759
+ const output = isRecord(response) && Array.isArray(response.output) ? response.output : [];
2760
+ const item = output.at(-1);
2761
+ const retainedItems = output.slice(0, -1);
2762
+ const retainedUserMessageCount = retainedItems.filter((candidate) => isRecord(candidate) && candidate.type === "message" && candidate.role === "user" && Array.isArray(candidate.content)).length;
2763
+ const inputUserMessageCount = Array.isArray(params.request.input) ? params.request.input.filter((candidate) => isRecord(candidate) && candidate.type === "message" && candidate.role === "user").length : 0;
2764
+ const retainedMessagePrefixSupported = supportsNativeOpenAIResponsesEndpoint(params.model);
2765
+ const usage = isRecord(response) && isRecord(response.usage) ? response.usage : void 0;
2766
+ 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");
2590
2767
  return {
2591
- type: "input_text",
2592
- text: `[${IMAGE_OMITTED_TEXT}]`
2768
+ output,
2769
+ item,
2770
+ historyMode: retainedUserMessageCount > 0 ? "retained-users" : "compacted-prefix",
2771
+ usage,
2772
+ model: params.model,
2773
+ replayMetadata: buildOpenAIResponsesReasoningReplayMetadata(params.model, {
2774
+ authProfileId: params.options?.authProfileId,
2775
+ sessionId: params.options?.sessionId
2776
+ })
2593
2777
  };
2594
2778
  }
2595
- function sanitizeValue(value) {
2596
- if (Array.isArray(value)) return value.map(sanitizeValue);
2597
- if (!isRecord(value)) return value;
2598
- if (value.type === "input_image" && typeof value.image_url === "string") {
2599
- const imageUrl = sanitizeInlineImageDataUrl(value.image_url);
2600
- return imageUrl ? {
2601
- ...value,
2602
- image_url: imageUrl
2603
- } : invalidSnakeImage();
2779
+ //#endregion
2780
+ //#region packages/ai/src/transports/openai-responses-compact-request.ts
2781
+ const COMPACT_REQUEST = Symbol("openaiResponsesCompactRequest");
2782
+ function claimResponsesCompactRequest(options) {
2783
+ const controller = options ? Reflect.get(options, COMPACT_REQUEST) : void 0;
2784
+ if (controller?.claimed === false) {
2785
+ controller.claimed = true;
2786
+ return controller;
2604
2787
  }
2605
- const next = {};
2606
- for (const [key, child] of Object.entries(value)) next[key] = sanitizeValue(child);
2607
- return next;
2608
2788
  }
2609
- /** Sanitize inline image fields inside a Responses API payload. */
2610
- function sanitizeResponsesImagePayload(params) {
2611
- if (!Array.isArray(params.input)) return params;
2612
- return {
2613
- ...params,
2614
- input: sanitizeValue(params.input)
2789
+ /** Run a compact-endpoint request through the session's prepared stream stack. */
2790
+ async function requestPreparedOpenAIResponsesCompaction(streamFn, model, context, options) {
2791
+ const preparedOptions = { ...options };
2792
+ let resolveResult;
2793
+ let rejectResult;
2794
+ const result = new Promise((resolve, reject) => {
2795
+ resolveResult = resolve;
2796
+ rejectResult = reject;
2797
+ });
2798
+ const controller = {
2799
+ claimed: false,
2800
+ resolve: resolveResult,
2801
+ reject: rejectResult
2615
2802
  };
2803
+ Reflect.set(preparedOptions, COMPACT_REQUEST, controller);
2804
+ const stream = await Promise.resolve(streamFn(model, context, preparedOptions));
2805
+ if (!controller.claimed) throw new Error("Prepared stream did not reach an OpenAI Responses transport");
2806
+ try {
2807
+ return await result;
2808
+ } finally {
2809
+ await stream.result().catch(() => void 0);
2810
+ }
2616
2811
  }
2617
2812
  //#endregion
2618
2813
  //#region packages/ai/src/transports/openai-responses-client.ts
@@ -2648,47 +2843,16 @@ function resolveProviderTransportTurnState(model, params) {
2648
2843
  }
2649
2844
  });
2650
2845
  }
2651
- function createOpenAIResponsesClient(model, context, apiKey, optionHeaders, turnHeaders, sessionId) {
2846
+ function createOpenAIResponsesClient(model, context, apiKey, optionHeaders, turnHeaders, sessionId, fetchOverride) {
2652
2847
  return new OpenAI({
2653
2848
  apiKey,
2654
2849
  baseURL: resolveOpenAIClientBaseUrl(model),
2655
2850
  dangerouslyAllowBrowser: true,
2656
2851
  defaultHeaders: buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders, sessionId),
2657
- fetch: buildGuardedModelFetch(model),
2852
+ fetch: fetchOverride ?? buildGuardedModelFetch(model),
2658
2853
  ...buildOpenAISdkClientOptions(model)
2659
2854
  });
2660
2855
  }
2661
- async function postOpenAIResponsesCompaction(params) {
2662
- const response = await params.client.post("/responses/compact", {
2663
- ...buildOpenAISdkRequestOptions(params.model, params.options?.signal, {
2664
- timeoutMs: params.options?.timeoutMs,
2665
- maxRetries: params.options?.maxRetries
2666
- }),
2667
- body: {
2668
- model: params.request.model,
2669
- input: params.request.input
2670
- }
2671
- });
2672
- const output = isRecord(response) && Array.isArray(response.output) ? response.output : [];
2673
- const item = output.at(-1);
2674
- const retainedItems = output.slice(0, -1);
2675
- const retainedMessagesAreValid = retainedItems.every((candidate) => isRecord(candidate) && candidate.type === "message" && (candidate.role === "user" || candidate.role === "developer" || candidate.role === "system") && Array.isArray(candidate.content));
2676
- const retainedUserMessageCount = retainedItems.filter((candidate) => isRecord(candidate) && candidate.type === "message" && candidate.role === "user" && Array.isArray(candidate.content)).length;
2677
- const inputUserMessageCount = Array.isArray(params.request.input) ? params.request.input.filter((candidate) => isRecord(candidate) && candidate.type === "message" && candidate.role === "user").length : 0;
2678
- const retainedMessagePrefixSupported = supportsNativeOpenAIResponsesEndpoint(params.model);
2679
- const usage = isRecord(response) && isRecord(response.usage) ? response.usage : void 0;
2680
- 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");
2681
- return {
2682
- item,
2683
- historyMode: retainedUserMessageCount > 0 ? "retained-users" : "compacted-prefix",
2684
- usage,
2685
- model: params.model,
2686
- replayMetadata: buildOpenAIResponsesReasoningReplayMetadata(params.model, {
2687
- authProfileId: params.options?.authProfileId,
2688
- sessionId: params.options?.sessionId
2689
- })
2690
- };
2691
- }
2692
2856
  function createResponsesTransportExecutor(config) {
2693
2857
  return (model, context, options) => {
2694
2858
  const responsesOptions = options;
@@ -2709,9 +2873,11 @@ function createResponsesTransportExecutor(config) {
2709
2873
  });
2710
2874
  const websocketSessionPolicy = websocketMode ? turnState?.websocket : void 0;
2711
2875
  const websocketHeaders = websocketMode ? buildOpenAIClientHeaders(model, context, options?.headers, websocketSessionPolicy?.headers, options?.sessionId) : void 0;
2712
- const client = config.createClient(model, context, apiKey, options?.headers, turnState?.headers, options?.sessionId);
2713
- const buildRequest = async (replayMode) => {
2714
- let params = config.buildRequest(model, context, responsesOptions, turnState?.metadata, replayMode);
2876
+ const client = config.createClient(model, context, apiKey, options?.headers, turnState?.headers, options?.sessionId, compactRequest ? createBoundedOpenAIResponsesCompactionFetch(buildGuardedModelFetch(model)) : void 0);
2877
+ const nativeAstra = model.id === "gpt-6-astra" && supportsNativeOpenAIResponsesEndpoint(model);
2878
+ const asyncToolExecutionEligible = nativeAstra && options?.asyncToolExecution === true && !responsesOptions?.openclawCodeModeToolSurface;
2879
+ const prepareRequest = async (request) => {
2880
+ let params = request;
2715
2881
  const nextParams = await options?.onPayload?.(params, model);
2716
2882
  if (nextParams !== void 0) params = nextParams;
2717
2883
  if (!isOpenAICodexResponsesModel(model)) params = mergeTransportMetadata(params, turnState?.metadata);
@@ -2723,9 +2889,15 @@ function createResponsesTransportExecutor(config) {
2723
2889
  enforceCodeModeResponsesToolSurface(params, visibleToolNames, allowedHostedToolTypes, codeModeToolSurfaceObserver.get(options));
2724
2890
  assertCodeModeResponsesToolSurface(params, visibleToolNames, allowedHostedToolTypes);
2725
2891
  }
2892
+ if (asyncToolExecutionEligible && params.model === "gpt-6-astra" && params.multi_agent?.enabled !== true && params.tools) params.tools = params.tools.map((tool) => tool.type === "function" ? {
2893
+ ...tool,
2894
+ async: true
2895
+ } : tool);
2726
2896
  return params;
2727
2897
  };
2728
- const params = await buildRequest("checkpoint");
2898
+ const buildRequest = (replayMode, requestContext = context) => prepareRequest(config.buildRequest(model, requestContext, responsesOptions, turnState?.metadata, replayMode));
2899
+ let params = await buildRequest("checkpoint");
2900
+ const asyncTools = asyncToolExecutionEligible && params.model === "gpt-6-astra" && params.multi_agent?.enabled !== true;
2729
2901
  if (compactRequest) {
2730
2902
  const compacted = await postOpenAIResponsesCompaction({
2731
2903
  client,
@@ -2749,13 +2921,16 @@ function createResponsesTransportExecutor(config) {
2749
2921
  provider: model.provider,
2750
2922
  api: model.api,
2751
2923
  baseUrl: model.baseUrl
2752
- }) && sessionId && params.store === true && !params.previous_response_id) continuationClaim = claimOpenAIResponsesHttpContinuation({
2753
- sessionId,
2754
- apiKey,
2755
- baseUrl: model.baseUrl,
2756
- headers: buildOpenAIClientHeaders(model, context, options?.headers, turnState?.headers, sessionId),
2757
- request: params
2758
- });
2924
+ }) && sessionId && (params.store === true || supportsResponsesReasoningUpdate(params)) && !params.previous_response_id) {
2925
+ continuationClaim = claimOpenAIResponsesHttpContinuation({
2926
+ sessionId,
2927
+ apiKey,
2928
+ baseUrl: model.baseUrl,
2929
+ headers: buildOpenAIClientHeaders(model, context, options?.headers, turnState?.headers, sessionId),
2930
+ request: params
2931
+ });
2932
+ if (continuationClaim) params = continuationClaim.fullRequest;
2933
+ }
2759
2934
  const observePrompt = createResponsesPromptEgressObserver(responsesOptions, context.systemPrompt);
2760
2935
  const requestStartedAt = Date.now();
2761
2936
  let started = false;
@@ -2772,14 +2947,13 @@ function createResponsesTransportExecutor(config) {
2772
2947
  firstEventAbort = firstEvent;
2773
2948
  const requestOptions = buildOpenAISdkRequestOptions(model, firstEvent.signal, {
2774
2949
  stream: config.streamRequest,
2775
- timeoutMs: options?.timeoutMs,
2776
- maxRetries: options?.maxRetries
2950
+ timeoutMs: options?.timeoutMs
2777
2951
  });
2778
2952
  const websocketSignal = combineWebSocketTimeoutSignal(firstEvent.signal, model, requestOptions?.timeout);
2779
2953
  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)}`);
2780
2954
  let continuationBaseline;
2781
2955
  const createSseStream = async (initialRequest = continuationClaim?.request ?? params, initialAttemptKind = "initial", initialRejectedCompaction) => {
2782
- const { stream: responseStream } = await config.createResponseStream({
2956
+ const { stream: responseStream } = await createResponsesStreamWithEncryptedContentRetry({
2783
2957
  client,
2784
2958
  request: initialRequest,
2785
2959
  requestOptions,
@@ -2825,9 +2999,15 @@ function createResponsesTransportExecutor(config) {
2825
2999
  headers: websocketHeaders,
2826
3000
  signal: websocketSignal,
2827
3001
  callerSignal: options?.signal,
2828
- degradeCooldownMs: websocketSessionPolicy?.degradeCooldownMs
3002
+ degradeCooldownMs: websocketSessionPolicy?.degradeCooldownMs,
3003
+ onActiveResponse: nativeAstra && params.model === "gpt-6-astra" ? options?.onActiveResponse : void 0,
3004
+ steeringInput: (messages) => projectResponsesSteeringInput(params, () => buildRequest("checkpoint", {
3005
+ ...context,
3006
+ messages: [...context.messages, ...messages]
3007
+ }))
2829
3008
  });
2830
3009
  finishWebSocket = websocket.finish;
3010
+ recordResponsesInputReplay(output, websocket.inputReplay);
2831
3011
  observePrompt?.(websocket.request, {
2832
3012
  egress: "responses-websocket",
2833
3013
  payloadVariant: "initial"
@@ -2869,7 +3049,8 @@ function createResponsesTransportExecutor(config) {
2869
3049
  yield* await createSseStream();
2870
3050
  }
2871
3051
  } };
2872
- } catch {
3052
+ } catch (error) {
3053
+ if (error instanceof OpenAIResponsesWebSocketPostDispatchError) throw error;
2873
3054
  closeWebSocketForFallback("setup_failure");
2874
3055
  responseStream = await createSseStream();
2875
3056
  }
@@ -2884,7 +3065,8 @@ function createResponsesTransportExecutor(config) {
2884
3065
  reasoningReplayMetadata: buildOpenAIResponsesReasoningReplayMetadata(model, {
2885
3066
  authProfileId: responsesOptions?.authProfileId,
2886
3067
  sessionId: options?.sessionId
2887
- })
3068
+ }),
3069
+ asyncToolExecution: asyncTools
2888
3070
  });
2889
3071
  finishWebSocket?.();
2890
3072
  if (options?.signal?.aborted) throw transportAbortError(options.signal);
@@ -2933,7 +3115,6 @@ function createOpenAIResponsesTransportStreamFn() {
2933
3115
  httpContinuation: true,
2934
3116
  createClient: createOpenAIResponsesClient,
2935
3117
  buildRequest: buildOpenAIResponsesParams,
2936
- createResponseStream: createResponsesStreamWithEncryptedContentRetry,
2937
3118
  pricingOptions: (options, model) => ({
2938
3119
  serviceTier: options?.serviceTier,
2939
3120
  applyServiceTierPricing: (usage, serviceTier) => applyResponsesServiceTierPricing(usage, serviceTier, model)
@@ -2945,27 +3126,23 @@ function createAzureOpenAIResponsesTransportStreamFn() {
2945
3126
  outputApi: "azure-openai-responses",
2946
3127
  firstEventTimeoutMs: AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS,
2947
3128
  createClient: createAzureOpenAIClient,
2948
- buildRequest: (model, context, options, metadata, replayMode) => buildAzureOpenAIResponsesParams(model, context, options, resolveAzureDeploymentName(model), metadata, replayMode),
2949
- createResponseStream: createResponsesStreamWithEncryptedContentRetry
3129
+ buildRequest: (model, context, options, metadata, replayMode) => buildAzureOpenAIResponsesParams(model, context, options, resolveAzureDeploymentName(model), metadata, replayMode)
2950
3130
  });
2951
3131
  }
2952
- function normalizeAzureBaseUrl(baseUrl) {
2953
- return baseUrl.replace(/\/+$/, "");
2954
- }
2955
3132
  function resolveAzureDeploymentName(model) {
2956
3133
  return resolveAzureDeploymentNameFromMap({
2957
3134
  modelId: model.id,
2958
3135
  deploymentMap: process.env.AZURE_OPENAI_DEPLOYMENT_NAME_MAP
2959
3136
  });
2960
3137
  }
2961
- function createAzureOpenAIClient(model, context, apiKey, optionHeaders, turnHeaders) {
2962
- const baseURL = normalizeAzureBaseUrl(model.baseUrl);
3138
+ function createAzureOpenAIClient(model, context, apiKey, optionHeaders, turnHeaders, _sessionId, fetchOverride) {
3139
+ const baseURL = model.baseUrl.replace(/\/+$/, "");
2963
3140
  const clientOptions = {
2964
3141
  apiKey,
2965
3142
  dangerouslyAllowBrowser: true,
2966
3143
  defaultHeaders: buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders),
2967
3144
  baseURL,
2968
- fetch: buildGuardedModelFetch(model),
3145
+ fetch: fetchOverride ?? buildGuardedModelFetch(model),
2969
3146
  ...buildOpenAISdkClientOptions(model)
2970
3147
  };
2971
3148
  if (isOpenAICompatibleAzureResponsesBaseUrl(baseURL)) return new OpenAI(clientOptions);
@@ -3011,6 +3188,112 @@ const responsesTesting = {
3011
3188
  if (process.env.VITEST || false) globalThis.openclawOpenAIResponsesTransportTestApi = responsesTesting;
3012
3189
  //#endregion
3013
3190
  //#region packages/ai/src/transports/provider-compaction-replay.ts
3191
+ function isAssistantReplayMessage(message) {
3192
+ return message.role === "assistant";
3193
+ }
3194
+ /** Resolve from prepared transport facts; never retain or return credential material. */
3195
+ function resolveCompactionReplayEligibility(model, options) {
3196
+ if (OPENAI_RESPONSES_APIS.has(model.api)) return true;
3197
+ return Boolean(options.apiKey?.trim()) && resolveAnthropicServerCompactionPlan(model, options.extraParams, options.apiKey).enabled;
3198
+ }
3199
+ function resolveCompactionSource(messages, model, identity) {
3200
+ if (identity.enabled === false) return;
3201
+ const assistants = messages.filter(isAssistantReplayMessage);
3202
+ const selected = (() => {
3203
+ if (OPENAI_RESPONSES_APIS.has(model.api)) {
3204
+ const responses = resolveNewestOpenAIResponsesCompactionReplay(assistants, model, identity);
3205
+ return responses ? {
3206
+ family: "responses",
3207
+ ...responses
3208
+ } : void 0;
3209
+ }
3210
+ if (identity.enabled !== true) return;
3211
+ const anthropic = resolveNewestAnthropicCompaction(assistants, model, identity);
3212
+ return anthropic ? {
3213
+ family: "anthropic",
3214
+ ...anthropic
3215
+ } : void 0;
3216
+ })();
3217
+ if (!selected) return;
3218
+ const owner = assistants.find((message) => message === selected.owner);
3219
+ return owner ? {
3220
+ ...selected,
3221
+ owner
3222
+ } : void 0;
3223
+ }
3224
+ /** Manual recovery uses the durable client compactor, never a guessed retained-user prefix. */
3225
+ function requiresCompactionReplayRefresh(messages, model, identity) {
3226
+ const checkpoint = resolveCompactionSource(messages, model, identity);
3227
+ return checkpoint?.family === "responses" && checkpoint.mode === "refresh-required";
3228
+ }
3229
+ /** Carry a checkpoint immediately after reference-preserving history limiting, before repair. */
3230
+ function preserveCompactionReplayWindow(source, windowed, model, identity) {
3231
+ const checkpoint = resolveCompactionSource(source, model, identity);
3232
+ if (!checkpoint || windowed.some((message) => message === checkpoint.owner)) return windowed;
3233
+ const owner = checkpoint.owner;
3234
+ const replay = checkpoint.owner.providerReplay;
3235
+ const providerReplay = replay?.type === "openai-responses-retained-compaction" ? replay : {
3236
+ ...replay,
3237
+ replayIndex: 0
3238
+ };
3239
+ const suffix = new Set(source.slice(source.indexOf(owner) + 1));
3240
+ return [{
3241
+ ...owner,
3242
+ content: [],
3243
+ providerReplay
3244
+ }, ...windowed.filter((message) => suffix.has(message))];
3245
+ }
3246
+ function estimateResponsesWindow(checkpoint, estimate) {
3247
+ return checkpoint.output.reduce((tokens, entry) => {
3248
+ if (entry.type === "compaction") {
3249
+ const { encrypted_content, ...metadata } = entry;
3250
+ return tokens + estimate.text(encrypted_content) + estimate.json(metadata);
3251
+ }
3252
+ const { content, ...metadata } = entry;
3253
+ return tokens + estimate.json(metadata) + content.reduce((sum, block) => {
3254
+ if (block.type === "input_text") {
3255
+ const { text, ...fields } = block;
3256
+ return sum + estimate.text(text) + estimate.json(fields);
3257
+ }
3258
+ if (block.type === "input_image") {
3259
+ const { image_url: _imageUrl, ...fields } = block;
3260
+ return sum + estimate.image() + estimate.json(block.image_url?.startsWith("data:") ? fields : block);
3261
+ }
3262
+ return sum + estimate.json(block);
3263
+ }, 0);
3264
+ }, 0);
3265
+ }
3266
+ /** Estimate the canonical prefix and its tail once, independent of unbound usage snapshots. */
3267
+ function resolveCompactionReplayPressure(messages, model, identity, estimate) {
3268
+ const checkpoint = resolveCompactionSource(messages, model, identity);
3269
+ if (!checkpoint) return;
3270
+ if (checkpoint.family === "responses" && checkpoint.mode === "refresh-required") throw new CompactionReplayRefreshRequiredError();
3271
+ const ownerIndex = messages.findIndex((message) => message === checkpoint.owner);
3272
+ const owner = messages[ownerIndex];
3273
+ if (!owner) return;
3274
+ const prefixTokens = checkpoint.family === "anthropic" ? estimate.text(checkpoint.summary) : checkpoint.mode === "complete-window" ? estimateResponsesWindow(checkpoint, estimate) : estimate.text(checkpoint.item.encrypted_content);
3275
+ const { contextUsage: _staleContextUsage, ...usage } = checkpoint.owner.usage;
3276
+ const tail = [];
3277
+ for (const message of messages.slice(ownerIndex + 1)) {
3278
+ if (!isAssistantReplayMessage(message) || message.usage.contextUsage === void 0) {
3279
+ tail.push(message);
3280
+ continue;
3281
+ }
3282
+ const { contextUsage: _unboundContextUsage, ...billedUsage } = message.usage;
3283
+ tail.push({
3284
+ ...message,
3285
+ usage: billedUsage
3286
+ });
3287
+ }
3288
+ return {
3289
+ messages: [{
3290
+ ...owner,
3291
+ content: checkpoint.owner.content.slice(checkpoint.replayIndex),
3292
+ usage
3293
+ }, ...tail],
3294
+ prefixTokens
3295
+ };
3296
+ }
3014
3297
  /** Whether provider replay state is a prefix-bound server compaction checkpoint. */
3015
3298
  function isCompactionReplayCheckpoint(replay) {
3016
3299
  const type = replay && typeof replay === "object" ? replay.type : void 0;
@@ -3306,4 +3589,4 @@ function prepareModelForSimpleCompletion(params) {
3306
3589
  return applyProviderSimpleCompletionWrapper(apiRegistry, model, cfg);
3307
3590
  }
3308
3591
  //#endregion
3309
- 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, resolveOpenAIClientBaseUrl, resolveOpenAICompletionsCompat, resolveOpenAIReasoningEffortMap, resolveOpenAIResponsesCompactEndpointPlan, resolveOpenAIResponsesPayloadPolicy, resolveOpenAIResponsesServerCompactionPlan, resolveOpenAIStrictToolFlagWithDiagnostics, resolvePromptCacheKey, resolveReplayableResponsesMessageId, resolveTransportAwareSimpleApi, sanitizeNonEmptyTransportPayloadText, sanitizeResponsesImagePayload, sanitizeTransportPayloadText, sortPromptCacheToolsByName as sortTransportToolsByName, stripCompactionReplayCheckpoint, stripCompactionReplayCheckpointInPlace, stripCompletionMessagesToRoleContent, throwIfModelStreamAborted, transportAbortError, usesNativeOpenAICodexResponsesBackend, withProviderAcceptanceObserver, withProviderResponseHook };
3592
+ export { CompactionReplayRefreshRequiredError, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, applyAnthropicCacheControlToMessages, applyAnthropicContextManagementToRequest, 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, isAnthropicServerToolClearingEnabled, isCodeModeModelVisibleToolName, isCompactionReplayCheckpoint, isDirectAnthropicModel, isOpenAICodexResponsesModel, isOpenAICompletionsThinkingEnabled, log, logAnthropicContextEdits, measureUtf8AppendBytes, mergeTransportHeaders, mergeTransportMetadata, normalizeCodexResponsesBaseUrlForOpenAISdk, notifyProviderHttpMetadata, notifyProviderHttpResponse, notifyProviderStreamOpened, parseJsonObjectPreservingUnsafeIntegers, parseJsonPreservingUnsafeIntegers, parseOpenAICompletionsUsage, parseTerminalToolCallArguments, prepareModelForSimpleCompletion, prepareTransportAwareSimpleModel, preserveCompactionReplayWindow, quoteUnsafeIntegerLiterals, readCodeModePayloadToolName, readOpenAICompletionsContentDeltas, readOpenAICompletionsReasoningBatch, replaceCompactionReplayOwnerContent, requestPreparedOpenAIResponsesCompaction, requiresCompactionReplayRefresh, resolveAnthropicContextManagementBetaHeader, 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 };