@warlock.js/ai-bedrock 5.29.0 → 5.31.0

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 (41) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/cjs/index.cjs +350 -57
  3. package/cjs/index.cjs.map +1 -1
  4. package/esm/config.type.d.mts +31 -6
  5. package/esm/config.type.d.mts.map +1 -1
  6. package/esm/embedder.mjs +1 -1
  7. package/esm/embedder.mjs.map +1 -1
  8. package/esm/index.d.mts +3 -1
  9. package/esm/index.mjs +2 -1
  10. package/esm/known-capabilities.mjs +42 -4
  11. package/esm/known-capabilities.mjs.map +1 -1
  12. package/esm/known-pricing.d.mts +48 -0
  13. package/esm/known-pricing.d.mts.map +1 -0
  14. package/esm/known-pricing.mjs +99 -0
  15. package/esm/known-pricing.mjs.map +1 -0
  16. package/esm/known-vision-models.mjs +1 -1
  17. package/esm/known-vision-models.mjs.map +1 -1
  18. package/esm/model.mjs +122 -46
  19. package/esm/model.mjs.map +1 -1
  20. package/esm/provider-options.d.mts +8 -0
  21. package/esm/provider-options.d.mts.map +1 -0
  22. package/esm/provider-options.mjs +36 -0
  23. package/esm/provider-options.mjs.map +1 -0
  24. package/esm/sdk.d.mts +5 -1
  25. package/esm/sdk.d.mts.map +1 -1
  26. package/esm/sdk.mjs +35 -4
  27. package/esm/sdk.mjs.map +1 -1
  28. package/esm/utils/map-stop-reason.mjs +1 -1
  29. package/esm/utils/map-stop-reason.mjs.map +1 -1
  30. package/esm/utils/reasoning-blocks.mjs +1 -1
  31. package/esm/utils/reasoning-blocks.mjs.map +1 -1
  32. package/esm/utils/to-bedrock-messages.mjs +15 -2
  33. package/esm/utils/to-bedrock-messages.mjs.map +1 -1
  34. package/esm/utils/to-bedrock-tools.mjs +1 -1
  35. package/esm/utils/to-bedrock-tools.mjs.map +1 -1
  36. package/esm/utils/wrap-bedrock-error.mjs +6 -2
  37. package/esm/utils/wrap-bedrock-error.mjs.map +1 -1
  38. package/llms-full.txt +152 -38
  39. package/llms.txt +1 -1
  40. package/package.json +5 -4
  41. package/skills/setup-bedrock/SKILL.md +152 -38
@@ -1 +1 @@
1
- {"version":3,"file":"known-capabilities.mjs","names":[],"sources":["../../../../../../ai-bedrock/src/known-capabilities.ts"],"sourcesContent":["/**\n * Cost-truth capability inference for Bedrock Converse model ids.\n *\n * Bedrock model ids are provider-prefixed and version-suffixed\n * (`anthropic.claude-3-7-sonnet-20250219-v1:0`, `us.amazon.nova-pro-v1:0`),\n * so — exactly like `known-vision-models.ts` — a lowercase substring scan\n * is the only robust check across cross-region inference-profile prefixes\n * (`us.`, `eu.`, `apac.`) and date/version tags.\n *\n * Each predicate answers a single `ModelCapabilities` flag the agent reads\n * to decide whether to forward a cost-truth option (`reasoning`,\n * `cacheControl`) or up-front-reject an attachment (`pdf`). Unknown ids\n * default to `false` so an unsupported request fails fast with a clear\n * capability error instead of an opaque Bedrock `ValidationException`.\n * Every inference is overridable per-model via `bedrock.model({ name, … })`.\n */\n\n/**\n * Families that expose Anthropic-style extended thinking on Bedrock\n * Converse via `additionalModelRequestFields.thinking`. Only Claude 3.7\n * and the Claude 4 line (Sonnet / Opus / Haiku) support a configurable\n * thinking budget; earlier Claude, Nova, Llama, Mistral and Cohere do\n * not, so they are intentionally absent.\n */\nconst REASONING_CAPABLE_SUBSTRINGS = [\n \"claude-3-7\",\n \"claude-sonnet-4\",\n \"claude-opus-4\",\n \"claude-haiku-4\",\n];\n\n/**\n * Families that honor Converse `cachePoint` prompt-cache breakpoints.\n * Anthropic Claude 3.5+ / 3.7 / 4 and the Amazon Nova line support\n * cache points; text-only legacy families do not.\n */\nconst PROMPT_CACHING_CAPABLE_SUBSTRINGS = [\n \"claude-3-5\",\n \"claude-3-7\",\n \"claude-sonnet-4\",\n \"claude-opus-4\",\n \"claude-haiku-4\",\n \"nova-lite\",\n \"nova-pro\",\n \"nova-premier\",\n \"nova-micro\",\n];\n\n/**\n * Families that accept Converse `document` content blocks (PDF / docx /\n * txt input). The multimodal Claude 3+ and Nova families support\n * document blocks; the substring set mirrors the vision-capable list\n * minus the image-only Llama entries (Llama on Bedrock takes images but\n * not document blocks via Converse).\n */\nconst PDF_CAPABLE_SUBSTRINGS = [\n \"claude-3\",\n \"claude-sonnet-4\",\n \"claude-opus-4\",\n \"claude-haiku-4\",\n \"nova-lite\",\n \"nova-pro\",\n \"nova-premier\",\n];\n\nfunction matchesAny(modelId: string, fragments: string[]): boolean {\n const normalized = modelId.toLowerCase();\n\n return fragments.some((fragment) => normalized.includes(fragment));\n}\n\n/**\n * Infer whether a Bedrock model id exposes extended-thinking / reasoning\n * (Claude 3.7 + Claude 4). When true the adapter forwards\n * `ModelCallOptions.reasoning` as Converse\n * `additionalModelRequestFields.thinking`.\n *\n * @example\n * inferReasoningCapability(\"anthropic.claude-3-7-sonnet-20250219-v1:0\"); // → true\n * inferReasoningCapability(\"us.amazon.nova-pro-v1:0\"); // → false\n */\nexport function inferReasoningCapability(modelId: string): boolean {\n return matchesAny(modelId, REASONING_CAPABLE_SUBSTRINGS);\n}\n\n/**\n * Infer whether a Bedrock model id honors Converse `cachePoint`\n * breakpoints (Claude 3.5+ / Nova). When true the adapter both maps\n * `ModelCallOptions.cacheControl` write breakpoints to cache points and\n * reports `Usage.cachedTokens` / `Usage.cacheWriteTokens`.\n *\n * @example\n * inferPromptCachingCapability(\"us.amazon.nova-pro-v1:0\"); // → true\n * inferPromptCachingCapability(\"meta.llama3-1-8b-instruct-v1:0\"); // → false\n */\nexport function inferPromptCachingCapability(modelId: string): boolean {\n return matchesAny(modelId, PROMPT_CACHING_CAPABLE_SUBSTRINGS);\n}\n\n/**\n * Infer whether a Bedrock model id accepts Converse `document` content\n * blocks (PDF / document input — Claude 3+ / Nova). When false the agent\n * rejects a PDF attachment up front instead of dropping it at the wire.\n *\n * @example\n * inferPdfCapability(\"anthropic.claude-3-5-sonnet-20240620-v1:0\"); // → true\n * inferPdfCapability(\"meta.llama3-2-90b-instruct-v1:0\"); // → false\n */\nexport function inferPdfCapability(modelId: string): boolean {\n return matchesAny(modelId, PDF_CAPABLE_SUBSTRINGS);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,+BAA+B;CACnC;CACA;CACA;CACA;AACF;;;;;;AAOA,MAAM,oCAAoC;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;AASA,MAAM,yBAAyB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,WAAW,SAAiB,WAA8B;CACjE,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,UAAU,MAAM,aAAa,WAAW,SAAS,QAAQ,CAAC;AACnE;;;;;;;;;;;AAYA,SAAgB,yBAAyB,SAA0B;CACjE,OAAO,WAAW,SAAS,4BAA4B;AACzD;;;;;;;;;;;AAYA,SAAgB,6BAA6B,SAA0B;CACrE,OAAO,WAAW,SAAS,iCAAiC;AAC9D;;;;;;;;;;AAWA,SAAgB,mBAAmB,SAA0B;CAC3D,OAAO,WAAW,SAAS,sBAAsB;AACnD"}
1
+ {"version":3,"file":"known-capabilities.mjs","names":[],"sources":["../../../../../../../packages/ai-bedrock/src/known-capabilities.ts"],"sourcesContent":["/**\n * Cost-truth capability inference for Bedrock Converse model ids.\n *\n * Bedrock model ids are provider-prefixed and version-suffixed\n * (`anthropic.claude-3-7-sonnet-20250219-v1:0`, `us.amazon.nova-pro-v1:0`),\n * so — exactly like `known-vision-models.ts` — a lowercase substring scan\n * is the only robust check across cross-region inference-profile prefixes\n * (`us.`, `eu.`, `apac.`) and date/version tags.\n *\n * Each predicate answers a single `ModelCapabilities` flag the agent reads\n * to decide whether to forward a cost-truth option (`reasoning`,\n * `cacheControl`) or up-front-reject an attachment (`pdf`). Unknown ids\n * default to `false` so an unsupported request fails fast with a clear\n * capability error instead of an opaque Bedrock `ValidationException`.\n * Every inference is overridable per-model via `bedrock.model({ name, … })`.\n */\n\n/**\n * Families that expose Anthropic-style extended thinking on Bedrock\n * Converse via `additionalModelRequestFields.thinking`. Only Claude 3.7\n * and the Claude 4 line (Sonnet / Opus / Haiku) support a configurable\n * thinking budget; earlier Claude, Nova, Llama, Mistral and Cohere do\n * not, so they are intentionally absent.\n */\nconst REASONING_CAPABLE_SUBSTRINGS = [\n \"claude-3-7\",\n \"claude-sonnet-4\",\n \"claude-opus-4\",\n \"claude-haiku-4\",\n];\n\n/**\n * Families that honor Converse `cachePoint` prompt-cache breakpoints.\n * Anthropic Claude 3.5+ / 3.7 / 4 / 5 and the Amazon Nova line support\n * cache points; text-only legacy families do not. Per the \"Supported\n * models\" table of https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html\n * (checked 2026-10-17).\n */\nconst PROMPT_CACHING_CAPABLE_SUBSTRINGS = [\n \"claude-3-5\",\n \"claude-3-7\",\n \"claude-sonnet-4\",\n \"claude-opus-4\",\n \"claude-haiku-4\",\n \"claude-sonnet-5\",\n \"claude-opus-5\",\n \"claude-haiku-5\",\n \"claude-fable-5\",\n \"claude-mythos-5\",\n \"nova-2-lite\",\n \"nova-lite\",\n \"nova-pro\",\n \"nova-premier\",\n \"nova-micro\",\n];\n\n/**\n * Families that accept Converse `document` content blocks (PDF / docx /\n * txt input). The multimodal Claude 3+ and Nova families support\n * document blocks; the substring set mirrors the vision-capable list\n * minus the image-only Llama entries (Llama on Bedrock takes images but\n * not document blocks via Converse).\n */\nconst PDF_CAPABLE_SUBSTRINGS = [\n \"claude-3\",\n \"claude-sonnet-4\",\n \"claude-opus-4\",\n \"claude-haiku-4\",\n \"nova-lite\",\n \"nova-pro\",\n \"nova-premier\",\n];\n\nfunction matchesAny(modelId: string, fragments: string[]): boolean {\n const normalized = modelId.toLowerCase();\n\n return fragments.some((fragment) => normalized.includes(fragment));\n}\n\n/**\n * Infer whether a Bedrock model id exposes extended-thinking / reasoning\n * (Claude 3.7 + Claude 4). When true the adapter forwards\n * `ModelCallOptions.reasoning` as Converse\n * `additionalModelRequestFields.thinking`.\n *\n * @example\n * inferReasoningCapability(\"anthropic.claude-3-7-sonnet-20250219-v1:0\"); // → true\n * inferReasoningCapability(\"us.amazon.nova-pro-v1:0\"); // → false\n */\nexport function inferReasoningCapability(modelId: string): boolean {\n return matchesAny(modelId, REASONING_CAPABLE_SUBSTRINGS);\n}\n\n/**\n * Infer whether a Bedrock model id honors Converse `cachePoint`\n * breakpoints (Claude 3.5+ / Nova). When true the adapter both maps\n * `ModelCallOptions.cacheControl` write breakpoints to cache points and\n * reports `Usage.cachedTokens` / `Usage.cacheWriteTokens`.\n *\n * @example\n * inferPromptCachingCapability(\"us.amazon.nova-pro-v1:0\"); // → true\n * inferPromptCachingCapability(\"meta.llama3-1-8b-instruct-v1:0\"); // → false\n */\nexport function inferPromptCachingCapability(modelId: string): boolean {\n return matchesAny(modelId, PROMPT_CACHING_CAPABLE_SUBSTRINGS);\n}\n\n/**\n * Infer whether a Bedrock model id accepts Converse `document` content\n * blocks (PDF / document input — Claude 3+ / Nova). When false the agent\n * rejects a PDF attachment up front instead of dropping it at the wire.\n *\n * @example\n * inferPdfCapability(\"anthropic.claude-3-5-sonnet-20240620-v1:0\"); // → true\n * inferPdfCapability(\"meta.llama3-2-90b-instruct-v1:0\"); // → false\n */\nexport function inferPdfCapability(modelId: string): boolean {\n return matchesAny(modelId, PDF_CAPABLE_SUBSTRINGS);\n}\n\n/**\n * Claude on Bedrock accepts a `cachePoint` in `system`, `messages` and\n * `tools`; Amazon Nova accepts one only in `system` and `messages`\n * (https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html,\n * \"Fields that accept prompt cache checkpoints\", checked 2026-10-17).\n * Unknown families get no tool cache point.\n *\n * @example\n * supportsToolCachePoint(\"global.anthropic.claude-sonnet-4-6\"); // true\n * supportsToolCachePoint(\"amazon.nova-pro-v1:0\"); // false\n */\nexport function supportsToolCachePoint(modelId: string): boolean {\n return modelId.toLowerCase().includes(\"anthropic.claude\");\n}\n\n/** Claude families whose cache points accept the 1-hour TTL. */\nconst ONE_HOUR_TTL_PATTERN =\n /anthropic\\.claude-(?:(?:opus|sonnet|haiku|fable|mythos)-5|opus-4-[5-9]|sonnet-4-[5-9]|haiku-4-5)/;\n\n/**\n * Claude models whose Converse `cachePoint` accepts `ttl: \"1h\"`: Claude\n * Haiku 4.5, the 4.5+ Sonnet / Opus line and every Claude 5 family. Any\n * other model gets no `ttl` field (the 5-minute default), since AWS\n * warns that sending it to a 5-minute-only model \"can result in a\n * ValidationException\" (same page, checked 2026-10-17).\n *\n * @example\n * supportsOneHourCacheTtl(\"anthropic.claude-haiku-4-5-20251001-v1:0\"); // true\n * supportsOneHourCacheTtl(\"anthropic.claude-3-7-sonnet-20250219-v1:0\"); // false\n */\nexport function supportsOneHourCacheTtl(modelId: string): boolean {\n return ONE_HOUR_TTL_PATTERN.test(modelId.toLowerCase());\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,+BAA+B;CACnC;CACA;CACA;CACA;AACF;;;;;;;;AASA,MAAM,oCAAoC;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;AASA,MAAM,yBAAyB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,WAAW,SAAiB,WAA8B;CACjE,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,UAAU,MAAM,aAAa,WAAW,SAAS,QAAQ,CAAC;AACnE;;;;;;;;;;;AAYA,SAAgB,yBAAyB,SAA0B;CACjE,OAAO,WAAW,SAAS,4BAA4B;AACzD;;;;;;;;;;;AAYA,SAAgB,6BAA6B,SAA0B;CACrE,OAAO,WAAW,SAAS,iCAAiC;AAC9D;;;;;;;;;;AAWA,SAAgB,mBAAmB,SAA0B;CAC3D,OAAO,WAAW,SAAS,sBAAsB;AACnD;;;;;;;;;;;;AAaA,SAAgB,uBAAuB,SAA0B;CAC/D,OAAO,QAAQ,YAAY,CAAC,CAAC,SAAS,kBAAkB;AAC1D;;AAGA,MAAM,uBACJ;;;;;;;;;;;;AAaF,SAAgB,wBAAwB,SAA0B;CAChE,OAAO,qBAAqB,KAAK,QAAQ,YAAY,CAAC;AACxD"}
@@ -0,0 +1,48 @@
1
+ import { ModelPricing } from "@warlock.js/ai";
2
+
3
+ //#region ../../packages/ai-bedrock/src/known-pricing.d.ts
4
+ /**
5
+ * Bedrock on-demand list prices for Anthropic Claude, USD per 1,000,000
6
+ * tokens, keyed by Bedrock model id (without an inference-profile
7
+ * prefix). `cacheWrite` is the 5-minute write rate, `cacheWrite1h` the
8
+ * 1-hour write rate, `cachedInput` the cache-read rate.
9
+ *
10
+ * Source: https://aws.amazon.com/bedrock/pricing/ — the page's own price
11
+ * feed for "US East (N. Virginia)", fetched 2026-10-17 (Sonnet 5.5 cache
12
+ * reads already at the rate effective 2026-10-07). Model ids from
13
+ * https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html.
14
+ *
15
+ * Two tables, because AWS prices them differently:
16
+ * - {@link BEDROCK_GLOBAL_PRICING} — `global.` cross-Region inference
17
+ * profiles.
18
+ * - {@link BEDROCK_US_PRICING} — `us.` geographic profiles (the
19
+ * "Geo / In-region" rates, 10% above global for these models).
20
+ *
21
+ * In-Region ids without a profile prefix, other geographies (`eu.`,
22
+ * `apac.`, …), Claude Haiku 5.5 and non-Claude models stay unpriced —
23
+ * their rates vary by Region or were not verified — so pass `pricing`
24
+ * yourself for them.
25
+ */
26
+ declare const BEDROCK_GLOBAL_PRICING: Readonly<Record<string, ModelPricing>>;
27
+ /** `us.` geographic-profile prices — see {@link BEDROCK_GLOBAL_PRICING}. */
28
+ declare const BEDROCK_US_PRICING: Readonly<Record<string, ModelPricing>>;
29
+ /**
30
+ * Look up the built-in price for a Bedrock model id or inference-profile
31
+ * id: `global.<model>` reads {@link BEDROCK_GLOBAL_PRICING}, `us.<model>`
32
+ * reads {@link BEDROCK_US_PRICING}; anything else is `undefined`.
33
+ *
34
+ * @example
35
+ * bedrockPricingFor("global.anthropic.claude-sonnet-4-6"); // { input: 3, output: 15, … }
36
+ * bedrockPricingFor("anthropic.claude-sonnet-4-6"); // undefined — in-Region rates vary
37
+ */
38
+ declare function bedrockPricingFor(modelId: string): ModelPricing | undefined;
39
+ /**
40
+ * Fill the Claude cache-write rates (5-minute 1.25x, 1-hour 2x the input
41
+ * rate — the ratio of every Claude row in the tables above) into a
42
+ * caller-supplied entry for a Claude model that omits them. Non-Claude
43
+ * models are returned unchanged.
44
+ */
45
+ declare function withClaudeCacheWriteRates(modelId: string, pricing: ModelPricing | undefined): ModelPricing | undefined;
46
+ //#endregion
47
+ export { BEDROCK_GLOBAL_PRICING, BEDROCK_US_PRICING, bedrockPricingFor, withClaudeCacheWriteRates };
48
+ //# sourceMappingURL=known-pricing.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"known-pricing.d.mts","names":[],"sources":["../../../../../../../packages/ai-bedrock/src/known-pricing.ts"],"mappings":";;;;;AAwBA;;;;;;;;;;;;AAAyE;AAiBzE;;;;;;;cAjBa,sBAAA,EAAwB,QAAA,CAAS,MAAA,SAAe,YAAA;;cAiBhD,kBAAA,EAAoB,QAAA,CAAS,MAAA,SAAe,YAAA;;;AAAY;AAyBrE;;;;AAAgE;AAkBhE;iBAlBgB,iBAAA,CAAkB,OAAA,WAAkB,YAAY;;;;;;;iBAkBhD,yBAAA,CACd,OAAA,UACA,OAAA,EAAS,YAAA,eACR,YAAY"}
@@ -0,0 +1,99 @@
1
+ //#region ../../packages/ai-bedrock/src/known-pricing.ts
2
+ /**
3
+ * Bedrock on-demand list prices for Anthropic Claude, USD per 1,000,000
4
+ * tokens, keyed by Bedrock model id (without an inference-profile
5
+ * prefix). `cacheWrite` is the 5-minute write rate, `cacheWrite1h` the
6
+ * 1-hour write rate, `cachedInput` the cache-read rate.
7
+ *
8
+ * Source: https://aws.amazon.com/bedrock/pricing/ — the page's own price
9
+ * feed for "US East (N. Virginia)", fetched 2026-10-17 (Sonnet 5.5 cache
10
+ * reads already at the rate effective 2026-10-07). Model ids from
11
+ * https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html.
12
+ *
13
+ * Two tables, because AWS prices them differently:
14
+ * - {@link BEDROCK_GLOBAL_PRICING} — `global.` cross-Region inference
15
+ * profiles.
16
+ * - {@link BEDROCK_US_PRICING} — `us.` geographic profiles (the
17
+ * "Geo / In-region" rates, 10% above global for these models).
18
+ *
19
+ * In-Region ids without a profile prefix, other geographies (`eu.`,
20
+ * `apac.`, …), Claude Haiku 5.5 and non-Claude models stay unpriced —
21
+ * their rates vary by Region or were not verified — so pass `pricing`
22
+ * yourself for them.
23
+ */
24
+ const BEDROCK_GLOBAL_PRICING = {
25
+ "anthropic.claude-sonnet-5-5": claude(2, 10, .1),
26
+ "anthropic.claude-opus-5-5": claude(4, 20, .2),
27
+ "anthropic.claude-fable-5-1": claude(10, 50, .25),
28
+ "anthropic.claude-opus-5": claude(5, 25, .5),
29
+ "anthropic.claude-sonnet-5": claude(2, 10, .2),
30
+ "anthropic.claude-fable-5": claude(10, 50, 1),
31
+ "anthropic.claude-opus-4-8": claude(5, 25, .5),
32
+ "anthropic.claude-opus-4-7": claude(5, 25, .5),
33
+ "anthropic.claude-opus-4-6-v1": claude(5, 25, .5),
34
+ "anthropic.claude-sonnet-4-6": claude(3, 15, .3),
35
+ "anthropic.claude-opus-4-5-20251101-v1:0": claude(5, 25, .5),
36
+ "anthropic.claude-sonnet-4-5-20250929-v1:0": claude(3, 15, .3),
37
+ "anthropic.claude-haiku-4-5-20251001-v1:0": claude(1, 5, .1)
38
+ };
39
+ /** `us.` geographic-profile prices — see {@link BEDROCK_GLOBAL_PRICING}. */
40
+ const BEDROCK_US_PRICING = {
41
+ "anthropic.claude-sonnet-5-5": claude(2.2, 11, .11),
42
+ "anthropic.claude-opus-5-5": claude(4.4, 22, .22),
43
+ "anthropic.claude-fable-5-1": claude(11, 55, .275),
44
+ "anthropic.claude-opus-5": claude(5.5, 27.5, .55),
45
+ "anthropic.claude-sonnet-5": claude(2.2, 11, .22),
46
+ "anthropic.claude-fable-5": claude(11, 55, 1.1),
47
+ "anthropic.claude-opus-4-8": claude(5.5, 27.5, .55),
48
+ "anthropic.claude-opus-4-7": claude(5.5, 27.5, .55),
49
+ "anthropic.claude-opus-4-6-v1": claude(5.5, 27.5, .55),
50
+ "anthropic.claude-sonnet-4-6": claude(3.3, 16.5, .33),
51
+ "anthropic.claude-opus-4-5-20251101-v1:0": claude(5.5, 27.5, .55),
52
+ "anthropic.claude-sonnet-4-5-20250929-v1:0": claude(3.3, 16.5, .33),
53
+ "anthropic.claude-haiku-4-5-20251001-v1:0": claude(1.1, 5.5, .11)
54
+ };
55
+ /**
56
+ * Look up the built-in price for a Bedrock model id or inference-profile
57
+ * id: `global.<model>` reads {@link BEDROCK_GLOBAL_PRICING}, `us.<model>`
58
+ * reads {@link BEDROCK_US_PRICING}; anything else is `undefined`.
59
+ *
60
+ * @example
61
+ * bedrockPricingFor("global.anthropic.claude-sonnet-4-6"); // { input: 3, output: 15, … }
62
+ * bedrockPricingFor("anthropic.claude-sonnet-4-6"); // undefined — in-Region rates vary
63
+ */
64
+ function bedrockPricingFor(modelId) {
65
+ if (modelId.startsWith("global.")) return BEDROCK_GLOBAL_PRICING[modelId.slice(7)];
66
+ if (modelId.startsWith("us.")) return BEDROCK_US_PRICING[modelId.slice(3)];
67
+ }
68
+ /**
69
+ * Fill the Claude cache-write rates (5-minute 1.25x, 1-hour 2x the input
70
+ * rate — the ratio of every Claude row in the tables above) into a
71
+ * caller-supplied entry for a Claude model that omits them. Non-Claude
72
+ * models are returned unchanged.
73
+ */
74
+ function withClaudeCacheWriteRates(modelId, pricing) {
75
+ if (!pricing || !modelId.toLowerCase().includes("anthropic.claude")) return pricing;
76
+ if (pricing.cacheWrite !== void 0 && pricing.cacheWrite1h !== void 0) return pricing;
77
+ return {
78
+ ...pricing,
79
+ cacheWrite: pricing.cacheWrite ?? pricing.cachedOutput ?? round(pricing.input * 1.25),
80
+ cacheWrite1h: pricing.cacheWrite1h ?? round(pricing.input * 2)
81
+ };
82
+ }
83
+ function claude(input, output, cachedInput) {
84
+ return {
85
+ input,
86
+ output,
87
+ cachedInput,
88
+ cacheWrite: round(input * 1.25),
89
+ cacheWrite1h: round(input * 2)
90
+ };
91
+ }
92
+ /** Trim binary floating-point noise (2.2 * 1.25 = 2.7500000000000004). */
93
+ function round(value) {
94
+ return Math.round(value * 1e9) / 1e9;
95
+ }
96
+
97
+ //#endregion
98
+ export { BEDROCK_GLOBAL_PRICING, BEDROCK_US_PRICING, bedrockPricingFor, withClaudeCacheWriteRates };
99
+ //# sourceMappingURL=known-pricing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"known-pricing.mjs","names":[],"sources":["../../../../../../../packages/ai-bedrock/src/known-pricing.ts"],"sourcesContent":["import type { ModelPricing } from \"@warlock.js/ai\";\n\n/**\n * Bedrock on-demand list prices for Anthropic Claude, USD per 1,000,000\n * tokens, keyed by Bedrock model id (without an inference-profile\n * prefix). `cacheWrite` is the 5-minute write rate, `cacheWrite1h` the\n * 1-hour write rate, `cachedInput` the cache-read rate.\n *\n * Source: https://aws.amazon.com/bedrock/pricing/ — the page's own price\n * feed for \"US East (N. Virginia)\", fetched 2026-10-17 (Sonnet 5.5 cache\n * reads already at the rate effective 2026-10-07). Model ids from\n * https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html.\n *\n * Two tables, because AWS prices them differently:\n * - {@link BEDROCK_GLOBAL_PRICING} — `global.` cross-Region inference\n * profiles.\n * - {@link BEDROCK_US_PRICING} — `us.` geographic profiles (the\n * \"Geo / In-region\" rates, 10% above global for these models).\n *\n * In-Region ids without a profile prefix, other geographies (`eu.`,\n * `apac.`, …), Claude Haiku 5.5 and non-Claude models stay unpriced —\n * their rates vary by Region or were not verified — so pass `pricing`\n * yourself for them.\n */\nexport const BEDROCK_GLOBAL_PRICING: Readonly<Record<string, ModelPricing>> = {\n \"anthropic.claude-sonnet-5-5\": claude(2, 10, 0.1),\n \"anthropic.claude-opus-5-5\": claude(4, 20, 0.2),\n \"anthropic.claude-fable-5-1\": claude(10, 50, 0.25),\n \"anthropic.claude-opus-5\": claude(5, 25, 0.5),\n \"anthropic.claude-sonnet-5\": claude(2, 10, 0.2),\n \"anthropic.claude-fable-5\": claude(10, 50, 1),\n \"anthropic.claude-opus-4-8\": claude(5, 25, 0.5),\n \"anthropic.claude-opus-4-7\": claude(5, 25, 0.5),\n \"anthropic.claude-opus-4-6-v1\": claude(5, 25, 0.5),\n \"anthropic.claude-sonnet-4-6\": claude(3, 15, 0.3),\n \"anthropic.claude-opus-4-5-20251101-v1:0\": claude(5, 25, 0.5),\n \"anthropic.claude-sonnet-4-5-20250929-v1:0\": claude(3, 15, 0.3),\n \"anthropic.claude-haiku-4-5-20251001-v1:0\": claude(1, 5, 0.1),\n};\n\n/** `us.` geographic-profile prices — see {@link BEDROCK_GLOBAL_PRICING}. */\nexport const BEDROCK_US_PRICING: Readonly<Record<string, ModelPricing>> = {\n \"anthropic.claude-sonnet-5-5\": claude(2.2, 11, 0.11),\n \"anthropic.claude-opus-5-5\": claude(4.4, 22, 0.22),\n \"anthropic.claude-fable-5-1\": claude(11, 55, 0.275),\n \"anthropic.claude-opus-5\": claude(5.5, 27.5, 0.55),\n \"anthropic.claude-sonnet-5\": claude(2.2, 11, 0.22),\n \"anthropic.claude-fable-5\": claude(11, 55, 1.1),\n \"anthropic.claude-opus-4-8\": claude(5.5, 27.5, 0.55),\n \"anthropic.claude-opus-4-7\": claude(5.5, 27.5, 0.55),\n \"anthropic.claude-opus-4-6-v1\": claude(5.5, 27.5, 0.55),\n \"anthropic.claude-sonnet-4-6\": claude(3.3, 16.5, 0.33),\n \"anthropic.claude-opus-4-5-20251101-v1:0\": claude(5.5, 27.5, 0.55),\n \"anthropic.claude-sonnet-4-5-20250929-v1:0\": claude(3.3, 16.5, 0.33),\n \"anthropic.claude-haiku-4-5-20251001-v1:0\": claude(1.1, 5.5, 0.11),\n};\n\n/**\n * Look up the built-in price for a Bedrock model id or inference-profile\n * id: `global.<model>` reads {@link BEDROCK_GLOBAL_PRICING}, `us.<model>`\n * reads {@link BEDROCK_US_PRICING}; anything else is `undefined`.\n *\n * @example\n * bedrockPricingFor(\"global.anthropic.claude-sonnet-4-6\"); // { input: 3, output: 15, … }\n * bedrockPricingFor(\"anthropic.claude-sonnet-4-6\"); // undefined — in-Region rates vary\n */\nexport function bedrockPricingFor(modelId: string): ModelPricing | undefined {\n if (modelId.startsWith(\"global.\")) {\n return BEDROCK_GLOBAL_PRICING[modelId.slice(\"global.\".length)];\n }\n\n if (modelId.startsWith(\"us.\")) {\n return BEDROCK_US_PRICING[modelId.slice(\"us.\".length)];\n }\n\n return undefined;\n}\n\n/**\n * Fill the Claude cache-write rates (5-minute 1.25x, 1-hour 2x the input\n * rate — the ratio of every Claude row in the tables above) into a\n * caller-supplied entry for a Claude model that omits them. Non-Claude\n * models are returned unchanged.\n */\nexport function withClaudeCacheWriteRates(\n modelId: string,\n pricing: ModelPricing | undefined,\n): ModelPricing | undefined {\n if (!pricing || !modelId.toLowerCase().includes(\"anthropic.claude\")) {\n return pricing;\n }\n\n if (pricing.cacheWrite !== undefined && pricing.cacheWrite1h !== undefined) {\n return pricing;\n }\n\n return {\n ...pricing,\n cacheWrite: pricing.cacheWrite ?? pricing.cachedOutput ?? round(pricing.input * 1.25),\n cacheWrite1h: pricing.cacheWrite1h ?? round(pricing.input * 2),\n };\n}\n\nfunction claude(input: number, output: number, cachedInput: number): ModelPricing {\n return {\n input,\n output,\n cachedInput,\n cacheWrite: round(input * 1.25),\n cacheWrite1h: round(input * 2),\n };\n}\n\n/** Trim binary floating-point noise (2.2 * 1.25 = 2.7500000000000004). */\nfunction round(value: number): number {\n return Math.round(value * 1e9) / 1e9;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,yBAAiE;CAC5E,+BAA+B,OAAO,GAAG,IAAI,EAAG;CAChD,6BAA6B,OAAO,GAAG,IAAI,EAAG;CAC9C,8BAA8B,OAAO,IAAI,IAAI,GAAI;CACjD,2BAA2B,OAAO,GAAG,IAAI,EAAG;CAC5C,6BAA6B,OAAO,GAAG,IAAI,EAAG;CAC9C,4BAA4B,OAAO,IAAI,IAAI,CAAC;CAC5C,6BAA6B,OAAO,GAAG,IAAI,EAAG;CAC9C,6BAA6B,OAAO,GAAG,IAAI,EAAG;CAC9C,gCAAgC,OAAO,GAAG,IAAI,EAAG;CACjD,+BAA+B,OAAO,GAAG,IAAI,EAAG;CAChD,2CAA2C,OAAO,GAAG,IAAI,EAAG;CAC5D,6CAA6C,OAAO,GAAG,IAAI,EAAG;CAC9D,4CAA4C,OAAO,GAAG,GAAG,EAAG;AAC9D;;AAGA,MAAa,qBAA6D;CACxE,+BAA+B,OAAO,KAAK,IAAI,GAAI;CACnD,6BAA6B,OAAO,KAAK,IAAI,GAAI;CACjD,8BAA8B,OAAO,IAAI,IAAI,IAAK;CAClD,2BAA2B,OAAO,KAAK,MAAM,GAAI;CACjD,6BAA6B,OAAO,KAAK,IAAI,GAAI;CACjD,4BAA4B,OAAO,IAAI,IAAI,GAAG;CAC9C,6BAA6B,OAAO,KAAK,MAAM,GAAI;CACnD,6BAA6B,OAAO,KAAK,MAAM,GAAI;CACnD,gCAAgC,OAAO,KAAK,MAAM,GAAI;CACtD,+BAA+B,OAAO,KAAK,MAAM,GAAI;CACrD,2CAA2C,OAAO,KAAK,MAAM,GAAI;CACjE,6CAA6C,OAAO,KAAK,MAAM,GAAI;CACnE,4CAA4C,OAAO,KAAK,KAAK,GAAI;AACnE;;;;;;;;;;AAWA,SAAgB,kBAAkB,SAA2C;CAC3E,IAAI,QAAQ,WAAW,SAAS,GAC9B,OAAO,uBAAuB,QAAQ,MAAM,CAAgB;CAG9D,IAAI,QAAQ,WAAW,KAAK,GAC1B,OAAO,mBAAmB,QAAQ,MAAM,CAAY;AAIxD;;;;;;;AAQA,SAAgB,0BACd,SACA,SAC0B;CAC1B,IAAI,CAAC,WAAW,CAAC,QAAQ,YAAY,CAAC,CAAC,SAAS,kBAAkB,GAChE,OAAO;CAGT,IAAI,QAAQ,eAAe,UAAa,QAAQ,iBAAiB,QAC/D,OAAO;CAGT,OAAO;EACL,GAAG;EACH,YAAY,QAAQ,cAAc,QAAQ,gBAAgB,MAAM,QAAQ,QAAQ,IAAI;EACpF,cAAc,QAAQ,gBAAgB,MAAM,QAAQ,QAAQ,CAAC;CAC/D;AACF;AAEA,SAAS,OAAO,OAAe,QAAgB,aAAmC;CAChF,OAAO;EACL;EACA;EACA;EACA,YAAY,MAAM,QAAQ,IAAI;EAC9B,cAAc,MAAM,QAAQ,CAAC;CAC/B;AACF;;AAGA,SAAS,MAAM,OAAuB;CACpC,OAAO,KAAK,MAAM,QAAQ,GAAG,IAAI;AACnC"}
@@ -1,4 +1,4 @@
1
- //#region ../ai-bedrock/src/known-vision-models.ts
1
+ //#region ../../packages/ai-bedrock/src/known-vision-models.ts
2
2
  /**
3
3
  * Substrings that identify Bedrock model ids whose family accepts image
4
4
  * input on the Converse API.
@@ -1 +1 @@
1
- {"version":3,"file":"known-vision-models.mjs","names":[],"sources":["../../../../../../ai-bedrock/src/known-vision-models.ts"],"sourcesContent":["/**\n * Substrings that identify Bedrock model ids whose family accepts image\n * input on the Converse API.\n *\n * Bedrock model ids are provider-prefixed and version-suffixed\n * (`anthropic.claude-3-5-sonnet-20240620-v1:0`, `us.amazon.nova-pro-v1:0`,\n * `meta.llama3-2-90b-instruct-v1:0`), so a substring match is the only\n * robust check across the cross-region inference-profile prefixes\n * (`us.`, `eu.`, `apac.`) and date/version tags.\n *\n * Multimodal families covered: Anthropic Claude 3 / 3.5 / 3.7 / 4,\n * Amazon Nova Lite/Pro/Premier, Meta Llama 3.2 (11B/90B) and Llama 4.\n * Text-only families (Llama 3/3.1, Titan Text, Mistral 7B, Cohere\n * Command) are intentionally absent. Override per-model via\n * `bedrock.model({ name, vision: true | false })`.\n */\nconst VISION_CAPABLE_SUBSTRINGS = [\n \"claude-3\",\n \"claude-sonnet-4\",\n \"claude-opus-4\",\n \"claude-haiku-4\",\n \"nova-lite\",\n \"nova-pro\",\n \"nova-premier\",\n \"llama3-2-11b\",\n \"llama3-2-90b\",\n \"llama4\",\n];\n\n/**\n * Infer whether a Bedrock model id supports vision based on the known\n * multimodal-family substrings. Unknown ids default to `false` so that\n * passing an image attachment to an unsupported model surfaces a clear,\n * agent-side capability error instead of an opaque Bedrock validation\n * fault.\n *\n * @example\n * inferVisionCapability(\"anthropic.claude-3-5-sonnet-20240620-v1:0\"); // → true\n * inferVisionCapability(\"us.amazon.nova-pro-v1:0\"); // → true\n * inferVisionCapability(\"meta.llama3-1-8b-instruct-v1:0\"); // → false\n * inferVisionCapability(\"amazon.titan-text-express-v1\"); // → false\n */\nexport function inferVisionCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return VISION_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,MAAM,4BAA4B;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;;;AAeA,SAAgB,sBAAsB,SAA0B;CAC9D,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,0BAA0B,MAAM,aAAa,WAAW,SAAS,QAAQ,CAAC;AACnF"}
1
+ {"version":3,"file":"known-vision-models.mjs","names":[],"sources":["../../../../../../../packages/ai-bedrock/src/known-vision-models.ts"],"sourcesContent":["/**\n * Substrings that identify Bedrock model ids whose family accepts image\n * input on the Converse API.\n *\n * Bedrock model ids are provider-prefixed and version-suffixed\n * (`anthropic.claude-3-5-sonnet-20240620-v1:0`, `us.amazon.nova-pro-v1:0`,\n * `meta.llama3-2-90b-instruct-v1:0`), so a substring match is the only\n * robust check across the cross-region inference-profile prefixes\n * (`us.`, `eu.`, `apac.`) and date/version tags.\n *\n * Multimodal families covered: Anthropic Claude 3 / 3.5 / 3.7 / 4,\n * Amazon Nova Lite/Pro/Premier, Meta Llama 3.2 (11B/90B) and Llama 4.\n * Text-only families (Llama 3/3.1, Titan Text, Mistral 7B, Cohere\n * Command) are intentionally absent. Override per-model via\n * `bedrock.model({ name, vision: true | false })`.\n */\nconst VISION_CAPABLE_SUBSTRINGS = [\n \"claude-3\",\n \"claude-sonnet-4\",\n \"claude-opus-4\",\n \"claude-haiku-4\",\n \"nova-lite\",\n \"nova-pro\",\n \"nova-premier\",\n \"llama3-2-11b\",\n \"llama3-2-90b\",\n \"llama4\",\n];\n\n/**\n * Infer whether a Bedrock model id supports vision based on the known\n * multimodal-family substrings. Unknown ids default to `false` so that\n * passing an image attachment to an unsupported model surfaces a clear,\n * agent-side capability error instead of an opaque Bedrock validation\n * fault.\n *\n * @example\n * inferVisionCapability(\"anthropic.claude-3-5-sonnet-20240620-v1:0\"); // → true\n * inferVisionCapability(\"us.amazon.nova-pro-v1:0\"); // → true\n * inferVisionCapability(\"meta.llama3-1-8b-instruct-v1:0\"); // → false\n * inferVisionCapability(\"amazon.titan-text-express-v1\"); // → false\n */\nexport function inferVisionCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return VISION_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,MAAM,4BAA4B;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;;;AAeA,SAAgB,sBAAsB,SAA0B;CAC9D,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,0BAA0B,MAAM,aAAa,WAAW,SAAS,QAAQ,CAAC;AACnF"}
package/esm/model.mjs CHANGED
@@ -4,14 +4,20 @@ import { toBedrockMessages } from "./utils/to-bedrock-messages.mjs";
4
4
  import { toBedrockToolConfig } from "./utils/to-bedrock-tools.mjs";
5
5
  import { wrapBedrockError } from "./utils/wrap-bedrock-error.mjs";
6
6
  import "./utils/index.mjs";
7
- import { inferPdfCapability, inferPromptCachingCapability, inferReasoningCapability } from "./known-capabilities.mjs";
7
+ import { mergeProviderBody } from "./provider-options.mjs";
8
+ import { inferPdfCapability, inferPromptCachingCapability, inferReasoningCapability, supportsOneHourCacheTtl, supportsToolCachePoint } from "./known-capabilities.mjs";
9
+ import { bedrockPricingFor, withClaudeCacheWriteRates } from "./known-pricing.mjs";
8
10
  import { inferVisionCapability } from "./known-vision-models.mjs";
9
- import { ConverseCommand, ConverseStreamCommand } from "@aws-sdk/client-bedrock-runtime";
10
- import { safeJsonParse } from "@warlock.js/ai";
11
+ import { ConverseCommand, ConverseStreamCommand, CountTokensCommand } from "@aws-sdk/client-bedrock-runtime";
12
+ import { InvalidRequestError, attachCost, resolveStreamChunks, safeJsonParse, selectProviderTools } from "@warlock.js/ai";
11
13
  import { log } from "@warlock.js/logger";
12
14
 
13
- //#region ../ai-bedrock/src/model.ts
15
+ //#region ../../packages/ai-bedrock/src/model.ts
14
16
  const LOG_MODULE = "ai.bedrock";
17
+ /** `provider` value of `ai.providerTool()` entries this adapter sends verbatim. */
18
+ const BEDROCK_WIRE_FORMAT = "bedrock";
19
+ /** Converse `ToolUseBlock.type` of a tool use run by Bedrock itself (SDK `ToolUseType`). */
20
+ const SERVER_TOOL_USE = "server_tool_use";
15
21
  /** Default output allowance added to a thinking budget when maxTokens is unset. */
16
22
  const DEFAULT_MAX_TOKENS = 4096;
17
23
  const MIN_THINKING_BUDGET = 1024;
@@ -72,7 +78,7 @@ var BedrockModel = class {
72
78
  this.config = config;
73
79
  this.name = config.name;
74
80
  this.provider = provider;
75
- this.pricing = config.pricing;
81
+ this.pricing = withClaudeCacheWriteRates(config.name, config.pricing ?? bedrockPricingFor(config.name));
76
82
  this.capabilities = {
77
83
  structuredOutput: config.structuredOutput ?? true,
78
84
  vision: config.vision ?? inferVisionCapability(config.name),
@@ -103,7 +109,7 @@ var BedrockModel = class {
103
109
  }
104
110
  const blocks = response.output?.message?.content ?? [];
105
111
  const finishReason = mapStopReason(response.stopReason);
106
- const usage = this.extractUsage(response.usage);
112
+ const usage = attachCost(this.extractUsage(response.usage), this.pricing);
107
113
  const toolCalls = this.extractToolCalls(blocks);
108
114
  this.logger.debug(LOG_MODULE, "response", "Converse call succeeded", {
109
115
  finishReason,
@@ -116,11 +122,36 @@ var BedrockModel = class {
116
122
  toolCalls
117
123
  };
118
124
  }
125
+ /** Count native input tokens from the same Converse conversation and tool configuration. */
126
+ async countTokens(messages, options) {
127
+ const request = this.buildRequest(messages, options);
128
+ try {
129
+ const response = await this.client.send(new CountTokensCommand({
130
+ modelId: request.modelId,
131
+ input: { converse: {
132
+ messages: request.messages,
133
+ system: request.system,
134
+ toolConfig: request.toolConfig,
135
+ additionalModelRequestFields: request.additionalModelRequestFields
136
+ } }
137
+ }), options?.signal ? { abortSignal: options.signal } : void 0);
138
+ if (response.inputTokens === void 0) throw new InvalidRequestError("Bedrock countTokens returned no inputTokens.");
139
+ return response.inputTokens;
140
+ } catch (thrown) {
141
+ throw this.logAndWrap(thrown);
142
+ }
143
+ }
119
144
  /**
120
145
  * Incremental streaming completion via ConverseStream. Yields neutral
121
146
  * `ModelStreamChunk`s — `delta` for text, `tool-call` once a
122
147
  * `toolUse` block's accumulated input JSON is complete, and a
123
148
  * terminal `done` with the final finish reason + usage totals.
149
+ *
150
+ * With `options.streamChunks` it also yields `reasoning` for each
151
+ * `reasoningContent.text` delta and `tool-args` for each client
152
+ * `toolUse.input` delta. Usage arrives once, in the final `metadata`
153
+ * event, so no `usage` chunk is emitted. A system tool's
154
+ * `server_tool_use` block never becomes a `tool-call`.
124
155
  */
125
156
  async *stream(messages, options) {
126
157
  this.logger.debug(LOG_MODULE, "request", "Starting ConverseStream call", {
@@ -136,11 +167,12 @@ var BedrockModel = class {
136
167
  throw this.logAndWrap(thrown);
137
168
  }
138
169
  let rawStopReason;
139
- const usage = {
170
+ let usage = {
140
171
  input: 0,
141
172
  output: 0,
142
173
  total: 0
143
174
  };
175
+ const want = resolveStreamChunks(options);
144
176
  const toolBlocks = /* @__PURE__ */ new Map();
145
177
  const reasoningBlocks = /* @__PURE__ */ new Map();
146
178
  const completedReasoningBlocks = [];
@@ -148,6 +180,7 @@ var BedrockModel = class {
148
180
  for await (const event of response.stream ?? []) {
149
181
  if (event.contentBlockStart?.start?.toolUse) {
150
182
  const start = event.contentBlockStart.start.toolUse;
183
+ if (start.type === SERVER_TOOL_USE) continue;
151
184
  toolBlocks.set(event.contentBlockStart.contentBlockIndex ?? 0, {
152
185
  id: start.toolUseId ?? "",
153
186
  name: start.name ?? "",
@@ -163,11 +196,25 @@ var BedrockModel = class {
163
196
  };
164
197
  else if (delta.toolUse) {
165
198
  const accumulator = toolBlocks.get(event.contentBlockDelta.contentBlockIndex ?? 0);
166
- if (accumulator) accumulator.json += delta.toolUse.input ?? "";
199
+ if (accumulator) {
200
+ accumulator.json += delta.toolUse.input ?? "";
201
+ if (want.toolArgs && delta.toolUse.input) yield {
202
+ type: "tool-args",
203
+ callId: accumulator.id,
204
+ name: accumulator.name,
205
+ delta: delta.toolUse.input
206
+ };
207
+ }
167
208
  } else if (delta.reasoningContent) {
168
209
  const index = event.contentBlockDelta.contentBlockIndex ?? 0;
169
210
  const accumulator = reasoningBlocks.get(index) ?? {};
170
- if (delta.reasoningContent.text !== void 0) accumulator.text = (accumulator.text ?? "") + delta.reasoningContent.text;
211
+ if (delta.reasoningContent.text !== void 0) {
212
+ accumulator.text = (accumulator.text ?? "") + delta.reasoningContent.text;
213
+ if (want.reasoning && delta.reasoningContent.text !== "") yield {
214
+ type: "reasoning",
215
+ delta: delta.reasoningContent.text
216
+ };
217
+ }
171
218
  if (delta.reasoningContent.signature !== void 0) accumulator.signature = delta.reasoningContent.signature;
172
219
  if (delta.reasoningContent.redactedContent !== void 0) accumulator.redactedContent = delta.reasoningContent.redactedContent;
173
220
  reasoningBlocks.set(index, accumulator);
@@ -196,19 +243,13 @@ var BedrockModel = class {
196
243
  continue;
197
244
  }
198
245
  if (event.messageStop) rawStopReason = event.messageStop.stopReason;
199
- if (event.metadata?.usage) {
200
- const raw = event.metadata.usage;
201
- usage.input = raw.inputTokens ?? 0;
202
- usage.output = raw.outputTokens ?? 0;
203
- usage.total = raw.totalTokens ?? usage.input + usage.output;
204
- if (raw.cacheReadInputTokens && raw.cacheReadInputTokens > 0) usage.cachedTokens = raw.cacheReadInputTokens;
205
- if (raw.cacheWriteInputTokens && raw.cacheWriteInputTokens > 0) usage.cacheWriteTokens = raw.cacheWriteInputTokens;
206
- }
246
+ if (event.metadata?.usage) usage = this.extractUsage(event.metadata.usage);
207
247
  }
208
248
  } catch (thrown) {
209
249
  throw this.logAndWrap(thrown);
210
250
  }
211
251
  const finishReason = mapStopReason(rawStopReason);
252
+ attachCost(usage, this.pricing);
212
253
  this.logger.debug(LOG_MODULE, "response", "ConverseStream call succeeded", {
213
254
  finishReason,
214
255
  usage
@@ -231,44 +272,58 @@ var BedrockModel = class {
231
272
  const configuredMaxTokens = options?.maxTokens ?? this.config.maxTokens;
232
273
  const maxTokens = this.resolveMaxTokens(configuredMaxTokens, thinkingBudget);
233
274
  const temperature = options?.temperature ?? this.config.temperature;
234
- const cachedMessages = this.applyCacheBreakpoints(bedrockMessages, options?.cacheControl);
235
- return {
275
+ const cachePoint = this.resolveCachePoint(options?.cacheControl);
276
+ const cachedMessages = this.applyCacheBreakpoints(bedrockMessages, cachePoint);
277
+ const cachedSystem = system && cachePoint ? [...system, { cachePoint }] : system;
278
+ return mergeProviderBody({
236
279
  modelId: this.name,
237
280
  messages: cachedMessages,
238
- ...system ? { system } : {},
281
+ ...cachedSystem ? { system: cachedSystem } : {},
239
282
  inferenceConfig: {
240
283
  ...maxTokens !== void 0 ? { maxTokens } : {},
241
284
  ...temperature !== void 0 ? { temperature } : {}
242
285
  },
243
- ...this.buildToolConfig(options?.tools),
286
+ ...this.buildToolConfig(options, cachePoint),
244
287
  ...this.buildOutputConfig(options?.responseSchema),
245
288
  ...this.buildReasoningConfig(thinkingBudget)
246
- };
289
+ }, options);
247
290
  }
248
291
  /**
249
- * Append a Converse `cachePoint` block to the LAST message when the
250
- * caller supplies a `cacheControl` write breakpoint and the model is
251
- * `promptCaching`-capable. A cache point tells Bedrock to cache the
252
- * whole prefix up to that block, so subsequent calls reusing the same
253
- * prefix bill the cached portion at the discounted read rate
254
- * (surfaced as `Usage.cachedTokens`). No-ops gracefully when caching
255
- * is unsupported, no breakpoint was requested, or there are no
256
- * messages to mark — Bedrock then prices the call normally.
292
+ * Resolve the Converse `cachePoint` to place for this call, or
293
+ * `undefined` when no cache point applies (the model is not
294
+ * `promptCaching`-capable or no `cacheControl` breakpoint was asked
295
+ * for). Bedrock only honors `type: "default"`; the neutral
296
+ * `breakpoints` count is a presence hint.
257
297
  *
258
- * Bedrock only honors `CachePointType.DEFAULT`; the neutral
259
- * `breakpoints` count is a presence hint (one trailing breakpoint is
260
- * the only placement Converse supports without manual block surgery),
261
- * so any positive value marks the trailing message.
298
+ * The lifetime is the per-call `cacheControl.ttl`, else the model's
299
+ * `promptCacheTtl`. `ttl: "1h"` is sent only to models that accept it
300
+ * ({@link supportsOneHourCacheTtl}); any other model gets the 5-minute
301
+ * default, because AWS rejects the field there.
262
302
  */
263
- applyCacheBreakpoints(messages, cacheControl) {
303
+ resolveCachePoint(cacheControl) {
264
304
  const breakpoints = cacheControl?.breakpoints ?? 0;
265
- if (!this.capabilities.promptCaching || breakpoints <= 0 || !messages || messages.length === 0) return messages;
305
+ if (!this.capabilities.promptCaching || breakpoints <= 0) return;
306
+ return (cacheControl?.ttl ?? this.config.promptCacheTtl) === "1h" && supportsOneHourCacheTtl(this.name) ? {
307
+ type: "default",
308
+ ttl: "1h"
309
+ } : { type: "default" };
310
+ }
311
+ /**
312
+ * Append the call's `cachePoint` to the LAST message. Together with the
313
+ * `system` and `tools` cache points (see `buildRequest` /
314
+ * `buildToolConfig`) this caches every stable segment of the prefix —
315
+ * Bedrock processes them in `tools` → `system` → `messages` order, at
316
+ * most three of the four checkpoints it allows — so later calls reusing
317
+ * the prefix bill it at the cache-read rate (`Usage.cachedTokens`).
318
+ */
319
+ applyCacheBreakpoints(messages, cachePoint) {
320
+ if (!cachePoint || !messages || messages.length === 0) return messages;
266
321
  const last = messages.length - 1;
267
322
  const lastMessage = messages[last];
268
323
  if (!lastMessage) return messages;
269
324
  return [...messages.slice(0, last), {
270
325
  ...lastMessage,
271
- content: [...lastMessage.content ?? [], { cachePoint: { type: "default" } }]
326
+ content: [...lastMessage.content ?? [], { cachePoint }]
272
327
  }];
273
328
  }
274
329
  /**
@@ -304,11 +359,26 @@ var BedrockModel = class {
304
359
  }
305
360
  /**
306
361
  * Spread-friendly tool fragment. Returns an empty object when no
307
- * tools were supplied (Bedrock rejects an empty `tools` array).
362
+ * tools were supplied (Bedrock rejects an empty `tools` array). With a
363
+ * cache point, a trailing `{ cachePoint }` caches every tool definition
364
+ * — Claude only, since Nova accepts no cache point in `tools`.
308
365
  */
309
- buildToolConfig(tools) {
366
+ buildToolConfig(options, cachePoint) {
367
+ const { tools, definitions } = selectProviderTools(options, {
368
+ accepts: [BEDROCK_WIRE_FORMAT, this.provider],
369
+ module: LOG_MODULE,
370
+ model: this.name,
371
+ logger: this.logger
372
+ });
310
373
  const toolConfig = toBedrockToolConfig(tools);
311
- return toolConfig ? { toolConfig } : {};
374
+ const providerDefined = definitions;
375
+ const allTools = [...toolConfig?.tools ?? [], ...providerDefined];
376
+ if (allTools.length === 0) return toolConfig ? { toolConfig } : {};
377
+ const withCachePoint = cachePoint && supportsToolCachePoint(this.name) ? [...allTools, { cachePoint }] : allTools;
378
+ return { toolConfig: {
379
+ ...toolConfig,
380
+ tools: withCachePoint
381
+ } };
312
382
  }
313
383
  /**
314
384
  * Translate the neutral `responseSchema` into Converse's native
@@ -346,7 +416,7 @@ var BedrockModel = class {
346
416
  extractToolCalls(blocks) {
347
417
  const toolCalls = [];
348
418
  const reasoningBlocks = blocks.map(toReasoningMetadata).filter((block) => block !== void 0);
349
- for (const block of blocks) if ("toolUse" in block && block.toolUse) toolCalls.push({
419
+ for (const block of blocks) if ("toolUse" in block && block.toolUse && block.toolUse.type !== SERVER_TOOL_USE) toolCalls.push({
350
420
  id: block.toolUse.toolUseId ?? "",
351
421
  name: block.toolUse.name ?? "",
352
422
  input: block.toolUse.input ?? {},
@@ -366,10 +436,13 @@ var BedrockModel = class {
366
436
  * Normalize Converse's `TokenUsage` into the neutral `Usage` shape.
367
437
  * Bedrock supplies a pre-summed `totalTokens`; cache-read and
368
438
  * cache-write tokens are surfaced as `cachedTokens` /
369
- * `cacheWriteTokens` only when non-zero so callers can price the
370
- * discounted read rate and the one-time write cost separately.
371
- * Bedrock's Converse `TokenUsage` carries no reasoning-token channel,
372
- * so `Usage.reasoningTokens` is intentionally left unset here.
439
+ * `cacheWriteTokens` only when non-zero, and the 1-hour share of the
440
+ * writes (`cacheDetails` entries with `ttl: "1h"`) as
441
+ * `cacheWrite1hTokens`. With caching, `inputTokens` "represents only
442
+ * the non-cached input tokens" (AWS prompt-caching guide), so the usage
443
+ * is marked `inputIncludesCache: false`. Bedrock's Converse `TokenUsage`
444
+ * carries no reasoning-token channel, so `Usage.reasoningTokens` is
445
+ * intentionally left unset here.
373
446
  */
374
447
  extractUsage(raw) {
375
448
  if (!raw) return {
@@ -381,12 +454,15 @@ var BedrockModel = class {
381
454
  const output = raw.outputTokens ?? 0;
382
455
  const cached = raw.cacheReadInputTokens;
383
456
  const cacheWrite = raw.cacheWriteInputTokens;
457
+ const cacheWrite1h = (raw.cacheDetails ?? []).filter((detail) => detail.ttl === "1h").reduce((sum, detail) => sum + (detail.inputTokens ?? 0), 0);
384
458
  return {
385
459
  input,
386
460
  output,
387
461
  total: raw.totalTokens ?? input + output,
462
+ inputIncludesCache: false,
388
463
  ...cached && cached > 0 ? { cachedTokens: cached } : {},
389
- ...cacheWrite && cacheWrite > 0 ? { cacheWriteTokens: cacheWrite } : {}
464
+ ...cacheWrite && cacheWrite > 0 ? { cacheWriteTokens: cacheWrite } : {},
465
+ ...cacheWrite && cacheWrite > 0 && cacheWrite1h > 0 ? { cacheWrite1hTokens: Math.min(cacheWrite1h, cacheWrite) } : {}
390
466
  };
391
467
  }
392
468
  /**