@draht/ai 2026.10.20 → 2026.10.23

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 (269) hide show
  1. package/dist/api/anthropic-messages.d.ts.map +1 -1
  2. package/dist/api/anthropic-messages.js +155 -111
  3. package/dist/api/anthropic-messages.js.map +1 -1
  4. package/dist/api/azure-openai-config.d.ts +15 -0
  5. package/dist/api/azure-openai-config.d.ts.map +1 -0
  6. package/dist/api/azure-openai-config.js +76 -0
  7. package/dist/api/azure-openai-config.js.map +1 -0
  8. package/dist/api/azure-openai-responses.d.ts +3 -6
  9. package/dist/api/azure-openai-responses.d.ts.map +1 -1
  10. package/dist/api/azure-openai-responses.js +19 -83
  11. package/dist/api/azure-openai-responses.js.map +1 -1
  12. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  13. package/dist/api/bedrock-converse-stream.js +86 -22
  14. package/dist/api/bedrock-converse-stream.js.map +1 -1
  15. package/dist/api/classifier-shared.d.ts +21 -0
  16. package/dist/api/classifier-shared.d.ts.map +1 -0
  17. package/dist/api/classifier-shared.js +99 -0
  18. package/dist/api/classifier-shared.js.map +1 -0
  19. package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -1
  20. package/dist/api/cloudflare-workers-ai-system-one.js +15 -9
  21. package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -1
  22. package/dist/api/google-generative-ai.js +4 -4
  23. package/dist/api/google-generative-ai.js.map +1 -1
  24. package/dist/api/google-shared.d.ts.map +1 -1
  25. package/dist/api/google-shared.js +3 -1
  26. package/dist/api/google-shared.js.map +1 -1
  27. package/dist/api/google-vertex.d.ts.map +1 -1
  28. package/dist/api/google-vertex.js +9 -9
  29. package/dist/api/google-vertex.js.map +1 -1
  30. package/dist/api/lazy.d.ts +7 -2
  31. package/dist/api/lazy.d.ts.map +1 -1
  32. package/dist/api/lazy.js +28 -8
  33. package/dist/api/lazy.js.map +1 -1
  34. package/dist/api/llama-cpp-classify.d.ts.map +1 -1
  35. package/dist/api/llama-cpp-classify.js +4 -1
  36. package/dist/api/llama-cpp-classify.js.map +1 -1
  37. package/dist/api/mistral-conversations.d.ts.map +1 -1
  38. package/dist/api/mistral-conversations.js +38 -18
  39. package/dist/api/mistral-conversations.js.map +1 -1
  40. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  41. package/dist/api/openai-codex-responses.js +21 -13
  42. package/dist/api/openai-codex-responses.js.map +1 -1
  43. package/dist/api/openai-completions.d.ts.map +1 -1
  44. package/dist/api/openai-completions.js +49 -38
  45. package/dist/api/openai-completions.js.map +1 -1
  46. package/dist/api/openai-decisions.d.ts +4 -0
  47. package/dist/api/openai-decisions.d.ts.map +1 -0
  48. package/dist/api/openai-decisions.js +162 -0
  49. package/dist/api/openai-decisions.js.map +1 -0
  50. package/dist/api/openai-decisions.lazy.d.ts +3 -0
  51. package/dist/api/openai-decisions.lazy.d.ts.map +1 -0
  52. package/dist/api/openai-decisions.lazy.js +4 -0
  53. package/dist/api/openai-decisions.lazy.js.map +1 -0
  54. package/dist/api/openai-responses-shared.d.ts +26 -0
  55. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  56. package/dist/api/openai-responses-shared.js +82 -16
  57. package/dist/api/openai-responses-shared.js.map +1 -1
  58. package/dist/api/openai-responses.d.ts.map +1 -1
  59. package/dist/api/openai-responses.js +47 -18
  60. package/dist/api/openai-responses.js.map +1 -1
  61. package/dist/api/openrouter-images.d.ts.map +1 -1
  62. package/dist/api/openrouter-images.js +4 -3
  63. package/dist/api/openrouter-images.js.map +1 -1
  64. package/dist/api/pi-messages.d.ts.map +1 -1
  65. package/dist/api/pi-messages.js +3 -3
  66. package/dist/api/pi-messages.js.map +1 -1
  67. package/dist/api/simple-options.d.ts +2 -1
  68. package/dist/api/simple-options.d.ts.map +1 -1
  69. package/dist/api/simple-options.js +12 -2
  70. package/dist/api/simple-options.js.map +1 -1
  71. package/dist/api/system-one-shared.d.ts +0 -1
  72. package/dist/api/system-one-shared.d.ts.map +1 -1
  73. package/dist/api/system-one-shared.js +5 -89
  74. package/dist/api/system-one-shared.js.map +1 -1
  75. package/dist/api/transform-messages.d.ts +16 -1
  76. package/dist/api/transform-messages.d.ts.map +1 -1
  77. package/dist/api/transform-messages.js +28 -15
  78. package/dist/api/transform-messages.js.map +1 -1
  79. package/dist/api/typesafe-system-one.d.ts.map +1 -1
  80. package/dist/api/typesafe-system-one.js +2 -1
  81. package/dist/api/typesafe-system-one.js.map +1 -1
  82. package/dist/auth/oauth/anthropic.d.ts.map +1 -1
  83. package/dist/auth/oauth/anthropic.js +65 -7
  84. package/dist/auth/oauth/anthropic.js.map +1 -1
  85. package/dist/auth/oauth/load.d.ts +2 -0
  86. package/dist/auth/oauth/load.d.ts.map +1 -1
  87. package/dist/auth/oauth/load.js +5 -0
  88. package/dist/auth/oauth/load.js.map +1 -1
  89. package/dist/auth/oauth/openai-chatgpt.d.ts.map +1 -1
  90. package/dist/auth/oauth/openai-chatgpt.js +11 -14
  91. package/dist/auth/oauth/openai-chatgpt.js.map +1 -1
  92. package/dist/auth/oauth/openai-codex.d.ts.map +1 -1
  93. package/dist/auth/oauth/openai-codex.js +7 -5
  94. package/dist/auth/oauth/openai-codex.js.map +1 -1
  95. package/dist/auth/oauth/opencode-go.d.ts +3 -12
  96. package/dist/auth/oauth/opencode-go.d.ts.map +1 -1
  97. package/dist/auth/oauth/opencode-go.js +229 -34
  98. package/dist/auth/oauth/opencode-go.js.map +1 -1
  99. package/dist/auth/resolve.d.ts +16 -1
  100. package/dist/auth/resolve.d.ts.map +1 -1
  101. package/dist/auth/resolve.js +51 -27
  102. package/dist/auth/resolve.js.map +1 -1
  103. package/dist/auth/types.d.ts +5 -0
  104. package/dist/auth/types.d.ts.map +1 -1
  105. package/dist/auth/types.js.map +1 -1
  106. package/dist/bun-oauth.d.ts.map +1 -1
  107. package/dist/bun-oauth.js +2 -1
  108. package/dist/bun-oauth.js.map +1 -1
  109. package/dist/env-api-keys.js +1 -1
  110. package/dist/env-api-keys.js.map +1 -1
  111. package/dist/index.d.ts +2 -1
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +2 -1
  114. package/dist/index.js.map +1 -1
  115. package/dist/models.d.ts +9 -0
  116. package/dist/models.d.ts.map +1 -1
  117. package/dist/models.generated.d.ts +4 -4
  118. package/dist/models.generated.d.ts.map +1 -1
  119. package/dist/models.generated.js +4 -4
  120. package/dist/models.generated.js.map +1 -1
  121. package/dist/models.js +26 -14
  122. package/dist/models.js.map +1 -1
  123. package/dist/providers/all.js +2 -2
  124. package/dist/providers/all.js.map +1 -1
  125. package/dist/providers/azure.d.ts +3 -0
  126. package/dist/providers/azure.d.ts.map +1 -0
  127. package/dist/providers/azure.js +46 -0
  128. package/dist/providers/azure.js.map +1 -0
  129. package/dist/providers/azure.models.d.ts +6 -0
  130. package/dist/providers/azure.models.d.ts.map +1 -0
  131. package/dist/providers/azure.models.js +8 -0
  132. package/dist/providers/azure.models.js.map +1 -0
  133. package/dist/providers/compat-schema.d.ts +491 -0
  134. package/dist/providers/compat-schema.d.ts.map +1 -0
  135. package/dist/providers/compat-schema.js +386 -0
  136. package/dist/providers/compat-schema.js.map +1 -0
  137. package/dist/providers/data/.manifest.json +1 -1
  138. package/dist/providers/data/amazon-bedrock.json +1 -1
  139. package/dist/providers/data/anthropic.json +1 -1
  140. package/dist/providers/data/azure.json +1 -0
  141. package/dist/providers/data/baseten.json +1 -1
  142. package/dist/providers/data/cerebras.json +1 -1
  143. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  144. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  145. package/dist/providers/data/fireworks.json +1 -1
  146. package/dist/providers/data/github-copilot.json +1 -1
  147. package/dist/providers/data/google-vertex.json +1 -1
  148. package/dist/providers/data/google.json +1 -1
  149. package/dist/providers/data/groq.json +1 -1
  150. package/dist/providers/data/huggingface.json +1 -1
  151. package/dist/providers/data/kimi-coding.json +1 -1
  152. package/dist/providers/data/meta.json +1 -1
  153. package/dist/providers/data/minimax-cn.json +1 -1
  154. package/dist/providers/data/minimax.json +1 -1
  155. package/dist/providers/data/mistral.json +1 -1
  156. package/dist/providers/data/moonshotai-cn.json +1 -1
  157. package/dist/providers/data/nvidia.json +1 -1
  158. package/dist/providers/data/openai-codex.json +1 -1
  159. package/dist/providers/data/openai.json +1 -1
  160. package/dist/providers/data/opencode-go.json +1 -1
  161. package/dist/providers/data/opencode.json +1 -1
  162. package/dist/providers/data/openrouter.json +1 -1
  163. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  164. package/dist/providers/data/qwen-token-plan.json +1 -1
  165. package/dist/providers/data/radius.json +1 -1
  166. package/dist/providers/data/together.json +1 -1
  167. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  168. package/dist/providers/data/xai.json +1 -1
  169. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  170. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  171. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  172. package/dist/providers/data/xiaomi.json +1 -1
  173. package/dist/providers/data/zai-coding-cn.json +1 -1
  174. package/dist/providers/faux.d.ts.map +1 -1
  175. package/dist/providers/faux.js +25 -8
  176. package/dist/providers/faux.js.map +1 -1
  177. package/dist/providers/kimi-coding.d.ts +1 -1
  178. package/dist/providers/kimi-coding.js +3 -3
  179. package/dist/providers/kimi-coding.js.map +1 -1
  180. package/dist/providers/model-schema.d.ts +91 -0
  181. package/dist/providers/model-schema.d.ts.map +1 -0
  182. package/dist/providers/model-schema.js +57 -0
  183. package/dist/providers/model-schema.js.map +1 -0
  184. package/dist/providers/openai.d.ts.map +1 -1
  185. package/dist/providers/openai.js +12 -3
  186. package/dist/providers/openai.js.map +1 -1
  187. package/dist/providers/opencode-go.d.ts +3 -1
  188. package/dist/providers/opencode-go.d.ts.map +1 -1
  189. package/dist/providers/opencode-go.js +4 -3
  190. package/dist/providers/opencode-go.js.map +1 -1
  191. package/dist/providers/opencode.d.ts.map +1 -1
  192. package/dist/providers/opencode.js +10 -2
  193. package/dist/providers/opencode.js.map +1 -1
  194. package/dist/providers/openrouter-api.d.ts +40 -0
  195. package/dist/providers/openrouter-api.d.ts.map +1 -0
  196. package/dist/providers/openrouter-api.js +41 -0
  197. package/dist/providers/openrouter-api.js.map +1 -0
  198. package/dist/providers/openrouter.d.ts +11 -1
  199. package/dist/providers/openrouter.d.ts.map +1 -1
  200. package/dist/providers/openrouter.js +52 -1
  201. package/dist/providers/openrouter.js.map +1 -1
  202. package/dist/providers/radius.d.ts.map +1 -1
  203. package/dist/providers/radius.js +4 -12
  204. package/dist/providers/radius.js.map +1 -1
  205. package/dist/telemetry.d.ts +288 -0
  206. package/dist/telemetry.d.ts.map +1 -0
  207. package/dist/telemetry.js +191 -0
  208. package/dist/telemetry.js.map +1 -0
  209. package/dist/types.d.ts +42 -310
  210. package/dist/types.d.ts.map +1 -1
  211. package/dist/types.js.map +1 -1
  212. package/dist/utils/estimate.js +1 -1
  213. package/dist/utils/estimate.js.map +1 -1
  214. package/dist/utils/event-stream.d.ts +10 -1
  215. package/dist/utils/event-stream.d.ts.map +1 -1
  216. package/dist/utils/event-stream.js +25 -0
  217. package/dist/utils/event-stream.js.map +1 -1
  218. package/dist/utils/identity.d.ts +65 -0
  219. package/dist/utils/identity.d.ts.map +1 -0
  220. package/dist/utils/identity.js +145 -0
  221. package/dist/utils/identity.js.map +1 -0
  222. package/dist/utils/json-parse.d.ts +10 -0
  223. package/dist/utils/json-parse.d.ts.map +1 -1
  224. package/dist/utils/json-parse.js +26 -1
  225. package/dist/utils/json-parse.js.map +1 -1
  226. package/dist/utils/model-operations.d.ts +3 -1
  227. package/dist/utils/model-operations.d.ts.map +1 -1
  228. package/dist/utils/model-operations.js +6 -0
  229. package/dist/utils/model-operations.js.map +1 -1
  230. package/dist/utils/overflow.d.ts +1 -0
  231. package/dist/utils/overflow.d.ts.map +1 -1
  232. package/dist/utils/overflow.js +6 -1
  233. package/dist/utils/overflow.js.map +1 -1
  234. package/dist/utils/provider-retry.d.ts +2 -0
  235. package/dist/utils/provider-retry.d.ts.map +1 -1
  236. package/dist/utils/provider-retry.js +2 -0
  237. package/dist/utils/provider-retry.js.map +1 -1
  238. package/dist/utils/retry.d.ts.map +1 -1
  239. package/dist/utils/retry.js +30 -10
  240. package/dist/utils/retry.js.map +1 -1
  241. package/dist/utils/transcript.d.ts +27 -10
  242. package/dist/utils/transcript.d.ts.map +1 -1
  243. package/dist/utils/transcript.js +34 -20
  244. package/dist/utils/transcript.js.map +1 -1
  245. package/dist/utils/validation.d.ts.map +1 -1
  246. package/dist/utils/validation.js +3 -0
  247. package/dist/utils/validation.js.map +1 -1
  248. package/dist/utils/version.d.ts +2 -0
  249. package/dist/utils/version.d.ts.map +1 -0
  250. package/dist/utils/version.js +5 -0
  251. package/dist/utils/version.js.map +1 -0
  252. package/package.json +5 -5
  253. package/dist/providers/azure-openai-responses.d.ts +0 -3
  254. package/dist/providers/azure-openai-responses.d.ts.map +0 -1
  255. package/dist/providers/azure-openai-responses.js +0 -14
  256. package/dist/providers/azure-openai-responses.js.map +0 -1
  257. package/dist/providers/azure-openai-responses.models.d.ts +0 -6
  258. package/dist/providers/azure-openai-responses.models.d.ts.map +0 -1
  259. package/dist/providers/azure-openai-responses.models.js +0 -8
  260. package/dist/providers/azure-openai-responses.models.js.map +0 -1
  261. package/dist/providers/data/azure-openai-responses.json +0 -1
  262. package/dist/utils/assistant-message-frame.d.ts +0 -77
  263. package/dist/utils/assistant-message-frame.d.ts.map +0 -1
  264. package/dist/utils/assistant-message-frame.js +0 -425
  265. package/dist/utils/assistant-message-frame.js.map +0 -1
  266. package/dist/utils/draht-user-agent.d.ts +0 -2
  267. package/dist/utils/draht-user-agent.d.ts.map +0 -1
  268. package/dist/utils/draht-user-agent.js +0 -12
  269. package/dist/utils/draht-user-agent.js.map +0 -1
@@ -0,0 +1,76 @@
1
+ import { getProviderEnvValue } from "../utils/provider-env.js";
2
+ const DEFAULT_AZURE_API_VERSION = "v1";
3
+ function parseDeploymentNameMap(value) {
4
+ const map = new Map();
5
+ if (!value)
6
+ return map;
7
+ for (const entry of value.split(",")) {
8
+ const trimmed = entry.trim();
9
+ if (!trimmed)
10
+ continue;
11
+ const [modelId, deploymentName] = trimmed.split("=", 2);
12
+ if (!modelId || !deploymentName)
13
+ continue;
14
+ map.set(modelId.trim(), deploymentName.trim());
15
+ }
16
+ return map;
17
+ }
18
+ export function resolveDeploymentName(model, options) {
19
+ if (options?.azureDeploymentName) {
20
+ return options.azureDeploymentName;
21
+ }
22
+ const mappedDeployment = parseDeploymentNameMap(getProviderEnvValue("AZURE_OPENAI_DEPLOYMENT_NAME_MAP", options?.env)).get(model.id);
23
+ return mappedDeployment || model.id;
24
+ }
25
+ function normalizeAzureBaseUrl(baseUrl) {
26
+ const trimmed = baseUrl.trim().replace(/\/+$/, "");
27
+ let url;
28
+ try {
29
+ url = new URL(trimmed);
30
+ }
31
+ catch {
32
+ throw new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`);
33
+ }
34
+ const isAzureHost = url.hostname.endsWith(".openai.azure.com") ||
35
+ url.hostname.endsWith(".cognitiveservices.azure.com") ||
36
+ url.hostname.endsWith(".ai.azure.com");
37
+ const normalizedPath = url.pathname.replace(/\/+$/, "");
38
+ // Ensure Azure hosts have /openai/v1 as base path so the AzureOpenAI SDK
39
+ // can append /deployments/<model>/... and ?api-version=v1 correctly.
40
+ if (isAzureHost &&
41
+ (normalizedPath === "" ||
42
+ normalizedPath === "/" ||
43
+ normalizedPath === "/openai" ||
44
+ normalizedPath === "/openai/v1/responses")) {
45
+ url.pathname = "/openai/v1";
46
+ url.search = "";
47
+ }
48
+ return url.toString().replace(/\/+$/, "");
49
+ }
50
+ function buildDefaultBaseUrl(resourceName) {
51
+ return `https://${resourceName}.openai.azure.com/openai/v1`;
52
+ }
53
+ export function resolveAzureBaseUrl(model, options) {
54
+ const baseUrl = options?.azureBaseUrl?.trim() || getProviderEnvValue("AZURE_OPENAI_BASE_URL", options?.env)?.trim() || undefined;
55
+ const resourceName = options?.azureResourceName || getProviderEnvValue("AZURE_OPENAI_RESOURCE_NAME", options?.env);
56
+ let resolvedBaseUrl = baseUrl;
57
+ if (!resolvedBaseUrl && resourceName) {
58
+ resolvedBaseUrl = buildDefaultBaseUrl(resourceName);
59
+ }
60
+ if (!resolvedBaseUrl && model.baseUrl) {
61
+ resolvedBaseUrl = model.baseUrl;
62
+ }
63
+ if (!resolvedBaseUrl) {
64
+ throw new Error("Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.");
65
+ }
66
+ return normalizeAzureBaseUrl(resolvedBaseUrl);
67
+ }
68
+ export function resolveAzureConfig(model, options) {
69
+ return {
70
+ baseUrl: resolveAzureBaseUrl(model, options),
71
+ apiVersion: options?.azureApiVersion ||
72
+ getProviderEnvValue("AZURE_OPENAI_API_VERSION", options?.env) ||
73
+ DEFAULT_AZURE_API_VERSION,
74
+ };
75
+ }
76
+ //# sourceMappingURL=azure-openai-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure-openai-config.js","sourceRoot":"","sources":["../../src/api/azure-openai-config.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model, StreamOptions } from \"../types.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\n\nconst DEFAULT_AZURE_API_VERSION = \"v1\";\n\n/** Azure models ship without a baseUrl: one resource per user, resolved per request. */\nexport interface AzureEndpointOptions extends StreamOptions {\n\tazureApiVersion?: string;\n\tazureResourceName?: string;\n\tazureBaseUrl?: string;\n\tazureDeploymentName?: string;\n}\n\nfunction parseDeploymentNameMap(value: string | undefined): Map<string, string> {\n\tconst map = new Map<string, string>();\n\tif (!value) return map;\n\tfor (const entry of value.split(\",\")) {\n\t\tconst trimmed = entry.trim();\n\t\tif (!trimmed) continue;\n\t\tconst [modelId, deploymentName] = trimmed.split(\"=\", 2);\n\t\tif (!modelId || !deploymentName) continue;\n\t\tmap.set(modelId.trim(), deploymentName.trim());\n\t}\n\treturn map;\n}\n\nexport function resolveDeploymentName(model: Pick<Model<Api>, \"id\">, options?: AzureEndpointOptions): string {\n\tif (options?.azureDeploymentName) {\n\t\treturn options.azureDeploymentName;\n\t}\n\tconst mappedDeployment = parseDeploymentNameMap(\n\t\tgetProviderEnvValue(\"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\", options?.env),\n\t).get(model.id);\n\treturn mappedDeployment || model.id;\n}\n\nfunction normalizeAzureBaseUrl(baseUrl: string): string {\n\tconst trimmed = baseUrl.trim().replace(/\\/+$/, \"\");\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(trimmed);\n\t} catch {\n\t\tthrow new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`);\n\t}\n\n\tconst isAzureHost =\n\t\turl.hostname.endsWith(\".openai.azure.com\") ||\n\t\turl.hostname.endsWith(\".cognitiveservices.azure.com\") ||\n\t\turl.hostname.endsWith(\".ai.azure.com\");\n\tconst normalizedPath = url.pathname.replace(/\\/+$/, \"\");\n\n\t// Ensure Azure hosts have /openai/v1 as base path so the AzureOpenAI SDK\n\t// can append /deployments/<model>/... and ?api-version=v1 correctly.\n\tif (\n\t\tisAzureHost &&\n\t\t(normalizedPath === \"\" ||\n\t\t\tnormalizedPath === \"/\" ||\n\t\t\tnormalizedPath === \"/openai\" ||\n\t\t\tnormalizedPath === \"/openai/v1/responses\")\n\t) {\n\t\turl.pathname = \"/openai/v1\";\n\t\turl.search = \"\";\n\t}\n\n\treturn url.toString().replace(/\\/+$/, \"\");\n}\n\nfunction buildDefaultBaseUrl(resourceName: string): string {\n\treturn `https://${resourceName}.openai.azure.com/openai/v1`;\n}\n\nexport function resolveAzureBaseUrl(model: Pick<Model<Api>, \"baseUrl\">, options?: AzureEndpointOptions): string {\n\tconst baseUrl =\n\t\toptions?.azureBaseUrl?.trim() || getProviderEnvValue(\"AZURE_OPENAI_BASE_URL\", options?.env)?.trim() || undefined;\n\tconst resourceName = options?.azureResourceName || getProviderEnvValue(\"AZURE_OPENAI_RESOURCE_NAME\", options?.env);\n\n\tlet resolvedBaseUrl = baseUrl;\n\n\tif (!resolvedBaseUrl && resourceName) {\n\t\tresolvedBaseUrl = buildDefaultBaseUrl(resourceName);\n\t}\n\n\tif (!resolvedBaseUrl && model.baseUrl) {\n\t\tresolvedBaseUrl = model.baseUrl;\n\t}\n\n\tif (!resolvedBaseUrl) {\n\t\tthrow new Error(\n\t\t\t\"Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.\",\n\t\t);\n\t}\n\n\treturn normalizeAzureBaseUrl(resolvedBaseUrl);\n}\n\nexport function resolveAzureConfig(\n\tmodel: Pick<Model<Api>, \"baseUrl\">,\n\toptions?: AzureEndpointOptions,\n): { baseUrl: string; apiVersion: string } {\n\treturn {\n\t\tbaseUrl: resolveAzureBaseUrl(model, options),\n\t\tapiVersion:\n\t\t\toptions?.azureApiVersion ||\n\t\t\tgetProviderEnvValue(\"AZURE_OPENAI_API_VERSION\", options?.env) ||\n\t\t\tDEFAULT_AZURE_API_VERSION,\n\t};\n}\n"]}
@@ -1,13 +1,10 @@
1
1
  import type { ResponseCreateParamsStreaming } from "openai/resources/responses/responses.js";
2
- import type { SimpleStreamOptions, StreamFunction, StreamOptions } from "../types.ts";
3
- export interface AzureOpenAIResponsesOptions extends StreamOptions {
2
+ import type { SimpleStreamOptions, StreamFunction } from "../types.ts";
3
+ import { type AzureEndpointOptions } from "./azure-openai-config.ts";
4
+ export interface AzureOpenAIResponsesOptions extends AzureEndpointOptions {
4
5
  reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
5
6
  toolChoice?: ResponseCreateParamsStreaming["tool_choice"];
6
7
  reasoningSummary?: "auto" | "detailed" | "concise" | null;
7
- azureApiVersion?: string;
8
- azureResourceName?: string;
9
- azureBaseUrl?: string;
10
- azureDeploymentName?: string;
11
8
  }
12
9
  /**
13
10
  * Generate function for Azure OpenAI Responses API
@@ -1 +1 @@
1
- {"version":3,"file":"azure-openai-responses.d.ts","sourceRoot":"","sources":["../../src/api/azure-openai-responses.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AAE7F,OAAO,KAAK,EAIX,mBAAmB,EACnB,cAAc,EACd,aAAa,EAEb,MAAM,aAAa,CAAC;AA8CrB,MAAM,WAAW,2BAA4B,SAAQ,aAAa;IACjE,eAAe,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;IAC1E,UAAU,CAAC,EAAE,6BAA6B,CAAC,aAAa,CAAC,CAAC;IAC1D,gBAAgB,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,wBAAwB,EAAE,2BAA2B,CA+FxF,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,wBAAwB,EAAE,mBAAmB,CAqBtF,CAAC"}
1
+ {"version":3,"file":"azure-openai-responses.d.ts","sourceRoot":"","sources":["../../src/api/azure-openai-responses.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AAE7F,OAAO,KAAK,EAAgC,mBAAmB,EAAE,cAAc,EAAqB,MAAM,aAAa,CAAC;AAOxH,OAAO,EAAE,KAAK,oBAAoB,EAA6C,MAAM,0BAA0B,CAAC;AAoBhH,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACxE,eAAe,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;IAC1E,UAAU,CAAC,EAAE,6BAA6B,CAAC,aAAa,CAAC,CAAC;IAC1D,gBAAgB,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;CAC1D;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,wBAAwB,EAAE,2BAA2B,CA+FxF,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,wBAAwB,EAAE,mBAAmB,CAqBtF,CAAC"}
@@ -1,42 +1,19 @@
1
1
  import { AzureOpenAI } from "openai";
2
2
  import { clampThinkingLevel } from "../models.js";
3
- import { getDrahtUserAgent } from "../utils/draht-user-agent.js";
4
3
  import { formatProviderError, normalizeProviderError } from "../utils/error-body.js";
5
4
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
6
5
  import { headersToRecord } from "../utils/headers.js";
7
- import { getProviderEnvValue } from "../utils/provider-env.js";
6
+ import { getIdentityHeaders } from "../utils/identity.js";
8
7
  import { retryProviderRequest } from "../utils/provider-retry.js";
9
8
  import { getDeclaredTools, resolveTranscript, resolveTranscriptTools } from "../utils/transcript.js";
9
+ import { resolveAzureConfig, resolveDeploymentName } from "./azure-openai-config.js";
10
10
  import { createGrammarToolInputProperties } from "./constrained-sampling.js";
11
11
  import { clampOpenAIPromptCacheKey } from "./openai-prompt-cache.js";
12
- import { convertResponsesMessages, convertResponsesTools, processResponsesStream } from "./openai-responses-shared.js";
13
- import { buildBaseOptions } from "./simple-options.js";
14
- const DEFAULT_AZURE_API_VERSION = "v1";
15
- const AZURE_TOOL_CALL_PROVIDERS = new Set(["openai", "openai-codex", "opencode", "azure-openai-responses"]);
12
+ import { convertResponsesMessages, convertResponsesTools, getResponsesToolSupport, processResponsesStream, } from "./openai-responses-shared.js";
13
+ import { buildBaseOptions, resolveSamplingParams } from "./simple-options.js";
14
+ const AZURE_TOOL_CALL_PROVIDERS = new Set(["openai", "openai-codex", "opencode", "azure"]);
16
15
  // OpenAI Responses rejects max_output_tokens below 16: https://github.com/badlogic/pi-mono/issues/6265
17
16
  const OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;
18
- function parseDeploymentNameMap(value) {
19
- const map = new Map();
20
- if (!value)
21
- return map;
22
- for (const entry of value.split(",")) {
23
- const trimmed = entry.trim();
24
- if (!trimmed)
25
- continue;
26
- const [modelId, deploymentName] = trimmed.split("=", 2);
27
- if (!modelId || !deploymentName)
28
- continue;
29
- map.set(modelId.trim(), deploymentName.trim());
30
- }
31
- return map;
32
- }
33
- function resolveDeploymentName(model, options) {
34
- if (options?.azureDeploymentName) {
35
- return options.azureDeploymentName;
36
- }
37
- const mappedDeployment = parseDeploymentNameMap(getProviderEnvValue("AZURE_OPENAI_DEPLOYMENT_NAME_MAP", options?.env)).get(model.id);
38
- return mappedDeployment || model.id;
39
- }
40
17
  function formatAzureOpenAIError(error) {
41
18
  return formatProviderError(normalizeProviderError(error), "Azure OpenAI API error");
42
19
  }
@@ -138,57 +115,8 @@ export const streamSimple = (model, context, options) => {
138
115
  reasoningEffort,
139
116
  });
140
117
  };
141
- function normalizeAzureBaseUrl(baseUrl) {
142
- const trimmed = baseUrl.trim().replace(/\/+$/, "");
143
- let url;
144
- try {
145
- url = new URL(trimmed);
146
- }
147
- catch {
148
- throw new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`);
149
- }
150
- const isAzureHost = url.hostname.endsWith(".openai.azure.com") ||
151
- url.hostname.endsWith(".cognitiveservices.azure.com") ||
152
- url.hostname.endsWith(".ai.azure.com");
153
- const normalizedPath = url.pathname.replace(/\/+$/, "");
154
- // Ensure Azure hosts have /openai/v1 as base path so the AzureOpenAI SDK
155
- // can append /deployments/<model>/... and ?api-version=v1 correctly.
156
- if (isAzureHost &&
157
- (normalizedPath === "" ||
158
- normalizedPath === "/" ||
159
- normalizedPath === "/openai" ||
160
- normalizedPath === "/openai/v1/responses")) {
161
- url.pathname = "/openai/v1";
162
- url.search = "";
163
- }
164
- return url.toString().replace(/\/+$/, "");
165
- }
166
- function buildDefaultBaseUrl(resourceName) {
167
- return `https://${resourceName}.openai.azure.com/openai/v1`;
168
- }
169
- function resolveAzureConfig(model, options) {
170
- const apiVersion = options?.azureApiVersion ||
171
- getProviderEnvValue("AZURE_OPENAI_API_VERSION", options?.env) ||
172
- DEFAULT_AZURE_API_VERSION;
173
- const baseUrl = options?.azureBaseUrl?.trim() || getProviderEnvValue("AZURE_OPENAI_BASE_URL", options?.env)?.trim() || undefined;
174
- const resourceName = options?.azureResourceName || getProviderEnvValue("AZURE_OPENAI_RESOURCE_NAME", options?.env);
175
- let resolvedBaseUrl = baseUrl;
176
- if (!resolvedBaseUrl && resourceName) {
177
- resolvedBaseUrl = buildDefaultBaseUrl(resourceName);
178
- }
179
- if (!resolvedBaseUrl && model.baseUrl) {
180
- resolvedBaseUrl = model.baseUrl;
181
- }
182
- if (!resolvedBaseUrl) {
183
- throw new Error("Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.");
184
- }
185
- return {
186
- baseUrl: normalizeAzureBaseUrl(resolvedBaseUrl),
187
- apiVersion,
188
- };
189
- }
190
118
  function createClient(model, apiKey, options) {
191
- const headers = { "User-Agent": getDrahtUserAgent(), ...model.headers };
119
+ const headers = { ...getIdentityHeaders(model, options?.identity), ...model.headers };
192
120
  if (options?.headers) {
193
121
  Object.assign(headers, options.headers);
194
122
  }
@@ -205,7 +133,11 @@ function createClient(model, apiKey, options) {
205
133
  function buildParams(model, context, options, deploymentName, grammarToolInputProperties = createGrammarToolInputProperties(getDeclaredTools(context.messages), model.compat?.supportsOpenAIGrammarTools ?? false)) {
206
134
  const supportsAdditionalTools = model.compat?.supportsAdditionalTools ?? false;
207
135
  const supportsToolSearch = model.compat?.supportsToolSearch ?? false;
208
- const transcriptTools = resolveTranscriptTools(context.messages, supportsAdditionalTools || supportsToolSearch);
136
+ const transcriptTools = resolveTranscriptTools(context.messages, getResponsesToolSupport({
137
+ supportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,
138
+ supportsAdditionalTools,
139
+ supportsToolSearch,
140
+ }));
209
141
  const messages = convertResponsesMessages(model, context, AZURE_TOOL_CALL_PROVIDERS, {
210
142
  grammarToolInputProperties,
211
143
  supportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,
@@ -238,11 +170,12 @@ function buildParams(model, context, options, deploymentName, grammarToolInputPr
238
170
  if (options?.toolChoice !== undefined) {
239
171
  params.tool_choice = options.toolChoice;
240
172
  }
173
+ const reasoningEffort = options?.reasoningEffort ?? (options?.reasoningSummary ? "medium" : undefined);
241
174
  if (model.reasoning) {
242
- if (options?.reasoningEffort || options?.reasoningSummary) {
175
+ if (reasoningEffort) {
243
176
  const effort = options?.reasoningEffort
244
177
  ? (model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort)
245
- : "medium";
178
+ : reasoningEffort;
246
179
  params.reasoning = {
247
180
  effort: effort,
248
181
  summary: options?.reasoningSummary || "auto",
@@ -255,8 +188,11 @@ function buildParams(model, context, options, deploymentName, grammarToolInputPr
255
188
  };
256
189
  }
257
190
  }
258
- // Last so custom keys override the named request fields. Per-request keys override model defaults.
259
- Object.assign(params, model.samplingParams, options?.samplingParams);
191
+ // Last so model and request sampling parameters override named request fields.
192
+ const samplingParams = resolveSamplingParams(model, reasoningEffort ?? "off", options?.samplingParams);
193
+ if (samplingParams) {
194
+ Object.assign(params, samplingParams);
195
+ }
260
196
  return params;
261
197
  }
262
198
  //# sourceMappingURL=azure-openai-responses.js.map
@@ -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 {\n\tApi,\n\tAssistantMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tTranscriptContext,\n} from \"../types.ts\";\nimport { getDrahtUserAgent } from \"../utils/draht-user-agent.ts\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { headersToRecord } from \"../utils/headers.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\nimport { retryProviderRequest } from \"../utils/provider-retry.ts\";\nimport { getDeclaredTools, resolveTranscript, resolveTranscriptTools } from \"../utils/transcript.ts\";\nimport { createGrammarToolInputProperties } from \"./constrained-sampling.ts\";\nimport { clampOpenAIPromptCacheKey } from \"./openai-prompt-cache.ts\";\nimport { convertResponsesMessages, convertResponsesTools, processResponsesStream } from \"./openai-responses-shared.ts\";\nimport { buildBaseOptions } from \"./simple-options.ts\";\n\nconst DEFAULT_AZURE_API_VERSION = \"v1\";\nconst AZURE_TOOL_CALL_PROVIDERS = new Set([\"openai\", \"openai-codex\", \"opencode\", \"azure-openai-responses\"]);\n// OpenAI Responses rejects max_output_tokens below 16: https://github.com/badlogic/pi-mono/issues/6265\nconst OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;\n\nfunction parseDeploymentNameMap(value: string | undefined): Map<string, string> {\n\tconst map = new Map<string, string>();\n\tif (!value) return map;\n\tfor (const entry of value.split(\",\")) {\n\t\tconst trimmed = entry.trim();\n\t\tif (!trimmed) continue;\n\t\tconst [modelId, deploymentName] = trimmed.split(\"=\", 2);\n\t\tif (!modelId || !deploymentName) continue;\n\t\tmap.set(modelId.trim(), deploymentName.trim());\n\t}\n\treturn map;\n}\n\nfunction resolveDeploymentName(model: Model<\"azure-openai-responses\">, options?: AzureOpenAIResponsesOptions): string {\n\tif (options?.azureDeploymentName) {\n\t\treturn options.azureDeploymentName;\n\t}\n\tconst mappedDeployment = parseDeploymentNameMap(\n\t\tgetProviderEnvValue(\"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\", options?.env),\n\t).get(model.id);\n\treturn mappedDeployment || model.id;\n}\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 StreamOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\ttoolChoice?: ResponseCreateParamsStreaming[\"tool_choice\"];\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n\tazureApiVersion?: string;\n\tazureResourceName?: string;\n\tazureBaseUrl?: string;\n\tazureDeploymentName?: string;\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 normalizeAzureBaseUrl(baseUrl: string): string {\n\tconst trimmed = baseUrl.trim().replace(/\\/+$/, \"\");\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(trimmed);\n\t} catch {\n\t\tthrow new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`);\n\t}\n\n\tconst isAzureHost =\n\t\turl.hostname.endsWith(\".openai.azure.com\") ||\n\t\turl.hostname.endsWith(\".cognitiveservices.azure.com\") ||\n\t\turl.hostname.endsWith(\".ai.azure.com\");\n\tconst normalizedPath = url.pathname.replace(/\\/+$/, \"\");\n\n\t// Ensure Azure hosts have /openai/v1 as base path so the AzureOpenAI SDK\n\t// can append /deployments/<model>/... and ?api-version=v1 correctly.\n\tif (\n\t\tisAzureHost &&\n\t\t(normalizedPath === \"\" ||\n\t\t\tnormalizedPath === \"/\" ||\n\t\t\tnormalizedPath === \"/openai\" ||\n\t\t\tnormalizedPath === \"/openai/v1/responses\")\n\t) {\n\t\turl.pathname = \"/openai/v1\";\n\t\turl.search = \"\";\n\t}\n\n\treturn url.toString().replace(/\\/+$/, \"\");\n}\n\nfunction buildDefaultBaseUrl(resourceName: string): string {\n\treturn `https://${resourceName}.openai.azure.com/openai/v1`;\n}\n\nfunction resolveAzureConfig(\n\tmodel: Model<\"azure-openai-responses\">,\n\toptions?: AzureOpenAIResponsesOptions,\n): { baseUrl: string; apiVersion: string } {\n\tconst apiVersion =\n\t\toptions?.azureApiVersion ||\n\t\tgetProviderEnvValue(\"AZURE_OPENAI_API_VERSION\", options?.env) ||\n\t\tDEFAULT_AZURE_API_VERSION;\n\n\tconst baseUrl =\n\t\toptions?.azureBaseUrl?.trim() || getProviderEnvValue(\"AZURE_OPENAI_BASE_URL\", options?.env)?.trim() || undefined;\n\tconst resourceName = options?.azureResourceName || getProviderEnvValue(\"AZURE_OPENAI_RESOURCE_NAME\", options?.env);\n\n\tlet resolvedBaseUrl = baseUrl;\n\n\tif (!resolvedBaseUrl && resourceName) {\n\t\tresolvedBaseUrl = buildDefaultBaseUrl(resourceName);\n\t}\n\n\tif (!resolvedBaseUrl && model.baseUrl) {\n\t\tresolvedBaseUrl = model.baseUrl;\n\t}\n\n\tif (!resolvedBaseUrl) {\n\t\tthrow new Error(\n\t\t\t\"Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.\",\n\t\t);\n\t}\n\n\treturn {\n\t\tbaseUrl: normalizeAzureBaseUrl(resolvedBaseUrl),\n\t\tapiVersion,\n\t};\n}\n\nfunction createClient(model: Model<\"azure-openai-responses\">, apiKey: string, options?: AzureOpenAIResponsesOptions) {\n\tconst headers = { \"User-Agent\": getDrahtUserAgent(), ...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(context.messages, supportsAdditionalTools || supportsToolSearch);\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\tif (model.reasoning) {\n\t\tif (options?.reasoningEffort || options?.reasoningSummary) {\n\t\t\tconst effort = options?.reasoningEffort\n\t\t\t\t? (model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort)\n\t\t\t\t: \"medium\";\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 custom keys override the named request fields. Per-request keys override model defaults.\n\tObject.assign(params, model.samplingParams, options?.samplingParams);\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/badlogic/pi-mono/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 +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;AA0BrB,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;AAcD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,yBAAyB,EAAE,cAAc,CA4O5E,CAAC;AAwKF,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":"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"}
@@ -7,7 +7,8 @@ import { appendAssistantMessageDiagnostic } from "../utils/diagnostics.js";
7
7
  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
- import { parseStreamingJson } from "../utils/json-parse.js";
10
+ import { getClientVersion } from "../utils/identity.js";
11
+ import { parseStreamingJson, parseToolCallArguments } from "../utils/json-parse.js";
11
12
  import { resolveHttpProxyUrlForTarget } from "../utils/node-http-proxy.js";
12
13
  import { getProviderEnvValue } from "../utils/provider-env.js";
13
14
  import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
@@ -15,8 +16,9 @@ import { getSystemMessageText } from "../utils/text.js";
15
16
  import { collapseSystemMessages, getCurrentTools, getInitialSystemMessage, withoutInitialSystemMessage, } from "../utils/transcript.js";
16
17
  import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
17
18
  import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext, clampReasoning, } from "./simple-options.js";
18
- import { transformMessages } from "./transform-messages.js";
19
+ import { splitErrorToolResultImages, transformMessages } from "./transform-messages.js";
19
20
  const EMPTY_TEXT_PLACEHOLDER = "<empty>";
21
+ const THINKING_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
20
22
  /** Matches the placeholder the Anthropic API path uses for redacted thinking. */
21
23
  const REDACTED_THINKING_PLACEHOLDER = "[Reasoning redacted]";
22
24
  export const stream = (model, context, options = {}) => {
@@ -50,6 +52,7 @@ export const stream = (model, context, options = {}) => {
50
52
  const optionsProfile = options.profile || options.env?.AWS_PROFILE;
51
53
  const config = {
52
54
  profile: optionsProfile || getProviderEnvValue("AWS_PROFILE", options.env),
55
+ customUserAgent: bedrockUserAgent(options.identity),
53
56
  };
54
57
  const configuredRegion = getConfiguredBedrockRegion(options);
55
58
  const hasAmbientConfiguredProfile = Boolean(getProviderEnvValue("AWS_PROFILE"));
@@ -336,6 +339,16 @@ function isReservedHeader(key) {
336
339
  const lower = key.toLowerCase();
337
340
  return lower.startsWith("x-amz-") || RESERVED_HEADER_EXACT.has(lower);
338
341
  }
342
+ /**
343
+ * The client identity as AWS SDK user agent pairs. The SDK appends them to its own `User-Agent` and escapes characters
344
+ * that are not valid in a user agent token, so the detailed form is reduced to name and version.
345
+ */
346
+ function bedrockUserAgent(identity) {
347
+ const mode = identity?.userAgent ?? "detailed";
348
+ if (typeof mode === "object")
349
+ return mode.custom;
350
+ return mode === "short" ? [["draht"]] : [["draht", getClientVersion(identity)]];
351
+ }
339
352
  /**
340
353
  * Attach caller-supplied headers to the outgoing Bedrock request via a Smithy
341
354
  * `build`-step middleware. The `build` step runs after request serialisation but
@@ -557,7 +570,7 @@ function handleContentBlockStop(event, blocks, output, stream) {
557
570
  stream.push({ type: "thinking_end", contentIndex: index, content: block.thinking, partial: output });
558
571
  break;
559
572
  case "toolCall":
560
- block.arguments = parseStreamingJson(block.partialJson);
573
+ Object.assign(block, parseToolCallArguments(block.partialJson));
561
574
  // Finalize in-place and strip the scratch buffer so replay only
562
575
  // carries parsed arguments.
563
576
  delete block.partialJson;
@@ -585,6 +598,7 @@ function supportsAdaptiveThinking(modelId, modelName) {
585
598
  s.includes("opus-5") ||
586
599
  s.includes("sonnet-4-6") ||
587
600
  s.includes("sonnet-5") ||
601
+ s.includes("haiku-5") ||
588
602
  s.includes("fable-5"));
589
603
  }
590
604
  function supportsNativeXhighEffort(model) {
@@ -593,6 +607,20 @@ function supportsNativeXhighEffort(model) {
593
607
  s.includes("opus-4-8") ||
594
608
  s.includes("opus-5") ||
595
609
  s.includes("sonnet-5") ||
610
+ s.includes("haiku-5") ||
611
+ s.includes("fable-5"));
612
+ }
613
+ /**
614
+ * Check if the model accepts `thinking.block_binding`. Opus 4.6 and Sonnet 4.6 reject it with
615
+ * "thinking.adaptive.block_binding: Extra inputs are not permitted".
616
+ */
617
+ function supportsThinkingBlockBinding(model) {
618
+ const candidates = getModelMatchCandidates(model.id, model.name);
619
+ return candidates.some((s) => s.includes("opus-4-7") ||
620
+ s.includes("opus-4-8") ||
621
+ s.includes("opus-5") ||
622
+ s.includes("sonnet-5") ||
623
+ s.includes("haiku-5") ||
596
624
  s.includes("fable-5"));
597
625
  }
598
626
  function mapThinkingLevelToEffort(model, level) {
@@ -662,8 +690,8 @@ function supportsPromptCaching(model, env) {
662
690
  return true;
663
691
  return false;
664
692
  }
665
- // Claude 5 models (fable-5, opus-5, sonnet-5)
666
- if (candidates.some((s) => s.includes("fable-5") || s.includes("opus-5") || s.includes("sonnet-5")))
693
+ // Claude 5 models (fable-5, opus-5, sonnet-5, haiku-5)
694
+ if (candidates.some((s) => s.includes("fable-5") || s.includes("opus-5") || s.includes("sonnet-5") || s.includes("haiku-5")))
667
695
  return true;
668
696
  // Claude 4.x models (opus-4, sonnet-4, haiku-4)
669
697
  if (candidates.some((s) => s.includes("-4-")))
@@ -854,30 +882,28 @@ function convertMessages(context, model, cacheRetention, env) {
854
882
  // Collect all consecutive toolResult messages into a single user message
855
883
  // Bedrock requires all tool results to be in one message
856
884
  const toolResults = [];
857
- // Add current tool result with all content blocks combined
858
- toolResults.push({
859
- toolResult: {
860
- toolUseId: m.toolCallId,
861
- content: convertToolResultContent(m.content),
862
- status: m.isError ? ToolResultStatus.ERROR : ToolResultStatus.SUCCESS,
863
- },
864
- });
865
- // Look ahead for consecutive toolResult messages
866
- let j = i + 1;
885
+ // Claude rejects error tool results that contain anything but text, so for Claude their
886
+ // images follow all tool results of the turn (#10794). Other models keep them in place.
887
+ const errorImages = [];
888
+ let j = i;
867
889
  while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
868
- const nextMsg = transformedMessages[j];
890
+ const toolMsg = transformedMessages[j];
891
+ const split = isAnthropicClaudeModel(model) ? splitErrorToolResultImages(toolMsg) : undefined;
869
892
  toolResults.push({
870
893
  toolResult: {
871
- toolUseId: nextMsg.toolCallId,
872
- content: convertToolResultContent(nextMsg.content),
873
- status: nextMsg.isError ? ToolResultStatus.ERROR : ToolResultStatus.SUCCESS,
894
+ toolUseId: toolMsg.toolCallId,
895
+ content: convertToolResultContent(split?.content ?? toolMsg.content),
896
+ status: toolMsg.isError ? ToolResultStatus.ERROR : ToolResultStatus.SUCCESS,
874
897
  },
875
898
  });
899
+ if (split) {
900
+ errorImages.push({ text: split.caption }, ...split.images.map((image) => ({ image: createImageBlock(image.mimeType, image.data) })));
901
+ }
876
902
  j++;
877
903
  }
878
904
  // Skip the messages we've already processed
879
905
  i = j - 1;
880
- result.push({ role: ConversationRole.USER, content: toolResults });
906
+ result.push({ role: ConversationRole.USER, content: [...toolResults, ...errorImages] });
881
907
  break;
882
908
  }
883
909
  default:
@@ -999,11 +1025,21 @@ function buildAdditionalModelRequestFields(model, options) {
999
1025
  if (isAnthropicClaudeModel(model)) {
1000
1026
  // GovCloud Bedrock currently rejects the Claude thinking.display field.
1001
1027
  // Omit it there until the GovCloud Converse schema catches up.
1002
- const display = isGovCloudBedrockTarget(model, options) ? undefined : (options.thinkingDisplay ?? "summarized");
1028
+ const isGovCloud = isGovCloudBedrockTarget(model, options);
1029
+ const display = isGovCloud ? undefined : (options.thinkingDisplay ?? "summarized");
1030
+ // Replayed signed thinking blocks are bound to the system prompt and tools they were
1031
+ // created with. Bedrock 400s on replay after either changes unless stale blocks are
1032
+ // dropped, matching the Anthropic provider. Skipped on GovCloud like display.
1033
+ const useBlockBinding = !isGovCloud && supportsThinkingBlockBinding(model);
1003
1034
  const result = supportsAdaptiveThinking(model.id, model.name)
1004
1035
  ? {
1005
- thinking: { type: "adaptive", ...(display !== undefined ? { display } : {}) },
1036
+ thinking: {
1037
+ type: "adaptive",
1038
+ ...(display !== undefined ? { display } : {}),
1039
+ ...(useBlockBinding ? { block_binding: { prefix_mismatch_behavior: "drop_block" } } : {}),
1040
+ },
1006
1041
  output_config: { effort: mapThinkingLevelToEffort(model, options.reasoning) },
1042
+ ...(useBlockBinding ? { anthropic_beta: [THINKING_BINDING_CONTROLS_BETA] } : {}),
1007
1043
  }
1008
1044
  : (() => {
1009
1045
  const defaultBudgets = {
@@ -1030,8 +1066,36 @@ function buildAdditionalModelRequestFields(model, options) {
1030
1066
  }
1031
1067
  return result;
1032
1068
  }
1069
+ const candidates = getModelMatchCandidates(model.id, model.name);
1070
+ if (candidates.some((s) => s.includes("gpt-oss"))) {
1071
+ return { reasoning_effort: OPENAI_GPT_OSS_EFFORT[options.reasoning] };
1072
+ }
1073
+ if (candidates.some((s) => s.includes("gpt-"))) {
1074
+ const mapped = model.thinkingLevelMap?.[options.reasoning];
1075
+ return {
1076
+ reasoning: { effort: typeof mapped === "string" ? mapped : OPENAI_GPT_EFFORT[options.reasoning] },
1077
+ };
1078
+ }
1033
1079
  return undefined;
1034
1080
  }
1081
+ /** OpenAI GPT models (GPT-5.x, GPT-6) take a nested `reasoning.effort` and reject `minimal`. */
1082
+ const OPENAI_GPT_EFFORT = {
1083
+ minimal: "low",
1084
+ low: "low",
1085
+ medium: "medium",
1086
+ high: "high",
1087
+ xhigh: "xhigh",
1088
+ max: "max",
1089
+ };
1090
+ /** gpt-oss takes a flat `reasoning_effort` and only accepts low, medium and high. */
1091
+ const OPENAI_GPT_OSS_EFFORT = {
1092
+ minimal: "low",
1093
+ low: "low",
1094
+ medium: "medium",
1095
+ high: "high",
1096
+ xhigh: "high",
1097
+ max: "high",
1098
+ };
1035
1099
  function createImageBlock(mimeType, data) {
1036
1100
  let format;
1037
1101
  switch (mimeType) {