@openclaw/ai 2026.10.1 → 2026.10.5-beta.1

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 (106) hide show
  1. package/README.md +6 -0
  2. package/dist/{anthropic-BDfXKgF1.mjs → anthropic-BAHKgWam.mjs} +30 -59
  3. package/dist/{anthropic-payload-policy-BZUAchqb.d.mts → anthropic-payload-policy-DGblkHL5.d.mts} +19 -16
  4. package/dist/{anthropic-stream-reducer-DHt9uFWX.mjs → anthropic-stream-reducer-g6w1YVii.mjs} +195 -283
  5. package/dist/{api-registry-DcEP_o4h.d.mts → api-registry-BhXXYdRA.d.mts} +2 -2
  6. package/dist/assistant-message-events-CHMJgbhs.mjs +18 -0
  7. package/dist/{assistant-output-mJ9cL4Qg.mjs → assistant-output-CUEeSotf.mjs} +2 -2
  8. package/dist/{assistant-text-phase-DAv1BdTm.mjs → assistant-text-phase-BrV8KdFO.mjs} +7 -6
  9. package/dist/{azure-openai-responses-gn9hMf8x.mjs → azure-openai-responses-C7qBuR23.mjs} +8 -9
  10. package/dist/{credential-redaction-BKv49aiv.d.mts → credential-redaction-BHxruEH6.d.mts} +3 -1
  11. package/dist/{diagnostics-Caj-4RBA.mjs → diagnostics-tQasYct1.mjs} +10 -3
  12. package/dist/diagnostics.d.mts +7 -7
  13. package/dist/diagnostics.mjs +3 -3
  14. package/dist/{env-api-keys-CyX4VKGO.mjs → env-api-keys-CrxwdylR.mjs} +24 -35
  15. package/dist/event-stream-6UNs-AhN.d.mts +1 -0
  16. package/dist/{event-stream-DrRM_90c.d.mts → event-stream-BcqWLo_u.d.mts} +1 -1
  17. package/dist/{event-stream-C5AbCAaZ.mjs → event-stream-X2gmsUWv.mjs} +5 -8
  18. package/dist/event-stream.d.mts +2 -2
  19. package/dist/event-stream.mjs +1 -1
  20. package/dist/google-Boz2QcpK.mjs +20 -0
  21. package/dist/{google-interactions-DXu4IYGb.mjs → google-interactions-tjAb1mc5.mjs} +52 -84
  22. package/dist/{google-messages-Bmheetdg.mjs → google-messages-C-RZzloH.mjs} +25 -35
  23. package/dist/google-provider-stream-CMImyxbX.mjs +58 -0
  24. package/dist/{google-shared-DE_ddfsC.mjs → google-shared-OyAtMTZv.mjs} +6 -15
  25. package/dist/google-vertex-hCxTJea7.mjs +40 -0
  26. package/dist/{host-BjIYEjwT.d.mts → host-CTDz7LXD.d.mts} +6 -3
  27. package/dist/{host-JpNulOOs.mjs → host-JWXZWa-c.mjs} +3 -2
  28. package/dist/{host-policy-CC5H0iRZ.mjs → host-policy-q4Azym9F.mjs} +1 -1
  29. package/dist/{index-DJrNQnKw.d.mts → index-BYDvopUB.d.mts} +8 -5
  30. package/dist/index.d.mts +7 -7
  31. package/dist/index.mjs +7 -6
  32. package/dist/internal/anthropic.d.mts +5 -5
  33. package/dist/internal/anthropic.mjs +4 -4
  34. package/dist/internal/openai-completions-compat.d.mts +1 -1
  35. package/dist/internal/openai-completions-compat.mjs +1 -1
  36. package/dist/internal/openai-responses-payload-policy.d.mts +8 -1
  37. package/dist/internal/openai-responses-payload-policy.mjs +3 -3
  38. package/dist/internal/openai.d.mts +9 -9
  39. package/dist/internal/openai.mjs +9 -11
  40. package/dist/internal/runtime.d.mts +31 -13
  41. package/dist/internal/runtime.mjs +10 -13
  42. package/dist/internal/shared.d.mts +5 -5
  43. package/dist/internal/shared.mjs +6 -7
  44. package/dist/internal/tool-schema.mjs +2 -2
  45. package/dist/{llm-request-activity-D8f_oxHj.mjs → llm-request-activity-CfMuh5cC.mjs} +2 -2
  46. package/dist/{mistral-1Bnbneg1.mjs → mistral-DUveP4hF.mjs} +71 -146
  47. package/dist/{model-transport-url-C5f59L3Y.d.mts → model-transport-url-BrsjjdjR.d.mts} +5 -1
  48. package/dist/{number-coercion-V8-BhME4.mjs → number-coercion-C3hztWoY.mjs} +5 -4
  49. package/dist/{openai-chatgpt-responses-CB1JwNFF.mjs → openai-chatgpt-responses-OCwckGhY.mjs} +164 -234
  50. package/dist/{openai-completions-BPadHHKe.mjs → openai-completions-DOltBUe9.mjs} +7 -6
  51. package/dist/{openai-completions-compat-CJ0ktmGy.d.mts → openai-completions-compat-i-nLZxFy.d.mts} +10 -11
  52. package/dist/{openai-completions-compat-D7hWYB0G.mjs → openai-completions-compat-pg1q4uNG.mjs} +10 -6
  53. package/dist/{openai-completions-transport-DITBEALX.mjs → openai-completions-transport-OMrn7gnZ.mjs} +1429 -294
  54. package/dist/{openai-prompt-cache-Dj8qeOHT.mjs → openai-prompt-cache-Cr2xKVrS.mjs} +1 -1
  55. package/dist/{openai-prompt-cache-C-Q1Ksfs.d.mts → openai-prompt-cache-DIPMrMFy.d.mts} +2 -2
  56. package/dist/{openai-responses-1_TvcWI3.mjs → openai-responses-BSBJUA19.mjs} +9 -10
  57. package/dist/{openai-responses-compaction-replay-BB2SWdsx.d.mts → openai-responses-compaction-replay-B2FE4Nw8.d.mts} +4 -4
  58. package/dist/{openai-responses-contracts-sAvdqNjS.d.mts → openai-responses-contracts-DKqMJ1Ct.d.mts} +9 -4
  59. package/dist/{openai-responses-contracts-BKu8O7l4.mjs → openai-responses-contracts-DlKMMTxK.mjs} +26 -6
  60. package/dist/{openai-responses-compaction-window-m878aVpU.mjs → openai-responses-endpoint-CinGh4VZ.mjs} +14 -4
  61. package/dist/{openai-responses-prompt-observer-internal-CbH84xIS.mjs → openai-responses-request-lifecycle-D2IFiI0-.mjs} +39 -4
  62. package/dist/{openai-responses-shared-TCJRAoMW.mjs → openai-responses-shared-DVGhq5xF.mjs} +1036 -327
  63. package/dist/{openai-responses-terminal-usage-BVvyXZ8u.d.mts → openai-responses-terminal-usage-BygjiAdi.d.mts} +2 -2
  64. package/dist/{openai-tool-schema-DYNePiF8.mjs → openai-tool-schema-DDPXsvJP.mjs} +236 -399
  65. package/dist/{positive-integer-CwLi8LUL.mjs → positive-integer-CqWjqSi9.mjs} +1 -1
  66. package/dist/{provider-error-DQBE1bUQ.mjs → provider-error-CF9GWCs2.mjs} +5 -3
  67. package/dist/{provider-options-Dk4PeQV3.d.mts → provider-options-CVrXZBtA.d.mts} +3 -2
  68. package/dist/{provider-transport-turn-state-8c_Nj2NS.mjs → provider-transport-turn-state-LuCaTsSO.mjs} +2 -2
  69. package/dist/{provider-types-De8PRdR0.d.mts → provider-types-CHtRx0dI.d.mts} +3 -3
  70. package/dist/provider-types.d.mts +6 -6
  71. package/dist/providers.d.mts +2 -2
  72. package/dist/providers.mjs +12 -12
  73. package/dist/{reasoning-tag-text-partitioner-Ju9VpUGl.mjs → reasoning-tag-text-partitioner-0-Rsezog.mjs} +13 -12
  74. package/dist/{required-api-key-D4kn3252.mjs → required-api-key-CFJvcFy_.mjs} +1 -1
  75. package/dist/{simple-options-wW3117Fu.mjs → simple-options-BARFAzk9.mjs} +9 -11
  76. package/dist/{src-DWJq14pn.mjs → src-C_wfIUmV.mjs} +19 -4
  77. package/dist/{stream-CElngO8h.mjs → stream-DwrETW0_.mjs} +12 -21
  78. package/dist/{stream-first-event-timeout-D9ZmL_s9.mjs → stream-first-event-timeout-Dc42hKv6.mjs} +8 -21
  79. package/dist/{streaming-byte-guard-CC-HMn_u.mjs → streaming-byte-guard-DBXr1XYn.mjs} +16 -1
  80. package/dist/{string-normalization-PN10hf6d.mjs → string-normalization-I3ux50s9.mjs} +1 -1
  81. package/dist/{text-signature-rOn31nxc.mjs → text-signature-B_MB6U_9.mjs} +32 -5
  82. package/dist/{tool-schema-json-projection-Ct8SeBeJ.mjs → tool-schema-json-projection-B8sG1I9v.mjs} +29 -23
  83. package/dist/{transport-stream-shared-CAxkgOSj.d.mts → transport-stream-shared-BmpzDtdQ.d.mts} +4 -4
  84. package/dist/{transport-stream-shared-C5TAc3U_.mjs → transport-stream-shared-DH08b7Il.mjs} +8 -16
  85. package/dist/transports.d.mts +33 -22
  86. package/dist/transports.mjs +73 -1234
  87. package/dist/{types-DvzmWW8J.d.mts → types-Bd2T86VJ.d.mts} +5 -23
  88. package/dist/types-Kdfw_04V.d.mts +1 -0
  89. package/dist/types.d.mts +6 -6
  90. package/dist/types.mjs +5 -4
  91. package/dist/{validation-B3lQt_VE.d.mts → validation-DdGB1yy3.d.mts} +1 -1
  92. package/dist/{validation-DbqlIfDn.mjs → validation-opC2pjk9.mjs} +2 -3
  93. package/dist/validation.d.mts +1 -1
  94. package/dist/validation.mjs +1 -1
  95. package/package.json +4 -9
  96. package/dist/env-api-keys-BR0MUYYD.d.mts +0 -17
  97. package/dist/event-stream-DqDQWqiy.d.mts +0 -1
  98. package/dist/google-CyMz2jF_.mjs +0 -54
  99. package/dist/google-vertex-BEW0OQIA.mjs +0 -88
  100. package/dist/internal/env-api-keys.d.mts +0 -2
  101. package/dist/internal/env-api-keys.mjs +0 -2
  102. package/dist/openai-responses-request-lifecycle-Fsag-IGZ.mjs +0 -36
  103. package/dist/openai-transport-params-ildrm49s.mjs +0 -735
  104. package/dist/openai-web-search-tools-Cfu0uLyN.mjs +0 -14
  105. package/dist/provider-replay-context-ywPKKLjL.mjs +0 -25
  106. package/dist/types-Dlz-8qcy.d.mts +0 -1
@@ -1,5 +1,5 @@
1
- import "./index-DJrNQnKw.mjs";
2
- import { Q as SimpleStreamOptions, n as Api, nt as StreamOptions, tt as StreamFunction } from "./types-DvzmWW8J.mjs";
1
+ import "./index-BYDvopUB.mjs";
2
+ import { Q as SimpleStreamOptions, n as Api, nt as StreamOptions, tt as StreamFunction } from "./types-Bd2T86VJ.mjs";
3
3
  //#region packages/ai/src/api-registry.d.ts
4
4
  /** Runtime stream adapter signature stored in the API provider registry. */
5
5
  type ApiStreamFunction = StreamFunction;
@@ -0,0 +1,18 @@
1
+ //#region packages/llm-core/src/utils/assistant-message-events.ts
2
+ function appendTextDeltaToAssistantMessage(message, contentIndex, delta) {
3
+ const content = [...message.content];
4
+ const currentContent = content[contentIndex];
5
+ content[contentIndex] = currentContent?.type === "text" ? {
6
+ ...currentContent,
7
+ text: currentContent.text + delta
8
+ } : {
9
+ type: "text",
10
+ text: delta
11
+ };
12
+ return {
13
+ ...message,
14
+ content
15
+ };
16
+ }
17
+ //#endregion
18
+ export { appendTextDeltaToAssistantMessage as t };
@@ -1,5 +1,5 @@
1
- import { c as transformMessages } from "./host-JpNulOOs.mjs";
2
- import { a as createEmptyTransportUsage } from "./transport-stream-shared-C5TAc3U_.mjs";
1
+ import { c as transformMessages } from "./host-JWXZWa-c.mjs";
2
+ import { a as createEmptyTransportUsage } from "./transport-stream-shared-DH08b7Il.mjs";
3
3
  //#region packages/ai/src/provider-transcript-transform.ts
4
4
  const IMAGE_OMISSION = "(image omitted: model does not support images)";
5
5
  const VIDEO_OMISSION = "(video omitted: provider does not support video input)";
@@ -1,4 +1,4 @@
1
- import { t as encodeTextSignatureV1 } from "./text-signature-rOn31nxc.mjs";
1
+ import { t as encodeTextSignatureV1 } from "./text-signature-B_MB6U_9.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region packages/ai/src/utils/assistant-text-phase.ts
4
4
  const EMPTY_ASSISTANT_TEXT_BLOCK_SET = /* @__PURE__ */ new Set();
@@ -7,7 +7,8 @@ function isAssistantTextPhaseBlock(block) {
7
7
  const record = block;
8
8
  return record.type === "text" && typeof record.text === "string";
9
9
  }
10
- function tagUnphasedText(content, phase, idPrefix) {
10
+ function tagUnphasedText(content, phase) {
11
+ const idPrefix = phase === "commentary" ? "commentary" : "final-answer";
11
12
  const textBlocks = content.filter(isAssistantTextPhaseBlock);
12
13
  let phaseIndex = textBlocks.filter((block) => block.textSignature !== void 0).length;
13
14
  const tagged = /* @__PURE__ */ new Map();
@@ -22,7 +23,7 @@ function tagUnphasedText(content, phase, idPrefix) {
22
23
  }
23
24
  /** Tags unphased narration before a tool-call event becomes consumer-visible. */
24
25
  function tagPendingCommentaryText(content) {
25
- return tagUnphasedText(content, "commentary", "commentary");
26
+ return tagUnphasedText(content, "commentary");
26
27
  }
27
28
  /** Records the confirmed final-answer boundary after reasoning resumes. */
28
29
  function tagInterruptedTextPhases(content, interruptedText, preservedVisibleText = EMPTY_ASSISTANT_TEXT_BLOCK_SET) {
@@ -30,12 +31,12 @@ function tagInterruptedTextPhases(content, interruptedText, preservedVisibleText
30
31
  if (interruptedTextIndex === -1) return;
31
32
  const finalAnswerIndex = content.findIndex((block, index) => index > interruptedTextIndex && isAssistantTextPhaseBlock(block) && block.text.trim().length > 0);
32
33
  if (finalAnswerIndex === -1) return;
33
- tagUnphasedText(content.slice(0, finalAnswerIndex).filter((block) => !preservedVisibleText.has(block)), "commentary", "commentary");
34
- tagUnphasedText(content.filter((block, index) => index >= finalAnswerIndex || preservedVisibleText.has(block)), "final_answer", "final-answer");
34
+ tagUnphasedText(content.slice(0, finalAnswerIndex).filter((block) => !preservedVisibleText.has(block)), "commentary");
35
+ tagUnphasedText(content.filter((block, index) => index >= finalAnswerIndex || preservedVisibleText.has(block)), "final_answer");
35
36
  }
36
37
  /** Prevents unresolved completion text from becoming a fallback answer after stream failure. */
37
38
  function tagUnresolvedTextAsCommentary(message) {
38
- if (message.openclawDelivery?.textPhaseRequiresTerminal) tagUnphasedText(message.content, "commentary", "commentary");
39
+ if (message.openclawDelivery?.textPhaseRequiresTerminal) tagUnphasedText(message.content, "commentary");
39
40
  }
40
41
  /** Rolls back only the exact provisional signatures created by this transport turn. */
41
42
  function clearPendingCommentaryText(tags) {
@@ -1,12 +1,11 @@
1
- import { t as AssistantMessageEventStream } from "./event-stream-C5AbCAaZ.mjs";
2
- import { r as getAiTransportHost } from "./host-JpNulOOs.mjs";
3
- import { n as buildBaseOptions } from "./simple-options-wW3117Fu.mjs";
4
- import { g as resolveOpenAISimpleReasoningEffort, k as resolvePromptCacheKey } from "./openai-transport-params-ildrm49s.mjs";
5
- import { n as getEnvApiKey } from "./env-api-keys-CyX4VKGO.mjs";
6
- import { t as createAssistantOutput } from "./assistant-output-mJ9cL4Qg.mjs";
7
- import { P as convertProviderResponsesMessages, r as runResponsesStreamLifecycle, t as applyCommonResponsesParams } from "./openai-responses-shared-TCJRAoMW.mjs";
1
+ import { t as AssistantMessageEventStream } from "./event-stream-X2gmsUWv.mjs";
2
+ import { r as getAiTransportHost } from "./host-JWXZWa-c.mjs";
3
+ import { n as buildBaseOptions } from "./simple-options-BARFAzk9.mjs";
4
+ import { F as convertProviderResponsesMessages, Ft as resolvePromptCacheKey, _t as resolveOpenAISimpleReasoningEffort, r as runResponsesStreamLifecycle, t as applyCommonResponsesParams } from "./openai-responses-shared-DVGhq5xF.mjs";
5
+ import { n as getEnvApiKey } from "./env-api-keys-CrxwdylR.mjs";
6
+ import { t as createAssistantOutput } from "./assistant-output-CUEeSotf.mjs";
8
7
  import { i as resolveAzureDeploymentNameFromMap, n as isTraditionalAzureOpenAIHost, t as isOpenAICompatibleAzureResponsesBaseUrl } from "./azure-openai-responses-client-compat-D0dvJMbZ.mjs";
9
- import { t as requireApiKey } from "./required-api-key-D4kn3252.mjs";
8
+ import { t as requireApiKey } from "./required-api-key-CFJvcFy_.mjs";
10
9
  import OpenAI, { AzureOpenAI } from "openai";
11
10
  //#region packages/ai/src/providers/azure-openai-responses.ts
12
11
  const DEFAULT_AZURE_API_VERSION = "v1";
@@ -98,7 +97,7 @@ function createClient(model, apiKeyInput, options) {
98
97
  apiVersion
99
98
  });
100
99
  }
101
- function buildParams(model, context, options, deploymentName, replayMode = "checkpoint") {
100
+ function buildParams(model, context, options, deploymentName, replayMode) {
102
101
  const params = {
103
102
  model: deploymentName,
104
103
  input: convertProviderResponsesMessages(model, context, AZURE_TOOL_CALL_PROVIDERS, {
@@ -1,4 +1,6 @@
1
1
  //#region packages/ai/src/utils/credential-redaction.d.ts
2
+ /** Classifies credential-bearing fields, including case-insensitive HTTP header names. */
3
+ declare function isCredentialFieldName(name: string): boolean;
2
4
  type DiagnosticMediaField = {
3
5
  kind: "context";
4
6
  } | {
@@ -21,4 +23,4 @@ declare function projectDiagnosticValue(value: unknown, policy?: DiagnosticProje
21
23
  nodesRemaining: number;
22
24
  }): unknown;
23
25
  //#endregion
24
- export { createDiagnosticRecord as n, projectDiagnosticValue as r, DiagnosticProjectionPolicy as t };
26
+ export { projectDiagnosticValue as i, createDiagnosticRecord as n, isCredentialFieldName as r, DiagnosticProjectionPolicy as t };
@@ -1,8 +1,8 @@
1
1
  import { a as isProviderRefusalAssistantError } from "./diagnostics-DzrF1h4J.mjs";
2
2
  import { i as asOptionalRecord, o as isRecord } from "./record-coerce-CNDovvft.mjs";
3
3
  import { n as normalizeLowercaseStringOrEmpty } from "./string-coerce-CtgOVOSv.mjs";
4
- import { n as asNonNegativeFiniteNumber, t as asFiniteNumber } from "./number-coercion-V8-BhME4.mjs";
5
- import "./provider-error-DQBE1bUQ.mjs";
4
+ import { n as asNonNegativeFiniteNumber, t as asFiniteNumber } from "./number-coercion-C3hztWoY.mjs";
5
+ import "./provider-error-CF9GWCs2.mjs";
6
6
  //#region packages/normalization-core/src/error-coercion.ts
7
7
  function readProperty(value, key) {
8
8
  try {
@@ -301,6 +301,13 @@ function emitModelTransportDebug(log, message) {
301
301
  }
302
302
  log.debug(message);
303
303
  }
304
+ /** The requesting layer owns AbortError classification; deadlines remain failures here. */
305
+ function emitModelTransportError(log, label, detail, signal) {
306
+ const aborted = signal?.aborted === true && signal.reason instanceof Error && signal.reason.name === "AbortError";
307
+ const message = `[${label}] ${aborted ? "aborted" : "error"} ${detail}`;
308
+ if (aborted) emitModelTransportDebug(log, message);
309
+ else log.warn(message);
310
+ }
304
311
  //#endregion
305
312
  //#region packages/ai/src/transports/model-transport-url.ts
306
313
  /**
@@ -322,4 +329,4 @@ function formatModelTransportDebugBaseUrl(rawUrl) {
322
329
  return rawUrl ? formatModelTransportDebugUrl(rawUrl) : "default";
323
330
  }
324
331
  //#endregion
325
- export { extractErrorCodeOrErrno as _, resolveModelSseDebugMode as a, isTransientNetworkError as c, isResponsesProviderTool as d, resolveResponsesOutputIdentityRetry as f, resolveResponsesTerminalStopReason as g, readResponsesReasoningTokens as h, resolveModelPayloadDebugMode as i, ResponsesOutputIdentityError as l, mapResponsesTerminalUsage as m, formatModelTransportDebugUrl as n, WEBSOCKET_NON_RETRYABLE_CLOSE_ERROR_CODE as o, isResponsesOutputLimitToolCallError as p, emitModelTransportDebug as r, hasRetryableConnectionErrorCode as s, formatModelTransportDebugBaseUrl as t, hasOnlyResponsesFunctionTools as u, toErrorObject as v };
332
+ export { resolveResponsesTerminalStopReason as _, resolveModelPayloadDebugMode as a, hasRetryableConnectionErrorCode as c, hasOnlyResponsesFunctionTools as d, isResponsesProviderTool as f, readResponsesReasoningTokens as g, mapResponsesTerminalUsage as h, emitModelTransportError as i, isTransientNetworkError as l, isResponsesOutputLimitToolCallError as m, formatModelTransportDebugUrl as n, resolveModelSseDebugMode as o, resolveResponsesOutputIdentityRetry as p, emitModelTransportDebug as r, WEBSOCKET_NON_RETRYABLE_CLOSE_ERROR_CODE as s, formatModelTransportDebugBaseUrl as t, ResponsesOutputIdentityError as u, extractErrorCodeOrErrno as v, toErrorObject as y };
@@ -1,10 +1,10 @@
1
- import { a as ProviderRefusalReview, o as readProviderRefusalReview } from "./index-DJrNQnKw.mjs";
2
- import { At as extractDiagnosticError, Dt as DiagnosticErrorInfo, Et as AssistantMessageDiagnostic, Mt as isProviderRefusalAssistantError, Ot as appendAssistantMessageDiagnostic, a as AssistantMessage, jt as formatThrownValue, kt as createAssistantMessageDiagnostic } from "./types-DvzmWW8J.mjs";
3
- import "./types-Dlz-8qcy.mjs";
4
- import { n as isResponsesOutputLimitToolCallError } from "./openai-responses-terminal-usage-BVvyXZ8u.mjs";
1
+ import { o as ProviderRefusalReview, s as readProviderRefusalReview } from "./index-BYDvopUB.mjs";
2
+ import { At as extractDiagnosticError, Dt as DiagnosticErrorInfo, Et as AssistantMessageDiagnostic, Mt as isProviderRefusalAssistantError, Ot as appendAssistantMessageDiagnostic, a as AssistantMessage, jt as formatThrownValue, kt as createAssistantMessageDiagnostic } from "./types-Bd2T86VJ.mjs";
3
+ import "./types-Kdfw_04V.mjs";
4
+ import { n as isResponsesOutputLimitToolCallError } from "./openai-responses-terminal-usage-BygjiAdi.mjs";
5
5
  import { n as ProviderErrorRedactor, r as configureProviderErrorRedactor } from "./provider-error-xumb1V3F.mjs";
6
- import { r as projectDiagnosticValue, t as DiagnosticProjectionPolicy } from "./credential-redaction-BKv49aiv.mjs";
7
- import { n as formatModelTransportDebugUrl, r as emitModelTransportDebug, t as formatModelTransportDebugBaseUrl } from "./model-transport-url-C5f59L3Y.mjs";
6
+ import { i as projectDiagnosticValue, t as DiagnosticProjectionPolicy } from "./credential-redaction-BHxruEH6.mjs";
7
+ import { i as emitModelTransportError, n as formatModelTransportDebugUrl, r as emitModelTransportDebug, t as formatModelTransportDebugBaseUrl } from "./model-transport-url-BrsjjdjR.mjs";
8
8
  //#region packages/ai/src/transports/openai-responses-stream-errors.d.ts
9
9
  /** Resume only a response that could not have completed tools or exposed visible output. */
10
10
  export declare function resolveResponsesOutputIdentityRetry(message: Pick<AssistantMessage, "errorCode"> & Partial<Pick<AssistantMessage, "stopReason" | "errorBody" | "content">>): "retry" | "stop" | undefined;
@@ -15,4 +15,4 @@ export declare function hasRetryableConnectionErrorCode(message: string): boolea
15
15
  /** Returns true when any nested error proves a transient network failure. */
16
16
  export declare function isTransientNetworkError(err: unknown): boolean;
17
17
  //#endregion
18
- export { AssistantMessageDiagnostic, DiagnosticErrorInfo, type DiagnosticProjectionPolicy, type ProviderErrorRedactor, type ProviderRefusalReview, appendAssistantMessageDiagnostic, configureProviderErrorRedactor, createAssistantMessageDiagnostic, emitModelTransportDebug, extractDiagnosticError, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, formatThrownValue, isProviderRefusalAssistantError, isResponsesOutputLimitToolCallError, projectDiagnosticValue, readProviderRefusalReview };
18
+ export { AssistantMessageDiagnostic, DiagnosticErrorInfo, type DiagnosticProjectionPolicy, type ProviderErrorRedactor, type ProviderRefusalReview, appendAssistantMessageDiagnostic, configureProviderErrorRedactor, createAssistantMessageDiagnostic, emitModelTransportDebug, emitModelTransportError, extractDiagnosticError, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, formatThrownValue, isProviderRefusalAssistantError, isResponsesOutputLimitToolCallError, projectDiagnosticValue, readProviderRefusalReview };
@@ -1,4 +1,4 @@
1
1
  import { a as isProviderRefusalAssistantError, i as formatThrownValue, n as createAssistantMessageDiagnostic, o as readProviderRefusalReview, r as extractDiagnosticError, t as appendAssistantMessageDiagnostic } from "./diagnostics-DzrF1h4J.mjs";
2
- import { i as projectDiagnosticValue, t as configureProviderErrorRedactor } from "./provider-error-DQBE1bUQ.mjs";
3
- import { c as isTransientNetworkError, f as resolveResponsesOutputIdentityRetry, n as formatModelTransportDebugUrl, o as WEBSOCKET_NON_RETRYABLE_CLOSE_ERROR_CODE, p as isResponsesOutputLimitToolCallError, r as emitModelTransportDebug, s as hasRetryableConnectionErrorCode, t as formatModelTransportDebugBaseUrl } from "./diagnostics-Caj-4RBA.mjs";
4
- export { WEBSOCKET_NON_RETRYABLE_CLOSE_ERROR_CODE, appendAssistantMessageDiagnostic, configureProviderErrorRedactor, createAssistantMessageDiagnostic, emitModelTransportDebug, extractDiagnosticError, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, formatThrownValue, hasRetryableConnectionErrorCode, isProviderRefusalAssistantError, isResponsesOutputLimitToolCallError, isTransientNetworkError, projectDiagnosticValue, readProviderRefusalReview, resolveResponsesOutputIdentityRetry };
2
+ import { a as projectDiagnosticValue, t as configureProviderErrorRedactor } from "./provider-error-CF9GWCs2.mjs";
3
+ import { c as hasRetryableConnectionErrorCode, i as emitModelTransportError, l as isTransientNetworkError, m as isResponsesOutputLimitToolCallError, n as formatModelTransportDebugUrl, p as resolveResponsesOutputIdentityRetry, r as emitModelTransportDebug, s as WEBSOCKET_NON_RETRYABLE_CLOSE_ERROR_CODE, t as formatModelTransportDebugBaseUrl } from "./diagnostics-tQasYct1.mjs";
4
+ export { WEBSOCKET_NON_RETRYABLE_CLOSE_ERROR_CODE, appendAssistantMessageDiagnostic, configureProviderErrorRedactor, createAssistantMessageDiagnostic, emitModelTransportDebug, emitModelTransportError, extractDiagnosticError, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, formatThrownValue, hasRetryableConnectionErrorCode, isProviderRefusalAssistantError, isResponsesOutputLimitToolCallError, isTransientNetworkError, projectDiagnosticValue, readProviderRefusalReview, resolveResponsesOutputIdentityRetry };
@@ -1,8 +1,6 @@
1
1
  import { n as __require } from "./rolldown-runtime-BhDjJH2R.mjs";
2
2
  //#region packages/ai/src/env-api-keys.ts
3
- let existsSync = null;
4
- let homedir = null;
5
- let join = null;
3
+ let nodeHelpers;
6
4
  const dynamicImport = (specifier) => import(specifier);
7
5
  const NODE_FS_SPECIFIER = "node:fs";
8
6
  const NODE_OS_SPECIFIER = "node:os";
@@ -18,27 +16,26 @@ function loadNodeHelpersSync() {
18
16
  const fsModule = loadNodeBuiltinModule(NODE_FS_SPECIFIER);
19
17
  const osModule = loadNodeBuiltinModule(NODE_OS_SPECIFIER);
20
18
  const pathModule = loadNodeBuiltinModule(NODE_PATH_SPECIFIER);
21
- existsSync ??= fsModule?.existsSync ?? null;
22
- homedir ??= osModule?.homedir ?? null;
23
- join ??= pathModule?.join ?? null;
24
- if (!existsSync || !homedir || !join) return false;
25
- return true;
26
- } catch {
27
- return false;
28
- }
19
+ if (fsModule && osModule && pathModule) nodeHelpers = {
20
+ existsSync: fsModule.existsSync,
21
+ homedir: osModule.homedir,
22
+ join: pathModule.join
23
+ };
24
+ } catch {}
25
+ return nodeHelpers;
29
26
  }
30
27
  if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
31
- if (!loadNodeHelpersSync()) {
32
- dynamicImport(NODE_FS_SPECIFIER).then((m) => {
33
- existsSync = m.existsSync;
34
- });
35
- dynamicImport(NODE_OS_SPECIFIER).then((m) => {
36
- homedir = m.homedir;
37
- });
38
- dynamicImport(NODE_PATH_SPECIFIER).then((m) => {
39
- join = m.join;
40
- });
41
- }
28
+ if (!loadNodeHelpersSync()) Promise.all([
29
+ dynamicImport(NODE_FS_SPECIFIER),
30
+ dynamicImport(NODE_OS_SPECIFIER),
31
+ dynamicImport(NODE_PATH_SPECIFIER)
32
+ ]).then(([fsModule, osModule, pathModule]) => {
33
+ nodeHelpers = {
34
+ existsSync: fsModule.existsSync,
35
+ homedir: osModule.homedir,
36
+ join: pathModule.join
37
+ };
38
+ });
42
39
  }
43
40
  let procEnvCache = null;
44
41
  function getProcessEnv() {
@@ -51,9 +48,7 @@ function getProcessEnv() {
51
48
  */
52
49
  function getProcEnv(key) {
53
50
  if (typeof process === "undefined" || !process.versions?.bun) return;
54
- const env = getProcessEnv();
55
- if (!env) return;
56
- if (Object.keys(env).length > 0) return;
51
+ if (Object.keys(process.env).length > 0) return;
57
52
  if (procEnvCache === null) {
58
53
  procEnvCache = /* @__PURE__ */ new Map();
59
54
  try {
@@ -74,16 +69,10 @@ function getEnvValue(key) {
74
69
  let cachedVertexAdcCredentialsExists = null;
75
70
  function hasVertexAdcCredentials() {
76
71
  if (cachedVertexAdcCredentialsExists === null) {
77
- if (!existsSync || !homedir || !join) {
78
- if (!(typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) || !loadNodeHelpersSync()) return false;
79
- }
80
- const nodeExistsSync = existsSync;
81
- const nodeHomedir = homedir;
82
- const nodeJoin = join;
83
- if (!nodeExistsSync || !nodeHomedir || !nodeJoin) return false;
84
- const gacPath = getEnvValue("GOOGLE_APPLICATION_CREDENTIALS");
85
- if (gacPath) cachedVertexAdcCredentialsExists = nodeExistsSync(gacPath) ? true : null;
86
- else cachedVertexAdcCredentialsExists = nodeExistsSync(nodeJoin(nodeHomedir(), ".config", "gcloud", "application_default_credentials.json")) ? true : null;
72
+ const helpers = nodeHelpers ?? (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun) ? loadNodeHelpersSync() : void 0);
73
+ if (!helpers) return false;
74
+ const { existsSync, homedir, join } = helpers;
75
+ cachedVertexAdcCredentialsExists = existsSync(getEnvValue("GOOGLE_APPLICATION_CREDENTIALS") ?? join(homedir(), ".config", "gcloud", "application_default_credentials.json")) ? true : null;
87
76
  }
88
77
  return cachedVertexAdcCredentialsExists === true;
89
78
  }
@@ -0,0 +1 @@
1
+ import "./event-stream-BcqWLo_u.mjs";
@@ -1,4 +1,4 @@
1
- import { a as AssistantMessage, o as AssistantMessageEvent, ot as ThinkingContent, s as AssistantMessageEventStreamContract } from "./types-DvzmWW8J.mjs";
1
+ import { a as AssistantMessage, o as AssistantMessageEvent, ot as ThinkingContent, s as AssistantMessageEventStreamContract } from "./types-Bd2T86VJ.mjs";
2
2
  //#region packages/llm-core/src/utils/event-stream.d.ts
3
3
  /** Returns only an append whose current and previously observed snapshots still match. */
4
4
  declare function readAssistantThinkingAppend(block: ThinkingContent, previous: string): string | undefined;
@@ -88,14 +88,11 @@ var EventStream = class {
88
88
  this.finalResultPromise.catch(() => {});
89
89
  this.rejectFinalResult(/* @__PURE__ */ new Error("event stream ended without a terminal event or final result"));
90
90
  }
91
- while (this.waiting.length > 0) {
92
- const waiter = this.waiting.shift();
93
- if (!waiter) break;
94
- waiter({
95
- value: void 0,
96
- done: true
97
- });
98
- }
91
+ for (const waiter of this.waiting) waiter({
92
+ value: void 0,
93
+ done: true
94
+ });
95
+ this.waiting = [];
99
96
  }
100
97
  async *[Symbol.asyncIterator]() {
101
98
  while (true) if (this.queueHead < this.queue.length) {
@@ -1,3 +1,3 @@
1
- import { n as EventStream, r as createAssistantMessageEventStream, t as AssistantMessageEventStream } from "./event-stream-DrRM_90c.mjs";
2
- import "./event-stream-DqDQWqiy.mjs";
1
+ import { n as EventStream, r as createAssistantMessageEventStream, t as AssistantMessageEventStream } from "./event-stream-BcqWLo_u.mjs";
2
+ import "./event-stream-6UNs-AhN.mjs";
3
3
  export { AssistantMessageEventStream, EventStream, createAssistantMessageEventStream };
@@ -1,2 +1,2 @@
1
- import { a as createAssistantMessageEventStream, n as EventStream, t as AssistantMessageEventStream } from "./event-stream-C5AbCAaZ.mjs";
1
+ import { a as createAssistantMessageEventStream, n as EventStream, t as AssistantMessageEventStream } from "./event-stream-X2gmsUWv.mjs";
2
2
  export { AssistantMessageEventStream, EventStream, createAssistantMessageEventStream };
@@ -0,0 +1,20 @@
1
+ import { r as getAiTransportHost } from "./host-JWXZWa-c.mjs";
2
+ import { n as getEnvApiKey } from "./env-api-keys-CrxwdylR.mjs";
3
+ import { n as resolveOpencodeSessionHeaders } from "./session-affinity-DA4WHv1h.mjs";
4
+ import { t as requireApiKey } from "./required-api-key-CFJvcFy_.mjs";
5
+ import { n as buildGoogleHttpOptions, t as createGoogleGenerateContentStreams } from "./google-provider-stream-CMImyxbX.mjs";
6
+ import { GoogleGenAI } from "@google/genai";
7
+ //#region packages/ai/src/providers/google.ts
8
+ const { stream: streamGoogle, streamSimple: streamSimpleGoogle } = createGoogleGenerateContentStreams("google-generative-ai", (model, options) => {
9
+ return createClient(model, options?.apiKey || getEnvApiKey(model.provider) || "", resolveOpencodeSessionHeaders(model, options));
10
+ }, (model, options) => requireApiKey(model.provider, options?.apiKey));
11
+ function createClient(model, apiKey, optionsHeaders) {
12
+ const httpOptions = buildGoogleHttpOptions(model, optionsHeaders, "generative-ai");
13
+ const resolvedApiKey = apiKey ? getAiTransportHost().resolveSecretSentinel(apiKey) : void 0;
14
+ return new GoogleGenAI({
15
+ apiKey: resolvedApiKey,
16
+ httpOptions
17
+ });
18
+ }
19
+ //#endregion
20
+ export { streamGoogle, streamSimpleGoogle };
@@ -1,12 +1,12 @@
1
- import { t as AssistantMessageEventStream } from "./event-stream-C5AbCAaZ.mjs";
1
+ import { t as AssistantMessageEventStream } from "./event-stream-X2gmsUWv.mjs";
2
2
  import { a as asRecord, i as asOptionalRecord, s as readStringField } from "./record-coerce-CNDovvft.mjs";
3
- import { O as calculateCost, a as resolveAiTransportHeaderSentinels, r as getAiTransportHost } from "./host-JpNulOOs.mjs";
4
- import { t as buildGuardedModelFetch } from "./host-policy-CC5H0iRZ.mjs";
5
- import { P as sanitizeSurrogates, b as transportAbortError, c as failTransportStream, g as parseTerminalToolCallArguments, h as notifyProviderStreamOpened, m as notifyProviderHttpResponse, w as parseJsonPreservingUnsafeIntegers } from "./transport-stream-shared-C5TAc3U_.mjs";
6
- import { C as stripSystemPromptCacheBoundary, n as buildBaseOptions } from "./simple-options-wW3117Fu.mjs";
7
- import { n as getEnvApiKey } from "./env-api-keys-CyX4VKGO.mjs";
8
- import { n as transformProviderMessages, t as createAssistantOutput } from "./assistant-output-mJ9cL4Qg.mjs";
9
- import { n as buildGoogleInteractionsSimpleThinking } from "./google-shared-DE_ddfsC.mjs";
3
+ import { O as calculateCost, a as resolveAiTransportHeaderSentinels, r as getAiTransportHost } from "./host-JWXZWa-c.mjs";
4
+ import { t as buildGuardedModelFetch } from "./host-policy-q4Azym9F.mjs";
5
+ import { P as sanitizeSurrogates, b as transportAbortError, c as failTransportStream, g as parseTerminalToolCallArguments, h as notifyProviderStreamOpened, m as notifyProviderHttpResponse, w as parseJsonPreservingUnsafeIntegers } from "./transport-stream-shared-DH08b7Il.mjs";
6
+ import { C as stripSystemPromptCacheBoundary, n as buildBaseOptions } from "./simple-options-BARFAzk9.mjs";
7
+ import { n as getEnvApiKey } from "./env-api-keys-CrxwdylR.mjs";
8
+ import { n as transformProviderMessages, t as createAssistantOutput } from "./assistant-output-CUEeSotf.mjs";
9
+ import { n as buildGoogleInteractionsSimpleThinking } from "./google-shared-OyAtMTZv.mjs";
10
10
  import { createRequire } from "node:module";
11
11
  //#region packages/ai/src/providers/google-interactions-request.ts
12
12
  const DEFAULT_GOOGLE_API_BASE_URL = "https://generativelanguage.googleapis.com";
@@ -50,21 +50,6 @@ function resolveGoogleApiClientHeaders(params) {
50
50
  "x-goog-api-client": `openclaw/${resolvePackageVersion()}`
51
51
  };
52
52
  }
53
- function convertToolResultContent(content) {
54
- if (!Array.isArray(content)) return content;
55
- return content.map((item) => {
56
- if (item.type === "image") return {
57
- type: "image",
58
- mime_type: item.mimeType,
59
- data: item.data
60
- };
61
- if (item.type === "text") return {
62
- type: "text",
63
- text: sanitizeSurrogates(item.text)
64
- };
65
- return item;
66
- });
67
- }
68
53
  function convertMessages(model, context) {
69
54
  const steps = [];
70
55
  const messages = transformProviderMessages(context.messages, model);
@@ -96,7 +81,14 @@ function convertMessages(model, context) {
96
81
  type: "function_result",
97
82
  call_id: message.toolCallId,
98
83
  name: message.toolName || "tool",
99
- result: convertToolResultContent(message.content),
84
+ result: message.content.map((item) => item.type === "image" ? {
85
+ type: "image",
86
+ mime_type: item.mimeType,
87
+ data: item.data
88
+ } : {
89
+ type: "text",
90
+ text: sanitizeSurrogates(item.text)
91
+ }),
100
92
  is_error: message.isError
101
93
  });
102
94
  continue;
@@ -141,7 +133,7 @@ function convertMessages(model, context) {
141
133
  type: "function_call",
142
134
  id: block.id,
143
135
  name: block.name,
144
- arguments: block.arguments ?? {}
136
+ arguments: block.arguments
145
137
  });
146
138
  }
147
139
  flushText();
@@ -184,8 +176,8 @@ function buildGoogleInteractionsParams(model, context, options = {}) {
184
176
  * Gemini Interactions API adapter and lifecycle for OpenClaw.
185
177
  * POST /v1beta/interactions
186
178
  */
187
- function resolveGoogleInteractionsApiKey(model, options, apiKey) {
188
- return apiKey || options?.apiKey || getEnvApiKey(model.provider) || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || "";
179
+ function resolveGoogleInteractionsApiKey(model, options) {
180
+ return options?.apiKey || getEnvApiKey(model.provider) || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || "";
189
181
  }
190
182
  function logGoogleInteractionsDebug(message, data) {
191
183
  getAiTransportHost().logDebug("google-interactions", () => ({
@@ -206,7 +198,7 @@ async function runGoogleInteractionsLifecycle(params) {
206
198
  let reader;
207
199
  try {
208
200
  const host = getAiTransportHost();
209
- const unresolvedApiKey = resolveGoogleInteractionsApiKey(model, options, params.apiKey);
201
+ const unresolvedApiKey = resolveGoogleInteractionsApiKey(model, options);
210
202
  const apiKey = host.resolveSecretSentinel(unresolvedApiKey);
211
203
  if (!apiKey.trim()) throw new Error(`No API key for provider: ${model.provider}`);
212
204
  let body = buildGoogleInteractionsParams(model, context, options);
@@ -276,57 +268,48 @@ async function runGoogleInteractionsLifecycle(params) {
276
268
  });
277
269
  const decoder = new TextDecoder();
278
270
  let buffer = "";
279
- let currentBlockType = null;
271
+ let currentBlock = null;
280
272
  let currentBlockIndex = -1;
281
- let currentToolCall = null;
282
273
  let currentToolArgs = "";
283
274
  let latestThoughtSignature;
284
275
  let latestUsage;
285
276
  const endCurrentBlock = () => {
286
- if (currentBlockType === "text") {
287
- const block = output.content[currentBlockIndex];
288
- const textBlock = block?.type === "text" ? block : void 0;
277
+ if (!currentBlock) return;
278
+ if (currentBlock.type === "toolCall") {
279
+ if (currentToolArgs.trim()) currentBlock.arguments = parseTerminalToolCallArguments(currentToolArgs);
289
280
  stream.push({
290
- type: "text_end",
291
- contentIndex: currentBlockIndex,
292
- content: textBlock?.text ?? "",
293
- partial: output
294
- });
295
- } else if (currentBlockType === "thinking") {
296
- const block = output.content[currentBlockIndex];
297
- const thinkingBlock = block?.type === "thinking" ? block : void 0;
298
- if (thinkingBlock && !thinkingBlock.thinkingSignature && latestThoughtSignature) thinkingBlock.thinkingSignature = latestThoughtSignature;
299
- stream.push({
300
- type: "thinking_end",
281
+ type: "toolcall_end",
301
282
  contentIndex: currentBlockIndex,
302
- content: thinkingBlock?.thinking ?? "",
283
+ toolCall: currentBlock,
303
284
  partial: output
304
285
  });
305
- latestThoughtSignature = void 0;
306
- } else if (currentBlockType === "toolCall" && currentToolCall) {
307
- if (currentToolArgs.trim()) currentToolCall.arguments = parseTerminalToolCallArguments(currentToolArgs);
286
+ currentToolArgs = "";
287
+ } else {
288
+ if (currentBlock.type === "thinking") {
289
+ if (!currentBlock.thinkingSignature && latestThoughtSignature) currentBlock.thinkingSignature = latestThoughtSignature;
290
+ latestThoughtSignature = void 0;
291
+ }
308
292
  stream.push({
309
- type: "toolcall_end",
293
+ type: currentBlock.type === "text" ? "text_end" : "thinking_end",
310
294
  contentIndex: currentBlockIndex,
311
- toolCall: currentToolCall,
295
+ content: currentBlock.type === "text" ? currentBlock.text : currentBlock.thinking,
312
296
  partial: output
313
297
  });
314
- currentToolCall = null;
315
- currentToolArgs = "";
316
298
  }
317
- currentBlockType = null;
299
+ currentBlock = null;
318
300
  };
319
301
  const startTextBlock = (type, text = "") => {
320
302
  endCurrentBlock();
321
303
  currentBlockIndex = output.content.length;
322
- output.content.push(type === "text" ? {
304
+ const block = type === "text" ? {
323
305
  type,
324
306
  text
325
307
  } : {
326
308
  type,
327
309
  thinking: text,
328
310
  ...latestThoughtSignature ? { thinkingSignature: latestThoughtSignature } : {}
329
- });
311
+ };
312
+ output.content.push(block);
330
313
  stream.push({
331
314
  type: type === "text" ? "text_start" : "thinking_start",
332
315
  contentIndex: currentBlockIndex,
@@ -338,19 +321,14 @@ async function runGoogleInteractionsLifecycle(params) {
338
321
  delta: text,
339
322
  partial: output
340
323
  });
341
- return type;
324
+ return block;
342
325
  };
343
326
  const appendTextDelta = (type, text) => {
344
327
  if (!text) return;
345
- if (currentBlockType !== type) currentBlockType = startTextBlock(type);
346
- const block = output.content[currentBlockIndex];
347
- if (type === "text") {
348
- if (block?.type !== "text") throw new Error("Google Interactions text delta has no active text block");
349
- block.text += text;
350
- } else {
351
- if (block?.type !== "thinking") throw new Error("Google Interactions thought delta has no active thought block");
352
- block.thinking += text;
353
- }
328
+ const block = currentBlock?.type === type ? currentBlock : startTextBlock(type);
329
+ currentBlock = block;
330
+ if (block.type === "text") block.text += text;
331
+ else block.thinking += text;
354
332
  stream.push({
355
333
  type: type === "text" ? "text_delta" : "thinking_delta",
356
334
  contentIndex: currentBlockIndex,
@@ -423,10 +401,8 @@ async function runGoogleInteractionsLifecycle(params) {
423
401
  const signature = readStringField(delta, "signature") ?? "";
424
402
  if (signature) {
425
403
  latestThoughtSignature = signature;
426
- if (currentBlockType === "thinking") {
427
- const block = output.content[currentBlockIndex];
428
- if (block?.type === "thinking") block.thinkingSignature = signature;
429
- } else {
404
+ if (currentBlock?.type === "thinking") currentBlock.thinkingSignature = signature;
405
+ else {
430
406
  const lastThinking = output.content.findLast((block) => block.type === "thinking");
431
407
  if (lastThinking && !lastThinking.thinkingSignature) lastThinking.thinkingSignature = signature;
432
408
  else if (!lastThinking) output.content.push({
@@ -438,14 +414,11 @@ async function runGoogleInteractionsLifecycle(params) {
438
414
  }
439
415
  } else if (deltaType === "arguments" || deltaType === "arguments_delta") {
440
416
  const argText = readStringField(delta, "arguments") ?? readStringField(delta, "text") ?? "";
441
- if (currentBlockType !== "toolCall") {
442
- currentToolCall = startToolCallBlock(delta);
443
- currentBlockType = "toolCall";
444
- }
417
+ if (currentBlock?.type !== "toolCall") currentBlock = startToolCallBlock(delta);
445
418
  const streamedToolName = readStringField(delta, "name");
446
- if (streamedToolName && currentToolCall && (!currentToolCall.name || currentToolCall.name === "tool")) currentToolCall.name = streamedToolName;
419
+ if (streamedToolName && (!currentBlock.name || currentBlock.name === "tool")) currentBlock.name = streamedToolName;
447
420
  const streamedToolCallId = readStringField(delta, "id");
448
- if (streamedToolCallId && currentToolCall) currentToolCall.id = streamedToolCallId;
421
+ if (streamedToolCallId) currentBlock.id = streamedToolCallId;
449
422
  currentToolArgs += argText;
450
423
  stream.push({
451
424
  type: "toolcall_delta",
@@ -460,12 +433,9 @@ async function runGoogleInteractionsLifecycle(params) {
460
433
  const stepSignature = readStringField(step, "signature");
461
434
  if (stepSignature) latestThoughtSignature = stepSignature;
462
435
  const initialThinking = joinTextParts(step.summary);
463
- if (currentBlockType !== "thinking") currentBlockType = startTextBlock("thinking", initialThinking);
464
- } else if (step?.type === "model_output") currentBlockType = startTextBlock("text", joinTextParts(step.content));
465
- else if (step?.type === "function_call") {
466
- currentToolCall = startToolCallBlock(step, asRecord(step.arguments));
467
- currentBlockType = "toolCall";
468
- }
436
+ if (currentBlock?.type !== "thinking") currentBlock = startTextBlock("thinking", initialThinking);
437
+ } else if (step?.type === "model_output") currentBlock = startTextBlock("text", joinTextParts(step.content));
438
+ else if (step?.type === "function_call") currentBlock = startToolCallBlock(step, asRecord(step.arguments));
469
439
  } else if (eventType === "step.stop") {
470
440
  latestUsage = asOptionalRecord(event.usage) ?? latestUsage;
471
441
  endCurrentBlock();
@@ -511,7 +481,6 @@ async function runGoogleInteractionsLifecycle(params) {
511
481
  if (latestThoughtSignature) {
512
482
  for (const block of output.content) if (block.type === "thinking" && !block.thinkingSignature) block.thinkingSignature = latestThoughtSignature;
513
483
  }
514
- if (!output.stopReason) output.stopReason = output.content.some((b) => b.type === "toolCall") ? "toolUse" : "stop";
515
484
  if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error("An unknown error occurred");
516
485
  stream.push({
517
486
  type: "done",
@@ -546,8 +515,7 @@ const streamGoogleInteractions = (model, context, options) => {
546
515
  output: createAssistantOutput(model, "google-interactions"),
547
516
  options,
548
517
  context,
549
- nextToolCallId: (name) => `${name}_${Date.now()}_${++toolCallCounter}`,
550
- apiKey: resolveGoogleInteractionsApiKey(model, options)
518
+ nextToolCallId: (name) => `${name}_${Date.now()}_${++toolCallCounter}`
551
519
  });
552
520
  return stream;
553
521
  };