@gguf/coder 0.2.9 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/.editorconfig +16 -0
  2. package/.env.example +63 -0
  3. package/.gitattributes +1 -0
  4. package/.semgrepignore +19 -0
  5. package/coder-dummy-file.ts +52 -0
  6. package/coder.config.example.json +59 -0
  7. package/coder.config.json +13 -0
  8. package/color_picker.html +36 -0
  9. package/dist/tools/execute-bash.js +3 -3
  10. package/dist/tools/execute-bash.js.map +1 -1
  11. package/dist/tools/fetch-url.js +3 -3
  12. package/dist/tools/fetch-url.js.map +1 -1
  13. package/dist/tools/find-files.d.ts.map +1 -1
  14. package/dist/tools/find-files.js +1 -1
  15. package/dist/tools/find-files.js.map +1 -1
  16. package/dist/tools/lsp-get-diagnostics.js +1 -1
  17. package/dist/tools/lsp-get-diagnostics.js.map +1 -1
  18. package/dist/tools/read-file.d.ts.map +1 -1
  19. package/dist/tools/read-file.js +6 -6
  20. package/dist/tools/read-file.js.map +1 -1
  21. package/dist/tools/search-file-contents.d.ts.map +1 -1
  22. package/dist/tools/search-file-contents.js +1 -1
  23. package/dist/tools/search-file-contents.js.map +1 -1
  24. package/dist/tools/string-replace.js +11 -11
  25. package/dist/tools/string-replace.js.map +1 -1
  26. package/dist/tools/web-search.d.ts.map +1 -1
  27. package/dist/tools/web-search.js +3 -3
  28. package/dist/tools/web-search.js.map +1 -1
  29. package/dist/tools/write-file.js +4 -4
  30. package/dist/tools/write-file.js.map +1 -1
  31. package/dist/utils/tool-result-display.d.ts.map +1 -1
  32. package/dist/utils/tool-result-display.js +3 -3
  33. package/dist/utils/tool-result-display.js.map +1 -1
  34. package/package.json +2 -14
  35. package/scripts/extract-changelog.js +73 -0
  36. package/scripts/fetch-models.js +143 -0
  37. package/scripts/test.sh +40 -0
  38. package/scripts/update-homebrew-formula.sh +125 -0
  39. package/scripts/update-nix-version.sh +157 -0
  40. package/source/ai-sdk-client/AISDKClient.spec.ts +117 -0
  41. package/source/ai-sdk-client/AISDKClient.ts +155 -0
  42. package/source/ai-sdk-client/chat/chat-handler.spec.ts +121 -0
  43. package/source/ai-sdk-client/chat/chat-handler.ts +276 -0
  44. package/source/ai-sdk-client/chat/streaming-handler.spec.ts +173 -0
  45. package/source/ai-sdk-client/chat/streaming-handler.ts +110 -0
  46. package/source/ai-sdk-client/chat/tool-processor.spec.ts +92 -0
  47. package/source/ai-sdk-client/chat/tool-processor.ts +70 -0
  48. package/source/ai-sdk-client/converters/message-converter.spec.ts +220 -0
  49. package/source/ai-sdk-client/converters/message-converter.ts +113 -0
  50. package/source/ai-sdk-client/converters/tool-converter.spec.ts +90 -0
  51. package/source/ai-sdk-client/converters/tool-converter.ts +46 -0
  52. package/source/ai-sdk-client/error-handling/error-extractor.spec.ts +55 -0
  53. package/source/ai-sdk-client/error-handling/error-extractor.ts +15 -0
  54. package/source/ai-sdk-client/error-handling/error-parser.spec.ts +169 -0
  55. package/source/ai-sdk-client/error-handling/error-parser.ts +161 -0
  56. package/source/ai-sdk-client/index.ts +7 -0
  57. package/source/ai-sdk-client/providers/provider-factory.spec.ts +71 -0
  58. package/source/ai-sdk-client/providers/provider-factory.ts +41 -0
  59. package/source/ai-sdk-client/types.ts +9 -0
  60. package/source/ai-sdk-client-empty-message.spec.ts +141 -0
  61. package/source/ai-sdk-client-error-handling.spec.ts +186 -0
  62. package/source/ai-sdk-client-maxretries.spec.ts +114 -0
  63. package/source/ai-sdk-client-preparestep.spec.ts +279 -0
  64. package/source/app/App.spec.tsx +32 -0
  65. package/source/app/App.tsx +480 -0
  66. package/source/app/components/AppContainer.spec.tsx +96 -0
  67. package/source/app/components/AppContainer.tsx +56 -0
  68. package/source/app/components/ChatInterface.spec.tsx +163 -0
  69. package/source/app/components/ChatInterface.tsx +144 -0
  70. package/source/app/components/ModalSelectors.spec.tsx +141 -0
  71. package/source/app/components/ModalSelectors.tsx +135 -0
  72. package/source/app/helpers.spec.ts +97 -0
  73. package/source/app/helpers.ts +63 -0
  74. package/source/app/index.ts +4 -0
  75. package/source/app/types.ts +39 -0
  76. package/source/app/utils/appUtils.ts +294 -0
  77. package/source/app/utils/conversationState.ts +310 -0
  78. package/source/app.spec.tsx +244 -0
  79. package/source/cli.spec.ts +73 -0
  80. package/source/cli.tsx +51 -0
  81. package/source/client-factory.spec.ts +48 -0
  82. package/source/client-factory.ts +178 -0
  83. package/source/command-parser.spec.ts +127 -0
  84. package/source/command-parser.ts +36 -0
  85. package/source/commands/checkpoint.spec.tsx +277 -0
  86. package/source/commands/checkpoint.tsx +366 -0
  87. package/source/commands/clear.tsx +22 -0
  88. package/source/commands/custom-commands.tsx +121 -0
  89. package/source/commands/exit.ts +21 -0
  90. package/source/commands/export.spec.tsx +131 -0
  91. package/source/commands/export.tsx +79 -0
  92. package/source/commands/help.tsx +120 -0
  93. package/source/commands/index.ts +17 -0
  94. package/source/commands/init.tsx +339 -0
  95. package/source/commands/lsp-command.spec.tsx +281 -0
  96. package/source/commands/lsp.tsx +120 -0
  97. package/source/commands/mcp-command.spec.tsx +313 -0
  98. package/source/commands/mcp.tsx +162 -0
  99. package/source/commands/model-database.spec.tsx +758 -0
  100. package/source/commands/model-database.tsx +418 -0
  101. package/source/commands/model.ts +12 -0
  102. package/source/commands/provider.ts +12 -0
  103. package/source/commands/setup-config.tsx +16 -0
  104. package/source/commands/simple-commands.spec.tsx +175 -0
  105. package/source/commands/status.ts +12 -0
  106. package/source/commands/theme.ts +12 -0
  107. package/source/commands/update.spec.tsx +261 -0
  108. package/source/commands/update.tsx +201 -0
  109. package/source/commands/usage.spec.tsx +495 -0
  110. package/source/commands/usage.tsx +100 -0
  111. package/source/commands.spec.ts +436 -0
  112. package/source/commands.ts +83 -0
  113. package/source/components/assistant-message.spec.tsx +796 -0
  114. package/source/components/assistant-message.tsx +34 -0
  115. package/source/components/bash-execution-indicator.tsx +21 -0
  116. package/source/components/cancelling-indicator.tsx +16 -0
  117. package/source/components/chat-queue.spec.tsx +83 -0
  118. package/source/components/chat-queue.tsx +36 -0
  119. package/source/components/checkpoint-display.spec.tsx +219 -0
  120. package/source/components/checkpoint-display.tsx +126 -0
  121. package/source/components/checkpoint-selector.spec.tsx +173 -0
  122. package/source/components/checkpoint-selector.tsx +173 -0
  123. package/source/components/development-mode-indicator.spec.tsx +268 -0
  124. package/source/components/development-mode-indicator.tsx +38 -0
  125. package/source/components/message-box.spec.tsx +427 -0
  126. package/source/components/message-box.tsx +87 -0
  127. package/source/components/model-selector.tsx +132 -0
  128. package/source/components/provider-selector.tsx +75 -0
  129. package/source/components/random-spinner.tsx +19 -0
  130. package/source/components/security-disclaimer.tsx +73 -0
  131. package/source/components/status-connection-display.spec.tsx +133 -0
  132. package/source/components/status.tsx +267 -0
  133. package/source/components/theme-selector.tsx +126 -0
  134. package/source/components/tool-confirmation.tsx +190 -0
  135. package/source/components/tool-execution-indicator.tsx +33 -0
  136. package/source/components/tool-message.tsx +85 -0
  137. package/source/components/ui/titled-box.spec.tsx +207 -0
  138. package/source/components/ui/titled-box.tsx +57 -0
  139. package/source/components/usage/progress-bar.spec.tsx +398 -0
  140. package/source/components/usage/progress-bar.tsx +30 -0
  141. package/source/components/usage/usage-display.spec.tsx +780 -0
  142. package/source/components/usage/usage-display.tsx +291 -0
  143. package/source/components/user-input.spec.tsx +327 -0
  144. package/source/components/user-input.tsx +533 -0
  145. package/source/components/user-message.spec.tsx +230 -0
  146. package/source/components/user-message.tsx +84 -0
  147. package/source/components/welcome-message.tsx +76 -0
  148. package/source/config/env-substitution.ts +65 -0
  149. package/source/config/index.spec.ts +171 -0
  150. package/source/config/index.ts +154 -0
  151. package/source/config/paths.spec.ts +241 -0
  152. package/source/config/paths.ts +55 -0
  153. package/source/config/preferences.ts +51 -0
  154. package/source/config/themes.ts +315 -0
  155. package/source/constants.ts +130 -0
  156. package/source/context/mode-context.spec.ts +79 -0
  157. package/source/context/mode-context.ts +24 -0
  158. package/source/custom-commands/executor.spec.ts +142 -0
  159. package/source/custom-commands/executor.ts +64 -0
  160. package/source/custom-commands/loader.spec.ts +314 -0
  161. package/source/custom-commands/loader.ts +153 -0
  162. package/source/custom-commands/parser.ts +196 -0
  163. package/source/hooks/chat-handler/conversation/conversation-loop.spec.ts +39 -0
  164. package/source/hooks/chat-handler/conversation/conversation-loop.tsx +511 -0
  165. package/source/hooks/chat-handler/conversation/tool-executor.spec.ts +50 -0
  166. package/source/hooks/chat-handler/conversation/tool-executor.tsx +109 -0
  167. package/source/hooks/chat-handler/index.ts +12 -0
  168. package/source/hooks/chat-handler/state/streaming-state.spec.ts +26 -0
  169. package/source/hooks/chat-handler/state/streaming-state.ts +19 -0
  170. package/source/hooks/chat-handler/types.ts +38 -0
  171. package/source/hooks/chat-handler/useChatHandler.spec.tsx +321 -0
  172. package/source/hooks/chat-handler/useChatHandler.tsx +194 -0
  173. package/source/hooks/chat-handler/utils/context-checker.spec.ts +60 -0
  174. package/source/hooks/chat-handler/utils/context-checker.tsx +73 -0
  175. package/source/hooks/chat-handler/utils/message-helpers.spec.ts +42 -0
  176. package/source/hooks/chat-handler/utils/message-helpers.tsx +36 -0
  177. package/source/hooks/chat-handler/utils/tool-filters.spec.ts +109 -0
  178. package/source/hooks/chat-handler/utils/tool-filters.ts +64 -0
  179. package/source/hooks/useAppHandlers.tsx +291 -0
  180. package/source/hooks/useAppInitialization.tsx +422 -0
  181. package/source/hooks/useAppState.tsx +311 -0
  182. package/source/hooks/useDirectoryTrust.tsx +98 -0
  183. package/source/hooks/useInputState.ts +414 -0
  184. package/source/hooks/useModeHandlers.tsx +302 -0
  185. package/source/hooks/useNonInteractiveMode.ts +140 -0
  186. package/source/hooks/useTerminalWidth.tsx +81 -0
  187. package/source/hooks/useTheme.ts +18 -0
  188. package/source/hooks/useToolHandler.tsx +349 -0
  189. package/source/hooks/useUIState.ts +61 -0
  190. package/source/init/agents-template-generator.ts +421 -0
  191. package/source/init/existing-rules-extractor.ts +319 -0
  192. package/source/init/file-scanner.spec.ts +227 -0
  193. package/source/init/file-scanner.ts +238 -0
  194. package/source/init/framework-detector.ts +382 -0
  195. package/source/init/language-detector.ts +269 -0
  196. package/source/init/project-analyzer.spec.ts +231 -0
  197. package/source/init/project-analyzer.ts +458 -0
  198. package/source/lsp/index.ts +31 -0
  199. package/source/lsp/lsp-client.spec.ts +508 -0
  200. package/source/lsp/lsp-client.ts +487 -0
  201. package/source/lsp/lsp-manager.spec.ts +477 -0
  202. package/source/lsp/lsp-manager.ts +419 -0
  203. package/source/lsp/protocol.spec.ts +502 -0
  204. package/source/lsp/protocol.ts +360 -0
  205. package/source/lsp/server-discovery.spec.ts +654 -0
  206. package/source/lsp/server-discovery.ts +515 -0
  207. package/source/markdown-parser/html-entities.spec.ts +88 -0
  208. package/source/markdown-parser/html-entities.ts +45 -0
  209. package/source/markdown-parser/index.spec.ts +281 -0
  210. package/source/markdown-parser/index.ts +126 -0
  211. package/source/markdown-parser/table-parser.spec.ts +133 -0
  212. package/source/markdown-parser/table-parser.ts +114 -0
  213. package/source/markdown-parser/utils.spec.ts +70 -0
  214. package/source/markdown-parser/utils.ts +13 -0
  215. package/source/mcp/mcp-client.spec.ts +81 -0
  216. package/source/mcp/mcp-client.ts +625 -0
  217. package/source/mcp/transport-factory.spec.ts +406 -0
  218. package/source/mcp/transport-factory.ts +312 -0
  219. package/source/message-handler.ts +67 -0
  220. package/source/model-database/database-engine.spec.ts +494 -0
  221. package/source/model-database/database-engine.ts +50 -0
  222. package/source/model-database/model-database.spec.ts +363 -0
  223. package/source/model-database/model-database.ts +91 -0
  224. package/source/model-database/model-engine.spec.ts +447 -0
  225. package/source/model-database/model-engine.ts +65 -0
  226. package/source/model-database/model-fetcher.spec.ts +583 -0
  227. package/source/model-database/model-fetcher.ts +330 -0
  228. package/source/models/index.ts +1 -0
  229. package/source/models/models-cache.spec.ts +214 -0
  230. package/source/models/models-cache.ts +78 -0
  231. package/source/models/models-dev-client.spec.ts +379 -0
  232. package/source/models/models-dev-client.ts +329 -0
  233. package/source/models/models-types.ts +68 -0
  234. package/source/prompt-history.ts +155 -0
  235. package/source/security/command-injection.spec.ts +240 -0
  236. package/source/services/checkpoint-manager.spec.ts +523 -0
  237. package/source/services/checkpoint-manager.ts +466 -0
  238. package/source/services/file-snapshot.spec.ts +569 -0
  239. package/source/services/file-snapshot.ts +220 -0
  240. package/source/test-utils/render-with-theme.tsx +48 -0
  241. package/source/tokenization/index.ts +1 -0
  242. package/source/tokenization/tokenizer-factory.spec.ts +170 -0
  243. package/source/tokenization/tokenizer-factory.ts +125 -0
  244. package/source/tokenization/tokenizers/anthropic-tokenizer.spec.ts +200 -0
  245. package/source/tokenization/tokenizers/anthropic-tokenizer.ts +43 -0
  246. package/source/tokenization/tokenizers/fallback-tokenizer.spec.ts +236 -0
  247. package/source/tokenization/tokenizers/fallback-tokenizer.ts +26 -0
  248. package/source/tokenization/tokenizers/llama-tokenizer.spec.ts +224 -0
  249. package/source/tokenization/tokenizers/llama-tokenizer.ts +41 -0
  250. package/source/tokenization/tokenizers/openai-tokenizer.spec.ts +184 -0
  251. package/source/tokenization/tokenizers/openai-tokenizer.ts +57 -0
  252. package/source/tool-calling/index.ts +5 -0
  253. package/source/tool-calling/json-parser.spec.ts +639 -0
  254. package/source/tool-calling/json-parser.ts +247 -0
  255. package/source/tool-calling/tool-parser.spec.ts +395 -0
  256. package/source/tool-calling/tool-parser.ts +120 -0
  257. package/source/tool-calling/xml-parser.spec.ts +662 -0
  258. package/source/tool-calling/xml-parser.ts +289 -0
  259. package/source/tools/execute-bash.spec.tsx +353 -0
  260. package/source/tools/execute-bash.tsx +219 -0
  261. package/source/tools/execute-function.spec.ts +130 -0
  262. package/source/tools/fetch-url.spec.tsx +342 -0
  263. package/source/tools/fetch-url.tsx +172 -0
  264. package/source/tools/find-files.spec.tsx +924 -0
  265. package/source/tools/find-files.tsx +293 -0
  266. package/source/tools/index.ts +102 -0
  267. package/source/tools/lsp-get-diagnostics.tsx +192 -0
  268. package/source/tools/needs-approval.spec.ts +282 -0
  269. package/source/tools/read-file.spec.tsx +801 -0
  270. package/source/tools/read-file.tsx +387 -0
  271. package/source/tools/search-file-contents.spec.tsx +1273 -0
  272. package/source/tools/search-file-contents.tsx +293 -0
  273. package/source/tools/string-replace.spec.tsx +730 -0
  274. package/source/tools/string-replace.tsx +548 -0
  275. package/source/tools/tool-manager.ts +210 -0
  276. package/source/tools/tool-registry.spec.ts +415 -0
  277. package/source/tools/tool-registry.ts +228 -0
  278. package/source/tools/web-search.tsx +223 -0
  279. package/source/tools/write-file.spec.tsx +559 -0
  280. package/source/tools/write-file.tsx +228 -0
  281. package/source/types/app.ts +37 -0
  282. package/source/types/checkpoint.ts +48 -0
  283. package/source/types/commands.ts +46 -0
  284. package/source/types/components.ts +27 -0
  285. package/source/types/config.ts +103 -0
  286. package/source/types/core-connection-status.spec.ts +67 -0
  287. package/source/types/core.ts +181 -0
  288. package/source/types/hooks.ts +50 -0
  289. package/source/types/index.ts +12 -0
  290. package/source/types/markdown-parser.ts +11 -0
  291. package/source/types/mcp.ts +52 -0
  292. package/source/types/system.ts +16 -0
  293. package/source/types/tokenization.ts +41 -0
  294. package/source/types/ui.ts +40 -0
  295. package/source/types/usage.ts +58 -0
  296. package/source/types/utils.ts +16 -0
  297. package/source/usage/calculator.spec.ts +385 -0
  298. package/source/usage/calculator.ts +104 -0
  299. package/source/usage/storage.spec.ts +703 -0
  300. package/source/usage/storage.ts +238 -0
  301. package/source/usage/tracker.spec.ts +456 -0
  302. package/source/usage/tracker.ts +102 -0
  303. package/source/utils/atomic-deletion.spec.ts +194 -0
  304. package/source/utils/atomic-deletion.ts +127 -0
  305. package/source/utils/bounded-map.spec.ts +300 -0
  306. package/source/utils/bounded-map.ts +193 -0
  307. package/source/utils/checkpoint-utils.spec.ts +222 -0
  308. package/source/utils/checkpoint-utils.ts +92 -0
  309. package/source/utils/error-formatter.spec.ts +169 -0
  310. package/source/utils/error-formatter.ts +194 -0
  311. package/source/utils/file-autocomplete.spec.ts +173 -0
  312. package/source/utils/file-autocomplete.ts +196 -0
  313. package/source/utils/file-cache.spec.ts +309 -0
  314. package/source/utils/file-cache.ts +195 -0
  315. package/source/utils/file-content-loader.spec.ts +180 -0
  316. package/source/utils/file-content-loader.ts +179 -0
  317. package/source/utils/file-mention-handler.spec.ts +261 -0
  318. package/source/utils/file-mention-handler.ts +84 -0
  319. package/source/utils/file-mention-parser.spec.ts +182 -0
  320. package/source/utils/file-mention-parser.ts +170 -0
  321. package/source/utils/fuzzy-matching.spec.ts +149 -0
  322. package/source/utils/fuzzy-matching.ts +146 -0
  323. package/source/utils/indentation-normalizer.spec.ts +216 -0
  324. package/source/utils/indentation-normalizer.ts +76 -0
  325. package/source/utils/installation-detector.spec.ts +178 -0
  326. package/source/utils/installation-detector.ts +153 -0
  327. package/source/utils/logging/config.spec.ts +311 -0
  328. package/source/utils/logging/config.ts +210 -0
  329. package/source/utils/logging/console-facade.spec.ts +184 -0
  330. package/source/utils/logging/console-facade.ts +384 -0
  331. package/source/utils/logging/correlation.spec.ts +679 -0
  332. package/source/utils/logging/correlation.ts +474 -0
  333. package/source/utils/logging/formatters.spec.ts +464 -0
  334. package/source/utils/logging/formatters.ts +207 -0
  335. package/source/utils/logging/health-monitor/alerts/alert-manager.spec.ts +93 -0
  336. package/source/utils/logging/health-monitor/alerts/alert-manager.ts +79 -0
  337. package/source/utils/logging/health-monitor/checks/configuration-check.spec.ts +56 -0
  338. package/source/utils/logging/health-monitor/checks/configuration-check.ts +43 -0
  339. package/source/utils/logging/health-monitor/checks/logging-check.spec.ts +56 -0
  340. package/source/utils/logging/health-monitor/checks/logging-check.ts +58 -0
  341. package/source/utils/logging/health-monitor/checks/memory-check.spec.ts +100 -0
  342. package/source/utils/logging/health-monitor/checks/memory-check.ts +78 -0
  343. package/source/utils/logging/health-monitor/checks/performance-check.spec.ts +56 -0
  344. package/source/utils/logging/health-monitor/checks/performance-check.ts +56 -0
  345. package/source/utils/logging/health-monitor/checks/request-check.spec.ts +56 -0
  346. package/source/utils/logging/health-monitor/checks/request-check.ts +76 -0
  347. package/source/utils/logging/health-monitor/core/health-check-runner.spec.ts +70 -0
  348. package/source/utils/logging/health-monitor/core/health-check-runner.ts +138 -0
  349. package/source/utils/logging/health-monitor/core/health-monitor.spec.ts +58 -0
  350. package/source/utils/logging/health-monitor/core/health-monitor.ts +344 -0
  351. package/source/utils/logging/health-monitor/core/scoring.spec.ts +65 -0
  352. package/source/utils/logging/health-monitor/core/scoring.ts +91 -0
  353. package/source/utils/logging/health-monitor/index.ts +15 -0
  354. package/source/utils/logging/health-monitor/instances.ts +48 -0
  355. package/source/utils/logging/health-monitor/middleware/http-middleware.spec.ts +141 -0
  356. package/source/utils/logging/health-monitor/middleware/http-middleware.ts +75 -0
  357. package/source/utils/logging/health-monitor/types.ts +126 -0
  358. package/source/utils/logging/index.spec.ts +284 -0
  359. package/source/utils/logging/index.ts +236 -0
  360. package/source/utils/logging/integration.spec.ts +441 -0
  361. package/source/utils/logging/log-method-factory.spec.ts +573 -0
  362. package/source/utils/logging/log-method-factory.ts +233 -0
  363. package/source/utils/logging/log-query/aggregation/aggregator.spec.ts +277 -0
  364. package/source/utils/logging/log-query/aggregation/aggregator.ts +159 -0
  365. package/source/utils/logging/log-query/aggregation/facet-generator.spec.ts +159 -0
  366. package/source/utils/logging/log-query/aggregation/facet-generator.ts +47 -0
  367. package/source/utils/logging/log-query/index.ts +23 -0
  368. package/source/utils/logging/log-query/query/filter-predicates.spec.ts +247 -0
  369. package/source/utils/logging/log-query/query/filter-predicates.ts +154 -0
  370. package/source/utils/logging/log-query/query/query-builder.spec.ts +182 -0
  371. package/source/utils/logging/log-query/query/query-builder.ts +151 -0
  372. package/source/utils/logging/log-query/query/query-engine.spec.ts +214 -0
  373. package/source/utils/logging/log-query/query/query-engine.ts +45 -0
  374. package/source/utils/logging/log-query/storage/circular-buffer.spec.ts +143 -0
  375. package/source/utils/logging/log-query/storage/circular-buffer.ts +75 -0
  376. package/source/utils/logging/log-query/storage/index-manager.spec.ts +150 -0
  377. package/source/utils/logging/log-query/storage/index-manager.ts +71 -0
  378. package/source/utils/logging/log-query/storage/log-storage.spec.ts +257 -0
  379. package/source/utils/logging/log-query/storage/log-storage.ts +80 -0
  380. package/source/utils/logging/log-query/types.ts +163 -0
  381. package/source/utils/logging/log-query/utils/helpers.spec.ts +263 -0
  382. package/source/utils/logging/log-query/utils/helpers.ts +72 -0
  383. package/source/utils/logging/log-query/utils/sorting.spec.ts +182 -0
  384. package/source/utils/logging/log-query/utils/sorting.ts +61 -0
  385. package/source/utils/logging/logger-provider.spec.ts +262 -0
  386. package/source/utils/logging/logger-provider.ts +362 -0
  387. package/source/utils/logging/performance.spec.ts +209 -0
  388. package/source/utils/logging/performance.ts +757 -0
  389. package/source/utils/logging/pino-logger.spec.ts +425 -0
  390. package/source/utils/logging/pino-logger.ts +514 -0
  391. package/source/utils/logging/redaction.spec.ts +490 -0
  392. package/source/utils/logging/redaction.ts +267 -0
  393. package/source/utils/logging/request-tracker.spec.ts +1198 -0
  394. package/source/utils/logging/request-tracker.ts +803 -0
  395. package/source/utils/logging/transports.spec.ts +505 -0
  396. package/source/utils/logging/transports.ts +305 -0
  397. package/source/utils/logging/types.ts +216 -0
  398. package/source/utils/message-builder.spec.ts +179 -0
  399. package/source/utils/message-builder.ts +101 -0
  400. package/source/utils/message-queue.tsx +486 -0
  401. package/source/utils/paste-detection.spec.ts +69 -0
  402. package/source/utils/paste-detection.ts +124 -0
  403. package/source/utils/paste-roundtrip.spec.ts +442 -0
  404. package/source/utils/paste-utils.spec.ts +128 -0
  405. package/source/utils/paste-utils.ts +52 -0
  406. package/source/utils/programming-language-helper.spec.ts +74 -0
  407. package/source/utils/programming-language-helper.ts +32 -0
  408. package/source/utils/prompt-assembly.spec.ts +221 -0
  409. package/source/utils/prompt-processor.ts +173 -0
  410. package/source/utils/tool-args-parser.spec.ts +136 -0
  411. package/source/utils/tool-args-parser.ts +54 -0
  412. package/source/utils/tool-cancellation.spec.ts +230 -0
  413. package/source/utils/tool-cancellation.ts +28 -0
  414. package/source/utils/tool-result-display.spec.tsx +469 -0
  415. package/source/utils/tool-result-display.tsx +90 -0
  416. package/source/utils/update-checker.spec.ts +383 -0
  417. package/source/utils/update-checker.ts +183 -0
  418. package/source/wizard/config-wizard.spec.tsx +103 -0
  419. package/source/wizard/config-wizard.tsx +382 -0
  420. package/source/wizard/steps/location-step.spec.tsx +186 -0
  421. package/source/wizard/steps/location-step.tsx +147 -0
  422. package/source/wizard/steps/mcp-step.spec.tsx +607 -0
  423. package/source/wizard/steps/mcp-step.tsx +632 -0
  424. package/source/wizard/steps/provider-step.spec.tsx +342 -0
  425. package/source/wizard/steps/provider-step.tsx +957 -0
  426. package/source/wizard/steps/summary-step.spec.tsx +749 -0
  427. package/source/wizard/steps/summary-step.tsx +228 -0
  428. package/source/wizard/templates/mcp-templates.spec.ts +613 -0
  429. package/source/wizard/templates/mcp-templates.ts +570 -0
  430. package/source/wizard/templates/provider-templates.spec.ts +152 -0
  431. package/source/wizard/templates/provider-templates.ts +485 -0
  432. package/source/wizard/utils/fetch-cloud-models.spec.ts +428 -0
  433. package/source/wizard/utils/fetch-cloud-models.ts +223 -0
  434. package/source/wizard/utils/fetch-local-models.spec.ts +297 -0
  435. package/source/wizard/utils/fetch-local-models.ts +192 -0
  436. package/source/wizard/validation-array.spec.ts +264 -0
  437. package/source/wizard/validation.spec.ts +373 -0
  438. package/source/wizard/validation.ts +232 -0
  439. package/source/app/prompts/main-prompt.md +0 -122
@@ -0,0 +1,662 @@
1
+ import test from 'ava';
2
+ import {XMLToolCallParser} from './xml-parser';
3
+
4
+ console.log(`\nxml-parser.spec.ts`);
5
+
6
+ // Basic parsing tests
7
+ test('parseToolCalls - parses simple tool call', t => {
8
+ const content = '<read_file><path>/test/file.txt</path></read_file>';
9
+ const result = XMLToolCallParser.parseToolCalls(content);
10
+
11
+ t.is(result.length, 1);
12
+ t.is(result[0].toolName, 'read_file');
13
+ t.deepEqual(result[0].parameters, {path: '/test/file.txt'});
14
+ });
15
+
16
+ test('parseToolCalls - parses multiple parameters', t => {
17
+ const content =
18
+ '<create_file><path>/test/new.txt</path><content>Hello World</content><mode>0644</mode></create_file>';
19
+ const result = XMLToolCallParser.parseToolCalls(content);
20
+
21
+ t.is(result.length, 1);
22
+ t.is(result[0].toolName, 'create_file');
23
+ t.deepEqual(result[0].parameters, {
24
+ path: '/test/new.txt',
25
+ content: 'Hello World',
26
+ mode: '0644',
27
+ });
28
+ });
29
+
30
+ test('parseToolCalls - parses multiple tool calls', t => {
31
+ const content = `<read_file><path>/test/file1.txt</path></read_file>
32
+ <read_file><path>/test/file2.txt</path></read_file>`;
33
+ const result = XMLToolCallParser.parseToolCalls(content);
34
+
35
+ t.is(result.length, 2);
36
+ t.is(result[0].toolName, 'read_file');
37
+ t.deepEqual(result[0].parameters, {path: '/test/file1.txt'});
38
+ t.is(result[1].toolName, 'read_file');
39
+ t.deepEqual(result[1].parameters, {path: '/test/file2.txt'});
40
+ });
41
+
42
+ test('parseToolCalls - handles empty parameters', t => {
43
+ const content = '<list_files></list_files>';
44
+ const result = XMLToolCallParser.parseToolCalls(content);
45
+
46
+ t.is(result.length, 1);
47
+ t.is(result[0].toolName, 'list_files');
48
+ t.deepEqual(result[0].parameters, {});
49
+ });
50
+
51
+ test('parseToolCalls - handles empty parameter values', t => {
52
+ const content = '<search><query></query><path>/test</path></search>';
53
+ const result = XMLToolCallParser.parseToolCalls(content);
54
+
55
+ t.is(result.length, 1);
56
+ t.is(result[0].toolName, 'search');
57
+ t.deepEqual(result[0].parameters, {query: '', path: '/test'});
58
+ });
59
+
60
+ // JSON parameter tests
61
+ test('parseToolCalls - parses JSON array parameters', t => {
62
+ const content =
63
+ '<batch_read><files>["file1.txt", "file2.txt", "file3.txt"]</files></batch_read>';
64
+ const result = XMLToolCallParser.parseToolCalls(content);
65
+
66
+ t.is(result.length, 1);
67
+ t.is(result[0].toolName, 'batch_read');
68
+ t.deepEqual(result[0].parameters, {
69
+ files: ['file1.txt', 'file2.txt', 'file3.txt'],
70
+ });
71
+ });
72
+
73
+ test('parseToolCalls - parses JSON object parameters', t => {
74
+ const content =
75
+ '<configure><options>{"timeout": 5000, "retries": 3}</options></configure>';
76
+ const result = XMLToolCallParser.parseToolCalls(content);
77
+
78
+ t.is(result.length, 1);
79
+ t.is(result[0].toolName, 'configure');
80
+ t.deepEqual(result[0].parameters, {
81
+ options: {timeout: 5000, retries: 3},
82
+ });
83
+ });
84
+
85
+ test('parseToolCalls - parses JSON boolean parameters', t => {
86
+ const content =
87
+ '<set_flag><enabled>true</enabled><verbose>false</verbose></set_flag>';
88
+ const result = XMLToolCallParser.parseToolCalls(content);
89
+
90
+ t.is(result.length, 1);
91
+ t.is(result[0].toolName, 'set_flag');
92
+ t.deepEqual(result[0].parameters, {enabled: true, verbose: false});
93
+ });
94
+
95
+ test('parseToolCalls - parses JSON number parameters', t => {
96
+ const content = '<calculate><x>42</x><y>3.14</y><z>-10</z></calculate>';
97
+ const result = XMLToolCallParser.parseToolCalls(content);
98
+
99
+ t.is(result.length, 1);
100
+ t.is(result[0].toolName, 'calculate');
101
+ t.deepEqual(result[0].parameters, {x: 42, y: 3.14, z: -10});
102
+ });
103
+
104
+ test('parseToolCalls - treats invalid JSON as string', t => {
105
+ const content = '<test><invalid>{not valid json}</invalid></test>';
106
+ const result = XMLToolCallParser.parseToolCalls(content);
107
+
108
+ t.is(result.length, 1);
109
+ t.is(result[0].toolName, 'test');
110
+ t.deepEqual(result[0].parameters, {invalid: '{not valid json}'});
111
+ });
112
+
113
+ // Markdown code block tests
114
+ test('parseToolCalls - extracts tool calls from markdown code blocks', t => {
115
+ const content =
116
+ '```xml\n<read_file><path>/test/file.txt</path></read_file>\n```';
117
+ const result = XMLToolCallParser.parseToolCalls(content);
118
+
119
+ t.is(result.length, 1);
120
+ t.is(result[0].toolName, 'read_file');
121
+ t.deepEqual(result[0].parameters, {path: '/test/file.txt'});
122
+ });
123
+
124
+ test('parseToolCalls - handles code blocks without language identifier', t => {
125
+ const content =
126
+ '```\n<read_file><path>/test/file.txt</path></read_file>\n```';
127
+ const result = XMLToolCallParser.parseToolCalls(content);
128
+
129
+ t.is(result.length, 1);
130
+ t.is(result[0].toolName, 'read_file');
131
+ t.deepEqual(result[0].parameters, {path: '/test/file.txt'});
132
+ });
133
+
134
+ test('parseToolCalls - handles code blocks with various languages', t => {
135
+ const content =
136
+ '```typescript\n<read_file><path>/test/file.txt</path></read_file>\n```';
137
+ const result = XMLToolCallParser.parseToolCalls(content);
138
+
139
+ t.is(result.length, 1);
140
+ t.is(result[0].toolName, 'read_file');
141
+ });
142
+
143
+ // tool_call wrapper tests
144
+ test('parseToolCalls - removes tool_call wrapper tags', t => {
145
+ const content =
146
+ '<tool_call><read_file><path>/test/file.txt</path></read_file></tool_call>';
147
+ const result = XMLToolCallParser.parseToolCalls(content);
148
+
149
+ t.is(result.length, 1);
150
+ t.is(result[0].toolName, 'read_file');
151
+ t.deepEqual(result[0].parameters, {path: '/test/file.txt'});
152
+ });
153
+
154
+ test('parseToolCalls - skips tool_call tags when found as top-level match', t => {
155
+ const content =
156
+ '<tool_call><read_file><path>/test/file.txt</path></read_file></tool_call>';
157
+ const result = XMLToolCallParser.parseToolCalls(content);
158
+
159
+ // Should parse read_file, not tool_call
160
+ t.is(result.length, 1);
161
+ t.is(result[0].toolName, 'read_file');
162
+ });
163
+
164
+ // Special characters and content tests
165
+ test('parseToolCalls - handles multiline content', t => {
166
+ const content = `<create_file>
167
+ <path>/test/file.txt</path>
168
+ <content>Line 1
169
+ Line 2
170
+ Line 3</content>
171
+ </create_file>`;
172
+ const result = XMLToolCallParser.parseToolCalls(content);
173
+
174
+ t.is(result.length, 1);
175
+ t.is(result[0].toolName, 'create_file');
176
+ t.is(result[0].parameters.path, '/test/file.txt');
177
+ t.is(result[0].parameters.content, 'Line 1\nLine 2\nLine 3');
178
+ });
179
+
180
+ test('parseToolCalls - handles special characters in content', t => {
181
+ const content =
182
+ '<execute_bash><command>echo "Hello & goodbye" | grep -v "test"</command></execute_bash>';
183
+ const result = XMLToolCallParser.parseToolCalls(content);
184
+
185
+ t.is(result.length, 1);
186
+ t.is(result[0].toolName, 'execute_bash');
187
+ t.deepEqual(result[0].parameters, {
188
+ command: 'echo "Hello & goodbye" | grep -v "test"',
189
+ });
190
+ });
191
+
192
+ test('parseToolCalls - handles XML-like content in parameters', t => {
193
+ const content =
194
+ '<create_file><content><div>HTML content</div></content></create_file>';
195
+ const result = XMLToolCallParser.parseToolCalls(content);
196
+
197
+ t.is(result.length, 1);
198
+ t.is(result[0].toolName, 'create_file');
199
+ // Should capture the innermost match first
200
+ t.truthy(result[0].parameters.content);
201
+ });
202
+
203
+ test('parseToolCalls - handles escaped characters', t => {
204
+ const content = '<test><value>&lt;tag&gt;</value></test>';
205
+ const result = XMLToolCallParser.parseToolCalls(content);
206
+
207
+ t.is(result.length, 1);
208
+ t.is(result[0].toolName, 'test');
209
+ t.deepEqual(result[0].parameters, {value: '&lt;tag&gt;'});
210
+ });
211
+
212
+ // Edge cases
213
+ test('parseToolCalls - returns empty array for no tool calls', t => {
214
+ const content = 'Just some regular text without any tool calls';
215
+ const result = XMLToolCallParser.parseToolCalls(content);
216
+
217
+ t.deepEqual(result, []);
218
+ });
219
+
220
+ test('parseToolCalls - handles empty string', t => {
221
+ const content = '';
222
+ const result = XMLToolCallParser.parseToolCalls(content);
223
+
224
+ t.deepEqual(result, []);
225
+ });
226
+
227
+ test('parseToolCalls - handles whitespace-only content', t => {
228
+ const content = ' \n\t\n ';
229
+ const result = XMLToolCallParser.parseToolCalls(content);
230
+
231
+ t.deepEqual(result, []);
232
+ });
233
+
234
+ test('parseToolCalls - handles unclosed tags gracefully', t => {
235
+ const content = '<read_file><path>/test/file.txt</path>';
236
+ const result = XMLToolCallParser.parseToolCalls(content);
237
+
238
+ // Should not match incomplete XML
239
+ t.deepEqual(result, []);
240
+ });
241
+
242
+ test('parseToolCalls - handles mismatched tags gracefully', t => {
243
+ const content = '<read_file><path>/test/file.txt</wrong_close></read_file>';
244
+ const result = XMLToolCallParser.parseToolCalls(content);
245
+
246
+ // Regex should still match the outer tags
247
+ t.is(result.length, 1);
248
+ t.is(result[0].toolName, 'read_file');
249
+ });
250
+
251
+ test('parseToolCalls - handles nested tool names', t => {
252
+ // Parameters can have same name as parent tool
253
+ const content = '<read_file><read_file>nested_value</read_file></read_file>';
254
+ const result = XMLToolCallParser.parseToolCalls(content);
255
+
256
+ // Should parse the outer read_file
257
+ t.truthy(result.length > 0);
258
+ });
259
+
260
+ test('parseToolCalls - handles tool names with underscores and numbers', t => {
261
+ const content = '<tool_name_123><param_1>value</param_1></tool_name_123>';
262
+ const result = XMLToolCallParser.parseToolCalls(content);
263
+
264
+ t.is(result.length, 1);
265
+ t.is(result[0].toolName, 'tool_name_123');
266
+ t.deepEqual(result[0].parameters, {param_1: 'value'});
267
+ });
268
+
269
+ test('parseToolCalls - handles case sensitivity', t => {
270
+ const content = '<ReadFile><Path>/test/file.txt</Path></ReadFile>';
271
+ const result = XMLToolCallParser.parseToolCalls(content);
272
+
273
+ t.is(result.length, 1);
274
+ t.is(result[0].toolName, 'ReadFile');
275
+ t.deepEqual(result[0].parameters, {Path: '/test/file.txt'});
276
+ });
277
+
278
+ // convertToToolCalls tests
279
+ test('convertToToolCalls - converts parsed calls to ToolCall format', t => {
280
+ const parsed = [
281
+ {toolName: 'read_file', parameters: {path: '/test/file.txt'}},
282
+ {toolName: 'create_file', parameters: {path: '/new.txt', content: 'test'}},
283
+ ];
284
+
285
+ const result = XMLToolCallParser.convertToToolCalls(parsed);
286
+
287
+ t.is(result.length, 2);
288
+ t.is(result[0].id, 'xml_call_0');
289
+ t.is(result[0].function.name, 'read_file');
290
+ t.deepEqual(result[0].function.arguments, {path: '/test/file.txt'});
291
+ t.is(result[1].id, 'xml_call_1');
292
+ t.is(result[1].function.name, 'create_file');
293
+ t.deepEqual(result[1].function.arguments, {
294
+ path: '/new.txt',
295
+ content: 'test',
296
+ });
297
+ });
298
+
299
+ test('convertToToolCalls - generates unique IDs', t => {
300
+ const parsed = [
301
+ {toolName: 'tool1', parameters: {}},
302
+ {toolName: 'tool2', parameters: {}},
303
+ {toolName: 'tool3', parameters: {}},
304
+ ];
305
+
306
+ const result = XMLToolCallParser.convertToToolCalls(parsed);
307
+
308
+ const ids = result.map(call => call.id);
309
+ const uniqueIds = new Set(ids);
310
+ t.is(ids.length, uniqueIds.size);
311
+ });
312
+
313
+ // removeToolCallsFromContent tests
314
+ test('removeToolCallsFromContent - removes tool calls from plain text', t => {
315
+ const content = `Here is some text
316
+ <read_file><path>/test/file.txt</path></read_file>
317
+ And some more text`;
318
+
319
+ const result = XMLToolCallParser.removeToolCallsFromContent(content);
320
+
321
+ t.is(result, 'Here is some text\n\nAnd some more text');
322
+ });
323
+
324
+ test('removeToolCallsFromContent - removes code blocks containing tool calls', t => {
325
+ const content = `Some text
326
+ \`\`\`xml
327
+ <read_file><path>/test/file.txt</path></read_file>
328
+ \`\`\`
329
+ More text`;
330
+
331
+ const result = XMLToolCallParser.removeToolCallsFromContent(content);
332
+
333
+ t.is(result, 'Some text\n\nMore text');
334
+ });
335
+
336
+ test('removeToolCallsFromContent - keeps code blocks without tool calls', t => {
337
+ const content = `Some text
338
+ \`\`\`javascript
339
+ const x = 42;
340
+ \`\`\`
341
+ More text`;
342
+
343
+ const result = XMLToolCallParser.removeToolCallsFromContent(content);
344
+
345
+ t.true(result.includes('const x = 42;'));
346
+ });
347
+
348
+ test('removeToolCallsFromContent - removes multiple tool calls', t => {
349
+ const content = `Text
350
+ <read_file><path>/file1.txt</path></read_file>
351
+ Middle text
352
+ <read_file><path>/file2.txt</path></read_file>
353
+ End text`;
354
+
355
+ const result = XMLToolCallParser.removeToolCallsFromContent(content);
356
+
357
+ t.false(result.includes('<read_file>'));
358
+ t.true(result.includes('Text'));
359
+ t.true(result.includes('Middle text'));
360
+ t.true(result.includes('End text'));
361
+ });
362
+
363
+ test('removeToolCallsFromContent - removes tool_call wrappers', t => {
364
+ const content = `Text
365
+ <tool_call><read_file><path>/test.txt</path></read_file></tool_call>
366
+ More text`;
367
+
368
+ const result = XMLToolCallParser.removeToolCallsFromContent(content);
369
+
370
+ t.false(result.includes('<tool_call>'));
371
+ t.false(result.includes('<read_file>'));
372
+ t.true(result.includes('Text'));
373
+ });
374
+
375
+ test('removeToolCallsFromContent - cleans up excessive whitespace', t => {
376
+ const content = `Line 1
377
+
378
+
379
+ <read_file><path>/test.txt</path></read_file>
380
+
381
+
382
+ Line 2`;
383
+
384
+ const result = XMLToolCallParser.removeToolCallsFromContent(content);
385
+
386
+ // Should reduce multiple newlines to double newlines
387
+ t.false(result.includes('\n\n\n'));
388
+ });
389
+
390
+ test('removeToolCallsFromContent - handles empty content', t => {
391
+ const content = '';
392
+ const result = XMLToolCallParser.removeToolCallsFromContent(content);
393
+
394
+ t.is(result, '');
395
+ });
396
+
397
+ test('removeToolCallsFromContent - handles content with only tool calls', t => {
398
+ const content = '<read_file><path>/test.txt</path></read_file>';
399
+ const result = XMLToolCallParser.removeToolCallsFromContent(content);
400
+
401
+ t.is(result, '');
402
+ });
403
+
404
+ // hasToolCalls tests
405
+ test('hasToolCalls - returns true for content with tool calls', t => {
406
+ const content = '<read_file><path>/test/file.txt</path></read_file>';
407
+ const result = XMLToolCallParser.hasToolCalls(content);
408
+
409
+ t.true(result);
410
+ });
411
+
412
+ test('hasToolCalls - returns true for tool calls in code blocks', t => {
413
+ const content =
414
+ '```\n<read_file><path>/test/file.txt</path></read_file>\n```';
415
+ const result = XMLToolCallParser.hasToolCalls(content);
416
+
417
+ t.true(result);
418
+ });
419
+
420
+ test('hasToolCalls - returns false for plain text', t => {
421
+ const content = 'Just some regular text';
422
+ const result = XMLToolCallParser.hasToolCalls(content);
423
+
424
+ t.false(result);
425
+ });
426
+
427
+ test('hasToolCalls - returns false for empty string', t => {
428
+ const content = '';
429
+ const result = XMLToolCallParser.hasToolCalls(content);
430
+
431
+ t.false(result);
432
+ });
433
+
434
+ test('hasToolCalls - returns false for incomplete XML', t => {
435
+ const content = '<read_file><path>/test';
436
+ const result = XMLToolCallParser.hasToolCalls(content);
437
+
438
+ t.false(result);
439
+ });
440
+
441
+ // detectMalformedToolCall tests
442
+ test('detectMalformedToolCall - detects [tool_use: name] syntax', t => {
443
+ const content = '[tool_use: read_file]';
444
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
445
+
446
+ t.truthy(result);
447
+ t.true(result!.error.includes('[tool_use: name]'));
448
+ t.true(result!.examples.includes('native tool calling'));
449
+ });
450
+
451
+ test('detectMalformedToolCall - detects [Tool: name] syntax', t => {
452
+ const content = '[Tool: read_file]';
453
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
454
+
455
+ t.truthy(result);
456
+ t.true(result!.error.includes('[tool_use: name]'));
457
+ t.true(result!.examples.includes('native tool calling'));
458
+ });
459
+
460
+ test('detectMalformedToolCall - detects [Tool: name] in context', t => {
461
+ const content =
462
+ 'Let me read the file for you.\n\n[Tool: read_file]\nThe file contains...';
463
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
464
+
465
+ t.truthy(result);
466
+ t.true(result!.error.includes('[tool_use: name]'));
467
+ });
468
+
469
+ test('detectMalformedToolCall - detects <function=name> syntax', t => {
470
+ const content = '<function=read_file><path>/test.txt</path></function>';
471
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
472
+
473
+ t.truthy(result);
474
+ t.true(result!.error.includes('<function=name>'));
475
+ t.true(result!.examples.includes('native tool calling'));
476
+ });
477
+
478
+ test('detectMalformedToolCall - detects <parameter=name> syntax', t => {
479
+ const content =
480
+ '<read_file><parameter=path>/test.txt</parameter></read_file>';
481
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
482
+
483
+ t.truthy(result);
484
+ t.true(result!.error.includes('<parameter=name>'));
485
+ });
486
+
487
+ test('detectMalformedToolCall - detects generic </parameter> closing tag', t => {
488
+ const content =
489
+ '<read_file><parameter=path>/test.txt</parameter></read_file>';
490
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
491
+
492
+ t.truthy(result);
493
+ t.truthy(result!.error);
494
+ });
495
+
496
+ test('detectMalformedToolCall - detects generic </function> closing tag', t => {
497
+ const content = '<function=read_file><path>/test.txt</path></function>';
498
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
499
+
500
+ t.truthy(result);
501
+ t.truthy(result!.error);
502
+ });
503
+
504
+ test('detectMalformedToolCall - returns null for valid XML', t => {
505
+ const content = '<read_file><path>/test.txt</path></read_file>';
506
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
507
+
508
+ t.is(result, null);
509
+ });
510
+
511
+ test('detectMalformedToolCall - returns null for plain text', t => {
512
+ const content = 'Just regular text';
513
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
514
+
515
+ t.is(result, null);
516
+ });
517
+
518
+ test('detectMalformedToolCall - includes helpful examples in error', t => {
519
+ const content = '<function=test><param>value</param></function>';
520
+ const result = XMLToolCallParser.detectMalformedToolCall(content);
521
+
522
+ t.truthy(result);
523
+ t.true(result!.examples.includes('native tool calling'));
524
+ t.true(result!.examples.includes('function calling interface'));
525
+ });
526
+
527
+ // Complex integration tests
528
+ test('full workflow - parse, convert, and extract multiple tool calls', t => {
529
+ const content = `Let me help you with that.
530
+
531
+ \`\`\`xml
532
+ <read_file><path>/src/app.ts</path></read_file>
533
+ <read_file><path>/src/config.ts</path></read_file>
534
+ \`\`\`
535
+
536
+ I'll read those files for you.`;
537
+
538
+ // Check detection
539
+ t.true(XMLToolCallParser.hasToolCalls(content));
540
+
541
+ // Parse
542
+ const parsed = XMLToolCallParser.parseToolCalls(content);
543
+ t.is(parsed.length, 2);
544
+
545
+ // Convert
546
+ const toolCalls = XMLToolCallParser.convertToToolCalls(parsed);
547
+ t.is(toolCalls.length, 2);
548
+ t.is(toolCalls[0].function.name, 'read_file');
549
+ t.is(toolCalls[1].function.name, 'read_file');
550
+
551
+ // Remove from content
552
+ const cleaned = XMLToolCallParser.removeToolCallsFromContent(content);
553
+ t.false(cleaned.includes('<read_file>'));
554
+ t.true(cleaned.includes('Let me help you'));
555
+ t.true(cleaned.includes("I'll read those files"));
556
+ });
557
+
558
+ test('full workflow - handles mixed content with malformed detection', t => {
559
+ const malformedContent = '<function=test><param>value</param></function>';
560
+
561
+ // Should detect malformation
562
+ const malformed = XMLToolCallParser.detectMalformedToolCall(malformedContent);
563
+ t.truthy(malformed);
564
+
565
+ // Should not parse as valid tool calls
566
+ const parsed = XMLToolCallParser.parseToolCalls(malformedContent);
567
+ t.is(parsed.length, 0);
568
+
569
+ // Should not be detected as having tool calls
570
+ t.false(XMLToolCallParser.hasToolCalls(malformedContent));
571
+ });
572
+
573
+ test('stress test - handles large number of tool calls', t => {
574
+ const toolCalls = Array.from(
575
+ {length: 100},
576
+ (_, i) => `<read_file><path>/file${i}.txt</path></read_file>`,
577
+ ).join('\n');
578
+
579
+ const parsed = XMLToolCallParser.parseToolCalls(toolCalls);
580
+ t.is(parsed.length, 100);
581
+
582
+ const converted = XMLToolCallParser.convertToToolCalls(parsed);
583
+ t.is(converted.length, 100);
584
+ });
585
+
586
+ test('stress test - handles deeply nested parameters', t => {
587
+ const content =
588
+ '<test><config>{"level1": {"level2": {"level3": {"value": 42}}}}</config></test>';
589
+ const parsed = XMLToolCallParser.parseToolCalls(content);
590
+
591
+ t.is(parsed.length, 1);
592
+ t.deepEqual(parsed[0].parameters.config, {
593
+ level1: {level2: {level3: {value: 42}}},
594
+ });
595
+ });
596
+
597
+ test('stress test - handles very long parameter values', t => {
598
+ const longValue = 'x'.repeat(10000);
599
+ const content = `<test><data>${longValue}</data></test>`;
600
+ const parsed = XMLToolCallParser.parseToolCalls(content);
601
+
602
+ t.is(parsed.length, 1);
603
+ t.is((parsed[0].parameters.data as string).length, 10000);
604
+ });
605
+
606
+ // HTML tag rejection tests
607
+ test('parseToolCalls - rejects HTML div tags', t => {
608
+ const content = '<div><p>Some HTML content</p></div>';
609
+ const result = XMLToolCallParser.parseToolCalls(content);
610
+
611
+ t.is(result.length, 0);
612
+ });
613
+
614
+ test('parseToolCalls - rejects HTML ul/li list tags', t => {
615
+ const content = '<ul><li>Item 1</li><li>Item 2</li></ul>';
616
+ const result = XMLToolCallParser.parseToolCalls(content);
617
+
618
+ t.is(result.length, 0);
619
+ });
620
+
621
+ test('parseToolCalls - rejects HTML table tags', t => {
622
+ const content = '<table><tr><td>Cell 1</td><td>Cell 2</td></tr></table>';
623
+ const result = XMLToolCallParser.parseToolCalls(content);
624
+
625
+ t.is(result.length, 0);
626
+ });
627
+
628
+ test('parseToolCalls - rejects HTML header tags', t => {
629
+ const content = '<h1>Title</h1><h2>Subtitle</h2>';
630
+ const result = XMLToolCallParser.parseToolCalls(content);
631
+
632
+ t.is(result.length, 0);
633
+ });
634
+
635
+ test('parseToolCalls - rejects HTML formatting tags', t => {
636
+ const content = '<strong>Bold</strong><em>Italic</em>';
637
+ const result = XMLToolCallParser.parseToolCalls(content);
638
+
639
+ t.is(result.length, 0);
640
+ });
641
+
642
+ test('parseToolCalls - rejects mixed HTML and valid tool calls correctly', t => {
643
+ const content = `<div>Some HTML</div>
644
+ <read_file><path>/test.txt</path></read_file>
645
+ <p>More HTML</p>`;
646
+ const result = XMLToolCallParser.parseToolCalls(content);
647
+
648
+ // Should only parse the valid tool call, not the HTML
649
+ t.is(result.length, 1);
650
+ t.is(result[0].toolName, 'read_file');
651
+ });
652
+
653
+ test('parseToolCalls - allows valid tool calls with HTML-like parameter content', t => {
654
+ const content =
655
+ '<create_file><path>/test.html</path><content><div>HTML content</div></content></create_file>';
656
+ const result = XMLToolCallParser.parseToolCalls(content);
657
+
658
+ // Should parse the tool call, with HTML as parameter value
659
+ t.is(result.length, 1);
660
+ t.is(result[0].toolName, 'create_file');
661
+ t.truthy(result[0].parameters.content);
662
+ });