@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
@@ -1,11 +1,11 @@
1
1
  import OpenAI from "openai";
2
2
  import { calculateCost, 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 { shortHash } from "../utils/hash.js";
7
6
  import { headersToRecord } from "../utils/headers.js";
8
- import { parseStreamingJson } from "../utils/json-parse.js";
7
+ import { getIdentityHeaders } from "../utils/identity.js";
8
+ import { parseStreamingJson, parseToolCallArguments } from "../utils/json-parse.js";
9
9
  import { getProviderEnvValue } from "../utils/provider-env.js";
10
10
  import { retryProviderRequest } from "../utils/provider-retry.js";
11
11
  import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
@@ -14,7 +14,7 @@ import { getDeclaredTools, resolveTranscript, resolveTranscriptTools, } from "..
14
14
  import { appendGrammarToolInputJsonDelta, createGrammarToolInputProperties, getGrammarToolInput, getJsonSchemaToolParameters, resolveGrammarConstrainedSampling, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
15
15
  import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
16
16
  import { clampOpenAIPromptCacheKey } from "./openai-prompt-cache.js";
17
- import { buildBaseOptions, clampThinkingBudgetToAnswerRoom, thinkingBudgetForLevel } from "./simple-options.js";
17
+ import { buildBaseOptions, clampThinkingBudgetToAnswerRoom, resolveSamplingParams, thinkingBudgetForLevel, } from "./simple-options.js";
18
18
  import { transformMessages } from "./transform-messages.js";
19
19
  /**
20
20
  * Check if conversation messages contain tool calls or tool results.
@@ -183,7 +183,7 @@ export const stream = (model, context, options) => {
183
183
  const grammarToolInputProperties = createGrammarToolInputProperties(getDeclaredTools(normalizedContext.messages), compat.supportsOpenAIGrammarTools);
184
184
  const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
185
185
  const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
186
- const client = createClient(model, normalizedContext, apiKey, options?.headers, options?.fetch, cacheSessionId, compat);
186
+ const client = createClient(model, normalizedContext, apiKey, options?.headers, options?.identity, options?.fetch, cacheSessionId, compat);
187
187
  let params = buildParams(model, normalizedContext, options, compat, cacheRetention, grammarToolInputProperties);
188
188
  const nextParams = await options?.onPayload?.(params, model);
189
189
  if (nextParams !== undefined) {
@@ -258,7 +258,7 @@ export const stream = (model, context, options) => {
258
258
  }
259
259
  }
260
260
  else {
261
- block.arguments = parseStreamingJson(block.partialArgs);
261
+ Object.assign(block, parseToolCallArguments(block.partialArgs));
262
262
  }
263
263
  // Finalize in-place and strip the scratch buffers so replay only
264
264
  // carries parsed arguments.
@@ -381,18 +381,8 @@ export const stream = (model, context, options) => {
381
381
  hasFinishReason = true;
382
382
  }
383
383
  if (choice.delta) {
384
- if (choice.delta.content !== null &&
385
- choice.delta.content !== undefined &&
386
- choice.delta.content.length > 0) {
387
- const block = ensureTextBlock();
388
- block.text += choice.delta.content;
389
- stream.push({
390
- type: "text_delta",
391
- contentIndex: getContentIndex(block),
392
- delta: choice.delta.content,
393
- partial: output,
394
- });
395
- }
384
+ // Handle reasoning before content: some proxies (e.g. LiteLLM) aggregate reasoning and
385
+ // answer into one delta, and the thinking block must precede the text block.
396
386
  // Some endpoints return reasoning in reasoning_content (llama.cpp),
397
387
  // or reasoning (other openai compatible endpoints)
398
388
  // Use the first non-empty reasoning field to avoid duplication
@@ -423,6 +413,31 @@ export const stream = (model, context, options) => {
423
413
  });
424
414
  }
425
415
  }
416
+ const reasoningDetails = choice.delta.reasoning_details;
417
+ if (Array.isArray(reasoningDetails)) {
418
+ for (const detail of reasoningDetails) {
419
+ if (!isOpenAIReasoningDetail(detail))
420
+ continue;
421
+ ensureThinkingBlock("");
422
+ streamedReasoningDetails ??= [];
423
+ // Keep provider replay data in the existing signature slot. OpenRouter streams
424
+ // reasoning_details as deltas: consecutive text/summary deltas are merged into
425
+ // logical entries, while encrypted entries remain opaque and discrete.
426
+ appendOpenAIReasoningDetail(streamedReasoningDetails, detail);
427
+ }
428
+ }
429
+ if (choice.delta.content !== null &&
430
+ choice.delta.content !== undefined &&
431
+ choice.delta.content.length > 0) {
432
+ const block = ensureTextBlock();
433
+ block.text += choice.delta.content;
434
+ stream.push({
435
+ type: "text_delta",
436
+ contentIndex: getContentIndex(block),
437
+ delta: choice.delta.content,
438
+ partial: output,
439
+ });
440
+ }
426
441
  if (choice?.delta?.tool_calls) {
427
442
  for (const toolCall of choice.delta.tool_calls) {
428
443
  const block = ensureToolCallBlock(toolCall);
@@ -452,19 +467,6 @@ export const stream = (model, context, options) => {
452
467
  });
453
468
  }
454
469
  }
455
- const reasoningDetails = choice.delta.reasoning_details;
456
- if (Array.isArray(reasoningDetails)) {
457
- for (const detail of reasoningDetails) {
458
- if (!isOpenAIReasoningDetail(detail))
459
- continue;
460
- ensureThinkingBlock("");
461
- streamedReasoningDetails ??= [];
462
- // Keep provider replay data in the existing signature slot. OpenRouter streams
463
- // reasoning_details as deltas: consecutive text/summary deltas are merged into
464
- // logical entries, while encrypted entries remain opaque and discrete.
465
- appendOpenAIReasoningDetail(streamedReasoningDetails, detail);
466
- }
467
- }
468
470
  }
469
471
  }
470
472
  for (const block of blocks) {
@@ -529,8 +531,8 @@ export const streamSimple = (model, context, options) => {
529
531
  thinkingBudgets: options?.thinkingBudgets,
530
532
  });
531
533
  };
532
- function createClient(model, context, apiKey, optionsHeaders, fetch, sessionId, compat = getCompat(model)) {
533
- const headers = { "User-Agent": getDrahtUserAgent(), ...model.headers };
534
+ function createClient(model, context, apiKey, optionsHeaders, identity, fetch, sessionId, compat = getCompat(model)) {
535
+ const headers = { ...getIdentityHeaders(model, identity), ...model.headers };
534
536
  if (model.provider === "github-copilot") {
535
537
  const hasImages = hasCopilotVisionInput(context.messages);
536
538
  const copilotHeaders = buildCopilotDynamicHeaders({
@@ -564,7 +566,9 @@ function createClient(model, context, apiKey, optionsHeaders, fetch, sessionId,
564
566
  });
565
567
  }
566
568
  function buildParams(model, context, options, compat = getCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env), grammarToolInputProperties = createGrammarToolInputProperties(getDeclaredTools(context.messages), compat.supportsOpenAIGrammarTools)) {
567
- const transcriptTools = resolveTranscriptTools(context.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true);
569
+ const transcriptTools = resolveTranscriptTools(context.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true
570
+ ? "additions"
571
+ : "none");
568
572
  const messages = convertMessages(model, context, compat, {
569
573
  grammarToolInputProperties,
570
574
  });
@@ -744,8 +748,11 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
744
748
  params.providerOptions = { gateway: gatewayOptions };
745
749
  }
746
750
  }
747
- // Last so custom keys override the named request fields. Per-request keys override model defaults.
748
- Object.assign(params, model.samplingParams, options?.samplingParams);
751
+ // Last so model and request sampling parameters override named request fields.
752
+ const samplingParams = resolveSamplingParams(model, options?.reasoningEffort ?? "off", options?.samplingParams);
753
+ if (samplingParams) {
754
+ Object.assign(params, samplingParams);
755
+ }
749
756
  return params;
750
757
  }
751
758
  function resolveThinkingTokenBudgetField(compat) {
@@ -892,9 +899,12 @@ export function convertMessages(model, context, compat, options) {
892
899
  return id;
893
900
  };
894
901
  const transformedMessages = transformMessages(normalizedContext.messages, model, (id) => normalizeToolCallId(id));
895
- const transcriptTools = resolveTranscriptTools(normalizedContext.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true);
902
+ const transcriptTools = resolveTranscriptTools(normalizedContext.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true
903
+ ? "additions"
904
+ : "none");
896
905
  const instructionRole = model.reasoning && compat.supportsDeveloperRole ? "developer" : "system";
897
906
  let lastRole = null;
907
+ let systemIndex = 0;
898
908
  for (let i = 0; i < transformedMessages.length; i++) {
899
909
  const msg = transformedMessages[i];
900
910
  // Some providers don't allow user messages directly after tool results
@@ -906,7 +916,8 @@ export function convertMessages(model, context, compat, options) {
906
916
  });
907
917
  }
908
918
  if (msg.role === "system") {
909
- const addedTools = i > 0 && transcriptTools.anchorsAdditions ? (msg.toolsAdded ?? []) : [];
919
+ // transformMessages keeps system messages in order, so their position matches the transcript.
920
+ const addedTools = systemIndex++ >= transcriptTools.foldedSystemMessages ? (msg.toolsAdded ?? []) : [];
910
921
  if (addedTools.length > 0) {
911
922
  const kimiToolMessage = {
912
923
  role: "system",
@@ -1071,7 +1082,7 @@ export function convertMessages(model, context, compat, options) {
1071
1082
  .join("\n");
1072
1083
  const hasImages = toolMsg.content.some((c) => c.type === "image");
1073
1084
  // Always send tool result with text (or placeholder if only images)
1074
- const hasText = textResult.length > 0;
1085
+ const hasText = textResult.trim().length > 0;
1075
1086
  const toolResultText = hasText ? textResult : hasImages ? "(see attached image)" : "(no tool output)";
1076
1087
  // Some providers require the 'name' field in tool results
1077
1088
  const toolResultMsg = {