@earendil-works/pi-ai 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/README.md +58 -39
  2. package/dist/api/anthropic-messages.d.ts.map +1 -1
  3. package/dist/api/anthropic-messages.js +282 -87
  4. package/dist/api/anthropic-messages.js.map +1 -1
  5. package/dist/api/azure-openai-responses.d.ts.map +1 -1
  6. package/dist/api/azure-openai-responses.js +1 -7
  7. package/dist/api/azure-openai-responses.js.map +1 -1
  8. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  9. package/dist/api/bedrock-converse-stream.js +127 -103
  10. package/dist/api/bedrock-converse-stream.js.map +1 -1
  11. package/dist/api/bedrock-converse-stream.lazy.d.ts +7 -0
  12. package/dist/api/bedrock-converse-stream.lazy.d.ts.map +1 -1
  13. package/dist/api/bedrock-converse-stream.lazy.js +18 -5
  14. package/dist/api/bedrock-converse-stream.lazy.js.map +1 -1
  15. package/dist/api/constrained-sampling.d.ts +13 -1
  16. package/dist/api/constrained-sampling.d.ts.map +1 -1
  17. package/dist/api/constrained-sampling.js +38 -18
  18. package/dist/api/constrained-sampling.js.map +1 -1
  19. package/dist/api/google-generative-ai.d.ts.map +1 -1
  20. package/dist/api/google-generative-ai.js +0 -6
  21. package/dist/api/google-generative-ai.js.map +1 -1
  22. package/dist/api/google-shared.d.ts +2 -1
  23. package/dist/api/google-shared.d.ts.map +1 -1
  24. package/dist/api/google-shared.js +57 -2
  25. package/dist/api/google-shared.js.map +1 -1
  26. package/dist/api/google-vertex.d.ts.map +1 -1
  27. package/dist/api/google-vertex.js +0 -6
  28. package/dist/api/google-vertex.js.map +1 -1
  29. package/dist/api/lazy.d.ts +1 -1
  30. package/dist/api/lazy.d.ts.map +1 -1
  31. package/dist/api/lazy.js +9 -8
  32. package/dist/api/lazy.js.map +1 -1
  33. package/dist/api/mistral-conversations.d.ts.map +1 -1
  34. package/dist/api/mistral-conversations.js +17 -44
  35. package/dist/api/mistral-conversations.js.map +1 -1
  36. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  37. package/dist/api/openai-codex-responses.js +7 -8
  38. package/dist/api/openai-codex-responses.js.map +1 -1
  39. package/dist/api/openai-completions.d.ts +2 -1
  40. package/dist/api/openai-completions.d.ts.map +1 -1
  41. package/dist/api/openai-completions.js +55 -59
  42. package/dist/api/openai-completions.js.map +1 -1
  43. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  44. package/dist/api/openai-responses-shared.js +58 -57
  45. package/dist/api/openai-responses-shared.js.map +1 -1
  46. package/dist/api/openai-responses.d.ts.map +1 -1
  47. package/dist/api/openai-responses.js +4 -8
  48. package/dist/api/openai-responses.js.map +1 -1
  49. package/dist/api/openrouter-images.js +1 -0
  50. package/dist/api/openrouter-images.js.map +1 -1
  51. package/dist/api/pi-messages.d.ts +2 -0
  52. package/dist/api/pi-messages.d.ts.map +1 -1
  53. package/dist/api/pi-messages.js +24 -9
  54. package/dist/api/pi-messages.js.map +1 -1
  55. package/dist/api/simple-options.d.ts +1 -0
  56. package/dist/api/simple-options.d.ts.map +1 -1
  57. package/dist/api/simple-options.js +16 -2
  58. package/dist/api/simple-options.js.map +1 -1
  59. package/dist/api/strict-tool-limits.d.ts +13 -0
  60. package/dist/api/strict-tool-limits.d.ts.map +1 -0
  61. package/dist/api/strict-tool-limits.js +50 -0
  62. package/dist/api/strict-tool-limits.js.map +1 -0
  63. package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  64. package/dist/auth/oauth/github-copilot.js +4 -11
  65. package/dist/auth/oauth/github-copilot.js.map +1 -1
  66. package/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
  67. package/dist/auth/oauth/kimi-coding.js +4 -22
  68. package/dist/auth/oauth/kimi-coding.js.map +1 -1
  69. package/dist/auth/oauth/load.d.ts.map +1 -1
  70. package/dist/auth/oauth/load.js +5 -2
  71. package/dist/auth/oauth/load.js.map +1 -1
  72. package/dist/auth/oauth/meta.d.ts.map +1 -1
  73. package/dist/auth/oauth/meta.js +1 -14
  74. package/dist/auth/oauth/meta.js.map +1 -1
  75. package/dist/auth/oauth/radius.d.ts.map +1 -1
  76. package/dist/auth/oauth/radius.js +9 -3
  77. package/dist/auth/oauth/radius.js.map +1 -1
  78. package/dist/auth/oauth/trusted-url.d.ts +7 -0
  79. package/dist/auth/oauth/trusted-url.d.ts.map +1 -0
  80. package/dist/auth/oauth/trusted-url.js +12 -0
  81. package/dist/auth/oauth/trusted-url.js.map +1 -0
  82. package/dist/auth/types.d.ts +4 -0
  83. package/dist/auth/types.d.ts.map +1 -1
  84. package/dist/auth/types.js.map +1 -1
  85. package/dist/cache-warming.d.ts +53 -0
  86. package/dist/cache-warming.d.ts.map +1 -0
  87. package/dist/cache-warming.js +82 -0
  88. package/dist/cache-warming.js.map +1 -0
  89. package/dist/cli.js +6 -2
  90. package/dist/cli.js.map +1 -1
  91. package/dist/compat/extension-oauth-types.d.ts +4 -0
  92. package/dist/compat/extension-oauth-types.d.ts.map +1 -1
  93. package/dist/compat/extension-oauth-types.js.map +1 -1
  94. package/dist/env-api-keys.d.ts.map +1 -1
  95. package/dist/env-api-keys.js +1 -0
  96. package/dist/env-api-keys.js.map +1 -1
  97. package/dist/index.d.ts +3 -3
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +3 -2
  100. package/dist/index.js.map +1 -1
  101. package/dist/lazy-bedrock-provider.d.ts +10 -0
  102. package/dist/lazy-bedrock-provider.d.ts.map +1 -0
  103. package/dist/lazy-bedrock-provider.js +13 -0
  104. package/dist/lazy-bedrock-provider.js.map +1 -0
  105. package/dist/lazy-oauth.d.ts +10 -0
  106. package/dist/lazy-oauth.d.ts.map +1 -0
  107. package/dist/lazy-oauth.js +23 -0
  108. package/dist/lazy-oauth.js.map +1 -0
  109. package/dist/models.d.ts +7 -0
  110. package/dist/models.d.ts.map +1 -1
  111. package/dist/models.generated.d.ts +4 -0
  112. package/dist/models.generated.d.ts.map +1 -1
  113. package/dist/models.generated.js +5 -1
  114. package/dist/models.generated.js.map +1 -1
  115. package/dist/models.js +20 -11
  116. package/dist/models.js.map +1 -1
  117. package/dist/providers/all.d.ts.map +1 -1
  118. package/dist/providers/all.js +2 -0
  119. package/dist/providers/all.js.map +1 -1
  120. package/dist/providers/amazon-bedrock.models.js +1 -1
  121. package/dist/providers/amazon-bedrock.models.js.map +1 -1
  122. package/dist/providers/ant-ling.models.js +1 -1
  123. package/dist/providers/ant-ling.models.js.map +1 -1
  124. package/dist/providers/anthropic.models.js +1 -1
  125. package/dist/providers/anthropic.models.js.map +1 -1
  126. package/dist/providers/azure.models.js +1 -1
  127. package/dist/providers/azure.models.js.map +1 -1
  128. package/dist/providers/baseten.models.js +1 -1
  129. package/dist/providers/baseten.models.js.map +1 -1
  130. package/dist/providers/cerebras.models.js +1 -1
  131. package/dist/providers/cerebras.models.js.map +1 -1
  132. package/dist/providers/cloudflare-ai-gateway.models.js +1 -1
  133. package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  134. package/dist/providers/cloudflare-workers-ai.models.js +1 -1
  135. package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
  136. package/dist/providers/compat-schema.d.ts +444 -456
  137. package/dist/providers/compat-schema.d.ts.map +1 -1
  138. package/dist/providers/compat-schema.js +166 -112
  139. package/dist/providers/compat-schema.js.map +1 -1
  140. package/dist/providers/data/.manifest.json +1 -1
  141. package/dist/providers/data/amazon-bedrock.json +1 -1
  142. package/dist/providers/data/anthropic.json +1 -1
  143. package/dist/providers/data/azure.json +1 -1
  144. package/dist/providers/data/baseten.json +1 -1
  145. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  146. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  147. package/dist/providers/data/fireworks.json +1 -1
  148. package/dist/providers/data/github-copilot.json +1 -1
  149. package/dist/providers/data/google-vertex.json +1 -1
  150. package/dist/providers/data/google.json +1 -1
  151. package/dist/providers/data/huggingface.json +1 -1
  152. package/dist/providers/data/kimi-coding.json +1 -1
  153. package/dist/providers/data/mistral.json +1 -1
  154. package/dist/providers/data/moonshotai-cn.json +1 -1
  155. package/dist/providers/data/moonshotai.json +1 -1
  156. package/dist/providers/data/nvidia.json +1 -1
  157. package/dist/providers/data/openai-codex.json +1 -1
  158. package/dist/providers/data/openai.json +1 -1
  159. package/dist/providers/data/opencode-go.json +1 -1
  160. package/dist/providers/data/opencode.json +1 -1
  161. package/dist/providers/data/openrouter.json +1 -1
  162. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  163. package/dist/providers/data/qwen-token-plan-individual-cn.json +1 -0
  164. package/dist/providers/data/qwen-token-plan-individual.json +1 -1
  165. package/dist/providers/data/qwen-token-plan.json +1 -1
  166. package/dist/providers/data/radius.json +1 -1
  167. package/dist/providers/data/together.json +1 -1
  168. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  169. package/dist/providers/data/xai.json +1 -1
  170. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  171. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  172. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  173. package/dist/providers/data/xiaomi.json +1 -1
  174. package/dist/providers/data/zai-coding-cn.json +1 -1
  175. package/dist/providers/data/zai.json +1 -1
  176. package/dist/providers/deepseek.models.js +1 -1
  177. package/dist/providers/deepseek.models.js.map +1 -1
  178. package/dist/providers/faux.d.ts.map +1 -1
  179. package/dist/providers/faux.js +7 -2
  180. package/dist/providers/faux.js.map +1 -1
  181. package/dist/providers/fireworks.models.js +1 -1
  182. package/dist/providers/fireworks.models.js.map +1 -1
  183. package/dist/providers/github-copilot.d.ts +3 -1
  184. package/dist/providers/github-copilot.d.ts.map +1 -1
  185. package/dist/providers/github-copilot.js +13 -2
  186. package/dist/providers/github-copilot.js.map +1 -1
  187. package/dist/providers/github-copilot.models.js +1 -1
  188. package/dist/providers/github-copilot.models.js.map +1 -1
  189. package/dist/providers/google-vertex.models.js +1 -1
  190. package/dist/providers/google-vertex.models.js.map +1 -1
  191. package/dist/providers/google.models.js +1 -1
  192. package/dist/providers/google.models.js.map +1 -1
  193. package/dist/providers/groq.models.js +1 -1
  194. package/dist/providers/groq.models.js.map +1 -1
  195. package/dist/providers/huggingface.models.js +1 -1
  196. package/dist/providers/huggingface.models.js.map +1 -1
  197. package/dist/providers/kimi-coding.models.js +1 -1
  198. package/dist/providers/kimi-coding.models.js.map +1 -1
  199. package/dist/providers/meta.models.js +1 -1
  200. package/dist/providers/meta.models.js.map +1 -1
  201. package/dist/providers/minimax-cn.models.js +1 -1
  202. package/dist/providers/minimax-cn.models.js.map +1 -1
  203. package/dist/providers/minimax.models.js +1 -1
  204. package/dist/providers/minimax.models.js.map +1 -1
  205. package/dist/providers/mistral.models.js +1 -1
  206. package/dist/providers/mistral.models.js.map +1 -1
  207. package/dist/providers/model-schema.d.ts +65 -65
  208. package/dist/providers/model-schema.d.ts.map +1 -1
  209. package/dist/providers/model-schema.js +41 -30
  210. package/dist/providers/model-schema.js.map +1 -1
  211. package/dist/providers/moonshotai-cn.models.js +1 -1
  212. package/dist/providers/moonshotai-cn.models.js.map +1 -1
  213. package/dist/providers/moonshotai.models.js +1 -1
  214. package/dist/providers/moonshotai.models.js.map +1 -1
  215. package/dist/providers/nvidia.models.js +1 -1
  216. package/dist/providers/nvidia.models.js.map +1 -1
  217. package/dist/providers/openai-codex.js +1 -1
  218. package/dist/providers/openai-codex.js.map +1 -1
  219. package/dist/providers/openai-codex.models.js +1 -1
  220. package/dist/providers/openai-codex.models.js.map +1 -1
  221. package/dist/providers/openai.models.js +1 -1
  222. package/dist/providers/openai.models.js.map +1 -1
  223. package/dist/providers/opencode-go.models.js +1 -1
  224. package/dist/providers/opencode-go.models.js.map +1 -1
  225. package/dist/providers/opencode.js +1 -1
  226. package/dist/providers/opencode.js.map +1 -1
  227. package/dist/providers/opencode.models.js +1 -1
  228. package/dist/providers/opencode.models.js.map +1 -1
  229. package/dist/providers/openrouter.models.js +1 -1
  230. package/dist/providers/openrouter.models.js.map +1 -1
  231. package/dist/providers/qwen-token-plan-cn.models.js +1 -1
  232. package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
  233. package/dist/providers/qwen-token-plan-individual-cn.d.ts +3 -0
  234. package/dist/providers/qwen-token-plan-individual-cn.d.ts.map +1 -0
  235. package/dist/providers/qwen-token-plan-individual-cn.js +15 -0
  236. package/dist/providers/qwen-token-plan-individual-cn.js.map +1 -0
  237. package/dist/providers/qwen-token-plan-individual-cn.models.d.ts +6 -0
  238. package/dist/providers/qwen-token-plan-individual-cn.models.d.ts.map +1 -0
  239. package/dist/providers/qwen-token-plan-individual-cn.models.js +8 -0
  240. package/dist/providers/qwen-token-plan-individual-cn.models.js.map +1 -0
  241. package/dist/providers/qwen-token-plan-individual.models.js +1 -1
  242. package/dist/providers/qwen-token-plan-individual.models.js.map +1 -1
  243. package/dist/providers/qwen-token-plan.models.js +1 -1
  244. package/dist/providers/qwen-token-plan.models.js.map +1 -1
  245. package/dist/providers/radius-config.d.ts.map +1 -1
  246. package/dist/providers/radius-config.js +2 -1
  247. package/dist/providers/radius-config.js.map +1 -1
  248. package/dist/providers/radius.models.js +1 -1
  249. package/dist/providers/radius.models.js.map +1 -1
  250. package/dist/providers/schema-builders.d.ts +10 -0
  251. package/dist/providers/schema-builders.d.ts.map +1 -0
  252. package/dist/providers/schema-builders.js +18 -0
  253. package/dist/providers/schema-builders.js.map +1 -0
  254. package/dist/providers/together.models.js +1 -1
  255. package/dist/providers/together.models.js.map +1 -1
  256. package/dist/providers/typesafe.models.js +1 -1
  257. package/dist/providers/typesafe.models.js.map +1 -1
  258. package/dist/providers/vercel-ai-gateway.models.js +1 -1
  259. package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  260. package/dist/providers/xai.models.js +1 -1
  261. package/dist/providers/xai.models.js.map +1 -1
  262. package/dist/providers/xiaomi-token-plan-ams.models.js +1 -1
  263. package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
  264. package/dist/providers/xiaomi-token-plan-cn.models.js +1 -1
  265. package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
  266. package/dist/providers/xiaomi-token-plan-sgp.models.js +1 -1
  267. package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
  268. package/dist/providers/xiaomi.models.js +1 -1
  269. package/dist/providers/xiaomi.models.js.map +1 -1
  270. package/dist/providers/zai-coding-cn.models.js +1 -1
  271. package/dist/providers/zai-coding-cn.models.js.map +1 -1
  272. package/dist/providers/zai.models.js +1 -1
  273. package/dist/providers/zai.models.js.map +1 -1
  274. package/dist/telemetry.d.ts.map +1 -1
  275. package/dist/telemetry.js +2 -1
  276. package/dist/telemetry.js.map +1 -1
  277. package/dist/types.d.ts +20 -3
  278. package/dist/types.d.ts.map +1 -1
  279. package/dist/types.js.map +1 -1
  280. package/dist/utils/error-body.d.ts +8 -0
  281. package/dist/utils/error-body.d.ts.map +1 -1
  282. package/dist/utils/error-body.js +30 -2
  283. package/dist/utils/error-body.js.map +1 -1
  284. package/dist/utils/openrouter-cost.d.ts +24 -0
  285. package/dist/utils/openrouter-cost.d.ts.map +1 -0
  286. package/dist/utils/openrouter-cost.js +34 -0
  287. package/dist/utils/openrouter-cost.js.map +1 -0
  288. package/dist/utils/overflow.d.ts.map +1 -1
  289. package/dist/utils/overflow.js +2 -0
  290. package/dist/utils/overflow.js.map +1 -1
  291. package/dist/utils/retry.d.ts.map +1 -1
  292. package/dist/utils/retry.js +6 -0
  293. package/dist/utils/retry.js.map +1 -1
  294. package/dist/utils/streaming-json.d.ts +84 -0
  295. package/dist/utils/streaming-json.d.ts.map +1 -0
  296. package/dist/utils/streaming-json.js +513 -0
  297. package/dist/utils/streaming-json.js.map +1 -0
  298. package/dist/utils/{typebox-helpers.d.ts → string-enum.d.ts} +5 -5
  299. package/dist/utils/string-enum.d.ts.map +1 -0
  300. package/dist/utils/{typebox-helpers.js → string-enum.js} +5 -6
  301. package/dist/utils/string-enum.js.map +1 -0
  302. package/dist/utils/text.d.ts +7 -0
  303. package/dist/utils/text.d.ts.map +1 -1
  304. package/dist/utils/text.js +9 -0
  305. package/dist/utils/text.js.map +1 -1
  306. package/dist/utils/transcript.d.ts +1 -1
  307. package/dist/utils/transcript.js +1 -1
  308. package/dist/utils/transcript.js.map +1 -1
  309. package/dist/utils/validation.d.ts +5 -3
  310. package/dist/utils/validation.d.ts.map +1 -1
  311. package/dist/utils/validation.js +27 -277
  312. package/dist/utils/validation.js.map +1 -1
  313. package/dist/utils/version.d.ts +1 -1
  314. package/dist/utils/version.js +1 -1
  315. package/dist/utils/version.js.map +1 -1
  316. package/package.json +19 -10
  317. package/dist/utils/typebox-helpers.d.ts.map +0 -1
  318. package/dist/utils/typebox-helpers.js.map +0 -1
@@ -85,12 +85,6 @@ export const stream = (model, context, options) => {
85
85
  stream.end();
86
86
  }
87
87
  catch (error) {
88
- for (const block of output.content) {
89
- delete block.index;
90
- // Streaming scratch buffers are only used during parsing; never persist them.
91
- delete block.partialJson;
92
- delete block.customInput;
93
- }
94
88
  output.stopReason = options?.signal?.aborted ? "aborted" : "error";
95
89
  output.errorMessage = formatAzureOpenAIError(error);
96
90
  stream.push({ type: "error", reason: output.stopReason, error: output });
@@ -152,7 +146,7 @@ function buildParams(model, context, options, deploymentName, grammarToolInputPr
152
146
  model: deploymentName,
153
147
  input: messages,
154
148
  stream: true,
155
- prompt_cache_key: clampOpenAIPromptCacheKey(options?.sessionId),
149
+ prompt_cache_key: model.compat?.promptCacheKeyMode === "disabled" ? undefined : clampOpenAIPromptCacheKey(options?.sessionId),
156
150
  store: false,
157
151
  };
158
152
  if (options?.maxTokens) {
@@ -1 +1 @@
1
- {"version":3,"file":"azure-openai-responses.js","sourceRoot":"","sources":["../../src/api/azure-openai-responses.ts"],"names":[],"mappings":"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","sourcesContent":["import { AzureOpenAI } from \"openai\";\nimport type { ResponseCreateParamsStreaming } from \"openai/resources/responses/responses.js\";\nimport { clampThinkingLevel } from \"../models.ts\";\nimport type { Api, AssistantMessage, Model, SimpleStreamOptions, StreamFunction, TranscriptContext } from \"../types.ts\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { headersToRecord } from \"../utils/headers.ts\";\nimport { getIdentityHeaders } from \"../utils/identity.ts\";\nimport { retryProviderRequest } from \"../utils/provider-retry.ts\";\nimport { getDeclaredTools, resolveTranscript, resolveTranscriptTools } from \"../utils/transcript.ts\";\nimport { type AzureEndpointOptions, resolveAzureConfig, resolveDeploymentName } from \"./azure-openai-config.ts\";\nimport { createGrammarToolInputProperties } from \"./constrained-sampling.ts\";\nimport { clampOpenAIPromptCacheKey } from \"./openai-prompt-cache.ts\";\nimport {\n\tconvertResponsesMessages,\n\tconvertResponsesTools,\n\tgetResponsesToolSupport,\n\tprocessResponsesStream,\n} from \"./openai-responses-shared.ts\";\nimport { buildBaseOptions, resolveSamplingParams } from \"./simple-options.ts\";\n\nconst AZURE_TOOL_CALL_PROVIDERS = new Set([\"openai\", \"openai-codex\", \"opencode\", \"azure\"]);\n// OpenAI Responses rejects max_output_tokens below 16: https://github.com/earendil-works/pi/issues/6265\nconst OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;\n\nfunction formatAzureOpenAIError(error: unknown): string {\n\treturn formatProviderError(normalizeProviderError(error), \"Azure OpenAI API error\");\n}\n\n// Azure OpenAI Responses-specific options\nexport interface AzureOpenAIResponsesOptions extends AzureEndpointOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\ttoolChoice?: ResponseCreateParamsStreaming[\"tool_choice\"];\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n}\n\n/**\n * Generate function for Azure OpenAI Responses API\n */\nexport const stream: StreamFunction<\"azure-openai-responses\", AzureOpenAIResponsesOptions> = (\n\tmodel: Model<\"azure-openai-responses\">,\n\tcontext: TranscriptContext,\n\toptions?: AzureOpenAIResponsesOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\tconst normalizedContext = resolveTranscript(context, model.compat?.supportsMidConvoSystemMessages);\n\n\t// Start async processing\n\t(async () => {\n\t\tconst deploymentName = resolveDeploymentName(model, options);\n\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: \"azure-openai-responses\" as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"pending\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\t// Create Azure OpenAI client\n\t\t\tconst apiKey = options?.apiKey;\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t\t\t}\n\t\t\tconst client = createClient(model, apiKey, options);\n\t\t\tconst grammarToolInputProperties = createGrammarToolInputProperties(\n\t\t\t\tgetDeclaredTools(normalizedContext.messages),\n\t\t\t\tmodel.compat?.supportsOpenAIGrammarTools ?? false,\n\t\t\t);\n\t\t\tlet params = buildParams(model, normalizedContext, options, deploymentName, grammarToolInputProperties);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as ResponseCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst requestOptions = {\n\t\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t\t\t...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),\n\t\t\t\tmaxRetries: 0,\n\t\t\t};\n\t\t\tconst { data: openaiStream, response } = await retryProviderRequest(\n\t\t\t\t() => client.responses.create(params, requestOptions).withResponse(),\n\t\t\t\t{\n\t\t\t\t\tmaxRetries: options?.maxRetries,\n\t\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\t\t\t\tsignal: options?.signal,\n\t\t\t\t},\n\t\t\t);\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\tawait processResponsesStream(openaiStream, output, stream, model, {\n\t\t\t\tonProviderStreamEvent: options?.onProviderStreamEvent,\n\t\t\t\tgrammarToolInputProperties,\n\t\t\t});\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"pending\") {\n\t\t\t\tthrow new Error(\"Azure OpenAI Responses stream ended without a stop reason\");\n\t\t\t}\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(output.errorMessage || \"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) {\n\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t// Streaming scratch buffers are only used during parsing; never persist them.\n\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t\tdelete (block as { customInput?: unknown }).customInput;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatAzureOpenAIError(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\nexport const streamSimple: StreamFunction<\"azure-openai-responses\", SimpleStreamOptions> = (\n\tmodel: Model<\"azure-openai-responses\">,\n\tcontext: TranscriptContext,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey;\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = {\n\t\t...buildBaseOptions(model, context, options, apiKey),\n\t\ttoolChoice: options?.toolChoice,\n\t} satisfies AzureOpenAIResponsesOptions;\n\tconst clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;\n\tconst reasoningEffort = clampedReasoning === \"off\" ? undefined : clampedReasoning;\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\treasoningEffort,\n\t} satisfies AzureOpenAIResponsesOptions);\n};\n\nfunction createClient(model: Model<\"azure-openai-responses\">, apiKey: string, options?: AzureOpenAIResponsesOptions) {\n\tconst headers = { ...getIdentityHeaders(model, options?.identity), ...model.headers };\n\n\tif (options?.headers) {\n\t\tObject.assign(headers, options.headers);\n\t}\n\n\tconst { baseUrl, apiVersion } = resolveAzureConfig(model, options);\n\n\treturn new AzureOpenAI({\n\t\tapiKey,\n\t\tapiVersion,\n\t\tdangerouslyAllowBrowser: true,\n\t\tfetch: options?.fetch,\n\t\tdefaultHeaders: headers,\n\t\tbaseURL: baseUrl,\n\t});\n}\n\nfunction buildParams(\n\tmodel: Model<\"azure-openai-responses\">,\n\tcontext: TranscriptContext,\n\toptions: AzureOpenAIResponsesOptions | undefined,\n\tdeploymentName: string,\n\tgrammarToolInputProperties: ReadonlyMap<string, string> = createGrammarToolInputProperties(\n\t\tgetDeclaredTools(context.messages),\n\t\tmodel.compat?.supportsOpenAIGrammarTools ?? false,\n\t),\n) {\n\tconst supportsAdditionalTools = model.compat?.supportsAdditionalTools ?? false;\n\tconst supportsToolSearch = model.compat?.supportsToolSearch ?? false;\n\tconst transcriptTools = resolveTranscriptTools(\n\t\tcontext.messages,\n\t\tgetResponsesToolSupport({\n\t\t\tsupportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,\n\t\t\tsupportsAdditionalTools,\n\t\t\tsupportsToolSearch,\n\t\t}),\n\t);\n\tconst messages = convertResponsesMessages(model, context, AZURE_TOOL_CALL_PROVIDERS, {\n\t\tgrammarToolInputProperties,\n\t\tsupportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,\n\t\tsupportsAdditionalTools,\n\t\tsupportsToolSearch,\n\t\ttoolOptions: {\n\t\t\tsupportsStrictMode: model.compat?.supportsStrictMode ?? true,\n\t\t\tsupportsOpenAIGrammarTools: model.compat?.supportsOpenAIGrammarTools ?? false,\n\t\t},\n\t});\n\n\tconst params: ResponseCreateParamsStreaming = {\n\t\tmodel: deploymentName,\n\t\tinput: messages,\n\t\tstream: true,\n\t\tprompt_cache_key: clampOpenAIPromptCacheKey(options?.sessionId),\n\t\tstore: false,\n\t};\n\n\tif (options?.maxTokens) {\n\t\tparams.max_output_tokens = Math.max(options.maxTokens, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS);\n\t}\n\n\tif (options?.temperature !== undefined) {\n\t\tparams.temperature = options?.temperature;\n\t}\n\n\tif (transcriptTools.requestTools.length > 0) {\n\t\tparams.tools = convertResponsesTools(transcriptTools.requestTools, {\n\t\t\tsupportsStrictMode: model.compat?.supportsStrictMode ?? true,\n\t\t\tsupportsOpenAIGrammarTools: model.compat?.supportsOpenAIGrammarTools ?? false,\n\t\t});\n\t}\n\tif (options?.toolChoice !== undefined) {\n\t\tparams.tool_choice = options.toolChoice;\n\t}\n\n\tconst reasoningEffort = options?.reasoningEffort ?? (options?.reasoningSummary ? \"medium\" : undefined);\n\tif (model.reasoning) {\n\t\tif (reasoningEffort) {\n\t\t\tconst effort = options?.reasoningEffort\n\t\t\t\t? (model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort)\n\t\t\t\t: reasoningEffort;\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: effort as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t\tsummary: options?.reasoningSummary || \"auto\",\n\t\t\t};\n\t\t\tparams.include = [\"reasoning.encrypted_content\"];\n\t\t} else if (model.thinkingLevelMap?.off !== null) {\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: (model.thinkingLevelMap?.off ?? \"none\") as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t};\n\t\t}\n\t}\n\n\t// Last so model and request sampling parameters override named request fields.\n\tconst samplingParams = resolveSamplingParams(model, reasoningEffort ?? \"off\", options?.samplingParams);\n\tif (samplingParams) {\n\t\tObject.assign(params, samplingParams);\n\t}\n\n\treturn params;\n}\n"]}
1
+ {"version":3,"file":"azure-openai-responses.js","sourceRoot":"","sources":["../../src/api/azure-openai-responses.ts"],"names":[],"mappings":"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","sourcesContent":["import { AzureOpenAI } from \"openai\";\nimport type { ResponseCreateParamsStreaming } from \"openai/resources/responses/responses.js\";\nimport { clampThinkingLevel } from \"../models.ts\";\nimport type { Api, AssistantMessage, Model, SimpleStreamOptions, StreamFunction, TranscriptContext } from \"../types.ts\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { headersToRecord } from \"../utils/headers.ts\";\nimport { getIdentityHeaders } from \"../utils/identity.ts\";\nimport { retryProviderRequest } from \"../utils/provider-retry.ts\";\nimport { getDeclaredTools, resolveTranscript, resolveTranscriptTools } from \"../utils/transcript.ts\";\nimport { type AzureEndpointOptions, resolveAzureConfig, resolveDeploymentName } from \"./azure-openai-config.ts\";\nimport { createGrammarToolInputProperties } from \"./constrained-sampling.ts\";\nimport { clampOpenAIPromptCacheKey } from \"./openai-prompt-cache.ts\";\nimport {\n\tconvertResponsesMessages,\n\tconvertResponsesTools,\n\tgetResponsesToolSupport,\n\tprocessResponsesStream,\n} from \"./openai-responses-shared.ts\";\nimport { buildBaseOptions, resolveSamplingParams } from \"./simple-options.ts\";\n\nconst AZURE_TOOL_CALL_PROVIDERS = new Set([\"openai\", \"openai-codex\", \"opencode\", \"azure\"]);\n// OpenAI Responses rejects max_output_tokens below 16: https://github.com/earendil-works/pi/issues/6265\nconst OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;\n\nfunction formatAzureOpenAIError(error: unknown): string {\n\treturn formatProviderError(normalizeProviderError(error), \"Azure OpenAI API error\");\n}\n\n// Azure OpenAI Responses-specific options\nexport interface AzureOpenAIResponsesOptions extends AzureEndpointOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\ttoolChoice?: ResponseCreateParamsStreaming[\"tool_choice\"];\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n}\n\n/**\n * Generate function for Azure OpenAI Responses API\n */\nexport const stream: StreamFunction<\"azure-openai-responses\", AzureOpenAIResponsesOptions> = (\n\tmodel: Model<\"azure-openai-responses\">,\n\tcontext: TranscriptContext,\n\toptions?: AzureOpenAIResponsesOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\tconst normalizedContext = resolveTranscript(context, model.compat?.supportsMidConvoSystemMessages);\n\n\t// Start async processing\n\t(async () => {\n\t\tconst deploymentName = resolveDeploymentName(model, options);\n\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: \"azure-openai-responses\" as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"pending\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\t// Create Azure OpenAI client\n\t\t\tconst apiKey = options?.apiKey;\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t\t\t}\n\t\t\tconst client = createClient(model, apiKey, options);\n\t\t\tconst grammarToolInputProperties = createGrammarToolInputProperties(\n\t\t\t\tgetDeclaredTools(normalizedContext.messages),\n\t\t\t\tmodel.compat?.supportsOpenAIGrammarTools ?? false,\n\t\t\t);\n\t\t\tlet params = buildParams(model, normalizedContext, options, deploymentName, grammarToolInputProperties);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as ResponseCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst requestOptions = {\n\t\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t\t\t...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),\n\t\t\t\tmaxRetries: 0,\n\t\t\t};\n\t\t\tconst { data: openaiStream, response } = await retryProviderRequest(\n\t\t\t\t() => client.responses.create(params, requestOptions).withResponse(),\n\t\t\t\t{\n\t\t\t\t\tmaxRetries: options?.maxRetries,\n\t\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\t\t\t\tsignal: options?.signal,\n\t\t\t\t},\n\t\t\t);\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\tawait processResponsesStream(openaiStream, output, stream, model, {\n\t\t\t\tonProviderStreamEvent: options?.onProviderStreamEvent,\n\t\t\t\tgrammarToolInputProperties,\n\t\t\t});\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"pending\") {\n\t\t\t\tthrow new Error(\"Azure OpenAI Responses stream ended without a stop reason\");\n\t\t\t}\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(output.errorMessage || \"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatAzureOpenAIError(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\nexport const streamSimple: StreamFunction<\"azure-openai-responses\", SimpleStreamOptions> = (\n\tmodel: Model<\"azure-openai-responses\">,\n\tcontext: TranscriptContext,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey;\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = {\n\t\t...buildBaseOptions(model, context, options, apiKey),\n\t\ttoolChoice: options?.toolChoice,\n\t} satisfies AzureOpenAIResponsesOptions;\n\tconst clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;\n\tconst reasoningEffort = clampedReasoning === \"off\" ? undefined : clampedReasoning;\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\treasoningEffort,\n\t} satisfies AzureOpenAIResponsesOptions);\n};\n\nfunction createClient(model: Model<\"azure-openai-responses\">, apiKey: string, options?: AzureOpenAIResponsesOptions) {\n\tconst headers = { ...getIdentityHeaders(model, options?.identity), ...model.headers };\n\n\tif (options?.headers) {\n\t\tObject.assign(headers, options.headers);\n\t}\n\n\tconst { baseUrl, apiVersion } = resolveAzureConfig(model, options);\n\n\treturn new AzureOpenAI({\n\t\tapiKey,\n\t\tapiVersion,\n\t\tdangerouslyAllowBrowser: true,\n\t\tfetch: options?.fetch,\n\t\tdefaultHeaders: headers,\n\t\tbaseURL: baseUrl,\n\t});\n}\n\nfunction buildParams(\n\tmodel: Model<\"azure-openai-responses\">,\n\tcontext: TranscriptContext,\n\toptions: AzureOpenAIResponsesOptions | undefined,\n\tdeploymentName: string,\n\tgrammarToolInputProperties: ReadonlyMap<string, string> = createGrammarToolInputProperties(\n\t\tgetDeclaredTools(context.messages),\n\t\tmodel.compat?.supportsOpenAIGrammarTools ?? false,\n\t),\n) {\n\tconst supportsAdditionalTools = model.compat?.supportsAdditionalTools ?? false;\n\tconst supportsToolSearch = model.compat?.supportsToolSearch ?? false;\n\tconst transcriptTools = resolveTranscriptTools(\n\t\tcontext.messages,\n\t\tgetResponsesToolSupport({\n\t\t\tsupportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,\n\t\t\tsupportsAdditionalTools,\n\t\t\tsupportsToolSearch,\n\t\t}),\n\t);\n\tconst messages = convertResponsesMessages(model, context, AZURE_TOOL_CALL_PROVIDERS, {\n\t\tgrammarToolInputProperties,\n\t\tsupportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,\n\t\tsupportsAdditionalTools,\n\t\tsupportsToolSearch,\n\t\ttoolOptions: {\n\t\t\tsupportsStrictMode: model.compat?.supportsStrictMode ?? true,\n\t\t\tsupportsOpenAIGrammarTools: model.compat?.supportsOpenAIGrammarTools ?? false,\n\t\t},\n\t});\n\n\tconst params: ResponseCreateParamsStreaming = {\n\t\tmodel: deploymentName,\n\t\tinput: messages,\n\t\tstream: true,\n\t\tprompt_cache_key:\n\t\t\tmodel.compat?.promptCacheKeyMode === \"disabled\" ? undefined : clampOpenAIPromptCacheKey(options?.sessionId),\n\t\tstore: false,\n\t};\n\n\tif (options?.maxTokens) {\n\t\tparams.max_output_tokens = Math.max(options.maxTokens, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS);\n\t}\n\n\tif (options?.temperature !== undefined) {\n\t\tparams.temperature = options?.temperature;\n\t}\n\n\tif (transcriptTools.requestTools.length > 0) {\n\t\tparams.tools = convertResponsesTools(transcriptTools.requestTools, {\n\t\t\tsupportsStrictMode: model.compat?.supportsStrictMode ?? true,\n\t\t\tsupportsOpenAIGrammarTools: model.compat?.supportsOpenAIGrammarTools ?? false,\n\t\t});\n\t}\n\tif (options?.toolChoice !== undefined) {\n\t\tparams.tool_choice = options.toolChoice;\n\t}\n\n\tconst reasoningEffort = options?.reasoningEffort ?? (options?.reasoningSummary ? \"medium\" : undefined);\n\tif (model.reasoning) {\n\t\tif (reasoningEffort) {\n\t\t\tconst effort = options?.reasoningEffort\n\t\t\t\t? (model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort)\n\t\t\t\t: reasoningEffort;\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: effort as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t\tsummary: options?.reasoningSummary || \"auto\",\n\t\t\t};\n\t\t\tparams.include = [\"reasoning.encrypted_content\"];\n\t\t} else if (model.thinkingLevelMap?.off !== null) {\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: (model.thinkingLevelMap?.off ?? \"none\") as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t};\n\t\t}\n\t}\n\n\t// Last so model and request sampling parameters override named request fields.\n\tconst samplingParams = resolveSamplingParams(model, reasoningEffort ?? \"off\", options?.samplingParams);\n\tif (samplingParams) {\n\t\tObject.assign(params, samplingParams);\n\t}\n\n\treturn params;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bedrock-converse-stream.d.ts","sourceRoot":"","sources":["../../src/api/bedrock-converse-stream.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAUX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAEb,eAAe,EAEf,aAAa,EAIb,MAAM,aAAa,CAAC;AA2BrB,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,cAAe,SAAQ,aAAa;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAEtE,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC;;;sGAGkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC;;;;yGAIqG;IACrG,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAgBD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,yBAAyB,EAAE,cAAc,CA6O5E,CAAC;AAkLF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,yBAAyB,EAAE,mBAAmB,CAiDvF,CAAC"}
1
+ {"version":3,"file":"bedrock-converse-stream.d.ts","sourceRoot":"","sources":["../../src/api/bedrock-converse-stream.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAUX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAEb,eAAe,EACf,aAAa,EAGb,MAAM,aAAa,CAAC;AAoCrB,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,cAAe,SAAQ,aAAa;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAEtE,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC;;;sGAGkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC;;;;yGAIqG;IACrG,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAsBD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,yBAAyB,EAAE,cAAc,CAsQ5E,CAAC;AAkLF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,yBAAyB,EAAE,mBAAmB,CAiDvF,CAAC"}
@@ -8,14 +8,15 @@ import { normalizeProviderError } from "../utils/error-body.js";
8
8
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
9
9
  import { providerHeadersToRecord } from "../utils/headers.js";
10
10
  import { getClientVersion } from "../utils/identity.js";
11
- import { parseStreamingJson, parseToolCallArguments } from "../utils/json-parse.js";
12
11
  import { resolveHttpProxyUrlForTarget } from "../utils/node-http-proxy.js";
13
12
  import { getProviderEnvValue } from "../utils/provider-env.js";
14
13
  import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
14
+ import { ToolCallArgumentsStream } from "../utils/streaming-json.js";
15
15
  import { getSystemMessageText } from "../utils/text.js";
16
16
  import { collapseSystemMessages, getCurrentTools, getInitialSystemMessage, withoutInitialSystemMessage, } from "../utils/transcript.js";
17
- import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
17
+ import { getJsonSchemaToolParameters, prefersJsonSchemaStrictSampling, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
18
18
  import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext, clampReasoning, } from "./simple-options.js";
19
+ import { hasExceededStrictToolLimits, isStrictToolLimitErrorMessage, markStrictToolLimitsExceeded, } from "./strict-tool-limits.js";
19
20
  import { splitErrorToolResultImages, transformMessages } from "./transform-messages.js";
20
21
  const EMPTY_TEXT_PLACEHOLDER = "<empty>";
21
22
  const THINKING_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
@@ -43,7 +44,7 @@ export const stream = (model, context, options = {}) => {
43
44
  stopReason: "pending",
44
45
  timestamp: Date.now(),
45
46
  };
46
- const blocks = output.content;
47
+ const openBlocks = new Map();
47
48
  // A profile explicitly configured through pi's auth flow (the `profile`
48
49
  // option or scoped `AWS_PROFILE` on the stored credential's env) must win
49
50
  // over ambient AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY. The SDK default
@@ -145,24 +146,50 @@ export const stream = (model, context, options = {}) => {
145
146
  const inferenceMaxTokens = options.maxTokens ?? (isAnthropicClaudeModel(model) ? model.maxTokens : undefined);
146
147
  const initialSystemMessage = getInitialSystemMessage(normalizedContext.messages);
147
148
  const initialSystemPrompt = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : undefined;
148
- let commandInput = {
149
- modelId: model.id,
150
- messages: convertMessages(normalizedContext, model, cacheRetention, options.env),
151
- system: buildSystemPrompt(initialSystemPrompt, model, cacheRetention, options.env),
152
- inferenceConfig: {
153
- ...(inferenceMaxTokens !== undefined && { maxTokens: inferenceMaxTokens }),
154
- ...(options.temperature !== undefined && { temperature: options.temperature }),
155
- },
156
- toolConfig: convertToolConfig(getCurrentTools(normalizedContext.messages), options.toolChoice, supportsStrictMode),
157
- additionalModelRequestFields: buildAdditionalModelRequestFields(model, options),
158
- ...(options.requestMetadata !== undefined && { requestMetadata: options.requestMetadata }),
159
- };
160
- const nextCommandInput = await options?.onPayload?.(commandInput, model);
161
- if (nextCommandInput !== undefined) {
162
- commandInput = nextCommandInput;
149
+ let disablePreferredStrictTools = hasExceededStrictToolLimits(options.sessionId);
150
+ let response;
151
+ for (;;) {
152
+ const tools = convertToolConfig(getCurrentTools(normalizedContext.messages), options.toolChoice, supportsStrictMode, disablePreferredStrictTools);
153
+ let commandInput = {
154
+ modelId: model.id,
155
+ messages: convertMessages(normalizedContext, model, cacheRetention, options.env),
156
+ system: buildSystemPrompt(initialSystemPrompt, model, cacheRetention, options.env),
157
+ inferenceConfig: {
158
+ ...(inferenceMaxTokens !== undefined && { maxTokens: inferenceMaxTokens }),
159
+ ...(options.temperature !== undefined && { temperature: options.temperature }),
160
+ },
161
+ toolConfig: tools.toolConfig,
162
+ additionalModelRequestFields: buildAdditionalModelRequestFields(model, options),
163
+ ...(options.requestMetadata !== undefined && { requestMetadata: options.requestMetadata }),
164
+ };
165
+ const nextCommandInput = await options?.onPayload?.(commandInput, model);
166
+ if (nextCommandInput !== undefined) {
167
+ commandInput = nextCommandInput;
168
+ }
169
+ try {
170
+ response = await client.send(new ConverseStreamCommand(commandInput), { abortSignal: options.signal });
171
+ break;
172
+ }
173
+ catch (error) {
174
+ // Bedrock checks the tool schemas before it starts the stream, so a retry never repeats streamed output.
175
+ if (options.signal?.aborted ||
176
+ disablePreferredStrictTools ||
177
+ !tools.hasPreferredStrictTools ||
178
+ !(error instanceof BedrockRuntimeServiceException) ||
179
+ error.name !== "ValidationException" ||
180
+ !isStrictToolLimitErrorMessage(error.message)) {
181
+ throw error;
182
+ }
183
+ disablePreferredStrictTools = true;
184
+ markStrictToolLimitsExceeded(options.sessionId);
185
+ appendAssistantMessageDiagnostic(output, {
186
+ type: "bedrock_strict_tools_fallback",
187
+ timestamp: Date.now(),
188
+ error: { message: error.message },
189
+ details: { reason: "strict_tool_limits_exceeded" },
190
+ });
191
+ }
163
192
  }
164
- const command = new ConverseStreamCommand(commandInput);
165
- const response = await client.send(command, { abortSignal: options.signal });
166
193
  responseRequestId = normalizeDiagnosticValue(response.$metadata.requestId);
167
194
  if (!observedRawResponse && response.$metadata.httpStatusCode !== undefined) {
168
195
  const responseHeaders = {};
@@ -180,13 +207,13 @@ export const stream = (model, context, options = {}) => {
180
207
  stream.push({ type: "start", partial: output });
181
208
  }
182
209
  else if (item.contentBlockStart) {
183
- handleContentBlockStart(item.contentBlockStart, blocks, output, stream);
210
+ handleContentBlockStart(item.contentBlockStart, openBlocks, output, stream);
184
211
  }
185
212
  else if (item.contentBlockDelta) {
186
- handleContentBlockDelta(item.contentBlockDelta, blocks, output, stream);
213
+ handleContentBlockDelta(item.contentBlockDelta, openBlocks, output, stream);
187
214
  }
188
215
  else if (item.contentBlockStop) {
189
- handleContentBlockStop(item.contentBlockStop, blocks, output, stream);
216
+ handleContentBlockStop(item.contentBlockStop, openBlocks, output, stream);
190
217
  }
191
218
  else if (item.messageStop) {
192
219
  output.rawStopReason = item.messageStop.stopReason;
@@ -225,15 +252,12 @@ export const stream = (model, context, options = {}) => {
225
252
  throw new Error(output.errorMessage || "An unknown error occurred");
226
253
  }
227
254
  // A stream can settle without stopping every block, so finalize here too.
228
- for (const block of output.content)
229
- finalizeStreamingBlock(block);
255
+ flushOpenBlocks(openBlocks, output);
230
256
  stream.push({ type: "done", reason: output.stopReason, message: output });
231
257
  stream.end();
232
258
  }
233
259
  catch (error) {
234
- for (const block of output.content) {
235
- finalizeStreamingBlock(block);
236
- }
260
+ flushOpenBlocks(openBlocks, output);
237
261
  output.stopReason = options.signal?.aborted ? "aborted" : "error";
238
262
  output.errorMessage = formatBedrockError(error);
239
263
  if (output.stopReason === "error") {
@@ -436,59 +460,60 @@ export const streamSimple = (model, context, options) => {
436
460
  thinkingBudgets: options.thinkingBudgets,
437
461
  });
438
462
  };
439
- function handleContentBlockStart(event, blocks, output, stream) {
440
- const index = event.contentBlockIndex;
463
+ function handleContentBlockStart(event, openBlocks, output, stream) {
441
464
  const start = event.start;
442
465
  if (start?.toolUse) {
443
- const block = {
466
+ output.content.push({
444
467
  type: "toolCall",
445
468
  id: start.toolUse.toolUseId || "",
446
469
  name: start.toolUse.name || "",
447
470
  arguments: {},
448
- partialJson: "",
449
- index,
450
- };
451
- output.content.push(block);
452
- stream.push({ type: "toolcall_start", contentIndex: blocks.length - 1, partial: output });
471
+ });
472
+ const contentIndex = output.content.length - 1;
473
+ openBlocks.set(event.contentBlockIndex, { contentIndex, arguments: new ToolCallArgumentsStream() });
474
+ stream.push({ type: "toolcall_start", contentIndex, partial: output });
453
475
  }
454
476
  }
455
- function handleContentBlockDelta(event, blocks, output, stream) {
477
+ function handleContentBlockDelta(event, openBlocks, output, stream) {
456
478
  const contentBlockIndex = event.contentBlockIndex;
457
479
  const delta = event.delta;
458
- let index = blocks.findIndex((b) => b.index === contentBlockIndex);
459
- let block = blocks[index];
480
+ let open = openBlocks.get(contentBlockIndex);
481
+ let block = open === undefined ? undefined : output.content[open.contentIndex];
460
482
  if (delta?.text !== undefined) {
461
483
  // If no text block exists yet, create one, as `handleContentBlockStart` is not sent for text blocks
462
- if (!block) {
463
- const newBlock = { type: "text", text: "", index: contentBlockIndex };
464
- output.content.push(newBlock);
465
- index = blocks.length - 1;
466
- block = blocks[index];
467
- stream.push({ type: "text_start", contentIndex: index, partial: output });
484
+ if (!open) {
485
+ output.content.push({ type: "text", text: "" });
486
+ open = { contentIndex: output.content.length - 1 };
487
+ openBlocks.set(contentBlockIndex, open);
488
+ block = output.content[open.contentIndex];
489
+ stream.push({ type: "text_start", contentIndex: open.contentIndex, partial: output });
468
490
  }
469
- if (block.type === "text") {
491
+ if (block?.type === "text") {
470
492
  block.text += delta.text;
471
- stream.push({ type: "text_delta", contentIndex: index, delta: delta.text, partial: output });
493
+ stream.push({ type: "text_delta", contentIndex: open.contentIndex, delta: delta.text, partial: output });
472
494
  }
473
495
  }
474
- else if (delta?.toolUse && block?.type === "toolCall") {
475
- block.partialJson = (block.partialJson || "") + (delta.toolUse.input || "");
476
- block.arguments = parseStreamingJson(block.partialJson);
477
- stream.push({ type: "toolcall_delta", contentIndex: index, delta: delta.toolUse.input || "", partial: output });
496
+ else if (delta?.toolUse && block?.type === "toolCall" && open?.arguments !== undefined) {
497
+ block.arguments = open.arguments.append(delta.toolUse.input || "");
498
+ stream.push({
499
+ type: "toolcall_delta",
500
+ contentIndex: open.contentIndex,
501
+ delta: delta.toolUse.input || "",
502
+ partial: output,
503
+ });
478
504
  }
479
505
  else if (delta?.reasoningContent) {
480
- let thinkingBlock = block;
481
- let thinkingIndex = index;
482
- if (!thinkingBlock) {
483
- const newBlock = { type: "thinking", thinking: "", thinkingSignature: "", index: contentBlockIndex };
484
- output.content.push(newBlock);
485
- thinkingIndex = blocks.length - 1;
486
- thinkingBlock = blocks[thinkingIndex];
487
- stream.push({ type: "thinking_start", contentIndex: thinkingIndex, partial: output });
506
+ if (!open) {
507
+ output.content.push({ type: "thinking", thinking: "", thinkingSignature: "" });
508
+ open = { contentIndex: output.content.length - 1 };
509
+ openBlocks.set(contentBlockIndex, open);
510
+ block = output.content[open.contentIndex];
511
+ stream.push({ type: "thinking_start", contentIndex: open.contentIndex, partial: output });
488
512
  }
489
- if (thinkingBlock?.type === "thinking") {
513
+ if (block?.type === "thinking") {
514
+ const thinkingIndex = open.contentIndex;
490
515
  if (delta.reasoningContent.text) {
491
- thinkingBlock.thinking += delta.reasoningContent.text;
516
+ block.thinking += delta.reasoningContent.text;
492
517
  stream.push({
493
518
  type: "thinking_delta",
494
519
  contentIndex: thinkingIndex,
@@ -498,18 +523,17 @@ function handleContentBlockDelta(event, blocks, output, stream) {
498
523
  }
499
524
  // `thinkingSignature` holds either an Anthropic signature or an opaque redacted
500
525
  // payload, never both: mixing them would corrupt whichever arrived first.
501
- if (delta.reasoningContent.signature && !thinkingBlock.redacted) {
502
- thinkingBlock.thinkingSignature =
503
- (thinkingBlock.thinkingSignature || "") + delta.reasoningContent.signature;
526
+ if (delta.reasoningContent.signature && !block.redacted) {
527
+ block.thinkingSignature = (block.thinkingSignature || "") + delta.reasoningContent.signature;
504
528
  }
505
529
  if (delta.reasoningContent.redactedContent?.length) {
506
530
  // Encrypted reasoning from non-Anthropic models on Bedrock (e.g. OpenAI GPT-5.6).
507
531
  // The payload is opaque, so keep it verbatim in `thinkingSignature` the way the
508
532
  // Anthropic path stores redacted thinking, and replay it on the next turn.
509
- if (!thinkingBlock.redacted) {
510
- thinkingBlock.redacted = true;
511
- thinkingBlock.thinkingSignature = "";
512
- thinkingBlock.thinking += REDACTED_THINKING_PLACEHOLDER;
533
+ if (!block.redacted) {
534
+ block.redacted = true;
535
+ block.thinkingSignature = "";
536
+ block.thinking += REDACTED_THINKING_PLACEHOLDER;
513
537
  stream.push({
514
538
  type: "thinking_delta",
515
539
  contentIndex: thinkingIndex,
@@ -517,32 +541,29 @@ function handleContentBlockDelta(event, blocks, output, stream) {
517
541
  partial: output,
518
542
  });
519
543
  }
520
- thinkingBlock.redactedChunks ??= [];
521
- thinkingBlock.redactedChunks.push(delta.reasoningContent.redactedContent);
544
+ open.redactedChunks ??= [];
545
+ open.redactedChunks.push(delta.reasoningContent.redactedContent);
522
546
  }
523
547
  }
524
548
  }
525
549
  }
526
550
  /**
527
- * Encodes buffered encrypted reasoning into `thinkingSignature` and drops the scratch
528
- * buffer, which must never reach a persisted message: `Uint8Array` serializes to an
529
- * index-keyed object roughly ten times the size of the base64 payload.
551
+ * Encodes buffered encrypted reasoning into `thinkingSignature`. The chunks stay in the stream state, never on the
552
+ * block: `Uint8Array` is not JSON and serializes to an index-keyed object roughly ten times the size of the base64
553
+ * payload.
530
554
  */
531
- function flushRedactedContent(block) {
532
- if (block.type !== "thinking" || !block.redactedChunks)
555
+ function flushRedactedContent(open, output) {
556
+ const block = output.content[open.contentIndex];
557
+ if (block?.type !== "thinking" || !open.redactedChunks)
533
558
  return;
534
- block.thinkingSignature = bytesToBase64(block.redactedChunks);
535
- delete block.redactedChunks;
559
+ block.thinkingSignature = bytesToBase64(open.redactedChunks);
560
+ open.redactedChunks = undefined;
536
561
  }
537
- /**
538
- * Strips every streaming scratch field. Runs from the terminal paths as well as
539
- * `contentBlockStop`, because a stream can settle without stopping each block.
540
- */
541
- function finalizeStreamingBlock(block) {
542
- delete block.index;
543
- // partialJson is only a streaming scratch buffer; never persist it.
544
- delete block.partialJson;
545
- flushRedactedContent(block);
562
+ /** Ends the stream state of blocks a stream settled without stopping. */
563
+ function flushOpenBlocks(openBlocks, output) {
564
+ for (const open of openBlocks.values())
565
+ flushRedactedContent(open, output);
566
+ openBlocks.clear();
546
567
  }
547
568
  function handleMetadata(event, model, output) {
548
569
  if (event.usage) {
@@ -555,25 +576,24 @@ function handleMetadata(event, model, output) {
555
576
  calculateCost(model, output.usage);
556
577
  }
557
578
  }
558
- function handleContentBlockStop(event, blocks, output, stream) {
559
- const index = blocks.findIndex((b) => b.index === event.contentBlockIndex);
560
- const block = blocks[index];
561
- if (!block)
579
+ function handleContentBlockStop(event, openBlocks, output, stream) {
580
+ const open = openBlocks.get(event.contentBlockIndex);
581
+ if (!open)
562
582
  return;
563
- delete block.index;
583
+ openBlocks.delete(event.contentBlockIndex);
584
+ const index = open.contentIndex;
585
+ const block = output.content[index];
564
586
  switch (block.type) {
565
587
  case "text":
566
588
  stream.push({ type: "text_end", contentIndex: index, content: block.text, partial: output });
567
589
  break;
568
590
  case "thinking":
569
- flushRedactedContent(block);
591
+ flushRedactedContent(open, output);
570
592
  stream.push({ type: "thinking_end", contentIndex: index, content: block.thinking, partial: output });
571
593
  break;
572
594
  case "toolCall":
573
- Object.assign(block, parseToolCallArguments(block.partialJson));
574
- // Finalize in-place and strip the scratch buffer so replay only
575
- // carries parsed arguments.
576
- delete block.partialJson;
595
+ if (open.arguments !== undefined)
596
+ Object.assign(block, open.arguments.finish());
577
597
  stream.push({ type: "toolcall_end", contentIndex: index, toolCall: block, partial: output });
578
598
  break;
579
599
  }
@@ -924,13 +944,17 @@ function convertMessages(context, model, cacheRetention, env) {
924
944
  }
925
945
  return result;
926
946
  }
927
- function convertToolConfig(tools, toolChoice, supportsStrictMode) {
928
- if (!tools?.length)
929
- return undefined;
930
- if (toolChoice === "none")
931
- return undefined;
947
+ function convertToolConfig(tools, toolChoice, supportsStrictMode, disablePreferredStrictTools) {
948
+ if (!tools?.length || toolChoice === "none")
949
+ return { toolConfig: undefined, hasPreferredStrictTools: false };
950
+ let hasPreferredStrictTools = false;
932
951
  const bedrockTools = tools.map((tool) => {
933
- const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictMode);
952
+ const preferred = prefersJsonSchemaStrictSampling(tool);
953
+ const strict = disablePreferredStrictTools && preferred
954
+ ? undefined
955
+ : resolveJsonSchemaStrictSampling(tool, supportsStrictMode);
956
+ if (strict === true && preferred)
957
+ hasPreferredStrictTools = true;
934
958
  return {
935
959
  toolSpec: {
936
960
  name: tool.name,
@@ -953,7 +977,7 @@ function convertToolConfig(tools, toolChoice, supportsStrictMode) {
953
977
  bedrockToolChoice = { tool: { name: toolChoice.name } };
954
978
  }
955
979
  }
956
- return { tools: bedrockTools, toolChoice: bedrockToolChoice };
980
+ return { toolConfig: { tools: bedrockTools, toolChoice: bedrockToolChoice }, hasPreferredStrictTools };
957
981
  }
958
982
  function mapStopReason(reason) {
959
983
  switch (reason) {