@opencode/ai 0.0.0-reserved → 2.0.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 (288) hide show
  1. package/README.md +879 -2
  2. package/dist/cache-policy.d.ts +2 -0
  3. package/dist/cache-policy.js +129 -0
  4. package/dist/image-client.d.ts +19 -0
  5. package/dist/image-client.js +28 -0
  6. package/dist/image.d.ts +110 -0
  7. package/dist/image.js +103 -0
  8. package/dist/index.d.ts +18 -0
  9. package/dist/index.js +12 -0
  10. package/dist/llm.d.ts +252 -0
  11. package/dist/llm.js +74 -0
  12. package/dist/protocols/alibaba-chat.d.ts +225 -0
  13. package/dist/protocols/alibaba-chat.js +75 -0
  14. package/dist/protocols/alibaba-messages.d.ts +350 -0
  15. package/dist/protocols/alibaba-messages.js +40 -0
  16. package/dist/protocols/alibaba-responses.d.ts +255 -0
  17. package/dist/protocols/alibaba-responses.js +80 -0
  18. package/dist/protocols/anthropic-messages.d.ts +980 -0
  19. package/dist/protocols/anthropic-messages.js +1460 -0
  20. package/dist/protocols/bedrock-converse.d.ts +499 -0
  21. package/dist/protocols/bedrock-converse.js +643 -0
  22. package/dist/protocols/bedrock-event-stream.d.ts +9 -0
  23. package/dist/protocols/bedrock-event-stream.js +97 -0
  24. package/dist/protocols/gemini.d.ts +285 -0
  25. package/dist/protocols/gemini.js +671 -0
  26. package/dist/protocols/google-images.d.ts +30 -0
  27. package/dist/protocols/google-images.js +181 -0
  28. package/dist/protocols/index.d.ts +12 -0
  29. package/dist/protocols/index.js +12 -0
  30. package/dist/protocols/meta-images.d.ts +26 -0
  31. package/dist/protocols/meta-images.js +89 -0
  32. package/dist/protocols/meta-messages.d.ts +356 -0
  33. package/dist/protocols/meta-messages.js +41 -0
  34. package/dist/protocols/meta-responses.d.ts +473 -0
  35. package/dist/protocols/meta-responses.js +173 -0
  36. package/dist/protocols/mistral-chat.d.ts +540 -0
  37. package/dist/protocols/mistral-chat.js +624 -0
  38. package/dist/protocols/open-responses-channel.d.ts +25 -0
  39. package/dist/protocols/open-responses-channel.js +141 -0
  40. package/dist/protocols/open-responses-continuation.d.ts +16 -0
  41. package/dist/protocols/open-responses-continuation.js +170 -0
  42. package/dist/protocols/open-responses.d.ts +1715 -0
  43. package/dist/protocols/open-responses.js +1228 -0
  44. package/dist/protocols/openai-chat.d.ts +860 -0
  45. package/dist/protocols/openai-chat.js +966 -0
  46. package/dist/protocols/openai-compatible-chat.d.ts +109 -0
  47. package/dist/protocols/openai-compatible-chat.js +19 -0
  48. package/dist/protocols/openai-compatible-responses.d.ts +172 -0
  49. package/dist/protocols/openai-compatible-responses.js +18 -0
  50. package/dist/protocols/openai-images.d.ts +32 -0
  51. package/dist/protocols/openai-images.js +183 -0
  52. package/dist/protocols/openai-responses.d.ts +1389 -0
  53. package/dist/protocols/openai-responses.js +260 -0
  54. package/dist/protocols/shared.d.ts +193 -0
  55. package/dist/protocols/shared.js +290 -0
  56. package/dist/protocols/utils/bedrock-auth.d.ts +60 -0
  57. package/dist/protocols/utils/bedrock-auth.js +85 -0
  58. package/dist/protocols/utils/bedrock-cache.d.ts +19 -0
  59. package/dist/protocols/utils/bedrock-cache.js +49 -0
  60. package/dist/protocols/utils/bedrock-media.d.ts +55 -0
  61. package/dist/protocols/utils/bedrock-media.js +73 -0
  62. package/dist/protocols/utils/cache.d.ts +6 -0
  63. package/dist/protocols/utils/cache.js +5 -0
  64. package/dist/protocols/utils/gemini-tool-schema.d.ts +2 -0
  65. package/dist/protocols/utils/gemini-tool-schema.js +103 -0
  66. package/dist/protocols/utils/image-input.d.ts +21 -0
  67. package/dist/protocols/utils/image-input.js +20 -0
  68. package/dist/protocols/utils/lifecycle.d.ts +24 -0
  69. package/dist/protocols/utils/lifecycle.js +72 -0
  70. package/dist/protocols/utils/meta-image.d.ts +2 -0
  71. package/dist/protocols/utils/meta-image.js +13 -0
  72. package/dist/protocols/utils/open-responses-options.d.ts +56 -0
  73. package/dist/protocols/utils/open-responses-options.js +61 -0
  74. package/dist/protocols/utils/openai-image.d.ts +5 -0
  75. package/dist/protocols/utils/openai-image.js +18 -0
  76. package/dist/protocols/utils/openai-options.d.ts +16 -0
  77. package/dist/protocols/utils/openai-options.js +14 -0
  78. package/dist/protocols/utils/partial-json-options.d.ts +62 -0
  79. package/dist/protocols/utils/partial-json-options.js +52 -0
  80. package/dist/protocols/utils/partial-json.d.ts +8 -0
  81. package/dist/protocols/utils/partial-json.js +279 -0
  82. package/dist/protocols/utils/responses-checkpoint.d.ts +4 -0
  83. package/dist/protocols/utils/responses-checkpoint.js +107 -0
  84. package/dist/protocols/utils/responses-compaction.d.ts +4 -0
  85. package/dist/protocols/utils/responses-compaction.js +129 -0
  86. package/dist/protocols/utils/responses-hosted-tools.d.ts +26 -0
  87. package/dist/protocols/utils/responses-hosted-tools.js +32 -0
  88. package/dist/protocols/utils/tool-schema.d.ts +8 -0
  89. package/dist/protocols/utils/tool-schema.js +54 -0
  90. package/dist/protocols/utils/tool-stream.d.ts +710 -0
  91. package/dist/protocols/utils/tool-stream.js +155 -0
  92. package/dist/protocols/xai-images.d.ts +26 -0
  93. package/dist/protocols/xai-images.js +106 -0
  94. package/dist/protocols/xai-responses.d.ts +250 -0
  95. package/dist/protocols/xai-responses.js +81 -0
  96. package/dist/protocols/zai-chat.d.ts +202 -0
  97. package/dist/protocols/zai-chat.js +49 -0
  98. package/dist/protocols/zai-images.d.ts +22 -0
  99. package/dist/protocols/zai-images.js +79 -0
  100. package/dist/protocols/zai-messages.d.ts +344 -0
  101. package/dist/protocols/zai-messages.js +27 -0
  102. package/dist/protocols.d.ts +1 -0
  103. package/dist/protocols.js +1 -0
  104. package/dist/provider-error.d.ts +15 -0
  105. package/dist/provider-error.js +125 -0
  106. package/dist/provider-package.d.ts +15 -0
  107. package/dist/provider-package.js +1 -0
  108. package/dist/provider.d.ts +23 -0
  109. package/dist/provider.js +2 -0
  110. package/dist/providers/alibaba/chat.d.ts +1 -0
  111. package/dist/providers/alibaba/chat.js +1 -0
  112. package/dist/providers/alibaba/messages.d.ts +3 -0
  113. package/dist/providers/alibaba/messages.js +1 -0
  114. package/dist/providers/alibaba/responses.d.ts +3 -0
  115. package/dist/providers/alibaba/responses.js +1 -0
  116. package/dist/providers/alibaba.d.ts +711 -0
  117. package/dist/providers/alibaba.js +94 -0
  118. package/dist/providers/amazon-bedrock/mantle/chat.d.ts +2 -0
  119. package/dist/providers/amazon-bedrock/mantle/chat.js +1 -0
  120. package/dist/providers/amazon-bedrock/mantle/responses.d.ts +2 -0
  121. package/dist/providers/amazon-bedrock/mantle/responses.js +1 -0
  122. package/dist/providers/amazon-bedrock/mantle.d.ts +2 -0
  123. package/dist/providers/amazon-bedrock/mantle.js +1 -0
  124. package/dist/providers/amazon-bedrock-mantle.d.ts +313 -0
  125. package/dist/providers/amazon-bedrock-mantle.js +79 -0
  126. package/dist/providers/amazon-bedrock.d.ts +173 -0
  127. package/dist/providers/amazon-bedrock.js +41 -0
  128. package/dist/providers/anthropic-compatible.d.ts +309 -0
  129. package/dist/providers/anthropic-compatible.js +50 -0
  130. package/dist/providers/anthropic.d.ts +307 -0
  131. package/dist/providers/anthropic.js +42 -0
  132. package/dist/providers/azure/chat.d.ts +2 -0
  133. package/dist/providers/azure/chat.js +1 -0
  134. package/dist/providers/azure/responses.d.ts +2 -0
  135. package/dist/providers/azure/responses.js +1 -0
  136. package/dist/providers/azure.d.ts +598 -0
  137. package/dist/providers/azure.js +115 -0
  138. package/dist/providers/baseten.d.ts +228 -0
  139. package/dist/providers/baseten.js +38 -0
  140. package/dist/providers/cerebras.d.ts +227 -0
  141. package/dist/providers/cerebras.js +40 -0
  142. package/dist/providers/cloudflare-ai-gateway.d.ts +237 -0
  143. package/dist/providers/cloudflare-ai-gateway.js +65 -0
  144. package/dist/providers/cloudflare-workers-ai.d.ts +231 -0
  145. package/dist/providers/cloudflare-workers-ai.js +51 -0
  146. package/dist/providers/deepinfra.d.ts +227 -0
  147. package/dist/providers/deepinfra.js +43 -0
  148. package/dist/providers/deepseek.d.ts +228 -0
  149. package/dist/providers/deepseek.js +41 -0
  150. package/dist/providers/fireworks.d.ts +228 -0
  151. package/dist/providers/fireworks.js +38 -0
  152. package/dist/providers/google-vertex/chat.d.ts +2 -0
  153. package/dist/providers/google-vertex/chat.js +1 -0
  154. package/dist/providers/google-vertex/gemini.d.ts +2 -0
  155. package/dist/providers/google-vertex/gemini.js +1 -0
  156. package/dist/providers/google-vertex/messages.d.ts +2 -0
  157. package/dist/providers/google-vertex/messages.js +1 -0
  158. package/dist/providers/google-vertex/responses.d.ts +2 -0
  159. package/dist/providers/google-vertex/responses.js +1 -0
  160. package/dist/providers/google-vertex-chat.d.ts +132 -0
  161. package/dist/providers/google-vertex-chat.js +55 -0
  162. package/dist/providers/google-vertex-messages.d.ts +306 -0
  163. package/dist/providers/google-vertex-messages.js +75 -0
  164. package/dist/providers/google-vertex-responses.d.ts +197 -0
  165. package/dist/providers/google-vertex-responses.js +56 -0
  166. package/dist/providers/google-vertex-shared.d.ts +22 -0
  167. package/dist/providers/google-vertex-shared.js +72 -0
  168. package/dist/providers/google-vertex.d.ts +119 -0
  169. package/dist/providers/google-vertex.js +98 -0
  170. package/dist/providers/google.d.ts +114 -0
  171. package/dist/providers/google.js +42 -0
  172. package/dist/providers/groq.d.ts +314 -0
  173. package/dist/providers/groq.js +81 -0
  174. package/dist/providers/index.d.ts +31 -0
  175. package/dist/providers/index.js +31 -0
  176. package/dist/providers/meta/chat.d.ts +2 -0
  177. package/dist/providers/meta/chat.js +1 -0
  178. package/dist/providers/meta/messages.d.ts +2 -0
  179. package/dist/providers/meta/messages.js +1 -0
  180. package/dist/providers/meta/responses.d.ts +2 -0
  181. package/dist/providers/meta/responses.js +1 -0
  182. package/dist/providers/meta.d.ts +636 -0
  183. package/dist/providers/meta.js +113 -0
  184. package/dist/providers/minimax/chat.d.ts +4 -0
  185. package/dist/providers/minimax/chat.js +8 -0
  186. package/dist/providers/minimax/messages.d.ts +1 -0
  187. package/dist/providers/minimax/messages.js +1 -0
  188. package/dist/providers/minimax/responses.d.ts +4 -0
  189. package/dist/providers/minimax/responses.js +8 -0
  190. package/dist/providers/minimax.d.ts +598 -0
  191. package/dist/providers/minimax.js +89 -0
  192. package/dist/providers/mistral.d.ts +207 -0
  193. package/dist/providers/mistral.js +28 -0
  194. package/dist/providers/moonshot/chat.d.ts +1 -0
  195. package/dist/providers/moonshot/chat.js +1 -0
  196. package/dist/providers/moonshot/messages.d.ts +4 -0
  197. package/dist/providers/moonshot/messages.js +8 -0
  198. package/dist/providers/moonshot/responses.d.ts +4 -0
  199. package/dist/providers/moonshot/responses.js +8 -0
  200. package/dist/providers/moonshot.d.ts +596 -0
  201. package/dist/providers/moonshot.js +90 -0
  202. package/dist/providers/open-responses-options.d.ts +6 -0
  203. package/dist/providers/open-responses-options.js +1 -0
  204. package/dist/providers/openai/chat.d.ts +2 -0
  205. package/dist/providers/openai/chat.js +1 -0
  206. package/dist/providers/openai/responses.d.ts +2 -0
  207. package/dist/providers/openai/responses.js +1 -0
  208. package/dist/providers/openai-compatible/responses.d.ts +1 -0
  209. package/dist/providers/openai-compatible/responses.js +1 -0
  210. package/dist/providers/openai-compatible-responses.d.ts +195 -0
  211. package/dist/providers/openai-compatible-responses.js +32 -0
  212. package/dist/providers/openai-compatible.d.ts +130 -0
  213. package/dist/providers/openai-compatible.js +33 -0
  214. package/dist/providers/openai-options.d.ts +26 -0
  215. package/dist/providers/openai-options.js +41 -0
  216. package/dist/providers/openai.d.ts +404 -0
  217. package/dist/providers/openai.js +82 -0
  218. package/dist/providers/openrouter.d.ts +563 -0
  219. package/dist/providers/openrouter.js +114 -0
  220. package/dist/providers/togetherai.d.ts +227 -0
  221. package/dist/providers/togetherai.js +40 -0
  222. package/dist/providers/xai.d.ts +163 -0
  223. package/dist/providers/xai.js +88 -0
  224. package/dist/providers/zai/chat.d.ts +1 -0
  225. package/dist/providers/zai/chat.js +1 -0
  226. package/dist/providers/zai-coding-plan/chat.d.ts +1 -0
  227. package/dist/providers/zai-coding-plan/chat.js +1 -0
  228. package/dist/providers/zai-coding-plan/messages.d.ts +4 -0
  229. package/dist/providers/zai-coding-plan/messages.js +8 -0
  230. package/dist/providers/zai-coding-plan/responses.d.ts +4 -0
  231. package/dist/providers/zai-coding-plan/responses.js +8 -0
  232. package/dist/providers/zai-coding-plan.d.ts +577 -0
  233. package/dist/providers/zai-coding-plan.js +63 -0
  234. package/dist/providers/zai.d.ts +149 -0
  235. package/dist/providers/zai.js +53 -0
  236. package/dist/providers.d.ts +1 -0
  237. package/dist/providers.js +1 -0
  238. package/dist/route/auth-options.d.ts +34 -0
  239. package/dist/route/auth-options.js +14 -0
  240. package/dist/route/auth.d.ts +51 -0
  241. package/dist/route/auth.js +87 -0
  242. package/dist/route/client.d.ts +430 -0
  243. package/dist/route/client.js +307 -0
  244. package/dist/route/endpoint.d.ts +28 -0
  245. package/dist/route/endpoint.js +21 -0
  246. package/dist/route/executor.d.ts +27 -0
  247. package/dist/route/executor.js +183 -0
  248. package/dist/route/framing.d.ts +29 -0
  249. package/dist/route/framing.js +14 -0
  250. package/dist/route/index.d.ts +16 -0
  251. package/dist/route/index.js +9 -0
  252. package/dist/route/protocol.d.ts +76 -0
  253. package/dist/route/protocol.js +16 -0
  254. package/dist/route/transport/http.d.ts +34 -0
  255. package/dist/route/transport/http.js +68 -0
  256. package/dist/route/transport/index.d.ts +41 -0
  257. package/dist/route/transport/index.js +4 -0
  258. package/dist/route/transport/websocket-channel.d.ts +57 -0
  259. package/dist/route/transport/websocket-channel.js +1 -0
  260. package/dist/route/transport/websocket.d.ts +56 -0
  261. package/dist/route/transport/websocket.js +370 -0
  262. package/dist/route.d.ts +1 -0
  263. package/dist/route.js +1 -0
  264. package/dist/schema/errors.d.ts +170 -0
  265. package/dist/schema/errors.js +131 -0
  266. package/dist/schema/events.d.ts +8123 -0
  267. package/dist/schema/events.js +550 -0
  268. package/dist/schema/ids.d.ts +17 -0
  269. package/dist/schema/ids.js +10 -0
  270. package/dist/schema/index.d.ts +5 -0
  271. package/dist/schema/index.js +5 -0
  272. package/dist/schema/messages.d.ts +646 -0
  273. package/dist/schema/messages.js +301 -0
  274. package/dist/schema/options.d.ts +159 -0
  275. package/dist/schema/options.js +189 -0
  276. package/dist/testing.d.ts +1693 -0
  277. package/dist/testing.js +129 -0
  278. package/dist/tool-history.d.ts +2 -0
  279. package/dist/tool-history.js +84 -0
  280. package/dist/tool-runtime.d.ts +15 -0
  281. package/dist/tool-runtime.js +62 -0
  282. package/dist/tool.d.ts +136 -0
  283. package/dist/tool.js +66 -0
  284. package/dist/utils/record.d.ts +2 -0
  285. package/dist/utils/record.js +2 -0
  286. package/dist/utils/sanitize.d.ts +1 -0
  287. package/dist/utils/sanitize.js +12 -0
  288. package/package.json +43 -10
@@ -0,0 +1,643 @@
1
+ import { Effect, Encoding, Schema } from "effect";
2
+ import { Route } from "../route/client.js";
3
+ import { Endpoint } from "../route/endpoint.js";
4
+ import { Protocol } from "../route/protocol.js";
5
+ import { AIError, LLMEvent, Usage, } from "../schema/index.js";
6
+ import { BedrockEventStream } from "./bedrock-event-stream.js";
7
+ import { classifyProviderFailure } from "../provider-error.js";
8
+ import { JsonObject, optionalArray, ProviderShared } from "./shared.js";
9
+ import { BedrockAuth } from "./utils/bedrock-auth.js";
10
+ import { BedrockCache } from "./utils/bedrock-cache.js";
11
+ import { BedrockMedia } from "./utils/bedrock-media.js";
12
+ import { Lifecycle } from "./utils/lifecycle.js";
13
+ import { ToolSchemaProjection } from "./utils/tool-schema.js";
14
+ import { ToolStream } from "./utils/tool-stream.js";
15
+ const ADAPTER = "bedrock-converse";
16
+ // =============================================================================
17
+ // Request Body Schema
18
+ // =============================================================================
19
+ const BedrockTextBlock = Schema.Struct({
20
+ text: Schema.String,
21
+ });
22
+ const BedrockToolUseBlock = Schema.Struct({
23
+ toolUse: Schema.Struct({
24
+ toolUseId: Schema.String,
25
+ name: Schema.String,
26
+ input: Schema.Unknown,
27
+ }),
28
+ });
29
+ const BedrockToolResultContentItem = Schema.Union([
30
+ Schema.Struct({ text: Schema.String }),
31
+ Schema.Struct({ json: Schema.Unknown }),
32
+ BedrockMedia.ImageBlock,
33
+ BedrockMedia.DocumentBlock,
34
+ ]);
35
+ const BedrockToolResultBlock = Schema.Struct({
36
+ toolResult: Schema.Struct({
37
+ toolUseId: Schema.String,
38
+ content: Schema.Array(BedrockToolResultContentItem),
39
+ status: Schema.optional(Schema.Literals(["success", "error"])),
40
+ }),
41
+ });
42
+ const BedrockReasoningBlock = Schema.Struct({
43
+ reasoningContent: Schema.Union([
44
+ Schema.Struct({
45
+ reasoningText: Schema.Struct({
46
+ text: Schema.String,
47
+ signature: Schema.optional(Schema.String),
48
+ }),
49
+ }),
50
+ Schema.Struct({ redactedContent: Schema.String }),
51
+ ]),
52
+ });
53
+ const BedrockUserBlock = Schema.Union([
54
+ BedrockTextBlock,
55
+ BedrockMedia.ImageBlock,
56
+ BedrockMedia.DocumentBlock,
57
+ BedrockToolResultBlock,
58
+ BedrockCache.CachePointBlock,
59
+ ]);
60
+ const BedrockAssistantBlock = Schema.Union([
61
+ BedrockTextBlock,
62
+ BedrockReasoningBlock,
63
+ BedrockToolUseBlock,
64
+ BedrockCache.CachePointBlock,
65
+ ]);
66
+ const BedrockMessage = Schema.Union([
67
+ Schema.Struct({ role: Schema.Literal("user"), content: Schema.Array(BedrockUserBlock) }),
68
+ Schema.Struct({ role: Schema.Literal("assistant"), content: Schema.Array(BedrockAssistantBlock) }),
69
+ ]).pipe(Schema.toTaggedUnion("role"));
70
+ const BedrockSystemBlock = Schema.Union([BedrockTextBlock, BedrockCache.CachePointBlock]);
71
+ const BedrockToolSpec = Schema.Struct({
72
+ toolSpec: Schema.Struct({
73
+ name: Schema.String,
74
+ description: Schema.String,
75
+ inputSchema: Schema.Struct({
76
+ json: JsonObject,
77
+ }),
78
+ }),
79
+ });
80
+ const BedrockTool = Schema.Union([BedrockToolSpec, BedrockCache.CachePointBlock]);
81
+ const BedrockToolChoice = Schema.Union([
82
+ Schema.Struct({ auto: Schema.Struct({}) }),
83
+ Schema.Struct({ any: Schema.Struct({}) }),
84
+ Schema.Struct({ tool: Schema.Struct({ name: Schema.String }) }),
85
+ ]);
86
+ const BedrockBodyFields = {
87
+ modelId: Schema.String,
88
+ messages: Schema.Array(BedrockMessage),
89
+ system: optionalArray(BedrockSystemBlock),
90
+ inferenceConfig: Schema.optional(Schema.Struct({
91
+ maxTokens: Schema.optional(Schema.Number),
92
+ temperature: Schema.optional(Schema.Number),
93
+ topP: Schema.optional(Schema.Number),
94
+ stopSequences: optionalArray(Schema.String),
95
+ })),
96
+ toolConfig: Schema.optional(Schema.Struct({
97
+ tools: Schema.Array(BedrockTool),
98
+ toolChoice: Schema.optional(BedrockToolChoice),
99
+ })),
100
+ additionalModelRequestFields: Schema.optional(JsonObject),
101
+ };
102
+ const BedrockConverseBody = Schema.Struct(BedrockBodyFields);
103
+ const BedrockUsageSchema = Schema.Struct({
104
+ inputTokens: Schema.optional(Schema.Number),
105
+ outputTokens: Schema.optional(Schema.Number),
106
+ totalTokens: Schema.optional(Schema.Number),
107
+ cacheReadInputTokens: Schema.optional(Schema.Number),
108
+ cacheWriteInputTokens: Schema.optional(Schema.Number),
109
+ });
110
+ const BedrockStreamException = Schema.Struct({
111
+ message: Schema.optional(Schema.String),
112
+ originalMessage: Schema.optional(Schema.String),
113
+ originalStatusCode: Schema.optional(Schema.Number),
114
+ });
115
+ // Streaming event shape — the AWS event stream wraps each JSON payload by its
116
+ // `:event-type` header (e.g. `messageStart`, `contentBlockDelta`). We
117
+ // reconstruct that wrapping in `decodeFrames` below so the event schema can
118
+ // stay a plain discriminated record.
119
+ const BedrockEvent = Schema.Struct({
120
+ messageStart: Schema.optional(Schema.Struct({ role: Schema.String })),
121
+ contentBlockStart: Schema.optional(Schema.Struct({
122
+ contentBlockIndex: Schema.Number,
123
+ start: Schema.optional(Schema.Struct({
124
+ toolUse: Schema.optional(Schema.Struct({ toolUseId: Schema.String, name: Schema.String })),
125
+ })),
126
+ })),
127
+ contentBlockDelta: Schema.optional(Schema.Struct({
128
+ contentBlockIndex: Schema.Number,
129
+ delta: Schema.optional(Schema.Struct({
130
+ text: Schema.optional(Schema.String),
131
+ toolUse: Schema.optional(Schema.Struct({ input: Schema.String })),
132
+ reasoningContent: Schema.optional(Schema.Struct({
133
+ text: Schema.optional(Schema.String),
134
+ signature: Schema.optional(Schema.String),
135
+ // Blob fields in Bedrock's JSON event stream are base64 strings.
136
+ redactedContent: Schema.optional(Schema.String),
137
+ // Vercel's Bedrock provider exposes the same delta under
138
+ // Anthropic's shorter `data` spelling.
139
+ data: Schema.optional(Schema.String),
140
+ })),
141
+ })),
142
+ })),
143
+ contentBlockStop: Schema.optional(Schema.Struct({ contentBlockIndex: Schema.Number })),
144
+ messageStop: Schema.optional(Schema.Struct({
145
+ stopReason: Schema.String,
146
+ additionalModelResponseFields: Schema.optional(Schema.Unknown),
147
+ })),
148
+ metadata: Schema.optional(Schema.Struct({
149
+ usage: Schema.optional(BedrockUsageSchema),
150
+ metrics: Schema.optional(Schema.Unknown),
151
+ })),
152
+ exception: Schema.optional(Schema.Struct({ type: Schema.String, details: BedrockStreamException })),
153
+ });
154
+ // =============================================================================
155
+ // Request Lowering
156
+ // =============================================================================
157
+ const lowerToolSpec = (tool, inputSchema) => ({
158
+ toolSpec: {
159
+ name: tool.name,
160
+ description: tool.description,
161
+ inputSchema: { json: inputSchema },
162
+ },
163
+ });
164
+ const lowerTools = (compatibility, breakpoints, tools) => {
165
+ const result = [];
166
+ for (const tool of tools) {
167
+ result.push(lowerToolSpec(tool, ToolSchemaProjection.modelCompatibility(tool.inputSchema, compatibility)));
168
+ const cachePoint = BedrockCache.block(breakpoints, tool.cache);
169
+ if (cachePoint)
170
+ result.push(cachePoint);
171
+ }
172
+ return result;
173
+ };
174
+ const textWithCache = (breakpoints, text, cache) => {
175
+ const cachePoint = BedrockCache.block(breakpoints, cache);
176
+ return cachePoint ? [{ text }, cachePoint] : [{ text }];
177
+ };
178
+ const lowerToolChoice = (toolChoice) => ProviderShared.matchToolChoice("Bedrock Converse", toolChoice, {
179
+ auto: () => ({ auto: {} }),
180
+ none: () => undefined,
181
+ required: () => ({ any: {} }),
182
+ tool: (name) => ({ tool: { name } }),
183
+ });
184
+ const providerMetadata = (key, metadata) => ({ [key]: metadata });
185
+ const reasoningSignature = (part, providerMetadataKey) => {
186
+ const metadata = part.providerMetadata?.[providerMetadataKey];
187
+ if (part.encrypted !== undefined)
188
+ return part.encrypted;
189
+ if (ProviderShared.isRecord(metadata) && typeof metadata.signature === "string")
190
+ return metadata.signature;
191
+ };
192
+ const reasoningRedactedData = (part, providerMetadataKey) => {
193
+ const metadata = part.providerMetadata?.[providerMetadataKey];
194
+ if (ProviderShared.isRecord(metadata) && typeof metadata.redactedData === "string")
195
+ return metadata.redactedData;
196
+ };
197
+ const removeEmptyToolInputKeys = (input) => {
198
+ if (Array.isArray(input))
199
+ return input.map(removeEmptyToolInputKeys);
200
+ if (!ProviderShared.isRecord(input))
201
+ return input;
202
+ return Object.fromEntries(Object.entries(input).flatMap(([key, value]) => (key === "" ? [] : [[key, removeEmptyToolInputKeys(value)]])));
203
+ };
204
+ const lowerToolCall = (part) => ({
205
+ toolUse: {
206
+ toolUseId: part.id,
207
+ name: part.name,
208
+ input: removeEmptyToolInputKeys(part.input),
209
+ },
210
+ });
211
+ const lowerToolResultContent = Effect.fn("BedrockConverse.lowerToolResultContent")(function* (part) {
212
+ if (part.result.type === "text" || part.result.type === "error")
213
+ return [{ text: ProviderShared.toolResultText(part) }];
214
+ if (part.result.type === "json")
215
+ return [{ json: part.result.value }];
216
+ const content = [];
217
+ for (const item of part.result.value) {
218
+ if (item.type === "text") {
219
+ content.push({ text: item.text });
220
+ continue;
221
+ }
222
+ const media = yield* BedrockMedia.lower({
223
+ type: "media",
224
+ mediaType: item.mime,
225
+ data: item.uri,
226
+ filename: item.name,
227
+ });
228
+ content.push(media);
229
+ }
230
+ return content;
231
+ });
232
+ const lowerToolResult = Effect.fn("BedrockConverse.lowerToolResult")(function* (part) {
233
+ return {
234
+ toolResult: {
235
+ toolUseId: part.id,
236
+ content: yield* lowerToolResultContent(part),
237
+ status: part.result.type === "error" ? "error" : "success",
238
+ },
239
+ };
240
+ });
241
+ const lowerMessages = Effect.fn("BedrockConverse.lowerMessages")(function* (request, breakpoints) {
242
+ const messages = [];
243
+ const providerMetadataKey = request.model.route.providerMetadataKey ?? String(request.model.provider);
244
+ for (const message of request.messages) {
245
+ if (message.role === "system") {
246
+ const part = yield* ProviderShared.wrappedSystemUpdate("Bedrock Converse", message);
247
+ const content = textWithCache(breakpoints, part.text, part.cache);
248
+ const previous = messages.at(-1);
249
+ if (previous?.role === "user")
250
+ messages[messages.length - 1] = { role: "user", content: [...previous.content, ...content] };
251
+ else
252
+ messages.push({ role: "user", content });
253
+ continue;
254
+ }
255
+ if (message.role === "user") {
256
+ const content = [];
257
+ for (const part of message.content) {
258
+ if (!ProviderShared.supportsContent(part, ["text", "media"]))
259
+ return yield* ProviderShared.unsupportedContent("Bedrock Converse", "user", ["text", "media"]);
260
+ if (part.type === "text") {
261
+ content.push(...textWithCache(breakpoints, part.text, part.cache));
262
+ continue;
263
+ }
264
+ if (part.type === "media") {
265
+ content.push(yield* BedrockMedia.lower(part));
266
+ continue;
267
+ }
268
+ }
269
+ const previous = messages.at(-1);
270
+ if (previous?.role === "user")
271
+ messages[messages.length - 1] = { role: "user", content: [...previous.content, ...content] };
272
+ else
273
+ messages.push({ role: "user", content });
274
+ continue;
275
+ }
276
+ if (message.role === "assistant") {
277
+ const content = [];
278
+ for (const part of message.content) {
279
+ if (!ProviderShared.supportsContent(part, ["text", "reasoning", "tool-call"]))
280
+ return yield* ProviderShared.unsupportedContent("Bedrock Converse", "assistant", [
281
+ "text",
282
+ "reasoning",
283
+ "tool-call",
284
+ ]);
285
+ if (part.type === "text") {
286
+ content.push(...textWithCache(breakpoints, part.text, part.cache));
287
+ continue;
288
+ }
289
+ if (part.type === "reasoning") {
290
+ const signature = reasoningSignature(part, providerMetadataKey);
291
+ const redactedData = reasoningRedactedData(part, providerMetadataKey);
292
+ if (signature === undefined && redactedData !== undefined) {
293
+ content.push({ reasoningContent: { redactedContent: redactedData } });
294
+ continue;
295
+ }
296
+ if (signature === undefined || signature.trim().length === 0) {
297
+ // Interrupted streams and model switches can leave unsigned reasoning.
298
+ // Preserve readable history as text rather than replay invalid reasoningContent.
299
+ if (part.text.trim().length > 0)
300
+ content.push(...textWithCache(breakpoints, part.text, part.cache));
301
+ continue;
302
+ }
303
+ content.push({ reasoningContent: { reasoningText: { text: part.text, signature } } });
304
+ continue;
305
+ }
306
+ if (part.type === "tool-call") {
307
+ content.push(lowerToolCall(part));
308
+ continue;
309
+ }
310
+ }
311
+ if (content.length > 0)
312
+ messages.push({ role: "assistant", content });
313
+ continue;
314
+ }
315
+ const content = [];
316
+ for (const part of message.content) {
317
+ if (!ProviderShared.supportsContent(part, ["tool-result"]))
318
+ return yield* ProviderShared.unsupportedContent("Bedrock Converse", "tool", ["tool-result"]);
319
+ content.push(yield* lowerToolResult(part));
320
+ const cachePoint = BedrockCache.block(breakpoints, part.cache);
321
+ if (cachePoint)
322
+ content.push(cachePoint);
323
+ }
324
+ const previous = messages.at(-1);
325
+ if (previous?.role === "user")
326
+ messages[messages.length - 1] = { role: "user", content: [...previous.content, ...content] };
327
+ else
328
+ messages.push({ role: "user", content });
329
+ }
330
+ return messages;
331
+ });
332
+ // System prompts share the cache-point convention: emit the text block, then
333
+ // optionally a positional `cachePoint` marker.
334
+ const lowerSystem = (breakpoints, system) => {
335
+ const content = system
336
+ .filter((part) => part.text.length > 0)
337
+ .flatMap((part) => textWithCache(breakpoints, part.text, part.cache));
338
+ return content.length === 0 ? undefined : content;
339
+ };
340
+ const fromRequest = Effect.fn("BedrockConverse.fromRequest")(function* (request) {
341
+ const toolChoice = request.toolChoice ? yield* lowerToolChoice(request.toolChoice) : undefined;
342
+ const flattened = ProviderShared.flattenToolRequest(request);
343
+ const generation = request.generation;
344
+ // Bedrock-Claude shares Anthropic's 4-breakpoint cap. Spend the budget in
345
+ // tools → system → messages order to favour the highest-impact prefixes.
346
+ const breakpoints = BedrockCache.breakpoints(request.model.id);
347
+ const toolConfig = (() => {
348
+ if (flattened.tools.length === 0)
349
+ return undefined;
350
+ return {
351
+ tools: lowerTools(request.model.compatibility?.toolSchema, breakpoints, flattened.tools),
352
+ // Converse has no native "none". Keep definitions stable for prompt
353
+ // caching and omit only the unsupported choice.
354
+ toolChoice,
355
+ };
356
+ })();
357
+ const system = lowerSystem(breakpoints, request.system);
358
+ const messages = yield* lowerMessages(flattened.request, breakpoints);
359
+ if (breakpoints.dropped > 0) {
360
+ yield* Effect.logWarning(`Bedrock Converse: dropped ${breakpoints.dropped} cache breakpoint(s); the API allows at most ${BedrockCache.BEDROCK_BREAKPOINT_CAP} per request.`);
361
+ }
362
+ const inferenceConfig = (() => {
363
+ if (generation?.maxTokens === undefined &&
364
+ generation?.temperature === undefined &&
365
+ generation?.topP === undefined &&
366
+ (generation?.stop === undefined || generation.stop.length === 0))
367
+ return undefined;
368
+ return {
369
+ maxTokens: generation?.maxTokens,
370
+ temperature: generation?.temperature,
371
+ topP: generation?.topP,
372
+ stopSequences: generation?.stop,
373
+ };
374
+ })();
375
+ return {
376
+ modelId: request.model.id,
377
+ messages,
378
+ system,
379
+ inferenceConfig,
380
+ toolConfig,
381
+ // Converse's base inferenceConfig has no topK; Anthropic/Nova accept it
382
+ // as a model-specific field, so it goes through additionalModelRequestFields.
383
+ additionalModelRequestFields: generation?.topK === undefined ? undefined : { top_k: generation.topK },
384
+ };
385
+ });
386
+ // =============================================================================
387
+ // Stream Parsing
388
+ // =============================================================================
389
+ const mapFinishReason = (reason) => {
390
+ if (reason === "end_turn" || reason === "stop_sequence")
391
+ return "stop";
392
+ if (reason === "max_tokens" || reason === "model_context_window_exceeded")
393
+ return "length";
394
+ if (reason === "tool_use")
395
+ return "tool-calls";
396
+ if (reason === "content_filtered" || reason === "guardrail_intervened")
397
+ return "content-filter";
398
+ return "unknown";
399
+ };
400
+ // AWS reports inputTokens separately from cache reads and writes.
401
+ // Bedrock does not break reasoning out of outputTokens for current models.
402
+ const mapUsage = (usage, providerMetadataKey) => {
403
+ if (!usage)
404
+ return undefined;
405
+ const inputTokens = ProviderShared.sumTokens(usage.inputTokens, usage.cacheReadInputTokens, usage.cacheWriteInputTokens);
406
+ return new Usage({
407
+ inputTokens,
408
+ outputTokens: usage.outputTokens,
409
+ nonCachedInputTokens: usage.inputTokens,
410
+ cacheReadInputTokens: usage.cacheReadInputTokens,
411
+ cacheWriteInputTokens: usage.cacheWriteInputTokens,
412
+ totalTokens: ProviderShared.totalTokens(inputTokens, usage.outputTokens, usage.totalTokens),
413
+ providerMetadata: { [providerMetadataKey]: usage },
414
+ });
415
+ };
416
+ const encodeRedactedContent = (chunks) => {
417
+ const bytes = new Uint8Array(chunks.reduce((total, chunk) => total + chunk.length, 0));
418
+ chunks.reduce((offset, chunk) => {
419
+ bytes.set(chunk, offset);
420
+ return offset + chunk.length;
421
+ }, 0);
422
+ return Encoding.encodeBase64(bytes);
423
+ };
424
+ const step = (state, event) => Effect.gen(function* () {
425
+ if (event.contentBlockStart?.start?.toolUse) {
426
+ const index = event.contentBlockStart.contentBlockIndex;
427
+ const events = [];
428
+ const lifecycle = Lifecycle.stepStart(state.lifecycle, events);
429
+ return [
430
+ {
431
+ ...state,
432
+ lifecycle,
433
+ tools: ToolStream.start(state.tools, index, {
434
+ id: event.contentBlockStart.start.toolUse.toolUseId,
435
+ name: event.contentBlockStart.start.toolUse.name,
436
+ }),
437
+ },
438
+ [
439
+ ...events,
440
+ LLMEvent.toolInputStart({
441
+ id: event.contentBlockStart.start.toolUse.toolUseId,
442
+ name: event.contentBlockStart.start.toolUse.name,
443
+ }),
444
+ ],
445
+ ];
446
+ }
447
+ if (event.contentBlockDelta?.delta?.text) {
448
+ const events = [];
449
+ return [
450
+ {
451
+ ...state,
452
+ lifecycle: Lifecycle.textDelta(state.lifecycle, events, `text-${event.contentBlockDelta.contentBlockIndex}`, event.contentBlockDelta.delta.text),
453
+ },
454
+ events,
455
+ ];
456
+ }
457
+ if (event.contentBlockDelta?.delta?.reasoningContent) {
458
+ const index = event.contentBlockDelta.contentBlockIndex;
459
+ const reasoning = event.contentBlockDelta.delta.reasoningContent;
460
+ const events = [];
461
+ const redactedChunks = yield* (() => {
462
+ if (reasoning.redactedContent === undefined)
463
+ return Effect.succeed(undefined);
464
+ return Effect.fromResult(Encoding.decodeBase64(reasoning.redactedContent)).pipe(Effect.map((chunk) => [...(state.reasoningRedactedContent[index] ?? []), chunk]), Effect.mapError((cause) => ProviderShared.eventError(ADAPTER, "Bedrock Converse reasoningContent.redactedContent contains invalid base64 data", undefined, cause)));
465
+ })();
466
+ const redactedData = redactedChunks === undefined ? reasoning.data : encodeRedactedContent(redactedChunks);
467
+ const metadata = (() => {
468
+ if (reasoning.signature)
469
+ return providerMetadata(state.providerMetadataKey, { signature: reasoning.signature });
470
+ if (redactedData !== undefined)
471
+ return providerMetadata(state.providerMetadataKey, { redactedData });
472
+ })();
473
+ const lifecycle = (() => {
474
+ if (reasoning.text === undefined && metadata === undefined)
475
+ return state.lifecycle;
476
+ return Lifecycle.reasoningDelta(state.lifecycle, events, `reasoning-${index}`, reasoning.text ?? "", metadata);
477
+ })();
478
+ const reasoningRedactedContent = (() => {
479
+ if (redactedChunks !== undefined)
480
+ return { ...state.reasoningRedactedContent, [index]: redactedChunks };
481
+ if (reasoning.data === undefined)
482
+ return state.reasoningRedactedContent;
483
+ return Object.fromEntries(Object.entries(state.reasoningRedactedContent).filter(([key]) => key !== String(index)));
484
+ })();
485
+ const reasoningSignatures = (() => {
486
+ if (!reasoning.signature)
487
+ return state.reasoningSignatures;
488
+ return { ...state.reasoningSignatures, [index]: reasoning.signature };
489
+ })();
490
+ return [
491
+ {
492
+ ...state,
493
+ lifecycle,
494
+ reasoningSignatures,
495
+ reasoningRedactedContent,
496
+ },
497
+ events,
498
+ ];
499
+ }
500
+ if (event.contentBlockDelta?.delta?.toolUse) {
501
+ // A delta for a block that is not open, whether it already stopped or never
502
+ // started, has nothing to attach to and is dropped.
503
+ const result = ToolStream.append(state.tools, event.contentBlockDelta.contentBlockIndex, event.contentBlockDelta.delta.toolUse.input);
504
+ if (!result)
505
+ return [state, []];
506
+ const events = [];
507
+ const lifecycle = result.events.length ? Lifecycle.stepStart(state.lifecycle, events) : state.lifecycle;
508
+ events.push(...result.events);
509
+ return [{ ...state, lifecycle, tools: result.tools }, events];
510
+ }
511
+ if (event.contentBlockStop) {
512
+ const index = event.contentBlockStop.contentBlockIndex;
513
+ const result = yield* ToolStream.finish(ADAPTER, state.tools, index);
514
+ const events = [];
515
+ const resultEvents = result.events ?? [];
516
+ const lifecycle = (() => {
517
+ if (resultEvents.length)
518
+ return Lifecycle.stepStart(state.lifecycle, events);
519
+ const metadata = (() => {
520
+ const signature = state.reasoningSignatures[index];
521
+ if (signature)
522
+ return providerMetadata(state.providerMetadataKey, { signature });
523
+ const redactedContent = state.reasoningRedactedContent[index];
524
+ if (redactedContent)
525
+ return providerMetadata(state.providerMetadataKey, {
526
+ redactedData: encodeRedactedContent(redactedContent),
527
+ });
528
+ })();
529
+ return Lifecycle.reasoningEnd(Lifecycle.textEnd(state.lifecycle, events, `text-${index}`), events, `reasoning-${index}`, metadata);
530
+ })();
531
+ events.push(...resultEvents);
532
+ return [
533
+ {
534
+ ...state,
535
+ hasToolCalls: resultEvents.some((event) => LLMEvent.is.toolCall(event) || LLMEvent.is.toolInputError(event)) ||
536
+ state.hasToolCalls,
537
+ lifecycle,
538
+ tools: result.tools,
539
+ reasoningSignatures: Object.fromEntries(Object.entries(state.reasoningSignatures).filter(([key]) => key !== String(index))),
540
+ reasoningRedactedContent: Object.fromEntries(Object.entries(state.reasoningRedactedContent).filter(([key]) => key !== String(index))),
541
+ },
542
+ events,
543
+ ];
544
+ }
545
+ if (event.messageStop) {
546
+ if (event.messageStop.stopReason === "malformed_model_output" ||
547
+ event.messageStop.stopReason === "malformed_tool_use")
548
+ return yield* ProviderShared.eventError(ADAPTER, `Bedrock Converse stopped with ${event.messageStop.stopReason}`, ProviderShared.encodeJson(event));
549
+ return [
550
+ {
551
+ ...state,
552
+ finishReason: {
553
+ normalized: mapFinishReason(event.messageStop.stopReason),
554
+ raw: event.messageStop.stopReason,
555
+ },
556
+ },
557
+ [],
558
+ ];
559
+ }
560
+ if (event.metadata) {
561
+ const usage = mapUsage(event.metadata.usage, state.providerMetadataKey) ?? state.usage;
562
+ return [
563
+ {
564
+ ...state,
565
+ usage,
566
+ },
567
+ [],
568
+ ];
569
+ }
570
+ if (event.exception) {
571
+ const message = event.exception.details.message ?? event.exception.details.originalMessage ?? "Bedrock Converse stream error";
572
+ const body = ProviderShared.encodeJson(event);
573
+ return yield* new AIError({
574
+ reason: classifyProviderFailure({
575
+ message,
576
+ rawBody: body,
577
+ }),
578
+ });
579
+ }
580
+ return [state, []];
581
+ });
582
+ const framing = BedrockEventStream.framing(ADAPTER);
583
+ const onHalt = (state) => {
584
+ if (!state.finishReason)
585
+ return [];
586
+ const normalized = (() => {
587
+ if (state.finishReason.normalized === "stop" && state.hasToolCalls)
588
+ return "tool-calls";
589
+ return state.finishReason.normalized;
590
+ })();
591
+ const events = [];
592
+ Lifecycle.finish(state.lifecycle, events, {
593
+ reason: {
594
+ ...state.finishReason,
595
+ normalized,
596
+ },
597
+ usage: state.usage,
598
+ });
599
+ return events;
600
+ };
601
+ // =============================================================================
602
+ // Protocol And Bedrock Route
603
+ // =============================================================================
604
+ /**
605
+ * The Bedrock Converse protocol — request body construction, body schema, and
606
+ * the streaming-event state machine.
607
+ */
608
+ export const protocol = Protocol.make({
609
+ id: ADAPTER,
610
+ body: {
611
+ schema: BedrockConverseBody,
612
+ from: fromRequest,
613
+ },
614
+ stream: {
615
+ event: BedrockEvent,
616
+ initial: (request) => ({
617
+ providerMetadataKey: request.model.route.providerMetadataKey ?? String(request.model.provider),
618
+ tools: ToolStream.empty(),
619
+ finishReason: undefined,
620
+ usage: undefined,
621
+ hasToolCalls: false,
622
+ lifecycle: Lifecycle.initial(),
623
+ reasoningSignatures: {},
624
+ reasoningRedactedContent: {},
625
+ }),
626
+ step,
627
+ onHalt: (state) => Effect.succeed(onHalt(state)),
628
+ },
629
+ });
630
+ export const route = Route.make({
631
+ id: ADAPTER,
632
+ provider: "bedrock",
633
+ providerMetadataKey: "bedrock",
634
+ protocol,
635
+ // Bedrock's URL embeds the region in the route endpoint host and the
636
+ // validated modelId in the path. We read the validated body so the URL
637
+ // matches the body that gets signed.
638
+ endpoint: Endpoint.path(({ body }) => `/model/${encodeURIComponent(body.modelId)}/converse-stream`),
639
+ auth: BedrockAuth.auth,
640
+ framing,
641
+ });
642
+ export const sigV4Auth = BedrockAuth.sigV4;
643
+ export * as BedrockConverse from "./bedrock-converse.js";
@@ -0,0 +1,9 @@
1
+ import { Framing } from "../route/framing.js";
2
+ /**
3
+ * AWS event-stream framing for Bedrock Converse. Each frame is decoded by
4
+ * `@smithy/eventstream-codec` (length + header + payload + CRC) and rewrapped
5
+ * under its `:event-type` header so the chunk schema can match the JSON
6
+ * payload directly.
7
+ */
8
+ export declare const framing: (route: string) => Framing.Definition<object>;
9
+ export * as BedrockEventStream from "./bedrock-event-stream.js";