@openclaw/ai 2026.9.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 (71) hide show
  1. package/dist/{anthropic-hk7F7ptG.mjs → anthropic-BDdqdVLK.mjs} +208 -205
  2. package/dist/{anthropic-compaction-replay-OMJZ0uyo.mjs → anthropic-compaction-replay-DB2FGLQc.mjs} +130 -41
  3. package/dist/{anthropic-payload-policy-DBT1itQ-.d.mts → anthropic-payload-policy-d46X2pR0.d.mts} +27 -3
  4. package/dist/{api-registry-Cs6HGNqY.d.mts → api-registry-DWtPjzyn.d.mts} +2 -2
  5. package/dist/{azure-openai-responses-CN4Fy5zV.mjs → azure-openai-responses-C5bZRfAP.mjs} +5 -5
  6. package/dist/{diagnostics-KhXK-QJI.mjs → diagnostics-DfFyKeX_.mjs} +1 -1
  7. package/dist/diagnostics.mjs +2 -2
  8. package/dist/{event-stream-uSMZJ3FA.mjs → event-stream-BgDvQeum.mjs} +3 -9
  9. package/dist/{event-stream-vK_7r3bj.d.mts → event-stream-BhT5T1Ay.d.mts} +1 -1
  10. package/dist/event-stream-zctLx0yr.d.mts +1 -0
  11. package/dist/event-stream.d.mts +2 -2
  12. package/dist/event-stream.mjs +1 -1
  13. package/dist/{google-CC-nrwXg.mjs → google-4qeuE8iX.mjs} +4 -4
  14. package/dist/{google-shared-CjPY0hZM.mjs → google-shared-CWeG8RIl.mjs} +7 -5
  15. package/dist/{google-vertex-DCr0pyzQ.mjs → google-vertex-O9BcnB6X.mjs} +4 -4
  16. package/dist/{host-BIaiBURL.mjs → host-CEvLw30U.mjs} +54 -9
  17. package/dist/{host-BztR4tQj.d.mts → host-DjzGmdZ2.d.mts} +3 -3
  18. package/dist/{index-AfaxKT8w.d.mts → index-FnHM2FcI.d.mts} +11 -5
  19. package/dist/index.d.mts +7 -7
  20. package/dist/index.mjs +4 -4
  21. package/dist/internal/anthropic.d.mts +12 -9
  22. package/dist/internal/anthropic.mjs +5 -5
  23. package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
  24. package/dist/internal/openai-responses-payload-policy.mjs +1 -1
  25. package/dist/internal/openai.d.mts +7 -7
  26. package/dist/internal/openai.mjs +10 -10
  27. package/dist/internal/runtime.d.mts +5 -5
  28. package/dist/internal/runtime.mjs +3 -3
  29. package/dist/internal/shared.d.mts +2 -2
  30. package/dist/internal/shared.mjs +3 -3
  31. package/dist/{mistral-B7etBd_H.mjs → mistral-Tb6oalqH.mjs} +10 -8
  32. package/dist/{openai-chatgpt-responses-BAJ4gq3i.mjs → openai-chatgpt-responses-yUXjPNfu.mjs} +26 -28
  33. package/dist/{openai-completions-D0QZ0AyB.mjs → openai-completions-BIUV3RDT.mjs} +8 -8
  34. package/dist/{openai-completions-compat-4IjSBpr6.d.mts → openai-completions-compat-CpjYUArk.d.mts} +3 -3
  35. package/dist/{openai-completions-stream-DZjwK8vp.mjs → openai-completions-stream-BsrBe3Gg.mjs} +16 -16
  36. package/dist/openai-prompt-cache-CGnVB74a.mjs +21 -0
  37. package/dist/openai-prompt-cache-CNoIfHYC.d.mts +16 -0
  38. package/dist/{openai-responses-BEUlxfDu.mjs → openai-responses-CCL41ALM.mjs} +8 -11
  39. package/dist/{openai-responses-compaction-window-DO7yV7az.mjs → openai-responses-compaction-window-BMVHFOtq.mjs} +18 -7
  40. package/dist/{openai-responses-contracts-bPzSN_Ba.d.mts → openai-responses-contracts-rF5DDRNS.d.mts} +12 -4
  41. package/dist/{openai-responses-prompt-observer-internal-C7x4IK7r.mjs → openai-responses-prompt-observer-internal-D0bhBfgL.mjs} +3 -3
  42. package/dist/{openai-responses-shared-DiAdpNAM.mjs → openai-responses-shared-Bmma_3Qc.mjs} +185 -109
  43. package/dist/{openai-tool-schema-BMiHFH36.mjs → openai-tool-schema-_pTAJqKF.mjs} +20 -32
  44. package/dist/{provider-error-B6EGq6gg.mjs → provider-error-9TraxGvt.mjs} +6 -7
  45. package/dist/{provider-options-CxFPtvh7.d.mts → provider-options-Bcc_p-TU.d.mts} +18 -6
  46. package/dist/provider-replay-context-BuSUaAk5.mjs +21 -0
  47. package/dist/{provider-transcript-transform-WvJmFUAf.mjs → provider-transcript-transform-BaMbI1hr.mjs} +1 -1
  48. package/dist/provider-types.d.mts +6 -6
  49. package/dist/providers.d.mts +2 -2
  50. package/dist/providers.mjs +11 -11
  51. package/dist/{reasoning-tag-text-partitioner-C-4uedDb.mjs → reasoning-tag-text-partitioner-DLCNXki6.mjs} +72 -24
  52. package/dist/{sanitize-unicode-S6binQG-.mjs → sanitize-unicode-D6xUvZaS.mjs} +1 -1
  53. package/dist/{simple-options-0PLDyJ-d.mjs → simple-options-BjHCCh4v.mjs} +2 -2
  54. package/dist/{src-C8U7lkoa.mjs → src-2qBGKg8O.mjs} +9 -1
  55. package/dist/{tool-schema-json-projection-BtZiml7r.mjs → tool-schema-json-projection-mJhXDcyz.mjs} +1 -1
  56. package/dist/{transport-stream-shared-CytPVLIg.mjs → transport-stream-shared-CZqMhfIw.mjs} +4 -4
  57. package/dist/{transport-stream-shared-BrvFTkoO.d.mts → transport-stream-shared-xnaqxmbP.d.mts} +4 -4
  58. package/dist/{transport-utils-CtuS1Upe.mjs → transport-utils-7il795_9.mjs} +1 -1
  59. package/dist/transports.d.mts +11 -10
  60. package/dist/transports.mjs +567 -253
  61. package/dist/types-3Lnm-QSJ.d.mts +1 -0
  62. package/dist/{types-DbrhszyQ.d.mts → types-CJ1-Ht7A.d.mts} +29 -7
  63. package/dist/types.d.mts +6 -6
  64. package/dist/types.mjs +3 -3
  65. package/dist/{validation-BOwtcl9X.d.mts → validation-AKZBDGQd.d.mts} +1 -1
  66. package/dist/validation.d.mts +1 -1
  67. package/package.json +2 -2
  68. package/dist/event-stream-DeDhbCc5.d.mts +0 -1
  69. package/dist/openai-prompt-cache-2uo_1OR1.d.mts +0 -7
  70. package/dist/openai-prompt-cache-mZTCdRPo.mjs +0 -12
  71. package/dist/types-B5EFUmXs.d.mts +0 -1
@@ -1,30 +1,31 @@
1
- import { g as supportsClaudeAdaptiveThinking, m as resolveClaudeSonnet5ModelIdentity, p as resolveClaudeOpus5ModelIdentity, y as supportsClaudeNativeXhighEffort } from "./src-C8U7lkoa.mjs";
1
+ import { _ as supportsClaudeAdaptiveThinking, b as supportsClaudeNativeXhighEffort, h as resolveClaudeSonnet5ModelIdentity, m as resolveClaudeOpus5ModelIdentity } from "./src-2qBGKg8O.mjs";
2
2
  import { c as normalizeLowercaseStringOrEmpty, o as isRecord, s as hasNonEmptyString } from "./utf16-slice-qz3nsy87.mjs";
3
- import { r as calculateCost } from "./sanitize-unicode-S6binQG-.mjs";
4
- import { S as usesClaudeStreamingRefusalContract, _ as prepareClaudeNoPrefillRequestContext, a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, f as ANTHROPIC_CLAUDE_CODE_BILLING_SYSTEM_BLOCK, g as mapAnthropicStopReason, h as defaultsClaudeAdaptiveThinking, m as applyClaudeRequestContract, n as getAiTransportHost, p as ANTHROPIC_CLAUDE_CODE_VERSION, r as resolveAiTransportHeaderSentinels, s as extractToolResultBlockText, v as requiresClaudeAdaptiveThinking, x as usesClaudeFable5MessagesContract, y as resolveAnthropicThinkingEffort } from "./host-BIaiBURL.mjs";
5
- import { i as stableStringify } from "./provider-error-B6EGq6gg.mjs";
6
- import { r as toErrorObject } from "./diagnostics-KhXK-QJI.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
7
  import { a as asNonNegativeFiniteNumber } from "./base64-CEFBpSkN.mjs";
8
8
  import { n as uniqueStrings } from "./string-normalization--fwJ4S2q.mjs";
9
- import { A as applyAnthropicCacheControlToMessages, C as applyAnthropicFallbackBoundary, D as createAnthropicInlineImageBudget, E as applyAnthropicRefusal, F as resolveAnthropicServerCompactionPlan, I as isAnthropicOAuthApiKey, L as omitFoundryBearerCredentialHeaders, M as applyAnthropicPayloadPolicyToParams, N as resolveAnthropicEphemeralCacheControl, O as normalizeAnthropicInlineContent, P as resolveAnthropicPayloadPolicy, R as usesFoundryBearerAuth, T as resolveAnthropicFallbackServingModelCost, _ as toClaudeCodeToolName, a as suppressAnthropicCompaction, b as ANTHROPIC_SERVER_SIDE_FALLBACKS, f as normalizeAnthropicToolCallId, g as resolveOriginalAnthropicToolName, h as reconcileAnthropicToolChoice, i as resolveNewestAnthropicCompaction, j as applyAnthropicEphemeralCacheControlMarkers, k as resolveAnthropicImageMediaType, m as projectAnthropicTools, n as createCompactionCapture, o as applyAnthropicMessageDeltaUsage, p as normalizeAnthropicToolChoice, r as isAnthropicReplayRejection, s as applyAnthropicMessageStartUsage, t as buildAnthropicReplayPlan, v as ANTHROPIC_OMITTED_REASONING_TEXT, w as readAnthropicFallbackBoundary, x as ANTHROPIC_SERVER_SIDE_FALLBACK_BETA, y as findActiveAnthropicToolTurnAssistantIndex } from "./anthropic-compaction-replay-OMJZ0uyo.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 { a as codeModeToolSurfaceObserver, d as stripSystemPromptCacheBoundary, m as sortPromptCacheToolsByName, o as reasoningTagTextPolicy, t as adjustMaxTokensForThinking } from "./simple-options-0PLDyJ-d.mjs";
12
- import { a as resolveProviderEndpoint, c as transformTransportMessages, i as resolveOpenAIStrictToolSetting, n as buildGuardedModelFetch } from "./tool-schema-json-projection-BtZiml7r.mjs";
13
- import { a as isGoogleGemini3FlashModel, c as parseRetryAfterSeconds, f as resolveModelHeaderSentinels$1, i as isCodeModeModelVisibleToolName, l as readResponseTextSnippet, m as supportsModelTools, n as createAbortError$1, o as isGoogleGemini3ProModel, p as sha256Hex, r as estimateStringChars, t as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, u as redactIdentifier } from "./transport-utils-CtuS1Upe.mjs";
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";
14
15
  import { n as getEnvApiKey } from "./env-api-keys-bktO00EJ.mjs";
15
- import { S as quoteUnsafeIntegerLiterals, _ as transportAbortError, a as createWritableTransportEventStream, b as parseJsonObjectPreservingUnsafeIntegers, c as finalizeTransportStream, d as notifyProviderHttpMetadata, f as notifyProviderHttpResponse, g as sanitizeTransportPayloadText, h as sanitizeNonEmptyTransportPayloadText, i as createEmptyTransportUsage, l as mergeTransportHeaders, m as parseTerminalToolCallArguments, n as coerceTransportToolCallArguments, o as failTransportStream, p as notifyProviderStreamOpened, r as copyProviderAcceptanceObserver, s as finalizeTerminalToolCallArguments, t as assignTransportErrorDetails, u as mergeTransportMetadata, v as withProviderAcceptanceObserver, x as parseJsonPreservingUnsafeIntegers, y as withProviderResponseHook } from "./transport-stream-shared-CytPVLIg.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-DZjwK8vp.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 captureOpenAIResponsesCompaction, H as createOpenAIResponsesAssistantOutput, I as createResponsesStreamWithEncryptedContentRetry, J as resolveReplayableResponsesMessageId, K as resolveNewestOpenAIResponsesCompactionReplay, L as isInvalidEncryptedContentError, R as resolveAzureOpenAIApiVersion, S as summarizeResponsesPayload, U as CompactionReplayRefreshRequiredError, V as convertResponsesMessages, W as buildOpenAIResponsesReasoningReplayMetadata, X as resolveModelPayloadDebugMode, Y as emitModelTransportDebug, Z as resolveModelSseDebugMode, _ as safeDebugValue, b as summarizeOpenAITransportError, c as processResponsesStream, f as observeResponsesStream, g as normalizeResponsesFailedEvent, h as logResponsesFailedNoDetails, m as buildResponsesFailedNoDetailsObservation, n as applyResponsesServiceTierPricing, p as ResponsesStreamFailure, q as suppressOpenAIResponsesCompaction, v as stringifyRedactedEvent, x as summarizeResponsesFailedNoDetailsObservation, y as stringifyRedactedPayload, z as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-DiAdpNAM.mjs";
22
- import { A as readOpenAICompletionsReasoningBatch, C as createOpenAIProviderAcceptanceHook, D as measureUtf8AppendBytes, E as log, M as resolvePromptCacheKey, N as throwIfModelStreamAborted, O as parseOpenAICompletionsUsage, S as createModelStreamCooperativeScheduler, T as isOpenAICompletionsThinkingEnabled, b as reconcileOpenAIResponsesToolChoice, j as resolveOpenAIClientBaseUrl, k as readOpenAICompletionsContentDeltas, r as normalizeOpenAIStrictToolParameters, v as projectOpenAITools, w as createOpenAIResponseHook, x as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, y as reconcileOpenAICompletionsToolChoice } from "./openai-tool-schema-BMiHFH36.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";
23
24
  import { i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-DcNjoFQE.mjs";
24
- import { C as isOpenAIGpt54MiniModel, D as resolveOpenAIReasoningEffortForModel, E as normalizeOpenAIReasoningEffort, T as isOpenAIGpt56Model, _ as OpenAIResponsesWebSocketPostDispatchError, a as applyOpenAIResponsesPayloadPolicy, c as resolveOpenAIResponsesServerCompactionPlan, d as OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS, f as OPENAI_RESPONSES_APIS, i as sanitizeResponsesImagePayload, l as AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS, n as isOpenAIResponsesCompactionOutput, o as resolveOpenAIResponsesCompactEndpointPlan, s as resolveOpenAIResponsesPayloadPolicy, t as createBoundedOpenAIResponsesCompactionFetch, v as OpenAIResponsesWebSocketPreDispatchError, w as isOpenAIGpt55Model, x as parseOpenAIResponsesWebSocketServerError, y as OpenAIResponsesWebSocketSafeRetryError } from "./openai-responses-compaction-window-DO7yV7az.mjs";
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";
25
26
  import { i as resolveAzureDeploymentNameFromMap, t as isOpenAICompatibleAzureResponsesBaseUrl } from "./azure-openai-responses-client-compat-C7K7QfUE.mjs";
26
27
  import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
27
- import { t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-C7x4IK7r.mjs";
28
+ import { t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-D0bhBfgL.mjs";
28
29
  import { randomUUID } from "node:crypto";
29
30
  import OpenAI, { AzureOpenAI } from "openai";
30
31
  import { ResponsesWS } from "openai/resources/responses/ws.js";
@@ -59,11 +60,6 @@ function resolveAnthropicMessagesMaxTokens(params) {
59
60
  const contextWindow = resolvePositiveAnthropicTokenLimit(params.modelContextWindow);
60
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)));
61
62
  }
62
- function isDirectAnthropicModel(model) {
63
- if (normalizeLowercaseStringOrEmpty(model.provider) !== "anthropic") return false;
64
- const endpointClass = resolveProviderEndpoint(model).endpointClass;
65
- return endpointClass === "default" || endpointClass === "anthropic-public";
66
- }
67
63
  function isKimiAnthropicProvider(provider) {
68
64
  return /^kimi(?:-|$)/.test(normalizeLowercaseStringOrEmpty(provider ?? ""));
69
65
  }
@@ -133,14 +129,12 @@ async function convertAnthropicMessages(messages, model, isOAuthToken, options)
133
129
  const msg = transformedMessages[i];
134
130
  if (!msg) continue;
135
131
  if (msg.role === "user") {
136
- const isRuntimeContextCarrier = msg.runtimeContextCarrier === true;
137
132
  if (typeof msg.content === "string") {
138
133
  if (msg.content.trim().length > 0) {
139
134
  const userParam = {
140
135
  role: "user",
141
136
  content: sanitizeTransportPayloadText(msg.content)
142
137
  };
143
- if (isRuntimeContextCarrier) options.cacheBreakpointOptOutMessageIndexes.add(params.length);
144
138
  params.push(userParam);
145
139
  }
146
140
  continue;
@@ -166,7 +160,6 @@ async function convertAnthropicMessages(messages, model, isOAuthToken, options)
166
160
  role: "user",
167
161
  content: filteredBlocks
168
162
  };
169
- if (isRuntimeContextCarrier) options.cacheBreakpointOptOutMessageIndexes.add(params.length);
170
163
  params.push(userParam);
171
164
  continue;
172
165
  }
@@ -402,12 +395,13 @@ async function* parseAnthropicSseBody(body, signal) {
402
395
  function createAnthropicMessagesClient(params) {
403
396
  const url = resolveAnthropicMessagesUrl(params.baseURL);
404
397
  return { messages: { async stream(body, options) {
405
- const headers = mergeTransportHeaders({
398
+ const headers = new Headers(mergeTransportHeaders({
406
399
  "content-type": "application/json",
407
400
  "anthropic-version": "2023-06-01",
408
401
  ...params.apiKey ? { "x-api-key": params.apiKey } : {},
409
402
  ...params.authToken ? { authorization: `Bearer ${params.authToken}` } : {}
410
- }, params.defaultHeaders);
403
+ }, params.defaultHeaders));
404
+ for (const [name, value] of Object.entries(options?.headers ?? {})) headers.set(name, value);
411
405
  const response = await params.fetch(url, {
412
406
  method: "POST",
413
407
  headers,
@@ -499,18 +493,20 @@ function createAnthropicTransportClient(params) {
499
493
  }
500
494
  if (useAnthropicServerSideFallback(model)) betaFeatures.push(ANTHROPIC_SERVER_SIDE_FALLBACK_BETA);
501
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);
502
501
  return {
503
502
  client: createAnthropicMessagesClient({
504
503
  apiKey,
505
504
  baseURL: model.baseUrl,
506
- defaultHeaders: mergeTransportHeaders({
507
- accept: "application/json",
508
- "anthropic-dangerous-direct-browser-access": "true",
509
- ...betaHeader ? { "anthropic-beta": betaHeader } : {}
510
- }, model.headers, options?.headers),
505
+ defaultHeaders,
511
506
  fetch
512
507
  }),
513
- isOAuthToken: false
508
+ isOAuthToken: false,
509
+ directApiKeyBetaHeader: isDirectAnthropicModel(model) ? new Headers(defaultHeaders).get("anthropic-beta") ?? "" : void 0
514
510
  };
515
511
  }
516
512
  async function buildAnthropicParams(model, context, isOAuthToken, options) {
@@ -529,7 +525,6 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
529
525
  cacheRetention: options?.cacheRetention,
530
526
  enableCacheControl: true
531
527
  }, model);
532
- const cacheBreakpointOptOutMessageIndexes = /* @__PURE__ */ new Set();
533
528
  const replayPlan = buildAnthropicReplayPlan(context.messages, model, {
534
529
  enabled: !isOAuthToken && options?.anthropicServerCompaction === true,
535
530
  authProfileId: options?.authProfileId,
@@ -537,7 +532,6 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
537
532
  });
538
533
  const messages = await convertAnthropicMessages(replayPlan.messages, model, isOAuthToken, {
539
534
  allowReasoningContentReplay: supportsReasoningContentReplay(model),
540
- cacheBreakpointOptOutMessageIndexes,
541
535
  compaction: replayPlan.compaction,
542
536
  replayThinkingEnabled
543
537
  });
@@ -595,7 +589,7 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
595
589
  const projectedToolChoice = toolProjection ? reconcileAnthropicToolChoice(normalizedToolChoice, toolProjection) : normalizedToolChoice;
596
590
  if (projectedToolChoice) params.tool_choice = projectedToolChoice;
597
591
  }
598
- applyAnthropicPayloadPolicyToParams(params, payloadPolicy, cacheBreakpointOptOutMessageIndexes);
592
+ applyAnthropicPayloadPolicyToParams(params, payloadPolicy, /* @__PURE__ */ new Set());
599
593
  return {
600
594
  params,
601
595
  toolProjection,
@@ -630,7 +624,9 @@ function resolveAnthropicTransportOptions(model, options, apiKey) {
630
624
  toolChoice: options?.toolChoice,
631
625
  thinkingBudgets: options?.thinkingBudgets,
632
626
  reasoning,
633
- ...options?.anthropicServerCompaction === true ? { anthropicServerCompaction: true } : {},
627
+ anthropicServerCompaction: options?.anthropicServerCompaction,
628
+ anthropicCompactThreshold: options?.anthropicCompactThreshold,
629
+ cacheTtlPruning: options?.cacheTtlPruning,
634
630
  ...options?.authProfileId ? { authProfileId: options.authProfileId } : {}
635
631
  });
636
632
  if (reasoning === "off") {
@@ -671,17 +667,18 @@ function createAnthropicMessagesTransportStreamFn() {
671
667
  stopReason: "stop",
672
668
  timestamp: Date.now()
673
669
  };
674
- const refusalBuffer = usesClaudeStreamingRefusalContract(model) ? createDeferredEventBuffer(stream, () => notifyLlmRequestActivity(options?.signal)) : void 0;
670
+ const refusalBuffer = usesClaudeStreamingRefusalContract(model) ? createDeferredEventBuffer(stream) : void 0;
675
671
  const eventSink = refusalBuffer ?? stream;
676
672
  let costModel = model;
677
673
  let messageStartPromptUsage;
678
674
  let usedCompactionReplay = false;
675
+ let inputTransformations;
679
676
  try {
680
677
  const apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? "";
681
678
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
682
679
  const transportOptions = resolveAnthropicTransportOptions(model, options, apiKey);
683
680
  const requestContext = prepareClaudeNoPrefillRequestContext(model, context);
684
- const { client, isOAuthToken } = createAnthropicTransportClient({
681
+ const { client, isOAuthToken, directApiKeyBetaHeader } = createAnthropicTransportClient({
685
682
  model,
686
683
  context: requestContext,
687
684
  apiKey,
@@ -691,13 +688,19 @@ function createAnthropicMessagesTransportStreamFn() {
691
688
  usedCompactionReplay = builtParams.usedCompactionReplay;
692
689
  let params = builtParams.params;
693
690
  const toolProjection = builtParams.toolProjection;
691
+ applyAnthropicContextManagementToRequest(params, model, transportOptions, directApiKeyBetaHeader);
694
692
  const nextParams = await transportOptions.onPayload?.(params, model);
695
693
  if (nextParams !== void 0) params = nextParams;
696
694
  applyClaudeRequestContract(params, model);
695
+ const betaHeader = resolveAnthropicContextManagementBetaHeader(params, directApiKeyBetaHeader);
696
+ const bindingHeaders = applyAnthropicThinkingBindingControls(params, betaHeader) ?? (betaHeader !== void 0 ? { "anthropic-beta": betaHeader } : void 0);
697
697
  const { response, stream: anthropicStream } = await client.messages.stream({
698
698
  ...params,
699
699
  stream: true
700
- }, transportOptions.signal ? { signal: transportOptions.signal } : void 0);
700
+ }, {
701
+ signal: transportOptions.signal,
702
+ headers: bindingHeaders
703
+ });
701
704
  await notifyProviderHttpResponse({
702
705
  options: transportOptions,
703
706
  response,
@@ -812,6 +815,8 @@ function createAnthropicMessagesTransportStreamFn() {
812
815
  });
813
816
  };
814
817
  for await (const event of anthropicStream) {
818
+ inputTransformations = readAnthropicInputTransformations(event) ?? inputTransformations;
819
+ notifyLlmRequestActivity(transportOptions.signal);
815
820
  if (event.type === "error") {
816
821
  const error = event.error;
817
822
  throw new Error(error?.message || "Anthropic Messages stream failed");
@@ -1101,6 +1106,7 @@ function createAnthropicMessagesTransportStreamFn() {
1101
1106
  continue;
1102
1107
  }
1103
1108
  if (event.type === "message_delta") {
1109
+ logAnthropicContextEdits(event);
1104
1110
  const delta = event.delta;
1105
1111
  const usage = event.usage;
1106
1112
  if (delta?.stop_reason) {
@@ -1149,6 +1155,8 @@ function createAnthropicMessagesTransportStreamFn() {
1149
1155
  for (const block of output.content) delete block.index;
1150
1156
  }
1151
1157
  });
1158
+ } finally {
1159
+ logAnthropicThinkingDrops(inputTransformations);
1152
1160
  }
1153
1161
  })();
1154
1162
  return eventStream;
@@ -1880,164 +1888,6 @@ function createOpenAICompletionsTransportStreamFn() {
1880
1888
  };
1881
1889
  }
1882
1890
  //#endregion
1883
- //#region packages/ai/src/transports/openai-responses-compact-request.ts
1884
- const COMPACT_REQUEST = Symbol("openaiResponsesCompactRequest");
1885
- function claimResponsesCompactRequest(options) {
1886
- const controller = options ? Reflect.get(options, COMPACT_REQUEST) : void 0;
1887
- if (controller?.claimed === false) {
1888
- controller.claimed = true;
1889
- return controller;
1890
- }
1891
- }
1892
- /** Run a compact-endpoint request through the session's prepared stream stack. */
1893
- async function requestPreparedOpenAIResponsesCompaction(streamFn, model, context, options) {
1894
- const preparedOptions = { ...options };
1895
- let resolveResult;
1896
- let rejectResult;
1897
- const result = new Promise((resolve, reject) => {
1898
- resolveResult = resolve;
1899
- rejectResult = reject;
1900
- });
1901
- const controller = {
1902
- claimed: false,
1903
- resolve: resolveResult,
1904
- reject: rejectResult
1905
- };
1906
- Reflect.set(preparedOptions, COMPACT_REQUEST, controller);
1907
- const stream = await Promise.resolve(streamFn(model, context, preparedOptions));
1908
- if (!controller.claimed) throw new Error("Prepared stream did not reach an OpenAI Responses transport");
1909
- try {
1910
- return await result;
1911
- } finally {
1912
- await stream.result().catch(() => void 0);
1913
- }
1914
- }
1915
- //#endregion
1916
- //#region packages/ai/src/transports/openai-responses-continuation.ts
1917
- const HTTP_CONTINUATION_IDLE_TTL_MS = 3e5;
1918
- const TURN_HEADERS = /* @__PURE__ */ new Set([
1919
- "traceparent",
1920
- "x-openclaw-turn-id",
1921
- "x-openclaw-turn-attempt"
1922
- ]);
1923
- function jsonValuesEqual(left, right) {
1924
- return stableStringify(JSON.parse(JSON.stringify(left))) === stableStringify(JSON.parse(JSON.stringify(right)));
1925
- }
1926
- function requestWithoutInput(request) {
1927
- const { input: _input, previous_response_id: _previousResponseId, instructions: _instructions, tools: _tools, ...rest } = request;
1928
- if (!isRecord(rest.metadata)) return rest;
1929
- const metadata = Object.fromEntries(Object.entries(rest.metadata).filter(([key]) => key !== "openclaw_turn_id" && key !== "openclaw_turn_attempt"));
1930
- return {
1931
- ...rest,
1932
- metadata
1933
- };
1934
- }
1935
- function normalizeAssistantReplayInput(input, fromResponse = false) {
1936
- return input.map((item) => {
1937
- if (!isRecord(item)) return item;
1938
- if (item.type === "reasoning") return { type: "reasoning" };
1939
- if (item.type !== "function_call" && !(item.type === "message" && item.role === "assistant")) return item;
1940
- const { id: _id, status: _status, ...stableItem } = item;
1941
- if (fromResponse && item.type === "function_call") {
1942
- const args = parseJsonObjectPreservingUnsafeIntegers(stableItem.arguments);
1943
- stableItem.arguments = args ? JSON.stringify(args) : stableItem.arguments;
1944
- }
1945
- if (item.type === "message" && Array.isArray(stableItem.content)) stableItem.content = stableItem.content.map((part) => {
1946
- if (!isRecord(part) || part.type !== "output_text") return part;
1947
- const { annotations: _annotations, logprobs: _logprobs, ...stablePart } = part;
1948
- return stablePart;
1949
- });
1950
- return stableItem;
1951
- });
1952
- }
1953
- function resolveResponsesContinuationRequest(continuation, request) {
1954
- if (!continuation) return {
1955
- request,
1956
- continuationStatus: "no_previous_response"
1957
- };
1958
- if (request.previous_response_id) return {
1959
- request,
1960
- continuationStatus: "explicit_previous_response_id"
1961
- };
1962
- if (!jsonValuesEqual(requestWithoutInput(request), requestWithoutInput(continuation.lastRequest))) return {
1963
- request,
1964
- continuationStatus: "request_changed"
1965
- };
1966
- const currentInput = request.input ?? [];
1967
- const previousInput = continuation.lastRequest.input ?? [];
1968
- const baselineLength = previousInput.length + continuation.lastResponseItems.length;
1969
- if (currentInput.length < baselineLength) return {
1970
- request,
1971
- continuationStatus: "history_shorter"
1972
- };
1973
- if (!jsonValuesEqual(normalizeAssistantReplayInput(currentInput.slice(0, previousInput.length)), normalizeAssistantReplayInput(previousInput)) || !jsonValuesEqual(normalizeAssistantReplayInput(currentInput.slice(previousInput.length, baselineLength)), normalizeAssistantReplayInput(continuation.lastResponseItems, true))) return {
1974
- request,
1975
- continuationStatus: "history_changed"
1976
- };
1977
- return {
1978
- request: {
1979
- ...request,
1980
- previous_response_id: continuation.lastResponseId,
1981
- input: currentInput.slice(baselineLength)
1982
- },
1983
- continuationStatus: "continued"
1984
- };
1985
- }
1986
- const httpContinuationEntries = /* @__PURE__ */ new Map();
1987
- let nextHttpContinuationGeneration = 1;
1988
- function connectionIdentity(params) {
1989
- 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));
1990
- return sha256Hex(JSON.stringify([
1991
- getAiTransportHost().resolveSecretSentinel(params.apiKey),
1992
- params.baseUrl,
1993
- headers
1994
- ]));
1995
- }
1996
- function claimOpenAIResponsesHttpContinuation(params) {
1997
- const key = `${params.sessionId}\0${connectionIdentity(params)}`;
1998
- const previous = httpContinuationEntries.get(key);
1999
- if (previous?.kind === "claimed") return;
2000
- if (previous?.kind === "ready") clearTimeout(previous.idleTimer);
2001
- const generation = nextHttpContinuationGeneration++;
2002
- const claimed = {
2003
- kind: "claimed",
2004
- sessionId: params.sessionId,
2005
- generation
2006
- };
2007
- httpContinuationEntries.set(key, claimed);
2008
- return {
2009
- request: resolveResponsesContinuationRequest(previous?.kind === "ready" ? previous.state : void 0, params.request).request,
2010
- commit: (effectiveRequest, response) => {
2011
- if (httpContinuationEntries.get(key) !== claimed) return;
2012
- const idleTimer = setTimeout(() => {
2013
- const current = httpContinuationEntries.get(key);
2014
- if (current?.kind === "ready" && current.generation === generation) httpContinuationEntries.delete(key);
2015
- }, HTTP_CONTINUATION_IDLE_TTL_MS);
2016
- idleTimer.unref?.();
2017
- const ready = {
2018
- ...claimed,
2019
- kind: "ready",
2020
- state: {
2021
- lastRequest: effectiveRequest,
2022
- lastResponseId: response.id,
2023
- lastResponseItems: response.output
2024
- },
2025
- idleTimer
2026
- };
2027
- httpContinuationEntries.set(key, ready);
2028
- },
2029
- release: () => {
2030
- if (httpContinuationEntries.get(key) === claimed) httpContinuationEntries.delete(key);
2031
- }
2032
- };
2033
- }
2034
- registerSessionResourceCleanup((sessionId) => {
2035
- for (const [key, entry] of httpContinuationEntries) if (!sessionId || entry.sessionId === sessionId) {
2036
- if (entry.kind === "ready") clearTimeout(entry.idleTimer);
2037
- httpContinuationEntries.delete(key);
2038
- }
2039
- });
2040
- //#endregion
2041
1891
  //#region packages/ai/src/transports/openai-responses-params-internal.ts
2042
1892
  const OPENAI_RESPONSES_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set([
2043
1893
  "openai",
@@ -2065,10 +1915,6 @@ function convertResponsesTools(tools, model, options) {
2065
1915
  })
2066
1916
  };
2067
1917
  }
2068
- function getPromptCacheRetention(baseUrl, cacheRetention) {
2069
- if (cacheRetention !== "long") return;
2070
- return baseUrl?.includes("api.openai.com") ? "24h" : void 0;
2071
- }
2072
1918
  function resolveOpenAIReasoningEffort(options) {
2073
1919
  return normalizeOpenAIReasoningEffort(options?.reasoningEffort ?? options?.reasoning ?? "high");
2074
1920
  }
@@ -2179,14 +2025,14 @@ function buildOpenAIResponsesParams(model, context, options, metadata, replayMod
2179
2025
  input: messages,
2180
2026
  stream: true,
2181
2027
  prompt_cache_key: promptCacheKey,
2182
- prompt_cache_retention: getPromptCacheRetention(model.baseUrl, cacheRetention),
2028
+ ...resolveOpenAIResponsesCacheParams(model, cacheRetention, model.baseUrl?.includes("api.openai.com")),
2183
2029
  ...instructions ? { instructions } : {},
2184
2030
  ...metadata ? { metadata } : {}
2185
2031
  };
2186
2032
  const effectiveMaxTokens = options?.maxTokens || model.maxTokens;
2187
- if (effectiveMaxTokens) params.max_output_tokens = effectiveMaxTokens;
2188
- if (options?.temperature !== void 0) params.temperature = options.temperature;
2189
- 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;
2190
2036
  if (options?.responseFormat !== void 0) params.text = {
2191
2037
  ...params.text,
2192
2038
  format: resolveOpenAIResponsesTextFormat(options.responseFormat)
@@ -2231,6 +2077,308 @@ function buildOpenAIResponsesParams(model, context, options, metadata, replayMod
2231
2077
  return sanitizeOpenAICodexResponsesParams(model, params);
2232
2078
  }
2233
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
2234
2382
  //#region packages/ai/src/transports/openai-responses-websocket.ts
2235
2383
  const SESSION_WEBSOCKET_CACHE_TTL_MS = 3e5;
2236
2384
  const SESSION_WEBSOCKET_MAX_AGE_MS = 33e5;
@@ -2263,6 +2411,9 @@ function invalidateOwnedWebSocketSession(cacheKey, entry, reason = "done") {
2263
2411
  entry.idleTimer = void 0;
2264
2412
  }
2265
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;
2266
2417
  if (websocketSessionCache.get(cacheKey) === entry) websocketSessionCache.delete(cacheKey);
2267
2418
  }
2268
2419
  function scheduleSessionWebSocketExpiry(cacheKey, entry) {
@@ -2312,11 +2463,14 @@ function createTransientWebSocketLease(connection) {
2312
2463
  }
2313
2464
  function createCachedWebSocketLease(cacheKey, entry, reusedConnection) {
2314
2465
  entry.busy = true;
2466
+ const steeringContinuation = entry.steeringContinuation;
2467
+ entry.steeringContinuation = void 0;
2315
2468
  return {
2316
2469
  socket: entry.socket,
2317
- iterator: entry.socket.stream(),
2470
+ iterator: steeringContinuation?.iterator ?? entry.socket.stream(),
2318
2471
  entry,
2319
2472
  reusedConnection,
2473
+ steeringContinuation,
2320
2474
  release: ({ keep } = {}) => {
2321
2475
  if (!keep || entry.socket.socket.readyState !== WEBSOCKET_OPEN_STATE) {
2322
2476
  invalidateOwnedWebSocketSession(cacheKey, entry);
@@ -2400,11 +2554,13 @@ function createOpenAIResponsesWebSocketStream(params) {
2400
2554
  throw new OpenAIResponsesWebSocketPreDispatchError(error);
2401
2555
  }
2402
2556
  let prepared;
2557
+ const resumedSteering = lease.steeringContinuation;
2558
+ const steeringMode = resumedSteering ? resumedSteering.requiresInput ? "required-input" : "automatic" : void 0;
2403
2559
  try {
2404
2560
  const continuation = lease.entry?.continuation;
2405
2561
  if (continuation && lease.entry) {
2406
2562
  lease.entry.continuation = void 0;
2407
- prepared = resolveResponsesContinuationRequest(continuation, fullRequest);
2563
+ prepared = resolveResponsesContinuationRequest(continuation, fullRequest, steeringMode);
2408
2564
  } else prepared = {
2409
2565
  request: fullRequest,
2410
2566
  continuationStatus: lease.entry ? "no_previous_response" : "socket_not_cached"
@@ -2418,11 +2574,54 @@ function createOpenAIResponsesWebSocketStream(params) {
2418
2574
  let terminalResponse;
2419
2575
  let terminalReceived = false;
2420
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;
2421
2620
  const finish = ({ keep = true } = {}) => {
2422
2621
  if (released) return;
2423
2622
  released = true;
2424
2623
  if (keep && lease.entry && terminalResponse) lease.entry.continuation = {
2425
- lastRequest: fullRequest,
2624
+ lastRequest: prepared.fullRequest ?? fullRequest,
2426
2625
  lastResponseId: terminalResponse.id,
2427
2626
  lastResponseItems: terminalResponse.output
2428
2627
  };
@@ -2436,8 +2635,19 @@ function createOpenAIResponsesWebSocketStream(params) {
2436
2635
  let requestDispatched = false;
2437
2636
  try {
2438
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
+ }
2439
2645
  for (;;) {
2440
- 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);
2441
2651
  if (next.done) throw new Error("OpenAI Responses WebSocket closed before a terminal response event");
2442
2652
  if (next.value.type === "open") {
2443
2653
  if (!requestDispatched) {
@@ -2451,8 +2661,51 @@ function createOpenAIResponsesWebSocketStream(params) {
2451
2661
  }
2452
2662
  const event = readServerEvent(next.value);
2453
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);
2454
2668
  if (event.type === "response.completed") terminalResponse = event.response;
2455
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
+ }
2456
2709
  yield event;
2457
2710
  if (terminalReceived) {
2458
2711
  degradedWebSocketConnections.delete(degradationKey);
@@ -2460,20 +2713,27 @@ function createOpenAIResponsesWebSocketStream(params) {
2460
2713
  }
2461
2714
  }
2462
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"));
2463
2718
  if (lease.entry) lease.entry.continuation = void 0;
2464
- const safeRetry = error instanceof OpenAIResponsesWebSocketSafeRetryError;
2719
+ const safeRetry = error instanceof OpenAIResponsesWebSocketSafeRetryError && !steeringDispatched;
2465
2720
  if (!params.callerSignal?.aborted && !safeRetry) markDegraded();
2466
2721
  if (!requestDispatched && !params.signal?.aborted) throw new OpenAIResponsesWebSocketPreDispatchError(error);
2467
2722
  if (!requestDispatched || params.callerSignal?.aborted || safeRetry) throw error;
2468
2723
  throw new OpenAIResponsesWebSocketPostDispatchError(error);
2469
2724
  } finally {
2470
- 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
+ }
2471
2730
  if (!terminalReceived) finish({ keep: false });
2472
2731
  }
2473
2732
  } },
2474
2733
  request: prepared.request,
2475
2734
  reusedConnection: lease.reusedConnection,
2476
2735
  continuationStatus: prepared.continuationStatus,
2736
+ inputReplay,
2477
2737
  finish
2478
2738
  };
2479
2739
  }
@@ -2486,6 +2746,70 @@ function closeOpenAIResponsesWebSocketSessions(sessionId) {
2486
2746
  }
2487
2747
  registerSessionResourceCleanup(closeOpenAIResponsesWebSocketSessions);
2488
2748
  //#endregion
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
+ }
2758
+ });
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");
2767
+ return {
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
+ })
2777
+ };
2778
+ }
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;
2787
+ }
2788
+ }
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
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
+ }
2811
+ }
2812
+ //#endregion
2489
2813
  //#region packages/ai/src/transports/openai-responses-client.ts
2490
2814
  function resolveNativeOpenAIResponsesWebSocketMode(model, transport) {
2491
2815
  if (transport !== "websocket" && transport !== "websocket-cached" && transport !== "auto") return;
@@ -2529,35 +2853,6 @@ function createOpenAIResponsesClient(model, context, apiKey, optionHeaders, turn
2529
2853
  ...buildOpenAISdkClientOptions(model)
2530
2854
  });
2531
2855
  }
2532
- async function postOpenAIResponsesCompaction(params) {
2533
- const compactInput = typeof params.request.instructions === "string" && params.request.instructions.length > 0 ? [buildOpenAIResponsesCompactSystemMessage(params.model, params.request.instructions), ...params.request.input ?? []] : params.request.input;
2534
- const response = await params.client.post("/responses/compact", {
2535
- ...buildOpenAISdkRequestOptions(params.model, params.options?.signal, { timeoutMs: params.options?.timeoutMs }),
2536
- body: {
2537
- model: params.request.model,
2538
- input: compactInput
2539
- }
2540
- });
2541
- const output = isRecord(response) && Array.isArray(response.output) ? response.output : [];
2542
- const item = output.at(-1);
2543
- const retainedItems = output.slice(0, -1);
2544
- const retainedUserMessageCount = retainedItems.filter((candidate) => isRecord(candidate) && candidate.type === "message" && candidate.role === "user" && Array.isArray(candidate.content)).length;
2545
- const inputUserMessageCount = Array.isArray(params.request.input) ? params.request.input.filter((candidate) => isRecord(candidate) && candidate.type === "message" && candidate.role === "user").length : 0;
2546
- const retainedMessagePrefixSupported = supportsNativeOpenAIResponsesEndpoint(params.model);
2547
- const usage = isRecord(response) && isRecord(response.usage) ? response.usage : void 0;
2548
- 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");
2549
- return {
2550
- output,
2551
- item,
2552
- historyMode: retainedUserMessageCount > 0 ? "retained-users" : "compacted-prefix",
2553
- usage,
2554
- model: params.model,
2555
- replayMetadata: buildOpenAIResponsesReasoningReplayMetadata(params.model, {
2556
- authProfileId: params.options?.authProfileId,
2557
- sessionId: params.options?.sessionId
2558
- })
2559
- };
2560
- }
2561
2856
  function createResponsesTransportExecutor(config) {
2562
2857
  return (model, context, options) => {
2563
2858
  const responsesOptions = options;
@@ -2579,8 +2874,10 @@ function createResponsesTransportExecutor(config) {
2579
2874
  const websocketSessionPolicy = websocketMode ? turnState?.websocket : void 0;
2580
2875
  const websocketHeaders = websocketMode ? buildOpenAIClientHeaders(model, context, options?.headers, websocketSessionPolicy?.headers, options?.sessionId) : void 0;
2581
2876
  const client = config.createClient(model, context, apiKey, options?.headers, turnState?.headers, options?.sessionId, compactRequest ? createBoundedOpenAIResponsesCompactionFetch(buildGuardedModelFetch(model)) : void 0);
2582
- const buildRequest = async (replayMode) => {
2583
- let params = config.buildRequest(model, context, responsesOptions, turnState?.metadata, replayMode);
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;
2584
2881
  const nextParams = await options?.onPayload?.(params, model);
2585
2882
  if (nextParams !== void 0) params = nextParams;
2586
2883
  if (!isOpenAICodexResponsesModel(model)) params = mergeTransportMetadata(params, turnState?.metadata);
@@ -2592,9 +2889,15 @@ function createResponsesTransportExecutor(config) {
2592
2889
  enforceCodeModeResponsesToolSurface(params, visibleToolNames, allowedHostedToolTypes, codeModeToolSurfaceObserver.get(options));
2593
2890
  assertCodeModeResponsesToolSurface(params, visibleToolNames, allowedHostedToolTypes);
2594
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);
2595
2896
  return params;
2596
2897
  };
2597
- 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;
2598
2901
  if (compactRequest) {
2599
2902
  const compacted = await postOpenAIResponsesCompaction({
2600
2903
  client,
@@ -2618,13 +2921,16 @@ function createResponsesTransportExecutor(config) {
2618
2921
  provider: model.provider,
2619
2922
  api: model.api,
2620
2923
  baseUrl: model.baseUrl
2621
- }) && sessionId && params.store === true && !params.previous_response_id) continuationClaim = claimOpenAIResponsesHttpContinuation({
2622
- sessionId,
2623
- apiKey,
2624
- baseUrl: model.baseUrl,
2625
- headers: buildOpenAIClientHeaders(model, context, options?.headers, turnState?.headers, sessionId),
2626
- request: params
2627
- });
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
+ }
2628
2934
  const observePrompt = createResponsesPromptEgressObserver(responsesOptions, context.systemPrompt);
2629
2935
  const requestStartedAt = Date.now();
2630
2936
  let started = false;
@@ -2693,9 +2999,15 @@ function createResponsesTransportExecutor(config) {
2693
2999
  headers: websocketHeaders,
2694
3000
  signal: websocketSignal,
2695
3001
  callerSignal: options?.signal,
2696
- 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
+ }))
2697
3008
  });
2698
3009
  finishWebSocket = websocket.finish;
3010
+ recordResponsesInputReplay(output, websocket.inputReplay);
2699
3011
  observePrompt?.(websocket.request, {
2700
3012
  egress: "responses-websocket",
2701
3013
  payloadVariant: "initial"
@@ -2737,7 +3049,8 @@ function createResponsesTransportExecutor(config) {
2737
3049
  yield* await createSseStream();
2738
3050
  }
2739
3051
  } };
2740
- } catch {
3052
+ } catch (error) {
3053
+ if (error instanceof OpenAIResponsesWebSocketPostDispatchError) throw error;
2741
3054
  closeWebSocketForFallback("setup_failure");
2742
3055
  responseStream = await createSseStream();
2743
3056
  }
@@ -2752,7 +3065,8 @@ function createResponsesTransportExecutor(config) {
2752
3065
  reasoningReplayMetadata: buildOpenAIResponsesReasoningReplayMetadata(model, {
2753
3066
  authProfileId: responsesOptions?.authProfileId,
2754
3067
  sessionId: options?.sessionId
2755
- })
3068
+ }),
3069
+ asyncToolExecution: asyncTools
2756
3070
  });
2757
3071
  finishWebSocket?.();
2758
3072
  if (options?.signal?.aborted) throw transportAbortError(options.signal);
@@ -3275,4 +3589,4 @@ function prepareModelForSimpleCompletion(params) {
3275
3589
  return applyProviderSimpleCompletionWrapper(apiRegistry, model, cfg);
3276
3590
  }
3277
3591
  //#endregion
3278
- export { CompactionReplayRefreshRequiredError, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, applyAnthropicCacheControlToMessages, applyAnthropicEphemeralCacheControlMarkers, applyAnthropicPayloadPolicyToParams, applyOpenAIResponsesPayloadPolicy, assertCodeModeResponsesToolSurface, assignTransportErrorDetails, buildOpenAIClientHeaders, buildOpenAICompletionsParams, buildOpenAISdkClientOptions, buildOpenAISdkRequestOptions, buildTransportAwareSimpleStreamFn, canonicalizeMaxTokensParam, captureOpenAIResponsesCompaction, coerceTransportToolCallArguments, copyProviderAcceptanceObserver, createAnthropicMessagesTransportStreamFn, createAzureOpenAIResponsesTransportStreamFn, createBoundaryAwareStreamFnForModel, createDeepSeekTextFilter, createEmptyTransportUsage, createModelStreamCooperativeScheduler, createOpenAICompletionsTransportStreamFn, createOpenAIProviderAcceptanceHook, createOpenAIResponseHook, createOpenAIResponsesTransportStreamFn, createOpenClawTransportStreamFnForModel, createTransportAwareStreamFnForModel, createWritableTransportEventStream, detectOpenAICompletionsCompat, emitModelTransportDebug, enforceCodeModeResponsesToolSurface, failTransportStream, filterCodeModePayloadTools, finalizeTerminalToolCallArguments, finalizeTransportStream, flattenCompletionMessagesToStringContent, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, getCompat, googleFlashSupportsMinimalThinking, hasOpenAICompatibleConversationTurn, isCodeModeModelVisibleToolName, isCompactionReplayCheckpoint, isOpenAICodexResponsesModel, isOpenAICompletionsThinkingEnabled, log, measureUtf8AppendBytes, mergeTransportHeaders, mergeTransportMetadata, normalizeCodexResponsesBaseUrlForOpenAISdk, notifyProviderHttpMetadata, notifyProviderHttpResponse, notifyProviderStreamOpened, parseJsonObjectPreservingUnsafeIntegers, parseJsonPreservingUnsafeIntegers, parseOpenAICompletionsUsage, parseTerminalToolCallArguments, prepareModelForSimpleCompletion, prepareTransportAwareSimpleModel, preserveCompactionReplayWindow, quoteUnsafeIntegerLiterals, readCodeModePayloadToolName, readOpenAICompletionsContentDeltas, readOpenAICompletionsReasoningBatch, replaceCompactionReplayOwnerContent, requestPreparedOpenAIResponsesCompaction, requiresCompactionReplayRefresh, resolveAnthropicEphemeralCacheControl, resolveAnthropicMessagesUrl, resolveAnthropicPayloadPolicy, resolveAnthropicServerCompactionPlan, resolveCodeModeResponsesVisibleToolNames, resolveCompactionReplayEligibility, resolveCompactionReplayPressure, resolveMaxTokensParam, resolveModelPayloadDebugMode, resolveModelSseDebugMode, resolveOpenAIClientBaseUrl, resolveOpenAICompletionsCompat, resolveOpenAIReasoningEffortMap, resolveOpenAIResponsesCompactEndpointPlan, resolveOpenAIResponsesPayloadPolicy, resolveOpenAIResponsesServerCompactionPlan, resolveOpenAIStrictToolFlagWithDiagnostics, resolvePromptCacheKey, resolveReplayableResponsesMessageId, resolveTransportAwareSimpleApi, sanitizeNonEmptyTransportPayloadText, sanitizeResponsesImagePayload, sanitizeTransportPayloadText, sortPromptCacheToolsByName as sortTransportToolsByName, stripCompactionReplayCheckpoint, stripCompactionReplayCheckpointInPlace, stripCompletionMessagesToRoleContent, throwIfModelStreamAborted, transportAbortError, usesNativeOpenAICodexResponsesBackend, withProviderAcceptanceObserver, withProviderResponseHook };
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 };