@xiaoso/dsh-tool-plus 0.1.0-beta.2 → 0.1.0-beta.4

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 (235) hide show
  1. package/README.en.md +122 -0
  2. package/README.md +3 -2
  3. package/THIRD_PARTY_NOTICES.md +4 -35
  4. package/lib/abort-B7izMMna.mjs +51 -0
  5. package/lib/abort-D1_Z5Ut5.mjs +51 -0
  6. package/lib/abort-dIkZBV7Q.mjs +51 -0
  7. package/lib/amazon-bedrock-B0nxT06F.mjs +917 -0
  8. package/lib/amazon-bedrock-D-shAr1X.mjs +917 -0
  9. package/lib/amazon-bedrock-WQhvjHYu.mjs +917 -0
  10. package/lib/anthropic-BWsZFzU8.mjs +262 -0
  11. package/lib/anthropic-CJCauvYz.mjs +3115 -0
  12. package/lib/anthropic-CMT1Qj1t.mjs +3115 -0
  13. package/lib/anthropic-CZghe_9U.mjs +3115 -0
  14. package/lib/anthropic-sCMH7JID.mjs +262 -0
  15. package/lib/anthropic-tTntD8BD.mjs +262 -0
  16. package/lib/api-key-login-BzqNdM2y.mjs +157 -0
  17. package/lib/api-key-login-CWVwvHT1.mjs +157 -0
  18. package/lib/api-key-login-CpzSezsi.mjs +157 -0
  19. package/lib/aws-credentials-8Mgn5MAy.mjs +867 -0
  20. package/lib/aws-credentials-CXryMobh.mjs +867 -0
  21. package/lib/aws-credentials-ChG79ey-.mjs +867 -0
  22. package/lib/azure-openai-responses-CNkHiLUh.mjs +274 -0
  23. package/lib/azure-openai-responses-Cgmc-rbL.mjs +274 -0
  24. package/lib/azure-openai-responses-DuukbD0F.mjs +274 -0
  25. package/lib/bun-shim.mjs +252 -12
  26. package/lib/bundled-references-CSuBco5p.mjs +55 -0
  27. package/lib/bundled-references-Cavaffah.mjs +55 -0
  28. package/lib/bundled-references-sLN0YdXU.mjs +55 -0
  29. package/lib/callback-server-BEFNf-jf.mjs +398 -0
  30. package/lib/callback-server-CQ5Jo8F-.mjs +398 -0
  31. package/lib/callback-server-DDSrZ6l_.mjs +398 -0
  32. package/lib/client.js +111 -41
  33. package/lib/cursor-B3zg7EHj.mjs +273 -0
  34. package/lib/cursor-B6TUEmgP.mjs +135 -0
  35. package/lib/cursor-BIQfBC6V.mjs +135 -0
  36. package/lib/cursor-D8gvtTL3.mjs +135 -0
  37. package/lib/cursor-DNk6eXDd.mjs +5470 -0
  38. package/lib/cursor-DkSX2h3H.mjs +5441 -0
  39. package/lib/cursor-MjSm74IJ.mjs +273 -0
  40. package/lib/cursor-aJrXeYCb.mjs +273 -0
  41. package/lib/cursor-mJQwUKXK.mjs +5441 -0
  42. package/lib/device-code-DBo3B5nh.mjs +51 -0
  43. package/lib/device-code-DIb0FU-H.mjs +51 -0
  44. package/lib/device-code-OI_tQcmc.mjs +51 -0
  45. package/lib/devin-BHZZyMhO.mjs +95 -0
  46. package/lib/devin-BK7DHeca.mjs +114 -0
  47. package/lib/devin-CfMp3cXS.mjs +95 -0
  48. package/lib/devin-CldyPD8K.mjs +95 -0
  49. package/lib/devin-CzRpTUOA.mjs +114 -0
  50. package/lib/devin-D9zR5B_R.mjs +542 -0
  51. package/lib/devin-DXOeNyU7.mjs +542 -0
  52. package/lib/devin-Q1yem3lp.mjs +114 -0
  53. package/lib/devin-vNZTNUON.mjs +542 -0
  54. package/lib/error-B3bevhrs.mjs +1449 -0
  55. package/lib/error-Dd8DIqs-.mjs +1449 -0
  56. package/lib/error-yCSG0mGC.mjs +1449 -0
  57. package/lib/event-stream-BDPi64mK.mjs +151 -0
  58. package/lib/event-stream-BbFZJy-z.mjs +151 -0
  59. package/lib/event-stream-loUa0s1T.mjs +151 -0
  60. package/lib/fs-promises-shim-Bx0fpxuk.mjs +57 -0
  61. package/lib/github-copilot-4GaMtQmg.mjs +208 -0
  62. package/lib/github-copilot-B1yiyVRh.mjs +104 -0
  63. package/lib/github-copilot-B2HGSIJK.mjs +104 -0
  64. package/lib/github-copilot-BWT3eAOF.mjs +208 -0
  65. package/lib/github-copilot-CYkjeTi3.mjs +208 -0
  66. package/lib/github-copilot-jscUZ8Hf.mjs +104 -0
  67. package/lib/gitlab-duo-CM7Ref1H.mjs +155 -0
  68. package/lib/gitlab-duo-akICyfeD.mjs +155 -0
  69. package/lib/gitlab-duo-gubO4FNw.mjs +155 -0
  70. package/lib/gitlab-duo-workflow-BGAF6JDw.mjs +91 -0
  71. package/lib/gitlab-duo-workflow-CSEgYk3N.mjs +91 -0
  72. package/lib/gitlab-duo-workflow-D78tdn8E.mjs +91 -0
  73. package/lib/google-BS4T25Pn.mjs +30 -0
  74. package/lib/google-TFe-7-of.mjs +30 -0
  75. package/lib/google-antigravity-DGmwC2KV.mjs +198 -0
  76. package/lib/google-antigravity-DNYhgTpA.mjs +198 -0
  77. package/lib/google-antigravity-Dlkdhahq.mjs +198 -0
  78. package/lib/google-auth-B6gjsZvg.mjs +232 -0
  79. package/lib/google-auth-De7_s3eo.mjs +232 -0
  80. package/lib/google-auth-DhqpOYrX.mjs +232 -0
  81. package/lib/google-gemini-cli-BG_LRdIV.mjs +850 -0
  82. package/lib/google-gemini-cli-CWu8HvXW.mjs +211 -0
  83. package/lib/google-gemini-cli-Cb97bzQc.mjs +850 -0
  84. package/lib/google-gemini-cli-Cqds_Q5T.mjs +850 -0
  85. package/lib/google-gemini-cli-Dsztq0N5.mjs +211 -0
  86. package/lib/google-gemini-cli-zJhiOcND.mjs +211 -0
  87. package/lib/google-oauth-shared-CuEHaDDj.mjs +147 -0
  88. package/lib/google-oauth-shared-CwNWYdmR.mjs +147 -0
  89. package/lib/google-oauth-shared-yqlyqPPC.mjs +147 -0
  90. package/lib/google-shared-CgKmmdO3.mjs +760 -0
  91. package/lib/google-shared-Dr-VG-ap.mjs +760 -0
  92. package/lib/google-shared-DzhCb9b0.mjs +760 -0
  93. package/lib/google-vertex-BDN2tLaD.mjs +99 -0
  94. package/lib/google-vertex-DopVOQOG.mjs +99 -0
  95. package/lib/google-vertex-kscbkyRb.mjs +99 -0
  96. package/lib/google-zyDOG9x7.mjs +30 -0
  97. package/lib/identity-Da1GPU9a.mjs +219 -0
  98. package/lib/identity-DnB63pS7.mjs +219 -0
  99. package/lib/identity-xRP7_eSR.mjs +219 -0
  100. package/lib/idle-iterator-Baoyn3Hp.mjs +366 -0
  101. package/lib/idle-iterator-C6XbWcuB.mjs +366 -0
  102. package/lib/idle-iterator-DUjKQEGT.mjs +366 -0
  103. package/lib/index.mjs +4608 -3935
  104. package/lib/kimi--wUOWER5.mjs +236 -0
  105. package/lib/kimi-DMVI-zrZ.mjs +236 -0
  106. package/lib/kimi-Dh0pv3WZ.mjs +236 -0
  107. package/lib/markit-BL3cH47U.mjs +1417 -0
  108. package/lib/markit-BNiNY6SE.mjs +1417 -0
  109. package/lib/markit-M0jhziqU.mjs +1417 -0
  110. package/lib/minimax-code-BK-3eBbz.mjs +53 -0
  111. package/lib/minimax-code-DCbuA6Yk.mjs +53 -0
  112. package/lib/minimax-code-Uq8Qu9LW.mjs +53 -0
  113. package/lib/models-CfT4coYT.mjs +104660 -0
  114. package/lib/models-D_XnT6ay.mjs +104660 -0
  115. package/lib/models-SGASygJ3.mjs +104660 -0
  116. package/lib/ollama-BQMGPxtV.mjs +589 -0
  117. package/lib/ollama-DPzBmq89.mjs +589 -0
  118. package/lib/ollama-DoBz5SFm.mjs +589 -0
  119. package/lib/openai-codex-Bi-4S4PX.mjs +255 -0
  120. package/lib/openai-codex-CQL_kvYL.mjs +255 -0
  121. package/lib/openai-codex-Ch8CkT3p.mjs +255 -0
  122. package/lib/openai-codex-responses-CvxL_FMF.mjs +3144 -0
  123. package/lib/openai-codex-responses-Cz-2qpC7.mjs +3144 -0
  124. package/lib/openai-codex-responses-pejZgdZo.mjs +3144 -0
  125. package/lib/openai-completions-CF8IyNtP.mjs +1360 -0
  126. package/lib/openai-completions-DIf361kF.mjs +1360 -0
  127. package/lib/openai-completions-i8doczAk.mjs +1360 -0
  128. package/lib/openai-reasoning-fallback-DGVVLgd1.mjs +286 -0
  129. package/lib/openai-reasoning-fallback-Nj6yB2rY.mjs +286 -0
  130. package/lib/openai-reasoning-fallback-OdJREP1o.mjs +286 -0
  131. package/lib/openai-responses-BqXJInHX.mjs +867 -0
  132. package/lib/openai-responses-DTkBiiy-.mjs +867 -0
  133. package/lib/openai-responses-Db_a-U4-.mjs +867 -0
  134. package/lib/opencode-DaJjcUbf.mjs +38 -0
  135. package/lib/opencode-DhMolSoB.mjs +38 -0
  136. package/lib/opencode-Rq_Q2vAO.mjs +38 -0
  137. package/lib/perplexity-9b-RQ0mV.mjs +194 -0
  138. package/lib/perplexity-C4iLVMUj.mjs +194 -0
  139. package/lib/perplexity-Uu7Jzg5b.mjs +194 -0
  140. package/lib/proxy-DDqrmjjC.mjs +190 -0
  141. package/lib/proxy-ZtUcl6r5.mjs +190 -0
  142. package/lib/proxy-pM_NIv-H.mjs +190 -0
  143. package/lib/request-debug-HJMoJncL.mjs +183 -0
  144. package/lib/sanitize-text-CfcXzw5X.mjs +33 -0
  145. package/lib/scrapers-BkFfcPHj.mjs +9198 -0
  146. package/lib/scrapers-CL-WgdU1.mjs +9198 -0
  147. package/lib/scrapers-CVptboMs.mjs +9198 -0
  148. package/lib/scrapers-CipyKyCH.mjs +9198 -0
  149. package/lib/scrapers-DGfrYhtw.mjs +9198 -0
  150. package/lib/scrapers-DSUPYoUF.mjs +9198 -0
  151. package/lib/scrapers-DZ2GXmp7.mjs +9198 -0
  152. package/lib/scrapers-nhQAvc8d.mjs +9198 -0
  153. package/lib/shell-snapshot-fn-env.sh +67 -43
  154. package/lib/src-BgpusnsB.mjs +5076 -0
  155. package/lib/src-DTid0g4K.mjs +5001 -0
  156. package/lib/src-lDmkSRbm.mjs +5006 -0
  157. package/lib/stream-BlldLkVq.mjs +10236 -0
  158. package/lib/stream-CRtexYLe.mjs +10236 -0
  159. package/lib/stream-C_RAoxJC.mjs +10236 -0
  160. package/lib/stream-markup-healing-2toHXWXM.mjs +491 -0
  161. package/lib/stream-markup-healing-DMsxBx1L.mjs +491 -0
  162. package/lib/stream-markup-healing-KMkiAA00.mjs +491 -0
  163. package/lib/turndown-DN7ByzEI.mjs +667 -0
  164. package/lib/types/client/locales.d.ts +1 -1
  165. package/lib/types/config/fields.d.ts +1 -1
  166. package/lib/types/config/settings.d.ts +25 -3
  167. package/lib/types/config/truncate.d.ts +9 -5
  168. package/lib/types/tools/bash/background.d.ts +1 -1
  169. package/lib/types/tools/bash/bash-executor.d.ts +4 -0
  170. package/lib/types/tools/bash/bash-interceptor.d.ts +10 -8
  171. package/lib/types/tools/bash/cd-workdir.d.ts +35 -0
  172. package/lib/types/tools/bash/non-interactive-env.d.ts +2 -0
  173. package/lib/types/tools/bash/render.d.ts +4 -3
  174. package/lib/types/tools/bash/sanitize-text.d.ts +5 -0
  175. package/lib/types/tools/bash/shell-snapshot.d.ts +4 -1
  176. package/lib/types/tools/bash/shell-tokenize.d.ts +60 -0
  177. package/lib/types/tools/bash/streaming-output.d.ts +12 -212
  178. package/lib/types/tools/bash/which.d.ts +20 -0
  179. package/lib/types/tools/bash/windows-shell.d.ts +31 -0
  180. package/lib/types/tools/edit/adapter/index.d.ts +25 -3
  181. package/lib/types/tools/edit/adapter/tools/auto-generated-guard.d.ts +7 -17
  182. package/lib/types/tools/glob/adapter/index.d.ts +27 -1
  183. package/lib/types/tools/grep/adapter/index.d.ts +29 -1
  184. package/lib/types/tools/omp/edit/dispatch.d.ts +43 -0
  185. package/lib/types/tools/omp/edit/hashline/noop-loop-guard.d.ts +3 -1
  186. package/lib/types/tools/omp/sdk.d.ts +6 -0
  187. package/lib/types/tools/omp/tools/auto-generated-guard.d.ts +20 -0
  188. package/lib/types/tools/omp/tools/fetch.d.ts +2 -0
  189. package/lib/types/tools/omp/tools/read.d.ts +2 -8
  190. package/lib/types/tools/omp/tools/write.d.ts +4 -4
  191. package/lib/types/tools/omp/utils/image-loading.d.ts +10 -36
  192. package/lib/types/tools/read/adapter/index.d.ts +4 -1
  193. package/lib/types/tools/read-image/index.d.ts +4 -0
  194. package/lib/types/tools/shared/auto-generated-guard.dsh.d.ts +16 -4
  195. package/lib/types/tools/shared/bun-shim.d.ts +39 -3
  196. package/lib/types/tools/shared/fs-promises-shim.d.ts +3 -1
  197. package/lib/types/tools/shared/image-bridge.d.ts +98 -0
  198. package/lib/types/tools/shared/omp-prompt.d.ts +17 -9
  199. package/lib/types/tools/shared/session-state.d.ts +9 -3
  200. package/lib/utils-2Wq2eATG.mjs +8119 -0
  201. package/lib/utils-BnX8O3vi.mjs +12303 -0
  202. package/lib/utils-Bw139LTz.mjs +8119 -0
  203. package/lib/utils-CE8N8P4Q.mjs +12315 -0
  204. package/lib/utils-CZw4tVZQ.mjs +12315 -0
  205. package/lib/utils-C_MrQ_0z.mjs +12301 -0
  206. package/lib/utils-CiGN7OHR.mjs +12315 -0
  207. package/lib/utils-Cp76gCyk.mjs +8119 -0
  208. package/lib/utils-D0GRDgAr.mjs +12315 -0
  209. package/lib/utils-D0Z1fyoO.mjs +12299 -0
  210. package/lib/utils-D2YknRk4.mjs +51 -0
  211. package/lib/utils-DppGHXQB.mjs +51 -0
  212. package/lib/utils-DzXZDfYc.mjs +51 -0
  213. package/lib/utils-W8WdSBpX.mjs +12315 -0
  214. package/lib/vision-guard-01qSwFpf.mjs +92 -0
  215. package/lib/vision-guard-BDD4OrKo.mjs +92 -0
  216. package/lib/vision-guard-DzZGaOga.mjs +92 -0
  217. package/lib/wafer-CgtPHerf.mjs +17 -0
  218. package/lib/wafer-DRU0EjZX.mjs +17 -0
  219. package/lib/wafer-cBtrn6q9.mjs +17 -0
  220. package/lib/xai-oauth-Buk8XVvM.mjs +446 -0
  221. package/lib/xai-oauth-CMal8l1O.mjs +446 -0
  222. package/lib/xai-oauth-DPHDXKD7.mjs +446 -0
  223. package/lib/xiaomi-CZgwvX2G.mjs +157 -0
  224. package/lib/xiaomi-D2qT5cAC.mjs +157 -0
  225. package/lib/xiaomi-Dd87KSg5.mjs +157 -0
  226. package/lib/zai-7DWMkEqM.mjs +203 -0
  227. package/lib/zai-C59YnomG.mjs +203 -0
  228. package/lib/zai-CFeOt-53.mjs +203 -0
  229. package/lib/zip-Cg9ANN_U.mjs +1316 -0
  230. package/lib/zip-D36ZKsP8.mjs +1316 -0
  231. package/lib/zip-D6QXpvaJ.mjs +1316 -0
  232. package/package.json +14 -10
  233. package/presets/package.json +1 -1
  234. package/presets/tool-plus-ptc/preset.yml +1 -1
  235. package/presets/tool-plus-standard/preset.yml +1 -1
@@ -0,0 +1,589 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { r as __exportAll } from "./fs-promises-shim-B-9cMxz5.mjs";
4
+ import { g as parseStreamingJson, i as readJsonl } from "./src-DTid0g4K.mjs";
5
+ import { G as fetchWithRetry, b as LLAMA_CPP_TOOL_CALL_PARSE_PATTERN, g as MissingApiKeyError, l as finalize, z as OllamaApiError } from "./error-B3bevhrs.mjs";
6
+ import { C as kStreamingPartialJson, I as sanitizeSchemaForOllama, a as normalizeSystemPrompts, h as clearStreamingPartialJson, k as toolWireSchema, m as transformMessages } from "./utils-2Wq2eATG.mjs";
7
+ import { Ct as withEmptyCompletionRetry, n as getEnvApiKey } from "./stream-C_RAoxJC.mjs";
8
+ import { i as partitionVisionContent, r as joinTextWithImagePlaceholder } from "./vision-guard-BDD4OrKo.mjs";
9
+ import { t as AssistantMessageEventStream } from "./event-stream-BDPi64mK.mjs";
10
+ import { n as getOpenAIStreamFirstEventTimeoutMs, r as getOpenAIStreamIdleTimeoutMs, t as armPreResponseTimeout } from "./idle-iterator-C6XbWcuB.mjs";
11
+ import { n as getStreamMarkupHealingPattern, t as StreamMarkupHealing } from "./stream-markup-healing-2toHXWXM.mjs";
12
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/ollama.ts
13
+ var ollama_exports = /* @__PURE__ */ __exportAll({ streamOllama: () => streamOllama });
14
+ function normalizeBaseUrl(baseUrl) {
15
+ const value = baseUrl?.trim();
16
+ if (!value) return "https://ollama.com";
17
+ const trimmed = value.endsWith("/") ? value.slice(0, -1) : value;
18
+ return trimmed.endsWith("/api") ? trimmed.slice(0, -4) : trimmed;
19
+ }
20
+ function mapReasoning(model, reasoning, disableReasoning) {
21
+ const modelReasoning = model.reasoning;
22
+ if (disableReasoning && modelReasoning) return false;
23
+ switch (model.provider === "ollama-cloud" && reasoning ? model.thinking?.effortMap?.[reasoning] ?? reasoning : reasoning) {
24
+ case "minimal":
25
+ case "low": return "low";
26
+ case "medium": return "medium";
27
+ case "high": return "high";
28
+ case "max": return "max";
29
+ case "xhigh": return "high";
30
+ default: return;
31
+ }
32
+ }
33
+ function mapToolChoice(toolChoice) {
34
+ if (!toolChoice || toolChoice === "auto") return;
35
+ if (toolChoice === "none") return "none";
36
+ if (toolChoice === "required" || toolChoice === "any") return "required";
37
+ if (typeof toolChoice === "object" && toolChoice.type === "computer") return void 0;
38
+ if (typeof toolChoice === "object") return "required";
39
+ }
40
+ function getNamedToolChoiceName(toolChoice) {
41
+ if (!toolChoice || typeof toolChoice === "string") return;
42
+ if (toolChoice.type === "computer") return void 0;
43
+ if ("function" in toolChoice) return toolChoice.function.name;
44
+ return toolChoice.name;
45
+ }
46
+ function selectToolsForToolChoice(tools, toolChoice) {
47
+ const toolName = getNamedToolChoiceName(toolChoice);
48
+ if (!toolName || !tools) return tools;
49
+ for (const tool of tools) if (tool.name === toolName) return [tool];
50
+ return [];
51
+ }
52
+ function toPlainContent(content, supportsImages) {
53
+ if (typeof content === "string") return { content };
54
+ const { textBlocks, imageBlocks, omittedImages } = partitionVisionContent(content, supportsImages);
55
+ const text = textBlocks.map((block) => block.text).join("\n");
56
+ return {
57
+ content: joinTextWithImagePlaceholder(text, omittedImages),
58
+ ...imageBlocks.length > 0 ? { images: imageBlocks.map((block) => block.data) } : {}
59
+ };
60
+ }
61
+ function convertMessage(message, supportsImages, developerRole = "user") {
62
+ if (message.role === "user") return {
63
+ role: "user",
64
+ ...toPlainContent(message.content, supportsImages)
65
+ };
66
+ if (message.role === "developer") return {
67
+ role: developerRole,
68
+ ...toPlainContent(message.content, supportsImages)
69
+ };
70
+ if (message.role === "toolResult") {
71
+ const converted = toPlainContent(message.content, supportsImages);
72
+ return {
73
+ role: "tool",
74
+ tool_name: message.toolName,
75
+ ...converted
76
+ };
77
+ }
78
+ const text = [];
79
+ const thinking = [];
80
+ const toolCalls = [];
81
+ for (const block of message.content) {
82
+ if (block.type === "text") {
83
+ text.push(block.text);
84
+ continue;
85
+ }
86
+ if (block.type === "thinking") {
87
+ thinking.push(block.thinking);
88
+ continue;
89
+ }
90
+ if (block.type === "toolCall") toolCalls.push({
91
+ type: "function",
92
+ function: {
93
+ name: block.name,
94
+ arguments: block.arguments
95
+ }
96
+ });
97
+ }
98
+ return {
99
+ role: "assistant",
100
+ content: text.join("\n"),
101
+ ...thinking.length > 0 ? { thinking: thinking.join("\n") } : {},
102
+ ...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}
103
+ };
104
+ }
105
+ function convertMessages(model, context) {
106
+ const systemPrompts = normalizeSystemPrompts(context.systemPrompt);
107
+ const messages = [...systemPrompts.map((systemPrompt) => ({
108
+ role: "developer",
109
+ content: systemPrompt,
110
+ timestamp: Date.now()
111
+ })), ...context.messages];
112
+ const isCloud = model.provider === "ollama-cloud";
113
+ const supportsImages = model.input.includes("image");
114
+ const converted = transformMessages(messages, model).map((msg, index) => {
115
+ const developerRole = msg.role === "developer" && (index < systemPrompts.length || msg.attribution !== "user") ? "system" : "user";
116
+ const converted = convertMessage(msg, supportsImages, developerRole);
117
+ if (isCloud && converted.role === "assistant" && converted.thinking) {
118
+ const { thinking: _t, ...rest } = converted;
119
+ return rest;
120
+ }
121
+ return converted;
122
+ });
123
+ if (!converted.some((m) => m.role === "user")) {
124
+ for (let i = converted.length - 1; i >= systemPrompts.length; i--) if (converted[i].role === "system") {
125
+ converted[i].role = "user";
126
+ break;
127
+ }
128
+ }
129
+ return converted;
130
+ }
131
+ function convertTools(tools) {
132
+ if (!tools || tools.length === 0) return;
133
+ return tools.map((tool) => ({
134
+ type: "function",
135
+ function: {
136
+ name: tool.name,
137
+ description: tool.description,
138
+ parameters: sanitizeSchemaForOllama(toolWireSchema(tool))
139
+ }
140
+ }));
141
+ }
142
+ /**
143
+ * Ollama Cloud rejects `num_predict` above this value with HTTP 400
144
+ * (`max_tokens (...) exceeds model's maximum output tokens (65536)`).
145
+ * The cap currently applies uniformly to cloud-served models; the cloud-side
146
+ * limit was confirmed empirically against `deepseek-v4-pro`/`-flash` and is
147
+ * the same cap surfaced for every other Ollama Cloud model we've probed.
148
+ *
149
+ * Acts as a wire-level safety net so stale `models.db` rows (or custom
150
+ * `modelOverrides` re-enabling `num_predict`) cannot 400 the request — even
151
+ * when `model.omitMaxOutputTokens` was never applied. See #3392.
152
+ */
153
+ const OLLAMA_CLOUD_NUM_PREDICT_CAP = 65536;
154
+ function resolveNumPredict(model, requested) {
155
+ if (model.provider === "ollama-cloud") return Math.min(requested, OLLAMA_CLOUD_NUM_PREDICT_CAP);
156
+ return requested;
157
+ }
158
+ function createChatBody(model, context, options) {
159
+ const think = mapReasoning(model, options?.reasoning, options?.disableReasoning);
160
+ const toolChoice = mapToolChoice(options?.toolChoice);
161
+ const tools = convertTools(selectToolsForToolChoice(context.tools, options?.toolChoice));
162
+ const runtimeOptions = {};
163
+ let hasRuntimeOptions = false;
164
+ if (options?.maxTokens !== void 0 && !model.omitMaxOutputTokens) {
165
+ runtimeOptions.num_predict = resolveNumPredict(model, options.maxTokens);
166
+ hasRuntimeOptions = true;
167
+ }
168
+ if (options?.temperature !== void 0) {
169
+ runtimeOptions.temperature = options.temperature;
170
+ hasRuntimeOptions = true;
171
+ }
172
+ if (options?.topP !== void 0) {
173
+ runtimeOptions.top_p = options.topP;
174
+ hasRuntimeOptions = true;
175
+ }
176
+ return {
177
+ model: model.id,
178
+ messages: convertMessages(model, context),
179
+ ...tools ? { tools } : {},
180
+ ...think !== void 0 ? { think } : {},
181
+ ...toolChoice !== void 0 ? { tool_choice: toolChoice } : {},
182
+ ...hasRuntimeOptions ? { options: runtimeOptions } : {},
183
+ stream: true
184
+ };
185
+ }
186
+ function shouldRetryOllamaResponse(response, bodyText) {
187
+ return response.status < 500 || !LLAMA_CPP_TOOL_CALL_PARSE_PATTERN.test(bodyText);
188
+ }
189
+ async function captureHttpErrorResponse(response) {
190
+ let bodyText;
191
+ let bodyJson;
192
+ try {
193
+ bodyText = await response.text();
194
+ if (bodyText.trim()) try {
195
+ bodyJson = JSON.parse(bodyText);
196
+ } catch {}
197
+ } catch {}
198
+ return {
199
+ status: response.status,
200
+ headers: response.headers,
201
+ bodyText,
202
+ bodyJson
203
+ };
204
+ }
205
+ function createEmptyOutput(model) {
206
+ return {
207
+ role: "assistant",
208
+ content: [],
209
+ api: "ollama-chat",
210
+ provider: model.provider,
211
+ model: model.id,
212
+ usage: {
213
+ input: 0,
214
+ output: 0,
215
+ cacheRead: 0,
216
+ cacheWrite: 0,
217
+ totalTokens: 0,
218
+ cost: {
219
+ input: 0,
220
+ output: 0,
221
+ cacheRead: 0,
222
+ cacheWrite: 0,
223
+ total: 0
224
+ }
225
+ },
226
+ stopReason: "stop",
227
+ timestamp: Date.now()
228
+ };
229
+ }
230
+ function endThinkingBlock(stream, output, index) {
231
+ const block = output.content[index];
232
+ if (block?.type === "thinking") stream.push({
233
+ type: "thinking_end",
234
+ contentIndex: index,
235
+ content: block.thinking,
236
+ partial: output
237
+ });
238
+ }
239
+ function endTextBlock(stream, output, index) {
240
+ const block = output.content[index];
241
+ if (block?.type === "text") stream.push({
242
+ type: "text_end",
243
+ contentIndex: index,
244
+ content: block.text,
245
+ partial: output
246
+ });
247
+ }
248
+ function endToolCallBlock(stream, output, index) {
249
+ const block = output.content[index];
250
+ if (block?.type !== "toolCall") return;
251
+ const toolCall = block;
252
+ if (toolCall[kStreamingPartialJson]) {
253
+ toolCall.arguments = parseStreamingJson(toolCall[kStreamingPartialJson]);
254
+ clearStreamingPartialJson(toolCall);
255
+ }
256
+ stream.push({
257
+ type: "toolcall_end",
258
+ contentIndex: index,
259
+ toolCall,
260
+ partial: output
261
+ });
262
+ }
263
+ function mapDoneReason(doneReason, output) {
264
+ if (doneReason === "length") return "length";
265
+ if (doneReason === "tool_calls") return "toolUse";
266
+ if (doneReason === "load") return "error";
267
+ if (doneReason === void 0 && output.content.some((block) => block.type === "toolCall")) return "toolUse";
268
+ return "stop";
269
+ }
270
+ const EMPTY_OLLAMA_LENGTH_COMPLETION_MESSAGE = "Model returned no content: prompt filled the context window; raise Ollama num_ctx or shorten the prompt.";
271
+ const EMPTY_OLLAMA_LOAD_COMPLETION_MESSAGE = "Ollama loaded the model but generated nothing (done_reason: load): the request contained no user-role message.";
272
+ function hasVisibleAssistantContent(output) {
273
+ return output.content.some((block) => {
274
+ if (block.type === "text") return block.text.trim().length > 0;
275
+ if (block.type === "thinking") return block.thinking.trim().length > 0;
276
+ return block.type === "toolCall";
277
+ });
278
+ }
279
+ const OLLAMA_RETRY_DELAYS_MS = [
280
+ 2e3,
281
+ 5e3,
282
+ 1e4
283
+ ];
284
+ const streamOllamaOnce = (model, context, options = {}) => {
285
+ const stream = new AssistantMessageEventStream();
286
+ (async () => {
287
+ const startTime = performance.now();
288
+ let firstTokenTime;
289
+ const output = createEmptyOutput(model);
290
+ let rawRequestDump;
291
+ let capturedErrorResponse;
292
+ let activeThinkingIndex;
293
+ let activeTextIndex;
294
+ const activeToolIndices = /* @__PURE__ */ new Set();
295
+ const streamMarkupHealingPattern = getStreamMarkupHealingPattern(model.provider, model.id);
296
+ const streamMarkupHealing = streamMarkupHealingPattern ? new StreamMarkupHealing({ pattern: streamMarkupHealingPattern }) : void 0;
297
+ let healedToolCallEmitted = false;
298
+ let suppressHealedThinking = false;
299
+ const endActiveTextBlock = () => {
300
+ if (activeTextIndex === void 0) return;
301
+ endTextBlock(stream, output, activeTextIndex);
302
+ activeTextIndex = void 0;
303
+ };
304
+ const endActiveThinkingBlock = () => {
305
+ if (activeThinkingIndex === void 0) return;
306
+ endThinkingBlock(stream, output, activeThinkingIndex);
307
+ activeThinkingIndex = void 0;
308
+ };
309
+ const appendVisibleText = (text) => {
310
+ if (text.length === 0) return;
311
+ endActiveThinkingBlock();
312
+ if (activeTextIndex === void 0) {
313
+ output.content.push({
314
+ type: "text",
315
+ text: ""
316
+ });
317
+ activeTextIndex = output.content.length - 1;
318
+ stream.push({
319
+ type: "text_start",
320
+ contentIndex: activeTextIndex,
321
+ partial: output
322
+ });
323
+ }
324
+ const block = output.content[activeTextIndex];
325
+ if (block?.type === "text") {
326
+ block.text += text;
327
+ stream.push({
328
+ type: "text_delta",
329
+ contentIndex: activeTextIndex,
330
+ delta: text,
331
+ partial: output
332
+ });
333
+ }
334
+ if (!firstTokenTime) firstTokenTime = performance.now();
335
+ };
336
+ const appendVisibleThinking = (thinking) => {
337
+ if (thinking.length === 0) return;
338
+ endActiveTextBlock();
339
+ if (activeThinkingIndex === void 0) {
340
+ output.content.push({
341
+ type: "thinking",
342
+ thinking: ""
343
+ });
344
+ activeThinkingIndex = output.content.length - 1;
345
+ stream.push({
346
+ type: "thinking_start",
347
+ contentIndex: activeThinkingIndex,
348
+ partial: output
349
+ });
350
+ }
351
+ const block = output.content[activeThinkingIndex];
352
+ if (block?.type === "thinking") {
353
+ block.thinking += thinking;
354
+ stream.push({
355
+ type: "thinking_delta",
356
+ contentIndex: activeThinkingIndex,
357
+ delta: thinking,
358
+ partial: output
359
+ });
360
+ }
361
+ if (!firstTokenTime) firstTokenTime = performance.now();
362
+ };
363
+ const emitHealedToolCall = (call) => {
364
+ endActiveThinkingBlock();
365
+ endActiveTextBlock();
366
+ const toolCall = {
367
+ type: "toolCall",
368
+ id: call.id,
369
+ name: call.name,
370
+ arguments: parseStreamingJson(call.arguments),
371
+ [kStreamingPartialJson]: call.arguments
372
+ };
373
+ output.content.push(toolCall);
374
+ const index = output.content.length - 1;
375
+ stream.push({
376
+ type: "toolcall_start",
377
+ contentIndex: index,
378
+ partial: output
379
+ });
380
+ stream.push({
381
+ type: "toolcall_delta",
382
+ contentIndex: index,
383
+ delta: call.arguments,
384
+ partial: output
385
+ });
386
+ endToolCallBlock(stream, output, index);
387
+ healedToolCallEmitted = true;
388
+ if (!firstTokenTime) firstTokenTime = performance.now();
389
+ };
390
+ const emitHealingEvent = (event) => {
391
+ if (event.type === "text") appendVisibleText(event.text);
392
+ else if (event.type === "thinking") {
393
+ if (!suppressHealedThinking) appendVisibleThinking(event.thinking);
394
+ } else emitHealedToolCall(event.call);
395
+ };
396
+ const drainHealedToolCalls = () => {
397
+ if (!streamMarkupHealing) return;
398
+ for (const call of streamMarkupHealing.drainCompleted()) emitHealedToolCall(call);
399
+ };
400
+ try {
401
+ const apiKey = options.apiKey || getEnvApiKey(model.provider);
402
+ if (!apiKey) throw new MissingApiKeyError(model.provider);
403
+ const baseUrl = normalizeBaseUrl(model.baseUrl);
404
+ let body = createChatBody(model, context, options);
405
+ const replacementPayload = await options.onPayload?.(body, model);
406
+ if (replacementPayload !== void 0) body = replacementPayload;
407
+ rawRequestDump = {
408
+ provider: model.provider,
409
+ api: model.api,
410
+ model: model.id,
411
+ method: "POST",
412
+ url: `${baseUrl}/api/chat`,
413
+ body
414
+ };
415
+ const idleTimeoutMs = options.streamIdleTimeoutMs ?? getOpenAIStreamIdleTimeoutMs();
416
+ const firstEventTimeoutMs = options.streamFirstEventTimeoutMs ?? getOpenAIStreamFirstEventTimeoutMs(idleTimeoutMs);
417
+ const watchdog = armPreResponseTimeout(options.signal, firstEventTimeoutMs);
418
+ let response;
419
+ try {
420
+ response = await fetchWithRetry(`${baseUrl}/api/chat`, {
421
+ method: "POST",
422
+ headers: {
423
+ ...model.headers,
424
+ ...options.headers,
425
+ Authorization: `Bearer ${apiKey}`,
426
+ "Content-Type": "application/json"
427
+ },
428
+ body: JSON.stringify(body),
429
+ signal: watchdog.signal,
430
+ defaultDelayMs: OLLAMA_RETRY_DELAYS_MS,
431
+ shouldRetryResponse: shouldRetryOllamaResponse,
432
+ fetch: options.fetch,
433
+ timeout: false
434
+ });
435
+ } finally {
436
+ watchdog.clear();
437
+ }
438
+ if (!response.ok) {
439
+ capturedErrorResponse = await captureHttpErrorResponse(response);
440
+ throw new OllamaApiError(`HTTP ${response.status} from ${baseUrl}/api/chat`, response.status, { headers: response.headers });
441
+ }
442
+ if (!response.body) throw new OllamaApiError("Ollama returned an empty response body", response.status, { headers: response.headers });
443
+ stream.push({
444
+ type: "start",
445
+ partial: output
446
+ });
447
+ for await (const chunk of readJsonl(response.body)) {
448
+ if (chunk.message?.thinking) {
449
+ suppressHealedThinking = true;
450
+ endActiveTextBlock();
451
+ if (activeThinkingIndex === void 0) {
452
+ output.content.push({
453
+ type: "thinking",
454
+ thinking: ""
455
+ });
456
+ activeThinkingIndex = output.content.length - 1;
457
+ stream.push({
458
+ type: "thinking_start",
459
+ contentIndex: activeThinkingIndex,
460
+ partial: output
461
+ });
462
+ }
463
+ const block = output.content[activeThinkingIndex];
464
+ if (block?.type === "thinking") {
465
+ block.thinking += chunk.message.thinking;
466
+ stream.push({
467
+ type: "thinking_delta",
468
+ contentIndex: activeThinkingIndex,
469
+ delta: chunk.message.thinking,
470
+ partial: output
471
+ });
472
+ }
473
+ if (!firstTokenTime) firstTokenTime = performance.now();
474
+ }
475
+ const chunkContent = chunk.message?.content;
476
+ const structuredCalls = chunk.message?.tool_calls?.length ? chunk.message.tool_calls : void 0;
477
+ if (chunkContent) {
478
+ if (streamMarkupHealing) {
479
+ const healingEvents = structuredCalls ? streamMarkupHealing.feedEventsWithoutCalls(chunkContent) : streamMarkupHealing.feedEvents(chunkContent);
480
+ for (const event of healingEvents) emitHealingEvent(event);
481
+ } else appendVisibleText(chunkContent);
482
+ }
483
+ if (structuredCalls) {
484
+ endActiveThinkingBlock();
485
+ endActiveTextBlock();
486
+ for (const call of structuredCalls) {
487
+ const name = call.function?.name ?? "unknown_tool";
488
+ const rawArgs = call.function?.arguments;
489
+ const partialJson = typeof rawArgs === "string" ? rawArgs : JSON.stringify(rawArgs ?? {});
490
+ const toolCall = {
491
+ type: "toolCall",
492
+ id: `ollama:${output.content.length}:${name}`,
493
+ name,
494
+ arguments: parseStreamingJson(partialJson),
495
+ [kStreamingPartialJson]: partialJson
496
+ };
497
+ output.content.push(toolCall);
498
+ const index = output.content.length - 1;
499
+ activeToolIndices.add(index);
500
+ stream.push({
501
+ type: "toolcall_start",
502
+ contentIndex: index,
503
+ partial: output
504
+ });
505
+ stream.push({
506
+ type: "toolcall_delta",
507
+ contentIndex: index,
508
+ delta: partialJson,
509
+ partial: output
510
+ });
511
+ if (!firstTokenTime) firstTokenTime = performance.now();
512
+ }
513
+ }
514
+ if (chunk.done) {
515
+ if (streamMarkupHealing) {
516
+ for (const event of streamMarkupHealing.flushEvents()) emitHealingEvent(event);
517
+ drainHealedToolCalls();
518
+ }
519
+ endActiveThinkingBlock();
520
+ endActiveTextBlock();
521
+ for (const index of activeToolIndices) endToolCallBlock(stream, output, index);
522
+ activeToolIndices.clear();
523
+ output.stopReason = mapDoneReason(chunk.done_reason, output);
524
+ if (healedToolCallEmitted && output.stopReason === "stop") output.stopReason = "toolUse";
525
+ output.usage.input = chunk.prompt_eval_count ?? 0;
526
+ output.usage.output = chunk.eval_count ?? 0;
527
+ output.usage.totalTokens = output.usage.input + output.usage.output;
528
+ }
529
+ }
530
+ if (streamMarkupHealing) {
531
+ for (const event of streamMarkupHealing.flushEvents()) emitHealingEvent(event);
532
+ drainHealedToolCalls();
533
+ if (healedToolCallEmitted && output.stopReason === "stop") output.stopReason = "toolUse";
534
+ }
535
+ endActiveThinkingBlock();
536
+ endActiveTextBlock();
537
+ if (output.stopReason === "length" && !hasVisibleAssistantContent(output)) {
538
+ output.stopReason = "error";
539
+ output.errorMessage = EMPTY_OLLAMA_LENGTH_COMPLETION_MESSAGE;
540
+ }
541
+ if (output.stopReason === "error" && !output.errorMessage) output.errorMessage = EMPTY_OLLAMA_LOAD_COMPLETION_MESSAGE;
542
+ if (output.stopReason === "stop" && output.content.some((block) => block.type === "toolCall")) output.stopReason = "toolUse";
543
+ output.duration = performance.now() - startTime;
544
+ if (firstTokenTime) output.ttft = firstTokenTime - startTime;
545
+ if (output.stopReason === "error") {
546
+ stream.push({
547
+ type: "error",
548
+ reason: "error",
549
+ error: output
550
+ });
551
+ stream.end();
552
+ return;
553
+ }
554
+ const doneReason = output.stopReason === "length" ? "length" : output.stopReason === "toolUse" ? "toolUse" : "stop";
555
+ stream.push({
556
+ type: "done",
557
+ reason: doneReason,
558
+ message: output
559
+ });
560
+ stream.end();
561
+ } catch (error) {
562
+ for (const block of output.content) if (block.type === "toolCall") clearStreamingPartialJson(block);
563
+ const result = await finalize(error, {
564
+ api: model.api,
565
+ provider: model.provider,
566
+ signal: options.signal,
567
+ rawRequestDump,
568
+ capturedErrorResponse
569
+ });
570
+ output.stopReason = result.stopReason;
571
+ output.errorStatus = result.status;
572
+ output.errorId = result.id;
573
+ output.errorMessage = result.message;
574
+ output.duration = performance.now() - startTime;
575
+ if (firstTokenTime) output.ttft = firstTokenTime - startTime;
576
+ stream.push({
577
+ type: "error",
578
+ reason: output.stopReason,
579
+ error: output
580
+ });
581
+ stream.end();
582
+ }
583
+ })();
584
+ return stream;
585
+ };
586
+ /** Retry EOS-only Ollama completions before the agent loop sees an empty stop. */
587
+ const streamOllama = (model, context, options) => withEmptyCompletionRetry(model, context, options, streamOllamaOnce);
588
+ //#endregion
589
+ export { ollama_exports as t };