@xiaoso/dsh-tool-plus 0.1.6 → 0.1.7-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/THIRD_PARTY_NOTICES.md +9 -3
  2. package/lib/{abort-Cwwm4Err.mjs → abort-Caqff3M6.mjs} +2 -2
  3. package/lib/alibaba-coding-plan-DTupMiAi.mjs +73 -0
  4. package/lib/alibaba-token-plan-CHGyWOfX.mjs +46 -0
  5. package/lib/alibaba-token-plan-Dj3OZhEE.mjs +82 -0
  6. package/lib/{amazon-bedrock-TVMpUTRG.mjs → amazon-bedrock-DbFSYXfJ.mjs} +117 -38
  7. package/lib/{anthropic-BL6LFDQS.mjs → anthropic-CTJ3IQVa.mjs} +675 -166
  8. package/lib/anthropic-CXfWlp-x.mjs +105 -0
  9. package/lib/{aws-credentials-B20dliS7.mjs → anthropic-wire-CKuhDwZ1.mjs} +74 -14
  10. package/lib/{api-key-login-CIDnXeYd.mjs → api-key-validation-CGCJFbFr.mjs} +27 -68
  11. package/lib/{azure-openai-responses-BkhsLmN3.mjs → azure-openai-responses-ChFbWaGj.mjs} +27 -16
  12. package/lib/{browser-render-CmgvSNte.mjs → browser-render-9o0Rknop.mjs} +4 -4
  13. package/lib/bun-shim.mjs +71 -2
  14. package/lib/{bundled-references-ChZSPDFw.mjs → bundled-references-DY3EJxZV.mjs} +6 -5
  15. package/lib/cline-pass-Bwg3esu9.mjs +44 -0
  16. package/lib/cloudflare-ai-gateway-BupNXyKK.mjs +35 -0
  17. package/lib/cloudflare-ai-gateway-EWo0VkP5.mjs +44 -0
  18. package/lib/collapse-DOR8sOGf.mjs +2304 -0
  19. package/lib/coreweave-C82HrLpb.mjs +31 -0
  20. package/lib/coreweave-Ct8cF-da.mjs +14 -0
  21. package/lib/{cursor-B6HcmplF.mjs → cursor-B95LzVWV.mjs} +11 -3
  22. package/lib/{cursor-CRpLpaZ3.mjs → cursor-DJV_dcgB.mjs} +887 -1784
  23. package/lib/{cursor-B8m6SqAH.mjs → cursor-LKGjucn2.mjs} +48 -38
  24. package/lib/cursor-proto-B8Wj8bv9.mjs +10513 -0
  25. package/lib/{deterministic-id-D-yIV_eI.mjs → deterministic-id-CUEIMSqR.mjs} +1 -1
  26. package/lib/devin-BMTdx_hx.mjs +316 -0
  27. package/lib/{devin-DUAfvBsW.mjs → devin-DSp0Rw_E.mjs} +172 -86
  28. package/lib/devin-ExGIghmx.mjs +69 -0
  29. package/lib/devin-proto-Br8fdyNl.mjs +2888 -0
  30. package/lib/{dom-CawWi8fa.mjs → dom-DG3sPESc.mjs} +8 -8
  31. package/lib/effort-BdtQMN-_.mjs +23 -0
  32. package/lib/{error-C-f_Wnw4.mjs → error-CORgGg5a.mjs} +275 -154
  33. package/lib/{event-stream-Dh2guZxS.mjs → event-stream-ulcDenZD.mjs} +20 -4
  34. package/lib/{gemini-headers-DKUShltF.mjs → gemini-headers-Co9cVvex.mjs} +2 -2
  35. package/lib/{github-copilot-suDymKrx.mjs → github-copilot-Dstq1D3s.mjs} +69 -29
  36. package/lib/github-copilot-headers-DOh1gt_w.mjs +312 -0
  37. package/lib/gitlab-duo-DSCMrU0m.mjs +11 -0
  38. package/lib/google-CtsKkOQK.mjs +38 -0
  39. package/lib/google-antigravity-z-5KsEci.mjs +252 -0
  40. package/lib/{google-auth-DYJLM792.mjs → google-auth-ieLBaneO.mjs} +4 -4
  41. package/lib/{google-gemini-cli-8BT513Ul.mjs → google-gemini-cli-C6NE5mWz.mjs} +28 -54
  42. package/lib/{google-gemini-cli-D6cSmfvB.mjs → google-gemini-cli-CAIPSl7e.mjs} +23 -29
  43. package/lib/google-oauth-shared-DhMllAkt.mjs +53 -0
  44. package/lib/{google-shared-CVbHK5vZ.mjs → google-shared-B0aNCYEH.mjs} +140 -44
  45. package/lib/{google-validation-Cgbn3tWJ.mjs → google-validation-BEkNs-Bx.mjs} +1 -1
  46. package/lib/{google-vertex-Bui-ypAe.mjs → google-vertex-Bbd1tYNc.mjs} +8 -8
  47. package/lib/hosts-00rjRzUD.mjs +203 -0
  48. package/lib/id-AL5obQzR.mjs +71 -0
  49. package/lib/{idle-iterator-CYAxUkSD.mjs → idle-iterator-DlUkEfzW.mjs} +3 -3
  50. package/lib/index.mjs +587 -5266
  51. package/lib/kilo-ChJL54wq.mjs +81 -0
  52. package/lib/kimi-C2c_Zq8A.mjs +67 -0
  53. package/lib/{launch-BmgEUycu.mjs → launch-DKDH71En.mjs} +1 -1
  54. package/lib/markit-CmRfm4E2.mjs +9885 -0
  55. package/lib/models-DnXMYGcJ.mjs +381604 -0
  56. package/lib/muse-code-Di1VZmB1.mjs +143 -0
  57. package/lib/{ollama-Df9ce-Cp.mjs → ollama-B8ic3sEp.mjs} +15 -30
  58. package/lib/{openai-codex-CAVI3Me-.mjs → openai-codex-DuJNC99x.mjs} +29 -99
  59. package/lib/{openai-codex-responses-BcnOotRB.mjs → openai-codex-responses-BL29nh9K.mjs} +204 -116
  60. package/lib/{openai-completions-Bq4WT47M.mjs → openai-completions-BK2f2dBv.mjs} +152 -82
  61. package/lib/openai-configuration-update-xMYUjaK_.mjs +150 -0
  62. package/lib/{openai-reasoning-fallback-DXsfiSXO.mjs → openai-reasoning-fallback-BdB3RCbj.mjs} +106 -12
  63. package/lib/{openai-responses-Mq_-PjvE.mjs → openai-responses-CGQPlIIy.mjs} +76 -82
  64. package/lib/{perplexity-XgLF73E7.mjs → perplexity-TBjz3VMB.mjs} +52 -9
  65. package/lib/{pkce-BlQikGPu.mjs → pkce-BYjmugmw.mjs} +1 -1
  66. package/lib/protobuf-aab1UGVn.mjs +717 -0
  67. package/lib/{provider-response-C6vcbQyO.mjs → provider-response-SqKSkkUc.mjs} +1 -1
  68. package/lib/{proxy-D9lm7ONA.mjs → proxy-5nWqRL1f.mjs} +45 -5
  69. package/lib/{readability-Cpm-ocau.mjs → readability-uGhqb4GC.mjs} +2 -2
  70. package/lib/reference-CtvM4zLU.mjs +114 -0
  71. package/lib/{request-debug-HJMoJncL.mjs → request-debug-NQN0BjHH.mjs} +1 -1
  72. package/lib/{sanitize-text-CfcXzw5X.mjs → sanitize-text-BCf5KmCf.mjs} +1 -1
  73. package/lib/{scrapers-Cg5w77td.mjs → scrapers-D8oWspgW.mjs} +12 -12
  74. package/lib/{src-BcD0_rQR.mjs → src-BwW51vA5.mjs} +979 -388
  75. package/lib/{sse-debug-CYdjOC96.mjs → sse-debug-B-tkLCPW.mjs} +1 -1
  76. package/lib/{stream-Bjq8wjfr.mjs → stream-B_7qN-bA.mjs} +3802 -2623
  77. package/lib/stream-markup-healing-DKT1lnkW.mjs +267 -0
  78. package/lib/{strict-tool-validation-imVLUcbI.mjs → strict-tool-validation-CBTz1dAA.mjs} +2 -2
  79. package/lib/taxonomy-DSIM99rS.mjs +15392 -0
  80. package/lib/{stream-markup-healing-DZ6bVDxH.mjs → thinking-CiLa2LFB.mjs} +31 -186
  81. package/lib/{turndown-DN7ByzEI.mjs → turndown-DrX1M4WG.mjs} +4 -4
  82. package/lib/{type-guards-B9VVjRDK.mjs → type-guards-CttAANEx.mjs} +1 -1
  83. package/lib/{types-DX_bvuus.mjs → types-PVueGi9S.mjs} +2 -2
  84. package/lib/{utils-C-dSORPa.mjs → utils-CCfhUQen.mjs} +2364 -2676
  85. package/lib/{utils-Cp2Mxf_U.mjs → utils-CUPhpw9A.mjs} +413 -134
  86. package/lib/{utils-CQHPEQ3W.mjs → utils-DeWqNWV8.mjs} +2 -2
  87. package/lib/{vision-guard-mBmtAHx0.mjs → vision-guard-_XwsL1DF.mjs} +14 -29
  88. package/lib/xai-oauth-CXhnz0gO.mjs +210 -0
  89. package/lib/{xiaomi-7mE345KX.mjs → xiaomi-psoUItal.mjs} +8 -37
  90. package/lib/{zai-CeNpMV3W.mjs → zai-ApJ8HBgT.mjs} +8 -71
  91. package/lib/{zip-BK7UHCwX.mjs → zip-Kd602XNe.mjs} +1 -1
  92. package/package.json +11 -11
  93. package/presets/package.json +1 -1
  94. package/presets/tool-plus-ptc/agent.cordis.yml +1 -1
  95. package/presets/tool-plus-standard/agent.cordis.yml +1 -1
  96. package/lib/agent_pb-Rizyt9Zg.mjs +0 -805
  97. package/lib/anthropic-CDmj476p.mjs +0 -262
  98. package/lib/api_server_pb-CDZgLMta.mjs +0 -252
  99. package/lib/callback-server-CFJK-jvK.mjs +0 -398
  100. package/lib/codex-P1dGpX7G.mjs +0 -54
  101. package/lib/device-code-CuXTWYwY.mjs +0 -51
  102. package/lib/devin-BcQwht1W.mjs +0 -114
  103. package/lib/devin-BvMfGevz.mjs +0 -95
  104. package/lib/github-copilot-B3kQl0g0.mjs +0 -104
  105. package/lib/gitlab-duo-BriUTP8k.mjs +0 -155
  106. package/lib/gitlab-duo-workflow-wK5Ljzmc.mjs +0 -91
  107. package/lib/google-CE5tFDod.mjs +0 -30
  108. package/lib/google-antigravity-C1jgNljz.mjs +0 -198
  109. package/lib/google-oauth-shared-BLVTvokk.mjs +0 -147
  110. package/lib/grammar-D-NqNUxQ.mjs +0 -49
  111. package/lib/identity-HNO1Oe9B.mjs +0 -219
  112. package/lib/kimi-DgcUpPtK.mjs +0 -236
  113. package/lib/markit-DtGoRE6M.mjs +0 -1417
  114. package/lib/minimax-code-Y3h5li9N.mjs +0 -53
  115. package/lib/models-DRA2c_8U.mjs +0 -104660
  116. package/lib/opencode-BsVw9rCD.mjs +0 -38
  117. package/lib/to-binary-B1BEBIPC.mjs +0 -6002
  118. package/lib/wafer-BlhWLweO.mjs +0 -17
  119. package/lib/xai-oauth-5pORHUrg.mjs +0 -446
@@ -1,28 +1,49 @@
1
1
  import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
2
  __installBunShim();
3
3
  import { r as __exportAll } from "./fs-promises-shim-Bx0fpxuk.mjs";
4
- import { P as $env, T as warn, _ as parseStreamingJsonThrottled, g as parseStreamingJson } from "./src-BcD0_rQR.mjs";
5
- import { B as OpenAIHttpError, d as callWithCopilotModelRetry, l as finalize, n as StreamTimeoutError, s as ProviderResponseError, t as ConfigurationError, v as AbortError } from "./error-C-f_Wnw4.mjs";
6
- import { A as NO_STRICT, F as sanitizeSchemaForGrammar, O as flattenExclusiveRequiredRootUnion, P as normalizeSchemaForMoonshot, S as kStreamingLastParseLen, a as normalizeSystemPrompts, g as isDemotedThinking, j as adaptSchemaForStrict, k as toolWireSchema, m as transformMessages, s as resolveCacheRetention, w as renderDemotedThinking } from "./utils-Cp2Mxf_U.mjs";
7
- import { $ as isOpenRouterAnthropicModel, Ct as withEmptyCompletionRetry, I as disableStrictToolsForScope, J as getOpenAIStrictToolsScope, K as getOpenAIPromptCacheKey, N as createInitialResponsesAssistantMessage, O as calculateOpenAIUsageAccounting, P as createOpenAIStrictToolsState, St as hasVisibleAssistantContent, T as applyWireModelIdTransform, Z as isCompiledGrammarTooLargeStrictError, _ as applyOpenAIExtraBody, _t as isForcedToolChoice, b as applyOpenRouterReportedCost, ct as resolveOpenAICompatPolicy, dt as resolveOpenAIRequestSetup, et as isStrictToolsDisabledForScope, h as applyChatCompletionsToolStream, it as parseAzureDeploymentNameMap, k as clearOpenAIStrictToolsState, lt as resolveOpenAICompletionsOutputClamp, m as applyChatCompletionsCompatPolicy, n as getEnvApiKey, pt as shouldRetryWithoutStrictTools, ut as resolveOpenAIOutputTokenParam, v as applyOpenAIGatewayRouting, vt as mapToOpenAICompletionsToolChoice, y as applyOpenAIServiceTier } from "./stream-Bjq8wjfr.mjs";
8
- import { t as createAbortSourceTracker } from "./abort-Cwwm4Err.mjs";
9
- import { b as isKimiModelId, c as resolveWireModelId, t as calculateCost } from "./models-DRA2c_8U.mjs";
10
- import "./identity-HNO1Oe9B.mjs";
11
- import { n as isDashscopeCompatibleModeTextOnlyQwen, r as joinTextWithImagePlaceholder, t as NON_VISION_IMAGE_PLACEHOLDER } from "./vision-guard-mBmtAHx0.mjs";
12
- import { t as findStrictToolSchemaViolation } from "./strict-tool-validation-imVLUcbI.mjs";
13
- import { t as AssistantMessageEventStream } from "./event-stream-Dh2guZxS.mjs";
14
- import { n as getOpenAIStreamFirstEventTimeoutMs, o as iterateWithIdleTimeout, r as getOpenAIStreamIdleTimeoutMs, s as iterateWithTerminalGrace } from "./idle-iterator-CYAxUkSD.mjs";
15
- import { t as getKimiCommonHeaders } from "./kimi-DgcUpPtK.mjs";
16
- import { t as notifyProviderResponse } from "./provider-response-C6vcbQyO.mjs";
17
- import { t as StreamMarkupHealing } from "./stream-markup-healing-DZ6bVDxH.mjs";
18
- import { a as getOpenAIReasoningEffortFallback, c as postOpenAIStream, i as createOpenAIReasoningEffortFallbackState, n as clearOpenAIReasoningEffortFallbackState, o as rememberOpenAIReasoningEffortFallback, r as createOpenAIReasoningEffortFallbackKey, s as resolveOpenAIReasoningEffortFallback, t as applyOpenAIReasoningEffortFallback } from "./openai-reasoning-fallback-DXsfiSXO.mjs";
19
- //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/openai-completions.ts
4
+ import { C as warn, N as $env, _ as parseStreamingJson, v as parseStreamingJsonThrottled } from "./src-BwW51vA5.mjs";
5
+ import { B as OpenAIHttpError, V as ProviderHttpError, _ as AbortError, c as finalize, n as StreamTimeoutError, s as ProviderResponseError, t as ConfigurationError } from "./error-CORgGg5a.mjs";
6
+ import { A as toolWireSchema, C as kStreamingLastParseLen, F as normalizeSchemaForMoonshot, L as sanitizeSchemaForGrammar, M as adaptSchemaForStrict, T as renderDemotedThinking, _ as isDemotedThinking, c as resolveCacheRetention, h as transformMessages, j as NO_STRICT, k as flattenExclusiveRequiredRootUnion, o as normalizeSystemPrompts } from "./utils-CUPhpw9A.mjs";
7
+ import { At as withReplaySafeStreamRetry, C as applyChatCompletionsToolStream, D as applyOpenAIServiceTier, E as applyOpenAIGatewayRouting, H as createOpenAIStrictToolsState, I as calculateOpenAIUsageAccounting, L as clearOpenAIStrictToolsState, N as applyWireModelIdTransform, O as applyProviderReportedCost, S as applyChatCompletionsReasoningParams, St as shouldRetryWithoutStrictTools, T as applyOpenAIExtraBody, Tt as mapToOpenAICompletionsToolChoice, V as createInitialResponsesAssistantMessage, W as disableStrictToolsForScope, _t as resolveOpenAIOutputTokenParam, at as isCompiledGrammarTooLargeStrictError, dt as parseAzureDeploymentNameMap, et as getOpenAIPromptCacheKey, gt as resolveOpenAICompletionsOutputClamp, ht as resolveOpenAICompatPolicy, kt as hasVisibleAssistantContent, n as getEnvApiKey, nt as getOpenAIStrictToolsScope, st as isStrictToolsDisabledForScope, vt as resolveOpenAIRequestSetup, wt as isForcedToolChoice, xt as shouldDropAutoToolChoiceForReasoning } from "./stream-B_7qN-bA.mjs";
8
+ import { s as resolveWireModelId } from "./anthropic-wire-CKuhDwZ1.mjs";
9
+ import { t as createAbortSourceTracker } from "./abort-Caqff3M6.mjs";
10
+ import { t as calculateCost } from "./models-DnXMYGcJ.mjs";
11
+ import { i as resolveCopilotRequestIdentity, o as wrapFetchForCopilotFallback } from "./github-copilot-headers-DOh1gt_w.mjs";
12
+ import { n as isOpenAICompletionsVisionSupported, r as joinTextWithImagePlaceholder, t as NON_VISION_IMAGE_PLACEHOLDER } from "./vision-guard-_XwsL1DF.mjs";
13
+ import { t as findStrictToolSchemaViolation } from "./strict-tool-validation-CBTz1dAA.mjs";
14
+ import { t as AssistantMessageEventStream } from "./event-stream-ulcDenZD.mjs";
15
+ import { n as clinePassClientHeaders } from "./cline-pass-Bwg3esu9.mjs";
16
+ import { n as getOpenAIStreamFirstEventTimeoutMs, o as iterateWithIdleTimeout, r as getOpenAIStreamIdleTimeoutMs, s as iterateWithTerminalGrace } from "./idle-iterator-DlUkEfzW.mjs";
17
+ import { t as getKimiCommonHeaders } from "./kimi-C2c_Zq8A.mjs";
18
+ import { t as notifyProviderResponse } from "./provider-response-SqKSkkUc.mjs";
19
+ import { a as getOpenAIReasoningEffortFallback, c as postOpenAIStream, i as createOpenAIReasoningEffortFallbackState, n as clearOpenAIReasoningEffortFallbackState, o as rememberOpenAIReasoningEffortFallback, r as createOpenAIReasoningEffortFallbackKey, s as resolveOpenAIReasoningEffortFallback, t as applyOpenAIReasoningEffortFallback } from "./openai-reasoning-fallback-BdB3RCbj.mjs";
20
+ import { t as StreamMarkupHealing } from "./stream-markup-healing-DKT1lnkW.mjs";
21
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/providers/openai-completions.ts
20
22
  var openai_completions_exports = /* @__PURE__ */ __exportAll({
21
23
  convertMessages: () => convertMessages,
22
24
  isOpenAICompletionsProgressChunk: () => isOpenAICompletionsProgressChunk,
23
25
  parseChunkUsage: () => parseChunkUsage,
24
26
  streamOpenAICompletions: () => streamOpenAICompletions
25
27
  });
28
+ const GEMINI_THOUGHT_SIGNATURE_NAMESPACES = ["google", "vertex"];
29
+ function getGeminiThoughtSignatureExtraContent(value) {
30
+ if (typeof value !== "object" || value === null) return void 0;
31
+ for (const namespace of GEMINI_THOUGHT_SIGNATURE_NAMESPACES) {
32
+ const providerContent = Reflect.get(value, namespace);
33
+ if (typeof providerContent !== "object" || providerContent === null) continue;
34
+ const thoughtSignature = Reflect.get(providerContent, "thought_signature");
35
+ if (typeof thoughtSignature !== "string" || thoughtSignature.length === 0) continue;
36
+ return namespace === "google" ? { google: { thought_signature: thoughtSignature } } : { vertex: { thought_signature: thoughtSignature } };
37
+ }
38
+ }
39
+ function parseGeminiThoughtSignatureExtraContent(thoughtSignature) {
40
+ if (!thoughtSignature) return void 0;
41
+ try {
42
+ return getGeminiThoughtSignatureExtraContent(JSON.parse(thoughtSignature));
43
+ } catch {
44
+ return;
45
+ }
46
+ }
26
47
  function firstPositiveNumber(...values) {
27
48
  for (const value of values) if (typeof value === "number" && value > 0) return value;
28
49
  return 0;
@@ -31,6 +52,7 @@ function hasPositiveCacheReadTokenField(rawUsage) {
31
52
  const usageLike = rawUsage;
32
53
  if (typeof usageLike.cached_tokens === "number" && usageLike.cached_tokens > 0) return true;
33
54
  if (typeof usageLike.prompt_cache_hit_tokens === "number" && usageLike.prompt_cache_hit_tokens > 0) return true;
55
+ if (typeof usageLike.cachedContentTokenCount === "number" && usageLike.cachedContentTokenCount > 0) return true;
34
56
  const rawPromptTokenDetails = usageLike.prompt_tokens_details;
35
57
  if (typeof rawPromptTokenDetails !== "object" || rawPromptTokenDetails === null) return false;
36
58
  const promptTokenDetails = rawPromptTokenDetails;
@@ -261,6 +283,37 @@ function getTrailingPartialDeepseekToken(text) {
261
283
  }
262
284
  const OPENAI_COMPLETIONS_FIRST_EVENT_TIMEOUT_MESSAGE = "OpenAI completions stream timed out while waiting for the first event";
263
285
  const OPENAI_COMPLETIONS_POST_FINISH_GRACE_MS = 2500;
286
+ const OPENAI_COMPLETIONS_ERROR_STATUS_BY_TYPE = {
287
+ SERVICE_UNAVAILABLE: 503,
288
+ TOO_MANY_REQUESTS: 429,
289
+ REQUEST_TIMEOUT: 408
290
+ };
291
+ function parseOpenAICompletionsErrorStatus(value) {
292
+ const status = typeof value === "number" ? value : typeof value === "string" && /^\d{3}$/.test(value.trim()) ? Number(value) : void 0;
293
+ return status !== void 0 && Number.isInteger(status) && status >= 400 && status <= 599 ? status : void 0;
294
+ }
295
+ function createOpenAICompletionsStreamError(chunk, provider) {
296
+ if (!chunk || typeof chunk !== "object") return void 0;
297
+ const error = Reflect.get(chunk, "error");
298
+ const flatMessage = Reflect.get(chunk, "message");
299
+ const structuredError = error !== null && typeof error === "object";
300
+ if (!structuredError && typeof error !== "string" && typeof flatMessage !== "string") return void 0;
301
+ const parsed = OpenAIHttpError.parseEnvelope(chunk, void 0);
302
+ const detail = parsed.detail ?? "Provider returned an in-band OpenAI completions stream error";
303
+ if (!structuredError) return new ProviderResponseError(detail, {
304
+ provider,
305
+ kind: "runtime"
306
+ });
307
+ const typeValue = Reflect.get(error, "type");
308
+ const codeValue = Reflect.get(error, "code");
309
+ const type = typeof typeValue === "string" ? typeValue.trim() : void 0;
310
+ const status = parseOpenAICompletionsErrorStatus(codeValue) ?? (type ? OPENAI_COMPLETIONS_ERROR_STATUS_BY_TYPE[type.toUpperCase()] : void 0);
311
+ if (status === void 0) return new ProviderResponseError(detail, {
312
+ provider,
313
+ kind: "runtime"
314
+ });
315
+ return new ProviderHttpError(`${status} ${detail}`, status, { code: parsed.code });
316
+ }
264
317
  const streamOpenAICompletionsOnce = (model, context, options) => {
265
318
  const stream = new AssistantMessageEventStream();
266
319
  (async () => {
@@ -273,17 +326,21 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
273
326
  const firstEventTimeoutAbortError = new StreamTimeoutError(OPENAI_COMPLETIONS_FIRST_EVENT_TIMEOUT_MESSAGE);
274
327
  const { requestAbortController, requestSignal } = abortTracker;
275
328
  const onSseEvent = options?.onSseEvent;
276
- const rawSseObserver = onSseEvent ? (event) => {
277
- if (!event.event && event.data && event.data !== "[DONE]") try {
278
- const parsed = JSON.parse(event.data);
279
- const resolvedEvent = typeof parsed.type === "string" ? parsed.type : typeof parsed.object === "string" ? parsed.object : null;
280
- if (resolvedEvent) {
281
- event.event = resolvedEvent;
282
- event.raw = [`event: ${resolvedEvent}`, ...event.raw];
283
- }
284
- } catch {}
285
- onSseEvent(event, model);
286
- } : void 0;
329
+ let sawDoneSentinel = false;
330
+ const rawSseObserver = (event) => {
331
+ if (event.data === "[DONE]") sawDoneSentinel = true;
332
+ if (onSseEvent) {
333
+ if (!event.event && event.data && event.data !== "[DONE]") try {
334
+ const parsed = JSON.parse(event.data);
335
+ const resolvedEvent = typeof parsed.type === "string" ? parsed.type : typeof parsed.object === "string" ? parsed.object : null;
336
+ if (resolvedEvent) {
337
+ event.event = resolvedEvent;
338
+ event.raw = [`event: ${resolvedEvent}`, ...event.raw];
339
+ }
340
+ } catch {}
341
+ onSseEvent(event, model);
342
+ }
343
+ };
287
344
  let finishOpenBlocksOnError = () => {};
288
345
  try {
289
346
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
@@ -291,7 +348,7 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
291
348
  const idleTimeoutMs = options?.streamIdleTimeoutMs ?? getOpenAIStreamIdleTimeoutMs(idleTimeoutFallbackMs);
292
349
  const firstEventTimeoutMs = options?.streamFirstEventTimeoutMs ?? getOpenAIStreamFirstEventTimeoutMs(idleTimeoutMs, model.compat.streamFirstEventTimeoutMs);
293
350
  const requestTimeoutMs = firstEventTimeoutMs !== void 0 && firstEventTimeoutMs > 0 ? firstEventTimeoutMs : void 0;
294
- const { copilotPremiumRequests, baseUrl, headers, query, requestHeaders } = createRequestSetup(model, context, apiKey, options?.headers, options?.initiatorOverride, getOpenAIPromptCacheKey(options));
351
+ const { copilotPremiumRequests, baseUrl, headers, query, requestHeaders } = createRequestSetup(model, context, apiKey, options?.headers, options?.initiatorOverride, getOpenAIPromptCacheKey(options), options?.sessionId);
295
352
  const premiumRequestsTotal = copilotPremiumRequests;
296
353
  let appliedStrictTools = false;
297
354
  const requestReasoningEffortFallbacks = /* @__PURE__ */ new Map();
@@ -304,14 +361,16 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
304
361
  const trimmedBaseUrl = baseUrl.replace(/\/+$/, "");
305
362
  const completionsUrl = query ? `${trimmedBaseUrl}/chat/completions?${new URLSearchParams(query)}` : `${trimmedBaseUrl}/chat/completions`;
306
363
  const createCompletionsStream = async (toolStrictModeOverride) => {
307
- const { params, strictToolsApplied } = buildParams(model, context, options, disableStrictTools ? "none" : toolStrictModeOverride);
308
- appliedStrictTools = strictToolsApplied;
364
+ const builtParams = buildParams(model, context, options, disableStrictTools ? "none" : toolStrictModeOverride);
365
+ appliedStrictTools = builtParams.strictToolsApplied;
366
+ let params = builtParams.params;
309
367
  const reasoningEffortFallbackKey = createOpenAIReasoningEffortFallbackKey("chat-completions", trimmedBaseUrl, params.model);
310
368
  const requestReasoningEffortFallback = requestReasoningEffortFallbacks.has(reasoningEffortFallbackKey) ? requestReasoningEffortFallbacks.get(reasoningEffortFallbackKey) : getOpenAIReasoningEffortFallback(providerSessionState, reasoningEffortFallbackKey);
311
369
  if (requestReasoningEffortFallback !== void 0) applyOpenAIReasoningEffortFallback(params, requestReasoningEffortFallback);
312
370
  activeReasoningEffortFallbackKey = reasoningEffortFallbackKey;
371
+ const replacedParams = await options?.onPayload?.(params, model);
372
+ if (replacedParams !== void 0) params = replacedParams;
313
373
  activeRequestParams = params;
314
- options?.onPayload?.(params, model);
315
374
  rawRequestDump = {
316
375
  provider: model.provider,
317
376
  api: output.api,
@@ -331,32 +390,30 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
331
390
  headers: headersWithTimeout,
332
391
  body: params,
333
392
  signal: requestSignal,
334
- fetch: options?.fetch,
393
+ fetch: wrapFetchForCopilotFallback(options?.fetch, model.provider === "github-copilot", resolveCopilotRequestIdentity(options?.headers)),
335
394
  onSseEvent: rawSseObserver
336
395
  });
337
396
  await notifyProviderResponse(options, response, model, requestId);
338
397
  return events;
339
398
  } finally {
340
- if (requestTimeout !== void 0) clearTimeout(requestTimeout);
399
+ clearTimeout(requestTimeout);
341
400
  }
342
401
  };
343
402
  let openaiStream;
344
403
  try {
345
- openaiStream = await callWithCopilotModelRetry(() => createCompletionsStream(), {
346
- provider: model.provider,
347
- signal: requestSignal
348
- });
404
+ openaiStream = await createCompletionsStream();
349
405
  } catch (error) {
350
406
  const capturedErrorResponse = error instanceof OpenAIHttpError ? error.captured : void 0;
351
- const reasoningEffortFallback = activeReasoningEffortFallbackKey && activeRequestParams && !requestSignal.aborted ? resolveOpenAIReasoningEffortFallback(error, capturedErrorResponse, activeRequestParams, { explicitDisable: options?.disableReasoning === true && options.reasoning === void 0 }) : void 0;
407
+ const isExplicitDisable = options?.disableReasoning === true;
408
+ const reasoningEffortFallback = activeReasoningEffortFallbackKey && activeRequestParams && !requestSignal.aborted ? resolveOpenAIReasoningEffortFallback(error, capturedErrorResponse, activeRequestParams, { explicitDisable: isExplicitDisable }) : void 0;
352
409
  if (reasoningEffortFallback !== void 0 && activeReasoningEffortFallbackKey) {
353
410
  const retryMarker = `${activeReasoningEffortFallbackKey}:${String(reasoningEffortFallback)}`;
354
411
  if (attemptedReasoningEffortFallbacks.has(retryMarker)) throw error;
355
412
  attemptedReasoningEffortFallbacks.add(retryMarker);
356
413
  requestReasoningEffortFallbacks.set(activeReasoningEffortFallbackKey, reasoningEffortFallback);
357
414
  openaiStream = await createCompletionsStream();
358
- rememberOpenAIReasoningEffortFallback(providerSessionState, activeReasoningEffortFallbackKey, reasoningEffortFallback);
359
- } else if (isOpenRouterAnthropicModel(model) && !disableStrictTools && isCompiledGrammarTooLargeStrictError(error, capturedErrorResponse)) {
415
+ if (!isExplicitDisable) rememberOpenAIReasoningEffortFallback(providerSessionState, activeReasoningEffortFallbackKey, reasoningEffortFallback);
416
+ } else if (model.compat.retryWithoutStrictOnGrammarError && !disableStrictTools && isCompiledGrammarTooLargeStrictError(error, capturedErrorResponse)) {
360
417
  disableStrictToolsForScope(providerSessionState, strictToolsScope);
361
418
  disableStrictTools = true;
362
419
  openaiStream = await createCompletionsStream("none");
@@ -418,7 +475,7 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
418
475
  });
419
476
  };
420
477
  const finishPendingToolCallBlocks = () => {
421
- for (const block of [...pendingToolCallBlocks]) finishToolCallBlock(block);
478
+ for (const block of Array.from(pendingToolCallBlocks)) finishToolCallBlock(block);
422
479
  };
423
480
  const finishCurrentBlock = (block) => {
424
481
  if (!block) return;
@@ -582,7 +639,7 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
582
639
  let sawUsagePayload = false;
583
640
  let awaitTrailingUsageDetails = false;
584
641
  const applyUsagePayload = (rawUsage) => {
585
- output.usage = parseChunkUsage(rawUsage, model, premiumRequestsTotal);
642
+ output.usage = parseChunkUsage(rawUsage, model, premiumRequestsTotal, output.timestamp);
586
643
  sawUsagePayload = true;
587
644
  awaitTrailingUsageDetails = !hasPositiveCacheReadTokenField(rawUsage);
588
645
  };
@@ -603,6 +660,8 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
603
660
  });
604
661
  for await (const chunk of terminalAwareStream) {
605
662
  if (!chunk || typeof chunk !== "object") continue;
663
+ const streamError = createOpenAICompletionsStreamError(chunk, model.provider);
664
+ if (streamError) throw streamError;
606
665
  output.responseId ||= chunk.id;
607
666
  if (!output.upstreamProvider) {
608
667
  const upstreamProvider = chunk.provider;
@@ -698,6 +757,8 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
698
757
  }
699
758
  if (toolCall.id) block.id = toolCall.id;
700
759
  if (incomingName) block.name = incomingName;
760
+ const extraContent = getGeminiThoughtSignatureExtraContent(Reflect.get(toolCall, "extra_content"));
761
+ if (extraContent) block.thoughtSignature = JSON.stringify(extraContent);
701
762
  let delta = "";
702
763
  const rawArgs = toolCall.function?.arguments;
703
764
  if (typeof rawArgs === "string") {
@@ -742,7 +803,7 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
742
803
  if (healedToolCallEmitted && output.stopReason === "stop") output.stopReason = "toolUse";
743
804
  }
744
805
  if (stripDeepseekChatTemplateTokens) flushDeepseekStripBuffer(true);
745
- if (streamFinishedAt === void 0 && output.content.length > 0) throw new ProviderResponseError("OpenAI completions stream closed before a finish_reason was received", {
806
+ if (streamFinishedAt === void 0 && !sawDoneSentinel && output.content.length > 0) throw new ProviderResponseError("OpenAI completions stream closed before a finish_reason was received", {
746
807
  provider: model.provider,
747
808
  kind: "incomplete-stream"
748
809
  });
@@ -804,13 +865,15 @@ const streamOpenAICompletionsOnce = (model, context, options) => {
804
865
  return stream;
805
866
  };
806
867
  /**
807
- * Public entry: wrap the single-attempt streamer with bounded empty-completion
808
- * retries — flaky gateways occasionally 200 with `delta: {}` + `finish_reason:
809
- * "stop"` and no usage, which would otherwise stall the agent loop. Shared with
810
- * the Anthropic provider via `withEmptyCompletionRetry`.
868
+ * Retries benign empty completions and transient provider failures only before
869
+ * assistant output commits the attempt.
811
870
  */
812
- const streamOpenAICompletions = (model, context, options) => withEmptyCompletionRetry(model, context, options, streamOpenAICompletionsOnce);
813
- function createRequestSetup(model, context, apiKey, extraHeaders, initiatorOverride, promptCacheSessionId) {
871
+ const streamOpenAICompletions = (model, context, options) => withReplaySafeStreamRetry(model, context, options, streamOpenAICompletionsOnce, {
872
+ retryEmptyCompletion: true,
873
+ retryProviderErrors: true,
874
+ maxProviderErrorRetries: 1
875
+ });
876
+ function createRequestSetup(model, context, apiKey, extraHeaders, initiatorOverride, promptCacheSessionId, sessionId) {
814
877
  const apiVersion = $env.AZURE_OPENAI_API_VERSION || "2024-10-21";
815
878
  const deploymentName = parseAzureDeploymentNameMap($env.AZURE_OPENAI_DEPLOYMENT_NAME_MAP).get(model.id) ?? model.id;
816
879
  const setup = resolveOpenAIRequestSetup(model, {
@@ -818,9 +881,10 @@ function createRequestSetup(model, context, apiKey, extraHeaders, initiatorOverr
818
881
  extraHeaders,
819
882
  initiatorOverride,
820
883
  promptCacheSessionId,
884
+ sessionId,
821
885
  messages: context.messages,
822
886
  defaultBaseUrl: "https://api.openai.com/v1",
823
- prependHeaders: model.provider === "kimi-code" ? getKimiCommonHeaders : void 0,
887
+ prependHeaders: model.provider === "kimi-code" ? getKimiCommonHeaders : model.provider === "cline-pass" ? () => clinePassClientHeaders(promptCacheSessionId) : void 0,
824
888
  alibabaCodingPlanAuth: true,
825
889
  azureChatCompletions: {
826
890
  apiVersion,
@@ -838,18 +902,12 @@ function resolveOpenAICompatForRequest(model, options) {
838
902
  toolChoice: mapToOpenAICompletionsToolChoice(options?.toolChoice)
839
903
  });
840
904
  }
841
- function dropOpenRouterKimiForcedToolReasoning(params, model, policy) {
842
- if (policy.reasoning.disableReason === "forced-tool-choice" && policy.reasoning.disableMode === "openrouter-enabled-false" && policy.compat.isOpenRouterHost && isKimiModelId(model.id)) delete params.reasoning;
905
+ function dropOpenRouterKimiForcedToolReasoning(params, _model, policy) {
906
+ if (policy.reasoning.disableReason === "forced-tool-choice" && policy.reasoning.disableMode === "openrouter-enabled-false" && policy.compat.isOpenRouterHost) delete params.reasoning;
843
907
  }
844
908
  function hasActiveNativeKimiK3Reasoning(model, options) {
845
- if (model.provider !== "kimi-code" || model.id.toLowerCase() !== "k3" || !model.reasoning) return false;
846
- if (options?.reasoning === void 0 || options.disableReasoning) return false;
847
- try {
848
- const url = new URL(model.baseUrl);
849
- return url.hostname === "api.kimi.com" && (url.pathname === "/coding" || url.pathname.startsWith("/coding/"));
850
- } catch {
851
- return false;
852
- }
909
+ if (!model.compat.nativeKimiK3Reasoning || !model.reasoning) return false;
910
+ return options?.reasoning !== void 0 && !options.disableReasoning;
853
911
  }
854
912
  function isChatCompletionsPromptCacheableContentBlock(block) {
855
913
  if (typeof block !== "object" || block === null || !("type" in block)) return false;
@@ -890,7 +948,7 @@ function markLatestStableChatCompletionsCacheBreakpoint(messages) {
890
948
  }
891
949
  function applyOpenAIChatCompletionsPromptCachePolicy(params, model, options) {
892
950
  const promptCacheKey = getOpenAIPromptCacheKey(options);
893
- if (model.provider === "kimi-code" && promptCacheKey !== void 0) params.prompt_cache_key = promptCacheKey;
951
+ if (model.compat.supportsPromptCacheKey && promptCacheKey !== void 0) params.prompt_cache_key = promptCacheKey;
894
952
  const promptCache = options?.promptCache;
895
953
  if (!promptCache || resolveCacheRetention(options?.cacheRetention) === "none") return;
896
954
  if (!model.compat.supportsPromptCacheBreakpoints) {
@@ -933,7 +991,7 @@ function buildParams(model, context, options, toolStrictModeOverride) {
933
991
  }
934
992
  applyOpenAIServiceTier(params, options?.serviceTier, model);
935
993
  if (context.tools?.length) {
936
- const builtTools = convertTools(context.tools, initialCompat, toolStrictModeOverride, model.provider);
994
+ const builtTools = convertTools(context.tools, initialCompat, toolStrictModeOverride);
937
995
  params.tools = builtTools.tools;
938
996
  toolStrictMode = builtTools.toolStrictMode;
939
997
  strictToolsApplied = builtTools.strictToolsApplied;
@@ -948,6 +1006,7 @@ function buildParams(model, context, options, toolStrictModeOverride) {
948
1006
  if (isForcedToolChoice(params.tool_choice) && !initialCompat.supportsForcedToolChoice) params.tool_choice = "auto";
949
1007
  if ((!Array.isArray(params.tools) || params.tools.length === 0) && (params.tool_choice === "none" || isForcedToolChoice(params.tool_choice))) delete params.tool_choice;
950
1008
  if (forcedToolName !== void 0 && (!Array.isArray(params.tools) || !params.tools.some((tool) => tool.type === "function" && tool.function.name === forcedToolName))) delete params.tool_choice;
1009
+ if (shouldDropAutoToolChoiceForReasoning(model, initialCompat, params.tool_choice, options)) delete params.tool_choice;
951
1010
  const finalPolicy = resolveOpenAICompatPolicy(model, {
952
1011
  endpoint: "chat-completions",
953
1012
  reasoning: options?.reasoning,
@@ -973,7 +1032,10 @@ function buildParams(model, context, options, toolStrictModeOverride) {
973
1032
  else if (outputToken.field === "max_completion_tokens") params.max_completion_tokens = outputToken.value;
974
1033
  }
975
1034
  applyChatCompletionsToolStream(params, model, compat);
976
- applyChatCompletionsCompatPolicy(params, finalPolicy);
1035
+ applyChatCompletionsReasoningParams(params, model, compat, {
1036
+ ...options,
1037
+ toolChoice: params.tool_choice
1038
+ });
977
1039
  dropOpenRouterKimiForcedToolReasoning(params, model, finalPolicy);
978
1040
  applyOpenAIGatewayRouting(params, compat, cacheRetention !== "none");
979
1041
  applyOpenAIExtraBody(params, compat.extraBody, { dropThinkingWhenReasoningEffort: compat.dropThinkingWhenReasoningEffort });
@@ -984,7 +1046,7 @@ function buildParams(model, context, options, toolStrictModeOverride) {
984
1046
  strictToolsApplied
985
1047
  };
986
1048
  }
987
- function parseChunkUsage(rawUsage, model, premiumRequests) {
1049
+ function parseChunkUsage(rawUsage, model, premiumRequests, timestamp) {
988
1050
  const usageLike = rawUsage;
989
1051
  const rawPromptTokenDetails = usageLike.prompt_tokens_details;
990
1052
  const promptTokenDetails = typeof rawPromptTokenDetails === "object" && rawPromptTokenDetails !== null ? rawPromptTokenDetails : void 0;
@@ -996,13 +1058,14 @@ function parseChunkUsage(rawUsage, model, premiumRequests) {
996
1058
  const promptCacheHitTokens = usageLike.prompt_cache_hit_tokens;
997
1059
  const promptCacheMissTokens = usageLike.prompt_cache_miss_tokens;
998
1060
  const promptTokenCachedTokens = promptTokenDetails?.cached_tokens;
1061
+ const cachedContentTokenCount = usageLike.cachedContentTokenCount;
999
1062
  const completionReasoningTokens = completionTokenDetails?.reasoning_tokens;
1000
1063
  const cacheWriteTokens = promptTokenDetails?.cache_write_tokens;
1001
1064
  const usage = {
1002
1065
  ...calculateOpenAIUsageAccounting({
1003
1066
  promptTokens: typeof promptTokens === "number" ? promptTokens : 0,
1004
1067
  outputTokens: typeof completionTokens === "number" ? completionTokens : 0,
1005
- cachedTokens: firstPositiveNumber(cachedTokens, promptCacheHitTokens, promptTokenCachedTokens),
1068
+ cachedTokens: firstPositiveNumber(cachedTokens, promptCacheHitTokens, promptTokenCachedTokens, cachedContentTokenCount),
1006
1069
  reasoningTokens: typeof completionReasoningTokens === "number" ? completionReasoningTokens : 0,
1007
1070
  cacheWriteOpenRouter: typeof cacheWriteTokens === "number" ? cacheWriteTokens : void 0,
1008
1071
  cacheWriteDeepSeek: typeof promptCacheMissTokens === "number" ? promptCacheMissTokens : void 0,
@@ -1017,8 +1080,8 @@ function parseChunkUsage(rawUsage, model, premiumRequests) {
1017
1080
  },
1018
1081
  ...premiumRequests !== void 0 ? { premiumRequests } : {}
1019
1082
  };
1020
- calculateCost(model, usage);
1021
- applyOpenRouterReportedCost(model, usage, rawUsage);
1083
+ calculateCost(model, usage, timestamp);
1084
+ applyProviderReportedCost(model, usage, rawUsage);
1022
1085
  return usage;
1023
1086
  }
1024
1087
  function maybeAddAnthropicCacheControl(compat, messages) {
@@ -1115,7 +1178,7 @@ function convertMessages(model, context, compat) {
1115
1178
  content: text
1116
1179
  });
1117
1180
  } else {
1118
- const supportsImages = model.input.includes("image") && !isDashscopeCompatibleModeTextOnlyQwen(model);
1181
+ const supportsImages = isOpenAICompletionsVisionSupported(model);
1119
1182
  const content = [];
1120
1183
  let omittedImages = false;
1121
1184
  for (const item of msg.content) if (item.type === "text") {
@@ -1128,7 +1191,7 @@ function convertMessages(model, context, compat) {
1128
1191
  } else if (supportsImages) content.push({
1129
1192
  type: "image_url",
1130
1193
  image_url: {
1131
- url: `data:${item.mimeType};base64,${item.data}`,
1194
+ url: item.url ?? `data:${item.mimeType};base64,${item.data}`,
1132
1195
  ...item.detail && item.detail !== "original" ? { detail: item.detail } : {}
1133
1196
  }
1134
1197
  });
@@ -1211,7 +1274,7 @@ function convertMessages(model, context, compat) {
1211
1274
  assistantMsg.tool_calls = toolCalls.map((tc, toolCallIndex) => {
1212
1275
  const toolCallId = ensureToolCallId(tc.id, `${i}:${toolCallIndex}:${tc.name}`, msg);
1213
1276
  rememberToolCallId(tc.id, toolCallId);
1214
- return {
1277
+ const replayedToolCall = {
1215
1278
  id: normalizeMistralToolId(toolCallId, compat.requiresMistralToolIds),
1216
1279
  type: "function",
1217
1280
  function: {
@@ -1219,14 +1282,20 @@ function convertMessages(model, context, compat) {
1219
1282
  arguments: serializeToolArguments(tc.arguments)
1220
1283
  }
1221
1284
  };
1285
+ const extraContent = parseGeminiThoughtSignatureExtraContent(tc.thoughtSignature);
1286
+ if (extraContent) replayedToolCall.extra_content = extraContent;
1287
+ return replayedToolCall;
1222
1288
  });
1223
- const reasoningDetails = toolCalls.filter((tc) => tc.thoughtSignature).map((tc) => {
1289
+ const reasoningDetails = toolCalls.flatMap((tc) => {
1290
+ const thoughtSignature = tc.thoughtSignature;
1291
+ if (!thoughtSignature) return [];
1224
1292
  try {
1225
- return JSON.parse(tc.thoughtSignature);
1293
+ const parsed = JSON.parse(thoughtSignature);
1294
+ return getGeminiThoughtSignatureExtraContent(parsed) ? [] : [parsed];
1226
1295
  } catch {
1227
- return null;
1296
+ return [];
1228
1297
  }
1229
- }).filter(Boolean);
1298
+ });
1230
1299
  if (reasoningDetails.length > 0) assistantMsg.reasoning_details = reasoningDetails;
1231
1300
  }
1232
1301
  if (assistantMsg.content === null && (hasReasoningField || assistantMsg.tool_calls)) assistantMsg.content = "";
@@ -1241,7 +1310,7 @@ function convertMessages(model, context, compat) {
1241
1310
  for (; j < transformedMessages.length && transformedMessages[j].role === "toolResult"; j++) {
1242
1311
  const toolMsg = transformedMessages[j];
1243
1312
  const textResult = toolMsg.content.filter((c) => c.type === "text").map((c) => c.text).join("\n");
1244
- const supportsImages = model.input.includes("image") && !isDashscopeCompatibleModeTextOnlyQwen(model);
1313
+ const supportsImages = isOpenAICompletionsVisionSupported(model);
1245
1314
  const hasImages = toolMsg.content.some((c) => c.type === "image");
1246
1315
  const omittedImages = hasImages && !supportsImages;
1247
1316
  const hasText = textResult.length > 0;
@@ -1256,7 +1325,7 @@ function convertMessages(model, context, compat) {
1256
1325
  if (hasImages && supportsImages) {
1257
1326
  for (const block of toolMsg.content) if (block.type === "image") imageBlocks.push({
1258
1327
  type: "image_url",
1259
- image_url: { url: `data:${block.mimeType};base64,${block.data}` }
1328
+ image_url: { url: block.url ?? `data:${block.mimeType};base64,${block.data}` }
1260
1329
  });
1261
1330
  }
1262
1331
  }
@@ -1281,11 +1350,11 @@ function convertMessages(model, context, compat) {
1281
1350
  }
1282
1351
  return params;
1283
1352
  }
1284
- function convertTools(tools, compat, toolStrictModeOverride, provider) {
1285
- const rejectXaiRootObjectUnion = provider === "xai" || provider === "xai-oauth";
1353
+ function convertTools(tools, compat, toolStrictModeOverride) {
1354
+ const rejectRootObjectUnion = compat.rejectRootObjectUnion;
1286
1355
  const adaptedTools = tools.map((tool) => {
1287
1356
  const strict = !NO_STRICT && compat.supportsStrictMode !== false && tool.strict !== false;
1288
- const baseParameters = rejectXaiRootObjectUnion ? flattenExclusiveRequiredRootUnion(toolWireSchema(tool)) : toolWireSchema(tool);
1357
+ const baseParameters = rejectRootObjectUnion ? flattenExclusiveRequiredRootUnion(toolWireSchema(tool)) : toolWireSchema(tool);
1289
1358
  const adapted = adaptSchemaForStrict(baseParameters, strict);
1290
1359
  return {
1291
1360
  tool,
@@ -1303,7 +1372,7 @@ function convertTools(tools, compat, toolStrictModeOverride, provider) {
1303
1372
  const includeExplicitFalse = !includeStrict && tool.strict === false && toolStrictMode === "mixed" && compat.supportsStrictMode !== false;
1304
1373
  const wireParameters = includeStrict ? parameters : baseParameters;
1305
1374
  const emittedParameters = compat.toolSchemaFlavor === "moonshot-mfjs" ? normalizeSchemaForMoonshot(wireParameters) : compat.toolSchemaFlavor === "grammar" ? sanitizeSchemaForGrammar(wireParameters) : wireParameters;
1306
- const violation = findStrictToolSchemaViolation(emittedParameters, "#", { rejectXaiRootObjectUnion });
1375
+ const violation = findStrictToolSchemaViolation(emittedParameters, "#", { rejectRootObjectUnion });
1307
1376
  if (violation) {
1308
1377
  warn(`Tool "${tool.name}" omitted from the openai-completions request: its parameter schema is invalid for this provider at ${violation} (an enum/const value cannot match its declared type, or leftover xAI object-root union). Other tools are unaffected.`);
1309
1378
  continue;
@@ -1328,10 +1397,11 @@ function convertTools(tools, compat, toolStrictModeOverride, provider) {
1328
1397
  const EMPTY_OLLAMA_LENGTH_COMPLETION_MESSAGE = "Model returned no content: prompt filled the context window; raise Ollama num_ctx or shorten the prompt.";
1329
1398
  function mapStopReason(reason) {
1330
1399
  if (reason === null) return { stopReason: "stop" };
1331
- switch (reason) {
1400
+ switch (typeof reason === "string" ? reason.toLowerCase() : reason) {
1332
1401
  case "stop":
1333
1402
  case "end": return { stopReason: "stop" };
1334
- case "length": return { stopReason: "length" };
1403
+ case "length":
1404
+ case "max_tokens": return { stopReason: "length" };
1335
1405
  case "function_call":
1336
1406
  case "tool_calls": return { stopReason: "toolUse" };
1337
1407
  case "content_filter": return {
@@ -0,0 +1,150 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/providers/grammar.ts
4
+ function compactGrammarDefinition(syntax, definition) {
5
+ if (syntax !== "lark") return definition;
6
+ return compactLarkGrammarDefinition(definition);
7
+ }
8
+ function compactLarkGrammarDefinition(definition) {
9
+ const lines = [];
10
+ for (const line of definition.split(/\r?\n/)) {
11
+ const uncommented = stripLarkLineComment(line).trimEnd();
12
+ if (uncommented.trim()) lines.push(uncommented);
13
+ }
14
+ return lines.join("\n");
15
+ }
16
+ function stripLarkLineComment(line) {
17
+ let inString;
18
+ let inRegex = false;
19
+ let escaped = false;
20
+ for (let i = 0; i < line.length; i++) {
21
+ const char = line[i];
22
+ const next = line[i + 1];
23
+ if (escaped) {
24
+ escaped = false;
25
+ continue;
26
+ }
27
+ if (char === "\\") {
28
+ escaped = true;
29
+ continue;
30
+ }
31
+ if (inString) {
32
+ if (char === inString) inString = void 0;
33
+ continue;
34
+ }
35
+ if (inRegex) {
36
+ if (char === "/") inRegex = false;
37
+ continue;
38
+ }
39
+ if (char === "/" && next === "/") return line.slice(0, i);
40
+ if (char === "\"" || char === "'") {
41
+ inString = char;
42
+ continue;
43
+ }
44
+ if (char === "/") inRegex = true;
45
+ }
46
+ return line;
47
+ }
48
+ //#endregion
49
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/providers/openai-configuration-update.ts
50
+ function createOpenAIEffortControlState() {
51
+ return { transitions: [] };
52
+ }
53
+ const MAX_EFFORT_CONTROL_STATES = 16;
54
+ /**
55
+ * Fetch (or create) the control state for one conversation from a provider's
56
+ * bounded per-session map, refreshing its LRU slot.
57
+ */
58
+ function getOpenAIEffortControlState(states, key) {
59
+ const existing = states.get(key);
60
+ if (existing) {
61
+ states.delete(key);
62
+ states.set(key, existing);
63
+ return existing;
64
+ }
65
+ const created = createOpenAIEffortControlState();
66
+ states.set(key, created);
67
+ if (states.size > MAX_EFFORT_CONTROL_STATES) {
68
+ const oldest = states.keys().next().value;
69
+ if (oldest !== void 0) states.delete(oldest);
70
+ }
71
+ return created;
72
+ }
73
+ /**
74
+ * Fingerprint of the item a transition sits after. Output-only lifecycle
75
+ * fields are excluded: a live response item carries `id`/`status` that the
76
+ * sanitized replay of the same item drops.
77
+ */
78
+ function effortControlAnchor(input, index) {
79
+ if (index === 0) return "";
80
+ const item = input[index - 1];
81
+ if (!item) return "";
82
+ const { id: _id, status: _status, ...stable } = item;
83
+ return String(Bun.hash(JSON.stringify(stable)));
84
+ }
85
+ function resetOpenAIEffortControlState(state) {
86
+ state.baseEffort = void 0;
87
+ state.currentEffort = void 0;
88
+ state.transitions = [];
89
+ }
90
+ /**
91
+ * Discard the baseline when the request no longer continues the conversation
92
+ * it was captured for: a wire history that shrank or was rewritten under a
93
+ * recorded transition (compaction, branch switch, `/clear`). The next request
94
+ * re-baselines from its own effort, which is what the API asks for after
95
+ * compaction anyway.
96
+ */
97
+ function syncOpenAIEffortControlState(state, input) {
98
+ for (const transition of state.transitions) if (transition.index > input.length || transition.anchor !== effortControlAnchor(input, transition.index)) {
99
+ resetOpenAIEffortControlState(state);
100
+ return;
101
+ }
102
+ }
103
+ /**
104
+ * Pin the request-level effort to the session baseline and splice pending
105
+ * `configuration_update` items into `input` (mutated in place).
106
+ *
107
+ * `input` is the freshly built transcript for this request, without any
108
+ * `configuration_update` items. `requested` is the wire effort the caller
109
+ * would otherwise send at the request level. Returns the effort to send at the
110
+ * request level (`requested` on the first request, the baseline afterwards).
111
+ */
112
+ function planStableOpenAIEffort(state, input, requested) {
113
+ syncOpenAIEffortControlState(state, input);
114
+ if (state.baseEffort === void 0) {
115
+ state.baseEffort = requested;
116
+ state.currentEffort = requested;
117
+ return requested;
118
+ }
119
+ if (state.currentEffort !== requested) {
120
+ const last = input[input.length - 1];
121
+ const index = last && "role" in last && last.role === "user" ? input.length - 1 : input.length;
122
+ const existing = state.transitions.find((transition) => transition.index === index);
123
+ if (existing) existing.effort = requested;
124
+ else state.transitions.push({
125
+ index,
126
+ anchor: effortControlAnchor(input, index),
127
+ effort: requested
128
+ });
129
+ let preceding = state.baseEffort;
130
+ let precedingIndex = -1;
131
+ for (const transition of state.transitions) if (transition.index < index && transition.index > precedingIndex) {
132
+ preceding = transition.effort;
133
+ precedingIndex = transition.index;
134
+ }
135
+ if (requested === preceding) state.transitions = state.transitions.filter((transition) => transition.index !== index);
136
+ state.currentEffort = requested;
137
+ }
138
+ state.transitions.sort((a, b) => a.index - b.index);
139
+ let offset = 0;
140
+ for (const transition of state.transitions) {
141
+ input.splice(transition.index + offset, 0, {
142
+ type: "configuration_update",
143
+ reasoning: { effort: transition.effort }
144
+ });
145
+ offset++;
146
+ }
147
+ return state.baseEffort;
148
+ }
149
+ //#endregion
150
+ export { planStableOpenAIEffort as n, compactGrammarDefinition as r, getOpenAIEffortControlState as t };