@openclaw/ai 2026.7.2-beta.2 → 2026.7.2-beta.4

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 (46) hide show
  1. package/README.md +6 -5
  2. package/dist/{anthropic-BIRSg5x9.mjs → anthropic-CrUDIBpM.mjs} +173 -47
  3. package/dist/{api-registry-Byvoz8Ha.d.mts → api-registry-BMphkFf1.d.mts} +1 -2
  4. package/dist/{azure-openai-responses-CHi7Wo4A.mjs → azure-openai-responses-CbrpVeEv.mjs} +9 -11
  5. package/dist/{env-api-keys-DnhYpc27.mjs → env-api-keys-DrgeBuva.mjs} +1 -1
  6. package/dist/{event-stream-uQspnL8S.d.mts → event-stream-Douf9dob.d.mts} +1 -1
  7. package/dist/event-stream.d.mts +1 -1
  8. package/dist/{google-BmsqsNwR.mjs → google-Cs62KA7t.mjs} +4 -4
  9. package/dist/{google-shared-Dx2aba47.mjs → google-shared-CMLI-tCZ.mjs} +4 -3
  10. package/dist/{google-vertex-HZ_0rTwS.mjs → google-vertex-B4SD3U0f.mjs} +3 -3
  11. package/dist/host-WvWBo4h8.d.mts +173 -0
  12. package/dist/host-XYGZcgO8.mjs +98 -0
  13. package/dist/index-BVVgDSdq.d.mts +1 -0
  14. package/dist/index.d.mts +7 -50
  15. package/dist/index.mjs +1 -1
  16. package/dist/internal/anthropic.d.mts +9 -3
  17. package/dist/internal/anthropic.mjs +3 -3
  18. package/dist/internal/openai.d.mts +2 -279
  19. package/dist/internal/openai.mjs +5 -5
  20. package/dist/internal/runtime.d.mts +8 -5
  21. package/dist/internal/runtime.mjs +22 -12
  22. package/dist/internal/shared.d.mts +4 -2
  23. package/dist/internal/shared.mjs +2 -2
  24. package/dist/{mistral-DxMPt9q9.mjs → mistral-D5Ps7Led.mjs} +26 -10
  25. package/dist/{model-utils-Q1LSRIdo.mjs → model-utils-1GiZ2_rr.mjs} +3 -1
  26. package/dist/openai-CoGicoDt.d.mts +332 -0
  27. package/dist/{openai-chatgpt-responses-BuH2NvsR.mjs → openai-chatgpt-responses-h0o5yV8Y.mjs} +47 -48
  28. package/dist/{openai-completions-DPR_O2RW.mjs → openai-completions-exO8NFQf.mjs} +342 -102
  29. package/dist/{openai-responses-Cov-Vdc2.mjs → openai-responses-BHpmtUKo.mjs} +5 -5
  30. package/dist/{openai-responses-shared-Befb4D6R.mjs → openai-responses-shared-CzCurmY1.mjs} +527 -268
  31. package/dist/{openai-tool-projection-CFqm42J2.mjs → openai-tool-projection-ITOU9bG1.mjs} +1 -1
  32. package/dist/provider-error-C4VvV_3t.mjs +41 -0
  33. package/dist/providers.d.mts +1 -1
  34. package/dist/providers.mjs +8 -8
  35. package/dist/{stream-first-event-timeout-RjWszj8c.mjs → stream-first-event-timeout-DP4xEyBY.mjs} +45 -1
  36. package/dist/{transform-messages-BmS70CP5.mjs → system-prompt-cache-boundary-CbHeV4_l.mjs} +171 -161
  37. package/dist/transports.d.mts +590 -0
  38. package/dist/transports.mjs +5701 -0
  39. package/dist/{types-Cx2zJtyz.d.mts → types-AFwwWium.d.mts} +7 -0
  40. package/dist/types.d.mts +4 -4
  41. package/dist/{validation-Cej7htKc.d.mts → validation-sxvxC8J-.d.mts} +1 -1
  42. package/dist/validation.d.mts +1 -1
  43. package/npm-shrinkwrap.json +43 -50
  44. package/package.json +36 -10
  45. package/dist/host-4t713IeR.mjs +0 -37
  46. /package/dist/{index-BoTnz8cv.d.mts → anthropic-BoTnz8cv.d.mts} +0 -0
package/README.md CHANGED
@@ -14,15 +14,16 @@ registerBuiltInApiProviders(runtime.registry);
14
14
 
15
15
  Provider-neutral contracts, validation, diagnostics, and event streams are
16
16
  available from the package root and focused subpaths such as
17
- `@openclaw/ai/event-stream` and `@openclaw/ai/validation`. No second OpenClaw
18
- runtime package is required.
17
+ `@openclaw/ai/event-stream`, `@openclaw/ai/transports`, and
18
+ `@openclaw/ai/validation`. No second OpenClaw runtime package is required.
19
19
 
20
20
  Provider ids, credentials, model catalogs, retries, and failover remain
21
21
  application concerns. OpenClaw supplies those policies around this package.
22
22
  Host policy (request fetch guarding, secret redaction, strict-tool defaults,
23
- diagnostics logging) can be injected with `configureAiTransportHost`; the
24
- defaults are inert.
23
+ provider plugin hooks, and diagnostics logging) can be injected with
24
+ `configureAiTransportHost`; the defaults are inert.
25
25
 
26
- `@openclaw/ai/internal/*` subpaths exist for the OpenClaw application itself.
26
+ The explicit `@openclaw/ai/internal/anthropic`, `openai`, `retry-after`,
27
+ `runtime`, and `shared` subpaths exist for the OpenClaw application itself.
27
28
  They carry no semver guarantee and can change or disappear in any release; do
28
29
  not depend on them outside OpenClaw.
@@ -1,17 +1,117 @@
1
- import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DnhYpc27.mjs";
1
+ import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DrgeBuva.mjs";
2
2
  import { c as resolveClaudeNativeThinkingLevelMap, d as supportsClaudeNativeMaxEffort, f as supportsClaudeNativeXhighEffort, l as resolveClaudeSonnet5ModelIdentity, u as supportsClaudeAdaptiveThinking } from "./src-CXno1H5g.mjs";
3
3
  import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
4
- import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-4t713IeR.mjs";
5
- import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-Q1LSRIdo.mjs";
4
+ import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-XYGZcgO8.mjs";
5
+ import { C as isImageWithMediaPayload, D as buildBaseOptions, E as adjustMaxTokensForThinking, O as clampMaxTokensToModel, T as isRecord, a as stripSystemPromptCacheBoundary, b as extractToolResultBlockText, c as transformMessages, d as prepareClaudeSonnet5RequestContext, f as requiresClaudeAdaptiveThinking, h as usesClaudeStreamingRefusalContract, i as splitSystemPromptCacheBoundary, l as applyClaudeRequestContract, m as usesClaudeFable5MessagesContract, x as extractToolResultText, y as describeToolResultMediaPlaceholder } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
6
+ import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
7
+ import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-1GiZ2_rr.mjs";
6
8
  import { r as createDeferredEventBuffer, t as notifyLlmRequestActivity } from "./llm-request-activity-CehVkZP-.mjs";
7
9
  import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
8
10
  import { n as parseStreamingJson, t as parseJsonWithRepair } from "./json-parse-BvXNt1-7.mjs";
9
- import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
10
- import { C as stripSystemPromptCacheBoundary, S as splitSystemPromptCacheBoundary, _ as usesClaudeFable5MessagesContract, c as adjustMaxTokensForThinking, d as isRecord, f as applyClaudeRequestContract, h as requiresClaudeAdaptiveThinking, i as extractToolResultText, l as buildBaseOptions, m as prepareClaudeSonnet5RequestContext, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, r as extractToolResultBlockText, t as transformMessages, v as usesClaudeStreamingRefusalContract } from "./transform-messages-BmS70CP5.mjs";
11
11
  import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-BwNu3nDi.mjs";
12
12
  import { a as resolveCacheRetention, i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-BsH5cqGj.mjs";
13
13
  import Anthropic from "@anthropic-ai/sdk";
14
14
  import { Stream } from "@anthropic-ai/sdk/core/streaming.js";
15
+ //#region packages/media-core/src/base64.ts
16
+ /** Estimates decoded bytes without allocating a cleaned copy of the base64 payload. */
17
+ function estimateBase64DecodedBytes(base64) {
18
+ let effectiveLen = 0;
19
+ for (let i = 0; i < base64.length; i += 1) {
20
+ if (base64.charCodeAt(i) <= 32) continue;
21
+ effectiveLen += 1;
22
+ }
23
+ if (effectiveLen === 0) return 0;
24
+ let padding = 0;
25
+ let end = base64.length - 1;
26
+ while (end >= 0 && base64.charCodeAt(end) <= 32) end -= 1;
27
+ if (end >= 0 && base64[end] === "=") {
28
+ padding = 1;
29
+ end -= 1;
30
+ while (end >= 0 && base64.charCodeAt(end) <= 32) end -= 1;
31
+ if (end >= 0 && base64[end] === "=") padding = 2;
32
+ }
33
+ const estimated = Math.floor(effectiveLen * 3 / 4) - padding;
34
+ return Math.max(0, estimated);
35
+ }
36
+ const CANONICALIZE_BASE64_CHUNK_SIZE = 8192;
37
+ function isBase64DataChar(code) {
38
+ return code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 43 || code === 47;
39
+ }
40
+ /**
41
+ * Normalizes and validates a base64 string, returning canonical no-whitespace
42
+ * base64 only when the input has valid alphabet, padding, and length.
43
+ */
44
+ function canonicalizeBase64(base64) {
45
+ const chunks = [];
46
+ let current = "";
47
+ let cleanedLength = 0;
48
+ let padding = 0;
49
+ let sawPadding = false;
50
+ const append = (char) => {
51
+ current += char;
52
+ cleanedLength += 1;
53
+ if (current.length >= CANONICALIZE_BASE64_CHUNK_SIZE) {
54
+ chunks.push(current);
55
+ current = "";
56
+ }
57
+ };
58
+ for (let i = 0; i < base64.length; i += 1) {
59
+ const code = base64.charCodeAt(i);
60
+ if (code <= 32) continue;
61
+ if (code === 61) {
62
+ padding += 1;
63
+ if (padding > 2) return;
64
+ sawPadding = true;
65
+ append("=");
66
+ continue;
67
+ }
68
+ if (sawPadding || !isBase64DataChar(code)) return;
69
+ append(base64[i] ?? "");
70
+ }
71
+ if (cleanedLength === 0) return;
72
+ const remainder = cleanedLength % 4;
73
+ if (remainder !== 0) {
74
+ if (sawPadding || remainder === 1) return;
75
+ current += "=".repeat(4 - remainder);
76
+ }
77
+ if (current) chunks.push(current);
78
+ return chunks.join("");
79
+ }
80
+ //#endregion
81
+ //#region packages/ai/src/internal/anthropic-inline-images.ts
82
+ const ANTHROPIC_IMAGE_MEDIA_TYPE_SET = /* @__PURE__ */ new Set([
83
+ "image/jpeg",
84
+ "image/png",
85
+ "image/gif",
86
+ "image/webp"
87
+ ]);
88
+ const ANTHROPIC_INLINE_IMAGES_DECODE_SAFETY_BYTES = 64 * 1024 * 1024;
89
+ function createAnthropicInlineImageBudget() {
90
+ return { totalBytes: 0 };
91
+ }
92
+ function resolveAnthropicImageMediaType(value) {
93
+ if (ANTHROPIC_IMAGE_MEDIA_TYPE_SET.has(value)) return value;
94
+ throw new Error(`Unsupported Anthropic image media type after normalization: ${value}`);
95
+ }
96
+ async function normalizeAnthropicInlineContent(content, budget) {
97
+ if (!content.some((block) => block.type === "image")) return content.filter((block) => block.type === "text");
98
+ const inputBytes = content.reduce((total, block) => block.type === "image" ? total + estimateBase64DecodedBytes(block.data) : total, 0);
99
+ if (budget.totalBytes + inputBytes > ANTHROPIC_INLINE_IMAGES_DECODE_SAFETY_BYTES) throw new Error("Anthropic inline images exceed the 64 MB aggregate decoded safety limit.");
100
+ const normalized = [];
101
+ for (const block of content) {
102
+ if (block.type !== "image") {
103
+ normalized.push(block);
104
+ continue;
105
+ }
106
+ const normalizedBlocks = await getAiTransportHost().normalizeAnthropicInlineContentBlocks([block]);
107
+ const outputBytes = normalizedBlocks.reduce((total, normalizedBlock) => normalizedBlock.type === "image" ? total + estimateBase64DecodedBytes(normalizedBlock.data) : total, 0);
108
+ if (budget.totalBytes + outputBytes > ANTHROPIC_INLINE_IMAGES_DECODE_SAFETY_BYTES) throw new Error("Anthropic inline images exceed the 64 MB aggregate decoded safety limit.");
109
+ budget.totalBytes += outputBytes;
110
+ normalized.push(...normalizedBlocks);
111
+ }
112
+ return normalized;
113
+ }
114
+ //#endregion
15
115
  //#region packages/ai/src/providers/anthropic-auth-headers.ts
16
116
  function usesFoundryBearerAuth(model) {
17
117
  return model.provider === "microsoft-foundry" && (model.authHeader === true || hasBearerAuthorizationHeader(model.headers));
@@ -295,6 +395,16 @@ function resolveOriginalAnthropicToolName(name, projection) {
295
395
  function readAnthropicUsageTokenCount(value) {
296
396
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
297
397
  }
398
+ function readAnthropicCacheWriteUsage(usage) {
399
+ if (!usage.cache_creation || typeof usage.cache_creation !== "object") return {};
400
+ const cacheCreation = usage.cache_creation;
401
+ const cacheWrite5m = readAnthropicUsageTokenCount(cacheCreation.ephemeral_5m_input_tokens);
402
+ const cacheWrite1h = readAnthropicUsageTokenCount(cacheCreation.ephemeral_1h_input_tokens);
403
+ return {
404
+ ...cacheWrite5m !== void 0 ? { cacheWrite5m } : {},
405
+ ...cacheWrite1h !== void 0 ? { cacheWrite1h } : {}
406
+ };
407
+ }
298
408
  function readAnthropicPromptUsageSnapshot(usage) {
299
409
  const input = readAnthropicUsageTokenCount(usage.input_tokens);
300
410
  const cacheRead = usage.cache_read_input_tokens == null ? 0 : readAnthropicUsageTokenCount(usage.cache_read_input_tokens);
@@ -371,7 +481,7 @@ const toClaudeCodeName = (name) => ccToolLookup.get(name.toLowerCase()) ?? name;
371
481
  /**
372
482
  * Convert content blocks to Anthropic API format
373
483
  */
374
- function convertContentBlocks(content, isError) {
484
+ async function convertContentBlocks(content, isError, imageBudget) {
375
485
  const text = extractToolResultText(content);
376
486
  const mediaPlaceholder = describeToolResultMediaPlaceholder(content);
377
487
  if (!content.some(isImageWithMediaPayload)) {
@@ -392,12 +502,18 @@ function convertContentBlocks(content, isError) {
392
502
  hasTextBlock = true;
393
503
  }
394
504
  if (!isImageWithMediaPayload(record)) continue;
505
+ const [normalizedImage] = await normalizeAnthropicInlineContent([{
506
+ type: "image",
507
+ data: typeof record.data === "string" ? record.data : "",
508
+ mimeType: typeof record.mimeType === "string" ? record.mimeType : "image/jpeg"
509
+ }], imageBudget);
510
+ if (normalizedImage?.type !== "image") continue;
395
511
  blocks.push({
396
512
  type: "image",
397
513
  source: {
398
514
  type: "base64",
399
- media_type: typeof record.mimeType === "string" ? record.mimeType : "image/jpeg",
400
- data: record.data
515
+ media_type: resolveAnthropicImageMediaType(normalizedImage.mimeType),
516
+ data: normalizedImage.data
401
517
  }
402
518
  });
403
519
  }
@@ -417,7 +533,8 @@ function getAnthropicCompat(model) {
417
533
  supportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? !isFireworks,
418
534
  supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? !isFireworks,
419
535
  sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? (isFireworks || isCloudflareAiGatewayAnthropic),
420
- supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? !isFireworks
536
+ supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? !isFireworks,
537
+ allowEmptySignature: model.compat?.allowEmptySignature ?? false
421
538
  };
422
539
  }
423
540
  function mergeHeaders(...headerSources) {
@@ -507,7 +624,7 @@ const streamAnthropic = (model, context, options) => {
507
624
  isOAuth = created.isOAuthToken;
508
625
  serverSideFallback = created.serverSideFallback;
509
626
  }
510
- const builtParams = buildParams(model, requestContext, isOAuth, requestOptions, serverSideFallback);
627
+ const builtParams = await buildParams(model, requestContext, isOAuth, requestOptions, serverSideFallback);
511
628
  let params = builtParams.params;
512
629
  const toolProjection = builtParams.toolProjection;
513
630
  const nextParams = await requestOptions?.onPayload?.(params, model);
@@ -516,7 +633,7 @@ const streamAnthropic = (model, context, options) => {
516
633
  const sdkRequestOptions = {
517
634
  ...requestOptions?.signal ? { signal: requestOptions.signal } : {},
518
635
  ...requestOptions?.timeoutMs !== void 0 ? { timeout: requestOptions.timeoutMs } : {},
519
- ...requestOptions?.maxRetries !== void 0 ? { maxRetries: requestOptions.maxRetries } : {}
636
+ maxRetries: requestOptions?.maxRetries ?? 0
520
637
  };
521
638
  const response = await client.messages.create({
522
639
  ...params,
@@ -542,6 +659,8 @@ const streamAnthropic = (model, context, options) => {
542
659
  if (cacheReadTokens !== void 0) output.usage.cacheRead = cacheReadTokens;
543
660
  const cacheWriteTokens = event.message.usage.cache_creation_input_tokens == null ? 0 : readAnthropicUsageTokenCount(event.message.usage.cache_creation_input_tokens);
544
661
  if (cacheWriteTokens !== void 0) output.usage.cacheWrite = cacheWriteTokens;
662
+ const cacheWriteUsage = readAnthropicCacheWriteUsage(event.message.usage);
663
+ if (cacheWriteUsage.cacheWrite1h !== void 0) output.usage.cacheWrite1h = cacheWriteUsage.cacheWrite1h;
545
664
  output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
546
665
  if (messageStartPromptUsage && outputTokens !== void 0) output.usage.contextUsage = {
547
666
  state: "available",
@@ -730,30 +849,34 @@ const streamAnthropic = (model, context, options) => {
730
849
  } else if (event.type === "message_delta") {
731
850
  if (event.delta.stop_reason) if (event.delta.stop_reason === "refusal") applyAnthropicRefusal(output, event.delta.stop_details, model.provider);
732
851
  else output.stopReason = mapStopReason(event.delta.stop_reason);
733
- const inputTokens = readAnthropicUsageTokenCount(event.usage.input_tokens);
734
- if (inputTokens !== void 0) output.usage.input = inputTokens;
735
- const outputTokens = readAnthropicUsageTokenCount(event.usage.output_tokens);
736
- if (outputTokens !== void 0) output.usage.output = outputTokens;
737
- const cacheReadTokens = readAnthropicUsageTokenCount(event.usage.cache_read_input_tokens);
738
- if (cacheReadTokens !== void 0) output.usage.cacheRead = cacheReadTokens;
739
- const cacheWriteTokens = readAnthropicUsageTokenCount(event.usage.cache_creation_input_tokens);
740
- if (cacheWriteTokens !== void 0) output.usage.cacheWrite = cacheWriteTokens;
741
- output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
742
- const iterationUsage = readLastAnthropicIterationUsage(event.usage);
743
- if (iterationUsage.state === "valid") output.usage.contextUsage = {
744
- state: "available",
745
- promptTokens: iterationUsage.usage.contextPromptTokens,
746
- totalTokens: iterationUsage.usage.totalTokens
747
- };
748
- else if (iterationUsage.state === "invalid") output.usage.contextUsage = { state: "unavailable" };
749
- else if (outputTokens !== void 0 && (messageStartPromptUsage !== void 0 || inputTokens !== void 0 && cacheReadTokens !== void 0 && cacheWriteTokens !== void 0)) {
750
- const promptTokens = output.usage.input + output.usage.cacheRead + output.usage.cacheWrite;
751
- output.usage.contextUsage = {
852
+ if (event.usage) {
853
+ const inputTokens = readAnthropicUsageTokenCount(event.usage.input_tokens);
854
+ if (inputTokens !== void 0) output.usage.input = inputTokens;
855
+ const outputTokens = readAnthropicUsageTokenCount(event.usage.output_tokens);
856
+ if (outputTokens !== void 0) output.usage.output = outputTokens;
857
+ const cacheReadTokens = readAnthropicUsageTokenCount(event.usage.cache_read_input_tokens);
858
+ if (cacheReadTokens !== void 0) output.usage.cacheRead = cacheReadTokens;
859
+ const cacheWriteTokens = readAnthropicUsageTokenCount(event.usage.cache_creation_input_tokens);
860
+ if (cacheWriteTokens !== void 0) output.usage.cacheWrite = cacheWriteTokens;
861
+ const cacheWriteUsage = readAnthropicCacheWriteUsage(event.usage);
862
+ if (cacheWriteUsage.cacheWrite1h !== void 0) output.usage.cacheWrite1h = cacheWriteUsage.cacheWrite1h;
863
+ output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
864
+ const iterationUsage = readLastAnthropicIterationUsage(event.usage);
865
+ if (iterationUsage.state === "valid") output.usage.contextUsage = {
752
866
  state: "available",
753
- promptTokens,
754
- totalTokens: promptTokens + output.usage.output
867
+ promptTokens: iterationUsage.usage.contextPromptTokens,
868
+ totalTokens: iterationUsage.usage.totalTokens
755
869
  };
756
- } else output.usage.contextUsage = { state: "unavailable" };
870
+ else if (iterationUsage.state === "invalid") output.usage.contextUsage = { state: "unavailable" };
871
+ else if (outputTokens !== void 0 && (messageStartPromptUsage !== void 0 || inputTokens !== void 0 && cacheReadTokens !== void 0 && cacheWriteTokens !== void 0)) {
872
+ const promptTokens = output.usage.input + output.usage.cacheRead + output.usage.cacheWrite;
873
+ output.usage.contextUsage = {
874
+ state: "available",
875
+ promptTokens,
876
+ totalTokens: promptTokens + output.usage.output
877
+ };
878
+ } else output.usage.contextUsage = { state: "unavailable" };
879
+ }
757
880
  calculateCost(costModel, output.usage);
758
881
  }
759
882
  if (requestOptions?.signal?.aborted) throw new Error("Request was aborted");
@@ -842,6 +965,7 @@ const streamSimpleAnthropic = (model, context, options) => {
842
965
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
843
966
  const base = {
844
967
  ...buildBaseOptions(model, options, apiKey),
968
+ maxTokens: clampMaxTokensToModel(model, options?.maxTokens ?? model.maxTokens),
845
969
  toolChoice: options?.toolChoice
846
970
  };
847
971
  const mandatoryAdaptiveThinking = requiresClaudeAdaptiveThinking(model);
@@ -869,10 +993,11 @@ const streamSimpleAnthropic = (model, context, options) => {
869
993
  });
870
994
  }
871
995
  const adjusted = adjustMaxTokensForThinking(base.maxTokens, model.maxTokens, reasoning, options?.thinkingBudgets);
872
- const thinkingEnabled = adjusted.thinkingBudget >= 1024;
996
+ const thinkingEnabled = adjusted.thinkingBudget >= ANTHROPIC_MIN_THINKING_BUDGET_TOKENS;
997
+ const maxTokens = thinkingEnabled ? adjusted.maxTokens : clampMaxTokensToModel(model, options?.maxTokens ?? model.maxTokens);
873
998
  return streamAnthropic(model, context, {
874
999
  ...base,
875
- maxTokens: adjusted.maxTokens,
1000
+ maxTokens,
876
1001
  thinkingEnabled,
877
1002
  thinkingBudgetTokens: thinkingEnabled ? adjusted.thinkingBudget : void 0
878
1003
  });
@@ -998,13 +1123,13 @@ function createClient(model, apiKey, thinkingEnabled, interleavedThinking, useFi
998
1123
  serverSideFallback
999
1124
  };
1000
1125
  }
1001
- function buildParams(model, context, isOAuthTokenResult, options, serverSideFallback = false) {
1126
+ async function buildParams(model, context, isOAuthTokenResult, options, serverSideFallback = false) {
1002
1127
  const mandatoryAdaptiveThinking = requiresClaudeAdaptiveThinking(model);
1003
1128
  const replayThinkingEnabled = mandatoryAdaptiveThinking || options?.thinkingEnabled === true;
1004
1129
  const { cacheControl } = getCacheControl(model, options?.cacheRetention);
1005
1130
  const system = buildAnthropicSystemBlocks(context.systemPrompt, isOAuthTokenResult, cacheControl);
1006
- const compat = context.tools ? getAnthropicCompat(model) : void 0;
1007
- const convertedTools = context.tools && compat ? convertTools(context.tools, isOAuthTokenResult, compat.supportsEagerToolInputStreaming, compat.supportsCacheControlOnTools ? cacheControl : void 0) : void 0;
1131
+ const compat = getAnthropicCompat(model);
1132
+ const convertedTools = context.tools ? convertTools(context.tools, isOAuthTokenResult, compat.supportsEagerToolInputStreaming, compat.supportsCacheControlOnTools ? cacheControl : void 0) : void 0;
1008
1133
  const tools = convertedTools?.tools;
1009
1134
  const toolProjection = convertedTools?.projection;
1010
1135
  const systemCacheControlCount = countNativeCacheControlMarkers(system);
@@ -1012,7 +1137,7 @@ function buildParams(model, context, isOAuthTokenResult, options, serverSideFall
1012
1137
  const messageCacheControlLimit = Math.max(0, ANTHROPIC_CACHE_CONTROL_LIMIT - systemCacheControlCount - toolCacheControlCount);
1013
1138
  const params = {
1014
1139
  model: model.id,
1015
- messages: convertMessages(context.messages, model, isOAuthTokenResult, cacheControl, messageCacheControlLimit, replayThinkingEnabled),
1140
+ messages: await convertMessages(context.messages, model, isOAuthTokenResult, cacheControl, messageCacheControlLimit, replayThinkingEnabled, compat.allowEmptySignature),
1016
1141
  max_tokens: options?.maxTokens ?? model.maxTokens,
1017
1142
  stream: true
1018
1143
  };
@@ -1055,8 +1180,9 @@ function buildParams(model, context, isOAuthTokenResult, options, serverSideFall
1055
1180
  function normalizeToolCallId(id) {
1056
1181
  return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
1057
1182
  }
1058
- function convertMessages(messages, model, isOAuthTokenValue, cacheControl, messageCacheControlLimit = 4, replayThinkingEnabled = true) {
1183
+ async function convertMessages(messages, model, isOAuthTokenValue, cacheControl, messageCacheControlLimit = 4, replayThinkingEnabled = true, allowEmptySignature = false) {
1059
1184
  const params = [];
1185
+ const imageBudget = createAnthropicInlineImageBudget();
1060
1186
  const cacheBreakpointOptOutParamIndexes = /* @__PURE__ */ new Set();
1061
1187
  const transformedMessages = transformMessages(messages, model, normalizeToolCallId);
1062
1188
  const activeToolTurnAssistantIndex = replayThinkingEnabled ? -1 : findActiveAnthropicToolTurnAssistantIndex(transformedMessages);
@@ -1074,7 +1200,7 @@ function convertMessages(messages, model, isOAuthTokenValue, cacheControl, messa
1074
1200
  });
1075
1201
  }
1076
1202
  } else {
1077
- const filteredBlocks = msg.content.map((item) => {
1203
+ const filteredBlocks = (await normalizeAnthropicInlineContent(msg.content, imageBudget)).map((item) => {
1078
1204
  if (item.type === "text") return {
1079
1205
  type: "text",
1080
1206
  text: sanitizeSurrogates(item.text)
@@ -1083,7 +1209,7 @@ function convertMessages(messages, model, isOAuthTokenValue, cacheControl, messa
1083
1209
  type: "image",
1084
1210
  source: {
1085
1211
  type: "base64",
1086
- media_type: item.mimeType,
1212
+ media_type: resolveAnthropicImageMediaType(item.mimeType),
1087
1213
  data: item.data
1088
1214
  }
1089
1215
  };
@@ -1123,7 +1249,7 @@ function convertMessages(messages, model, isOAuthTokenValue, cacheControl, messa
1123
1249
  const thinkingSignature = block.thinkingSignature?.trim();
1124
1250
  const hasNativeThinkingSignature = Boolean(thinkingSignature) && thinkingSignature !== "reasoning_content";
1125
1251
  if (block.thinking.trim().length === 0 && !hasNativeThinkingSignature) continue;
1126
- if (!thinkingSignature) blocks.push({
1252
+ if (!thinkingSignature && !allowEmptySignature) blocks.push({
1127
1253
  type: "text",
1128
1254
  text: sanitizeSurrogates(block.thinking)
1129
1255
  });
@@ -1132,7 +1258,7 @@ function convertMessages(messages, model, isOAuthTokenValue, cacheControl, messa
1132
1258
  blocks.push({
1133
1259
  type: "thinking",
1134
1260
  thinking: block.thinking,
1135
- signature: thinkingSignature
1261
+ signature: thinkingSignature ?? ""
1136
1262
  });
1137
1263
  }
1138
1264
  } else if (block.type === "toolCall") blocks.push({
@@ -1155,7 +1281,7 @@ function convertMessages(messages, model, isOAuthTokenValue, cacheControl, messa
1155
1281
  toolResults.push({
1156
1282
  type: "tool_result",
1157
1283
  tool_use_id: msg.toolCallId,
1158
- content: convertContentBlocks(msg.content, msg.isError),
1284
+ content: await convertContentBlocks(msg.content, msg.isError, imageBudget),
1159
1285
  is_error: msg.isError
1160
1286
  });
1161
1287
  let j = i + 1;
@@ -1165,7 +1291,7 @@ function convertMessages(messages, model, isOAuthTokenValue, cacheControl, messa
1165
1291
  toolResults.push({
1166
1292
  type: "tool_result",
1167
1293
  tool_use_id: nextMsg.toolCallId,
1168
- content: convertContentBlocks(nextMsg.content, nextMsg.isError),
1294
+ content: await convertContentBlocks(nextMsg.content, nextMsg.isError, imageBudget),
1169
1295
  is_error: nextMsg.isError
1170
1296
  });
1171
1297
  j++;
@@ -1302,4 +1428,4 @@ function mapStopReason(reason) {
1302
1428
  }
1303
1429
  }
1304
1430
  //#endregion
1305
- export { readAnthropicFallbackBoundary as _, readAnthropicUsageTokenCount as a, usesFoundryBearerAuth as b, reconcileAnthropicToolChoice as c, findActiveAnthropicToolTurnAssistantIndex as d, ANTHROPIC_SERVER_SIDE_FALLBACK_BETA as f, buildAnthropicServerSideFallbacks as g, applyAnthropicFallbackBoundary as h, readAnthropicPromptUsageSnapshot as i, resolveOriginalAnthropicToolName as l, CLAUDE_FABLE_5_FALLBACK_MODEL_COST as m, streamAnthropic as n, readLastAnthropicIterationUsage as o, CLAUDE_FABLE_5_FALLBACK_MODEL as p, streamSimpleAnthropic as r, projectAnthropicTools as s, anthropic_exports as t, ANTHROPIC_OMITTED_REASONING_TEXT as u, applyAnthropicRefusal as v, omitFoundryBearerCredentialHeaders as y };
1431
+ export { normalizeAnthropicInlineContent as C, createAnthropicInlineImageBudget as S, canonicalizeBase64 as T, buildAnthropicServerSideFallbacks as _, readAnthropicPromptUsageSnapshot as a, omitFoundryBearerCredentialHeaders as b, projectAnthropicTools as c, ANTHROPIC_OMITTED_REASONING_TEXT as d, findActiveAnthropicToolTurnAssistantIndex as f, applyAnthropicFallbackBoundary as g, CLAUDE_FABLE_5_FALLBACK_MODEL_COST as h, readAnthropicCacheWriteUsage as i, reconcileAnthropicToolChoice as l, CLAUDE_FABLE_5_FALLBACK_MODEL as m, streamAnthropic as n, readAnthropicUsageTokenCount as o, ANTHROPIC_SERVER_SIDE_FALLBACK_BETA as p, streamSimpleAnthropic as r, readLastAnthropicIterationUsage as s, anthropic_exports as t, resolveOriginalAnthropicToolName as u, readAnthropicFallbackBoundary as v, resolveAnthropicImageMediaType as w, usesFoundryBearerAuth as x, applyAnthropicRefusal as y };
@@ -1,5 +1,4 @@
1
- import { E as Model, F as SimpleStreamOptions, R as StreamFunction, n as Api, o as AssistantMessageEventStreamContract, u as Context, z as StreamOptions } from "./types-Cx2zJtyz.mjs";
2
-
1
+ import { E as Model, F as SimpleStreamOptions, R as StreamFunction, n as Api, o as AssistantMessageEventStreamContract, u as Context, z as StreamOptions } from "./types-AFwwWium.mjs";
3
2
  //#region packages/ai/src/api-registry.d.ts
4
3
  /** Runtime stream adapter signature stored in the API provider registry. */
5
4
  type ApiStreamFunction = (model: Model, context: Context, options?: StreamOptions) => AssistantMessageEventStreamContract;
@@ -1,10 +1,10 @@
1
- import { n as getEnvApiKey } from "./env-api-keys-DnhYpc27.mjs";
1
+ import { n as getEnvApiKey } from "./env-api-keys-DrgeBuva.mjs";
2
2
  import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
3
- import { n as getAiTransportHost } from "./host-4t713IeR.mjs";
4
- import { l as buildBaseOptions } from "./transform-messages-BmS70CP5.mjs";
5
- import { a as resolveResponsesReasoningEffort, n as convertResponsesMessages, o as runResponsesStreamLifecycle, r as createResponsesAssistantOutput, t as applyCommonResponsesParams } from "./openai-responses-shared-Befb4D6R.mjs";
3
+ import { n as getAiTransportHost } from "./host-XYGZcgO8.mjs";
4
+ import { D as buildBaseOptions } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
5
+ import { a as resolveResponsesReasoningEffort, n as convertResponsesMessages, o as runResponsesStreamLifecycle, r as createResponsesAssistantOutput, t as applyCommonResponsesParams } from "./openai-responses-shared-CzCurmY1.mjs";
6
6
  import { i as resolveAzureDeploymentNameFromMap, t as isOpenAICompatibleAzureResponsesBaseUrl } from "./azure-openai-responses-client-compat-C7K7QfUE.mjs";
7
- import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-CFqm42J2.mjs";
7
+ import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-ITOU9bG1.mjs";
8
8
  import OpenAI, { AzureOpenAI } from "openai";
9
9
  //#region packages/ai/src/providers/azure-openai-responses.ts
10
10
  const DEFAULT_AZURE_API_VERSION = "v1";
@@ -94,11 +94,8 @@ function resolveAzureConfig(model, options) {
94
94
  };
95
95
  }
96
96
  function createClient(model, apiKeyInput, options) {
97
- let apiKey = apiKeyInput;
98
- if (!apiKey) {
99
- if (!process.env.AZURE_OPENAI_API_KEY) throw new Error("Azure OpenAI API key is required. Set AZURE_OPENAI_API_KEY environment variable or pass it as an argument.");
100
- apiKey = process.env.AZURE_OPENAI_API_KEY;
101
- }
97
+ const apiKey = apiKeyInput.trim();
98
+ if (!apiKey) throw new Error("Azure OpenAI API key is required. Set AZURE_OPENAI_API_KEY environment variable or pass it as an argument.");
102
99
  const headers = { ...model.headers };
103
100
  if (options?.headers) Object.assign(headers, options.headers);
104
101
  const { baseUrl, apiVersion } = resolveAzureConfig(model, options);
@@ -127,7 +124,8 @@ function buildParams(model, context, options, deploymentName) {
127
124
  model: deploymentName,
128
125
  input: convertResponsesMessages(model, context, AZURE_TOOL_CALL_PROVIDERS),
129
126
  stream: true,
130
- prompt_cache_key: options?.cacheRetention === "none" ? void 0 : clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId)
127
+ prompt_cache_key: options?.cacheRetention === "none" ? void 0 : clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId),
128
+ store: false
131
129
  };
132
130
  applyCommonResponsesParams(params, model, context, options);
133
131
  return params;
@@ -82,7 +82,7 @@ function getProcEnv(key) {
82
82
  return procEnvCache.get(key);
83
83
  }
84
84
  function getEnvValue(key) {
85
- return getProcessEnv()?.[key] || getProcEnv(key);
85
+ return (getProcessEnv()?.[key] || getProcEnv(key))?.trim() || void 0;
86
86
  }
87
87
  let cachedVertexAdcCredentialsExists = null;
88
88
  function hasVertexAdcCredentials() {
@@ -1,4 +1,4 @@
1
- import { a as AssistantMessageEvent, i as AssistantMessage, o as AssistantMessageEventStreamContract } from "./types-Cx2zJtyz.mjs";
1
+ import { a as AssistantMessageEvent, i as AssistantMessage, o as AssistantMessageEventStreamContract } from "./types-AFwwWium.mjs";
2
2
 
3
3
  //#region packages/llm-core/src/utils/event-stream.d.ts
4
4
  /** Generic async-iterable event stream with a separately awaited final result. */
@@ -1,2 +1,2 @@
1
- import { n as EventStream, r as createAssistantMessageEventStream, t as AssistantMessageEventStream } from "./event-stream-uQspnL8S.mjs";
1
+ import { n as EventStream, r as createAssistantMessageEventStream, t as AssistantMessageEventStream } from "./event-stream-Douf9dob.mjs";
2
2
  export { AssistantMessageEventStream, EventStream, createAssistantMessageEventStream };
@@ -1,8 +1,8 @@
1
- import { n as getEnvApiKey } from "./env-api-keys-DnhYpc27.mjs";
1
+ import { n as getEnvApiKey } from "./env-api-keys-DrgeBuva.mjs";
2
2
  import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
3
- import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-4t713IeR.mjs";
4
- import { l as buildBaseOptions } from "./transform-messages-BmS70CP5.mjs";
5
- import { a as runGoogleGenerateContentLifecycle, i as getDisabledGoogleThinkingConfig, n as buildGoogleSimpleThinking, r as createGoogleAssistantOutput, t as buildGoogleGenerateContentParams } from "./google-shared-Dx2aba47.mjs";
3
+ import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-XYGZcgO8.mjs";
4
+ import { D as buildBaseOptions } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
5
+ import { a as runGoogleGenerateContentLifecycle, i as getDisabledGoogleThinkingConfig, n as buildGoogleSimpleThinking, r as createGoogleAssistantOutput, t as buildGoogleGenerateContentParams } from "./google-shared-CMLI-tCZ.mjs";
6
6
  import { GoogleGenAI } from "@google/genai";
7
7
  //#region packages/ai/src/providers/google.ts
8
8
  let toolCallCounter = 0;
@@ -1,6 +1,7 @@
1
- import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-Q1LSRIdo.mjs";
1
+ import { C as isImageWithMediaPayload, a as stripSystemPromptCacheBoundary, c as transformMessages, x as extractToolResultText, y as describeToolResultMediaPlaceholder } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
2
2
  import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
3
- import { C as stripSystemPromptCacheBoundary, i as extractToolResultText, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, t as transformMessages } from "./transform-messages-BmS70CP5.mjs";
3
+ import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-1GiZ2_rr.mjs";
4
+ import { t as formatProviderError } from "./provider-error-C4VvV_3t.mjs";
4
5
  import { FinishReason, FunctionCallingConfigMode, ThinkingLevel } from "@google/genai";
5
6
  //#region packages/ai/src/providers/google-shared.ts
6
7
  /**
@@ -273,7 +274,7 @@ async function runGoogleGenerateContentLifecycle(params) {
273
274
  } catch (error) {
274
275
  for (const block of output.content) if ("index" in block) delete block.index;
275
276
  output.stopReason = options?.signal?.aborted ? "aborted" : "error";
276
- output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
277
+ output.errorMessage = formatProviderError(error);
277
278
  stream.push({
278
279
  type: "error",
279
280
  reason: output.stopReason,
@@ -1,7 +1,7 @@
1
1
  import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
2
- import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-4t713IeR.mjs";
3
- import { l as buildBaseOptions } from "./transform-messages-BmS70CP5.mjs";
4
- import { a as runGoogleGenerateContentLifecycle, n as buildGoogleSimpleThinking, r as createGoogleAssistantOutput, t as buildGoogleGenerateContentParams } from "./google-shared-Dx2aba47.mjs";
2
+ import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-XYGZcgO8.mjs";
3
+ import { D as buildBaseOptions } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
4
+ import { a as runGoogleGenerateContentLifecycle, n as buildGoogleSimpleThinking, r as createGoogleAssistantOutput, t as buildGoogleGenerateContentParams } from "./google-shared-CMLI-tCZ.mjs";
5
5
  import { GoogleGenAI, ResourceScope } from "@google/genai";
6
6
  //#region packages/ai/src/providers/google-vertex.ts
7
7
  const API_VERSION = "v1";