@tyvm/knowhow 0.0.47 → 0.0.48

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 (459) hide show
  1. package/benchmarks/results/27b0a06/2025-09-27/xai/xai-grok-code-fast-1.json +2909 -0
  2. package/benchmarks/results/4057aed/2025-08-14/anthropic/anthropic-claude-sonnet-4-20250514.json +1671 -0
  3. package/jest.config.js +2 -2
  4. package/package.json +8 -3
  5. package/src/agents/base/base.ts +30 -24
  6. package/src/agents/patcher/patcher.ts +26 -5
  7. package/src/agents/tools/agentCall.ts +4 -2
  8. package/src/agents/tools/aiClient.ts +3 -11
  9. package/src/agents/tools/ast/astAppendNode.ts +90 -0
  10. package/src/agents/tools/ast/astDeleteNode.ts +88 -0
  11. package/src/agents/tools/ast/astEditNode.ts +95 -0
  12. package/src/agents/tools/ast/astGetPathForLine.ts +73 -0
  13. package/src/agents/tools/ast/astListPaths.ts +66 -0
  14. package/src/agents/tools/ast/index.ts +7 -0
  15. package/src/agents/tools/callPlugin.ts +8 -2
  16. package/src/agents/tools/embeddingSearch.ts +2 -1
  17. package/src/agents/tools/execCommand.ts +239 -94
  18. package/src/agents/tools/fileSearch.ts +15 -17
  19. package/src/agents/tools/index.ts +1 -0
  20. package/src/agents/tools/language/definitions.ts +10 -2
  21. package/src/agents/tools/language/index.ts +3 -2
  22. package/src/agents/tools/lintFile.ts +4 -2
  23. package/src/agents/tools/list.ts +203 -62
  24. package/src/agents/tools/patch.ts +48 -14
  25. package/src/agents/tools/readBlocks.ts +34 -0
  26. package/src/agents/tools/readFile.ts +23 -0
  27. package/src/agents/tools/stringReplace.ts +33 -9
  28. package/src/agents/tools/writeFile.ts +55 -0
  29. package/src/agents/tools/ycmd/server.ts +14 -4
  30. package/src/chat/CliChatService.ts +6 -1
  31. package/src/chat/modules/AgentModule.ts +107 -64
  32. package/src/chat/modules/AskModule.ts +0 -1
  33. package/src/chat/modules/SetupModule.ts +4 -4
  34. package/src/chat/modules/SystemModule.ts +28 -5
  35. package/src/chat/types.ts +2 -0
  36. package/src/chat-old.ts +2 -2
  37. package/src/clients/anthropic.ts +22 -1
  38. package/src/clients/openai.ts +1 -1
  39. package/src/clients/xai.ts +15 -5
  40. package/src/config.ts +17 -5
  41. package/src/dataset/diffs/generate.ts +2 -2
  42. package/src/dataset/diffs/jsonl.ts +0 -1
  43. package/src/embeddings.ts +6 -4
  44. package/src/index.ts +11 -5
  45. package/src/plugins/GitPlugin.ts +530 -0
  46. package/src/plugins/LinterPlugin.ts +89 -0
  47. package/src/plugins/PluginBase.ts +4 -2
  48. package/src/plugins/asana.ts +4 -2
  49. package/src/plugins/downloader/plugin.ts +5 -2
  50. package/src/plugins/embedding.ts +24 -4
  51. package/src/plugins/figma.ts +7 -3
  52. package/src/plugins/github.ts +4 -2
  53. package/src/plugins/jira.ts +4 -2
  54. package/src/plugins/language.ts +134 -27
  55. package/src/plugins/linear.ts +4 -2
  56. package/src/plugins/notion.ts +4 -2
  57. package/src/plugins/plugins.ts +27 -16
  58. package/src/plugins/tree-sitter/editor.ts +369 -0
  59. package/src/plugins/tree-sitter/lang-packs/index.ts +23 -0
  60. package/src/plugins/tree-sitter/lang-packs/java.ts +59 -0
  61. package/src/plugins/tree-sitter/lang-packs/javascript.ts +57 -0
  62. package/src/plugins/tree-sitter/lang-packs/python.ts +45 -0
  63. package/src/plugins/tree-sitter/lang-packs/types.ts +79 -0
  64. package/src/plugins/tree-sitter/lang-packs/typescript.ts +49 -0
  65. package/src/plugins/tree-sitter/parser.ts +444 -0
  66. package/src/plugins/tree-sitter/simple-paths.ts +467 -0
  67. package/src/plugins/types.ts +11 -0
  68. package/src/plugins/url.ts +5 -3
  69. package/src/plugins/vim.ts +8 -5
  70. package/src/processors/CustomVariables.ts +19 -7
  71. package/src/processors/TokenCompressor.ts +13 -13
  72. package/src/processors/ToolResponseCache.ts +15 -6
  73. package/src/services/EmbeddingService.ts +18 -9
  74. package/src/services/EventService.ts +80 -0
  75. package/src/services/Mcp.ts +5 -0
  76. package/src/services/S3.ts +4 -3
  77. package/src/services/Tools.ts +125 -53
  78. package/src/services/index.ts +16 -11
  79. package/src/services/types.ts +3 -3
  80. package/src/types.ts +7 -2
  81. package/src/worker.ts +14 -1
  82. package/test-comprehensive.ts +31 -0
  83. package/tests/clients/AIClient.test.ts +490 -0
  84. package/tests/manual/agent-events/run-test.ts +203 -0
  85. package/tests/{integration → manual/file-edits}/figma.test.ts +1 -1
  86. package/tests/{integration → manual/file-edits}/fileblocks/readwrite.test.ts +7 -3
  87. package/tests/{integration → manual/file-edits}/patching.test.ts +11 -8
  88. package/tests/plugins/language/languagePlugin-content-triggers.test.ts +332 -0
  89. package/tests/plugins/language/languagePlugin-integration.test.ts +456 -0
  90. package/tests/plugins/language/languagePlugin.test.ts +363 -0
  91. package/tests/processors/Base64ImageDetector.test.ts +403 -0
  92. package/tests/processors/CustomVariables.test.ts +430 -0
  93. package/tests/processors/HarmonyToolProcessor.test.ts +490 -0
  94. package/tests/processors/TokenCompressor.test.ts +391 -0
  95. package/tests/processors/ToolResponseCache.test.ts +688 -0
  96. package/tests/services/Tools.test.ts +1339 -0
  97. package/tests/test.spec.ts +162 -117
  98. package/tests/tree-sitter/editor.test.ts +113 -0
  99. package/tests/tree-sitter/invalid.test.ts +299 -0
  100. package/tests/tree-sitter/paths/common-edits.test.ts +564 -0
  101. package/tests/tree-sitter/paths/debug-exact-position.test.ts +44 -0
  102. package/tests/tree-sitter/paths/debug-line-indexing.test.ts +49 -0
  103. package/tests/tree-sitter/paths/debug-paths.test.ts +90 -0
  104. package/tests/tree-sitter/paths/paths.test.ts +170 -0
  105. package/tests/tree-sitter/paths/simple-paths.test.ts +367 -0
  106. package/tests/tree-sitter/sample-after.ts +48 -0
  107. package/tests/tree-sitter/sample-before.ts +25 -0
  108. package/tests/tree-sitter/test-files/completely-broken.ts +7 -0
  109. package/tests/tree-sitter/test-files/duplicate-braces.ts +39 -0
  110. package/tests/tree-sitter/test-files/invalid-nesting.ts +39 -0
  111. package/tests/tree-sitter/test-files/malformed-signature.ts +39 -0
  112. package/tests/tree-sitter/test-files/mismatched-parens.ts +39 -0
  113. package/tests/tree-sitter/test-files/missing-semicolon.ts +39 -0
  114. package/tests/tree-sitter/test-files/partially-broken.ts +20 -0
  115. package/tests/tree-sitter/test-files/specific-errors.ts +14 -0
  116. package/tests/tree-sitter/test-files/unclosed-string.ts +39 -0
  117. package/tests/tree-sitter/tree-sitter.test.ts +251 -0
  118. package/ts_build/package.json +8 -3
  119. package/ts_build/src/agents/base/base.d.ts +2 -2
  120. package/ts_build/src/agents/base/base.js +24 -20
  121. package/ts_build/src/agents/base/base.js.map +1 -1
  122. package/ts_build/src/agents/patcher/patcher.js +26 -5
  123. package/ts_build/src/agents/patcher/patcher.js.map +1 -1
  124. package/ts_build/src/agents/tools/agentCall.js +2 -1
  125. package/ts_build/src/agents/tools/agentCall.js.map +1 -1
  126. package/ts_build/src/agents/tools/aiClient.d.ts +7 -8
  127. package/ts_build/src/agents/tools/aiClient.js.map +1 -1
  128. package/ts_build/src/agents/tools/ast/astAppendNode.d.ts +1 -0
  129. package/ts_build/src/agents/tools/ast/astAppendNode.js +96 -0
  130. package/ts_build/src/agents/tools/ast/astAppendNode.js.map +1 -0
  131. package/ts_build/src/agents/tools/ast/astDeleteNode.d.ts +1 -0
  132. package/ts_build/src/agents/tools/ast/astDeleteNode.js +94 -0
  133. package/ts_build/src/agents/tools/ast/astDeleteNode.js.map +1 -0
  134. package/ts_build/src/agents/tools/ast/astEditNode.d.ts +1 -0
  135. package/ts_build/src/agents/tools/ast/astEditNode.js +96 -0
  136. package/ts_build/src/agents/tools/ast/astEditNode.js.map +1 -0
  137. package/ts_build/src/agents/tools/ast/astGetPathForLine.d.ts +1 -0
  138. package/ts_build/src/agents/tools/ast/astGetPathForLine.js +78 -0
  139. package/ts_build/src/agents/tools/ast/astGetPathForLine.js.map +1 -0
  140. package/ts_build/src/agents/tools/ast/astListPaths.d.ts +1 -0
  141. package/ts_build/src/agents/tools/ast/astListPaths.js +78 -0
  142. package/ts_build/src/agents/tools/ast/astListPaths.js.map +1 -0
  143. package/ts_build/src/agents/tools/ast/index.d.ts +5 -0
  144. package/ts_build/src/agents/tools/ast/index.js +14 -0
  145. package/ts_build/src/agents/tools/ast/index.js.map +1 -0
  146. package/ts_build/src/agents/tools/astAppendNode.d.ts +1 -0
  147. package/ts_build/src/agents/tools/astAppendNode.js +98 -0
  148. package/ts_build/src/agents/tools/astAppendNode.js.map +1 -0
  149. package/ts_build/src/agents/tools/astDeleteNode.d.ts +1 -0
  150. package/ts_build/src/agents/tools/astDeleteNode.js +95 -0
  151. package/ts_build/src/agents/tools/astDeleteNode.js.map +1 -0
  152. package/ts_build/src/agents/tools/astEditNode.d.ts +1 -0
  153. package/ts_build/src/agents/tools/astEditNode.js +98 -0
  154. package/ts_build/src/agents/tools/astEditNode.js.map +1 -0
  155. package/ts_build/src/agents/tools/astGetPathForLine.d.ts +1 -0
  156. package/ts_build/src/agents/tools/astGetPathForLine.js +89 -0
  157. package/ts_build/src/agents/tools/astGetPathForLine.js.map +1 -0
  158. package/ts_build/src/agents/tools/astListPaths.d.ts +1 -0
  159. package/ts_build/src/agents/tools/astListPaths.js +82 -0
  160. package/ts_build/src/agents/tools/astListPaths.js.map +1 -0
  161. package/ts_build/src/agents/tools/callPlugin.js +4 -2
  162. package/ts_build/src/agents/tools/callPlugin.js.map +1 -1
  163. package/ts_build/src/agents/tools/embeddingSearch.js +3 -2
  164. package/ts_build/src/agents/tools/embeddingSearch.js.map +1 -1
  165. package/ts_build/src/agents/tools/execCommand.d.ts +2 -2
  166. package/ts_build/src/agents/tools/execCommand.js +201 -67
  167. package/ts_build/src/agents/tools/execCommand.js.map +1 -1
  168. package/ts_build/src/agents/tools/fileSearch.d.ts +1 -1
  169. package/ts_build/src/agents/tools/fileSearch.js +11 -15
  170. package/ts_build/src/agents/tools/fileSearch.js.map +1 -1
  171. package/ts_build/src/agents/tools/github/index.d.ts +1 -1
  172. package/ts_build/src/agents/tools/index.d.ts +1 -0
  173. package/ts_build/src/agents/tools/index.js +1 -0
  174. package/ts_build/src/agents/tools/index.js.map +1 -1
  175. package/ts_build/src/agents/tools/language/definitions.js +11 -2
  176. package/ts_build/src/agents/tools/language/definitions.js.map +1 -1
  177. package/ts_build/src/agents/tools/language/index.js +4 -3
  178. package/ts_build/src/agents/tools/language/index.js.map +1 -1
  179. package/ts_build/src/agents/tools/lintFile.js +4 -2
  180. package/ts_build/src/agents/tools/lintFile.js.map +1 -1
  181. package/ts_build/src/agents/tools/list.js +185 -49
  182. package/ts_build/src/agents/tools/list.js.map +1 -1
  183. package/ts_build/src/agents/tools/patch.js +33 -10
  184. package/ts_build/src/agents/tools/patch.js.map +1 -1
  185. package/ts_build/src/agents/tools/readBlocks.js +23 -0
  186. package/ts_build/src/agents/tools/readBlocks.js.map +1 -1
  187. package/ts_build/src/agents/tools/readFile.js +14 -0
  188. package/ts_build/src/agents/tools/readFile.js.map +1 -1
  189. package/ts_build/src/agents/tools/stringReplace.js +19 -2
  190. package/ts_build/src/agents/tools/stringReplace.js.map +1 -1
  191. package/ts_build/src/agents/tools/writeFile.js +40 -0
  192. package/ts_build/src/agents/tools/writeFile.js.map +1 -1
  193. package/ts_build/src/agents/tools/ycmd/server.js +5 -0
  194. package/ts_build/src/agents/tools/ycmd/server.js.map +1 -1
  195. package/ts_build/src/chat/CliChatService.d.ts +1 -0
  196. package/ts_build/src/chat/CliChatService.js +6 -2
  197. package/ts_build/src/chat/CliChatService.js.map +1 -1
  198. package/ts_build/src/chat/modules/AgentModule.d.ts +5 -1
  199. package/ts_build/src/chat/modules/AgentModule.js +53 -31
  200. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  201. package/ts_build/src/chat/modules/AskModule.js.map +1 -1
  202. package/ts_build/src/chat/modules/SetupModule.js +4 -3
  203. package/ts_build/src/chat/modules/SetupModule.js.map +1 -1
  204. package/ts_build/src/chat/modules/SystemModule.js +19 -4
  205. package/ts_build/src/chat/modules/SystemModule.js.map +1 -1
  206. package/ts_build/src/chat/modules/index.d.ts +5 -0
  207. package/ts_build/src/chat/modules/index.js +14 -0
  208. package/ts_build/src/chat/modules/index.js.map +1 -0
  209. package/ts_build/src/chat/types.d.ts +2 -0
  210. package/ts_build/src/chat-old.js +3 -3
  211. package/ts_build/src/chat-old.js.map +1 -1
  212. package/ts_build/src/clients/anthropic.d.ts +1 -0
  213. package/ts_build/src/clients/anthropic.js +22 -1
  214. package/ts_build/src/clients/anthropic.js.map +1 -1
  215. package/ts_build/src/clients/openai.js +1 -1
  216. package/ts_build/src/clients/openai.js.map +1 -1
  217. package/ts_build/src/clients/xai.d.ts +7 -0
  218. package/ts_build/src/clients/xai.js +13 -4
  219. package/ts_build/src/clients/xai.js.map +1 -1
  220. package/ts_build/src/config.js +14 -3
  221. package/ts_build/src/config.js.map +1 -1
  222. package/ts_build/src/dataset/diffs/generate.js +2 -2
  223. package/ts_build/src/dataset/diffs/generate.js.map +1 -1
  224. package/ts_build/src/dataset/diffs/jsonl.js.map +1 -1
  225. package/ts_build/src/embeddings.js +7 -9
  226. package/ts_build/src/embeddings.js.map +1 -1
  227. package/ts_build/src/index.js +10 -10
  228. package/ts_build/src/index.js.map +1 -1
  229. package/ts_build/src/plugins/GitPlugin.d.ts +39 -0
  230. package/ts_build/src/plugins/GitPlugin.js +439 -0
  231. package/ts_build/src/plugins/GitPlugin.js.map +1 -0
  232. package/ts_build/src/plugins/LinterPlugin.d.ts +15 -0
  233. package/ts_build/src/plugins/LinterPlugin.js +65 -0
  234. package/ts_build/src/plugins/LinterPlugin.js.map +1 -0
  235. package/ts_build/src/plugins/PluginBase.d.ts +4 -3
  236. package/ts_build/src/plugins/PluginBase.js +3 -3
  237. package/ts_build/src/plugins/PluginBase.js.map +1 -1
  238. package/ts_build/src/plugins/asana.d.ts +3 -1
  239. package/ts_build/src/plugins/asana.js +3 -2
  240. package/ts_build/src/plugins/asana.js.map +1 -1
  241. package/ts_build/src/plugins/downloader/plugin.d.ts +3 -1
  242. package/ts_build/src/plugins/downloader/plugin.js +3 -2
  243. package/ts_build/src/plugins/downloader/plugin.js.map +1 -1
  244. package/ts_build/src/plugins/embedding.d.ts +5 -1
  245. package/ts_build/src/plugins/embedding.js +15 -3
  246. package/ts_build/src/plugins/embedding.js.map +1 -1
  247. package/ts_build/src/plugins/figma.d.ts +3 -1
  248. package/ts_build/src/plugins/figma.js +28 -4
  249. package/ts_build/src/plugins/figma.js.map +1 -1
  250. package/ts_build/src/plugins/github.d.ts +3 -1
  251. package/ts_build/src/plugins/github.js +3 -2
  252. package/ts_build/src/plugins/github.js.map +1 -1
  253. package/ts_build/src/plugins/jira.d.ts +3 -1
  254. package/ts_build/src/plugins/jira.js +3 -2
  255. package/ts_build/src/plugins/jira.js.map +1 -1
  256. package/ts_build/src/plugins/language.d.ts +7 -4
  257. package/ts_build/src/plugins/language.js +85 -20
  258. package/ts_build/src/plugins/language.js.map +1 -1
  259. package/ts_build/src/plugins/linear.d.ts +3 -1
  260. package/ts_build/src/plugins/linear.js +3 -2
  261. package/ts_build/src/plugins/linear.js.map +1 -1
  262. package/ts_build/src/plugins/notion.d.ts +3 -1
  263. package/ts_build/src/plugins/notion.js +3 -2
  264. package/ts_build/src/plugins/notion.js.map +1 -1
  265. package/ts_build/src/plugins/plugins.d.ts +4 -3
  266. package/ts_build/src/plugins/plugins.js +24 -14
  267. package/ts_build/src/plugins/plugins.js.map +1 -1
  268. package/ts_build/src/plugins/tree-sitter/editor.d.ts +34 -0
  269. package/ts_build/src/plugins/tree-sitter/editor.js +218 -0
  270. package/ts_build/src/plugins/tree-sitter/editor.js.map +1 -0
  271. package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.d.ts +29 -0
  272. package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.js +538 -0
  273. package/ts_build/src/plugins/tree-sitter/human-readable-paths-new.js.map +1 -0
  274. package/ts_build/src/plugins/tree-sitter/human-readable-paths.d.ts +22 -0
  275. package/ts_build/src/plugins/tree-sitter/human-readable-paths.js +332 -0
  276. package/ts_build/src/plugins/tree-sitter/human-readable-paths.js.map +1 -0
  277. package/ts_build/src/plugins/tree-sitter/lang-packs/index.d.ts +8 -0
  278. package/ts_build/src/plugins/tree-sitter/lang-packs/index.js +26 -0
  279. package/ts_build/src/plugins/tree-sitter/lang-packs/index.js.map +1 -0
  280. package/ts_build/src/plugins/tree-sitter/lang-packs/java.d.ts +2 -0
  281. package/ts_build/src/plugins/tree-sitter/lang-packs/java.js +61 -0
  282. package/ts_build/src/plugins/tree-sitter/lang-packs/java.js.map +1 -0
  283. package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.d.ts +2 -0
  284. package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.js +59 -0
  285. package/ts_build/src/plugins/tree-sitter/lang-packs/javascript.js.map +1 -0
  286. package/ts_build/src/plugins/tree-sitter/lang-packs/python.d.ts +2 -0
  287. package/ts_build/src/plugins/tree-sitter/lang-packs/python.js +47 -0
  288. package/ts_build/src/plugins/tree-sitter/lang-packs/python.js.map +1 -0
  289. package/ts_build/src/plugins/tree-sitter/lang-packs/types.d.ts +43 -0
  290. package/ts_build/src/plugins/tree-sitter/lang-packs/types.js +3 -0
  291. package/ts_build/src/plugins/tree-sitter/lang-packs/types.js.map +1 -0
  292. package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.d.ts +2 -0
  293. package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.js +50 -0
  294. package/ts_build/src/plugins/tree-sitter/lang-packs/typescript.js.map +1 -0
  295. package/ts_build/src/plugins/tree-sitter/parser.d.ts +75 -0
  296. package/ts_build/src/plugins/tree-sitter/parser.js +306 -0
  297. package/ts_build/src/plugins/tree-sitter/parser.js.map +1 -0
  298. package/ts_build/src/plugins/tree-sitter/simple-paths.d.ts +22 -0
  299. package/ts_build/src/plugins/tree-sitter/simple-paths.js +332 -0
  300. package/ts_build/src/plugins/tree-sitter/simple-paths.js.map +1 -0
  301. package/ts_build/src/plugins/types.d.ts +10 -0
  302. package/ts_build/src/plugins/url.d.ts +3 -2
  303. package/ts_build/src/plugins/url.js +3 -2
  304. package/ts_build/src/plugins/url.js.map +1 -1
  305. package/ts_build/src/plugins/vim.d.ts +4 -2
  306. package/ts_build/src/plugins/vim.js +6 -8
  307. package/ts_build/src/plugins/vim.js.map +1 -1
  308. package/ts_build/src/processors/CustomVariables.js +12 -3
  309. package/ts_build/src/processors/CustomVariables.js.map +1 -1
  310. package/ts_build/src/processors/TokenCompressor.js +8 -11
  311. package/ts_build/src/processors/TokenCompressor.js.map +1 -1
  312. package/ts_build/src/processors/ToolResponseCache.d.ts +2 -2
  313. package/ts_build/src/processors/ToolResponseCache.js +12 -2
  314. package/ts_build/src/processors/ToolResponseCache.js.map +1 -1
  315. package/ts_build/src/services/EmbeddingService.d.ts +10 -1
  316. package/ts_build/src/services/EmbeddingService.js +12 -12
  317. package/ts_build/src/services/EmbeddingService.js.map +1 -1
  318. package/ts_build/src/services/EventService.d.ts +7 -0
  319. package/ts_build/src/services/EventService.js +49 -0
  320. package/ts_build/src/services/EventService.js.map +1 -1
  321. package/ts_build/src/services/Mcp.js +8 -0
  322. package/ts_build/src/services/Mcp.js.map +1 -1
  323. package/ts_build/src/services/S3.js +4 -3
  324. package/ts_build/src/services/S3.js.map +1 -1
  325. package/ts_build/src/services/Tools.d.ts +1 -0
  326. package/ts_build/src/services/Tools.js +97 -35
  327. package/ts_build/src/services/Tools.js.map +1 -1
  328. package/ts_build/src/services/index.d.ts +4 -5
  329. package/ts_build/src/services/index.js +14 -9
  330. package/ts_build/src/services/index.js.map +1 -1
  331. package/ts_build/src/services/types.js +3 -3
  332. package/ts_build/src/services/types.js.map +1 -1
  333. package/ts_build/src/types.d.ts +7 -1
  334. package/ts_build/src/types.js +4 -0
  335. package/ts_build/src/types.js.map +1 -1
  336. package/ts_build/src/worker.js +12 -1
  337. package/ts_build/src/worker.js.map +1 -1
  338. package/ts_build/tests/clients/AIClient.test.d.ts +1 -0
  339. package/ts_build/tests/clients/AIClient.test.js +377 -0
  340. package/ts_build/tests/clients/AIClient.test.js.map +1 -0
  341. package/ts_build/tests/languagePlugin.test.js +217 -11
  342. package/ts_build/tests/languagePlugin.test.js.map +1 -1
  343. package/ts_build/tests/manual/agent-events/event-handler-reliability.test.d.ts +1 -0
  344. package/ts_build/tests/manual/agent-events/event-handler-reliability.test.js +315 -0
  345. package/ts_build/tests/manual/agent-events/event-handler-reliability.test.js.map +1 -0
  346. package/ts_build/tests/manual/agent-events/run-test.d.ts +2 -0
  347. package/ts_build/tests/manual/agent-events/run-test.js +148 -0
  348. package/ts_build/tests/manual/agent-events/run-test.js.map +1 -0
  349. package/ts_build/tests/manual/file-edits/figma.test.d.ts +1 -0
  350. package/ts_build/tests/manual/file-edits/figma.test.js +47 -0
  351. package/ts_build/tests/manual/file-edits/figma.test.js.map +1 -0
  352. package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.d.ts +1 -0
  353. package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.js +100 -0
  354. package/ts_build/tests/manual/file-edits/fileblocks/readwrite.test.js.map +1 -0
  355. package/ts_build/tests/manual/file-edits/patching.test.d.ts +1 -0
  356. package/ts_build/tests/manual/file-edits/patching.test.js +119 -0
  357. package/ts_build/tests/manual/file-edits/patching.test.js.map +1 -0
  358. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.d.ts +1 -0
  359. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +277 -0
  360. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js.map +1 -0
  361. package/ts_build/tests/plugins/language/languagePlugin-integration.test.d.ts +1 -0
  362. package/ts_build/tests/plugins/language/languagePlugin-integration.test.js +331 -0
  363. package/ts_build/tests/plugins/language/languagePlugin-integration.test.js.map +1 -0
  364. package/ts_build/tests/plugins/language/languagePlugin.test.d.ts +1 -0
  365. package/ts_build/tests/plugins/language/languagePlugin.test.js +286 -0
  366. package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -0
  367. package/ts_build/tests/processors/Base64ImageDetector.test.d.ts +1 -0
  368. package/ts_build/tests/processors/Base64ImageDetector.test.js +351 -0
  369. package/ts_build/tests/processors/Base64ImageDetector.test.js.map +1 -0
  370. package/ts_build/tests/processors/CustomVariables.test.d.ts +1 -0
  371. package/ts_build/tests/processors/CustomVariables.test.js +351 -0
  372. package/ts_build/tests/processors/CustomVariables.test.js.map +1 -0
  373. package/ts_build/tests/processors/HarmonyToolProcessor.test.d.ts +1 -0
  374. package/ts_build/tests/processors/HarmonyToolProcessor.test.js +382 -0
  375. package/ts_build/tests/processors/HarmonyToolProcessor.test.js.map +1 -0
  376. package/ts_build/tests/processors/TokenCompressor.test.d.ts +1 -0
  377. package/ts_build/tests/processors/TokenCompressor.test.js +300 -0
  378. package/ts_build/tests/processors/TokenCompressor.test.js.map +1 -0
  379. package/ts_build/tests/processors/ToolResponseCache.test.d.ts +1 -0
  380. package/ts_build/tests/processors/ToolResponseCache.test.js +539 -0
  381. package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -0
  382. package/ts_build/tests/services/Plugins/plugin-event-integration.test.d.ts +1 -0
  383. package/ts_build/tests/services/Plugins/plugin-event-integration.test.js +232 -0
  384. package/ts_build/tests/services/Plugins/plugin-event-integration.test.js.map +1 -0
  385. package/ts_build/tests/services/Tools.test.d.ts +1 -0
  386. package/ts_build/tests/services/Tools.test.js +1059 -0
  387. package/ts_build/tests/services/Tools.test.js.map +1 -0
  388. package/ts_build/tests/test.spec.js +110 -68
  389. package/ts_build/tests/test.spec.js.map +1 -1
  390. package/ts_build/tests/tree-sitter/editor.test.d.ts +1 -0
  391. package/ts_build/tests/tree-sitter/editor.test.js +85 -0
  392. package/ts_build/tests/tree-sitter/editor.test.js.map +1 -0
  393. package/ts_build/tests/tree-sitter/invalid.test.d.ts +1 -0
  394. package/ts_build/tests/tree-sitter/invalid.test.js +198 -0
  395. package/ts_build/tests/tree-sitter/invalid.test.js.map +1 -0
  396. package/ts_build/tests/tree-sitter/paths/common-edits.test.d.ts +1 -0
  397. package/ts_build/tests/tree-sitter/paths/common-edits.test.js +347 -0
  398. package/ts_build/tests/tree-sitter/paths/common-edits.test.js.map +1 -0
  399. package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.d.ts +1 -0
  400. package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.js +35 -0
  401. package/ts_build/tests/tree-sitter/paths/debug-exact-position.test.js.map +1 -0
  402. package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.d.ts +1 -0
  403. package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.js +38 -0
  404. package/ts_build/tests/tree-sitter/paths/debug-line-indexing.test.js.map +1 -0
  405. package/ts_build/tests/tree-sitter/paths/debug-paths.test.d.ts +1 -0
  406. package/ts_build/tests/tree-sitter/paths/debug-paths.test.js +74 -0
  407. package/ts_build/tests/tree-sitter/paths/debug-paths.test.js.map +1 -0
  408. package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.d.ts +1 -0
  409. package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.js +302 -0
  410. package/ts_build/tests/tree-sitter/paths/human-readable-paths.test.js.map +1 -0
  411. package/ts_build/tests/tree-sitter/paths/paths.test.d.ts +1 -0
  412. package/ts_build/tests/tree-sitter/paths/paths.test.js +116 -0
  413. package/ts_build/tests/tree-sitter/paths/paths.test.js.map +1 -0
  414. package/ts_build/tests/tree-sitter/paths/simple-paths.test.d.ts +1 -0
  415. package/ts_build/tests/tree-sitter/paths/simple-paths.test.js +302 -0
  416. package/ts_build/tests/tree-sitter/paths/simple-paths.test.js.map +1 -0
  417. package/ts_build/tests/tree-sitter/sample-after.d.ts +11 -0
  418. package/ts_build/tests/tree-sitter/sample-after.js +44 -0
  419. package/ts_build/tests/tree-sitter/sample-after.js.map +1 -0
  420. package/ts_build/tests/tree-sitter/sample-before.d.ts +9 -0
  421. package/ts_build/tests/tree-sitter/sample-before.js +28 -0
  422. package/ts_build/tests/tree-sitter/sample-before.js.map +1 -0
  423. package/ts_build/tests/tree-sitter/test-files/completely-broken.d.ts +2 -0
  424. package/ts_build/tests/tree-sitter/test-files/completely-broken.js +17 -0
  425. package/ts_build/tests/tree-sitter/test-files/completely-broken.js.map +1 -0
  426. package/ts_build/tests/tree-sitter/test-files/duplicate-braces.d.ts +8 -0
  427. package/ts_build/tests/tree-sitter/test-files/duplicate-braces.js +38 -0
  428. package/ts_build/tests/tree-sitter/test-files/duplicate-braces.js.map +1 -0
  429. package/ts_build/tests/tree-sitter/test-files/invalid-nesting.d.ts +8 -0
  430. package/ts_build/tests/tree-sitter/test-files/invalid-nesting.js +38 -0
  431. package/ts_build/tests/tree-sitter/test-files/invalid-nesting.js.map +1 -0
  432. package/ts_build/tests/tree-sitter/test-files/malformed-signature.d.ts +8 -0
  433. package/ts_build/tests/tree-sitter/test-files/malformed-signature.js +38 -0
  434. package/ts_build/tests/tree-sitter/test-files/malformed-signature.js.map +1 -0
  435. package/ts_build/tests/tree-sitter/test-files/mismatched-parens.d.ts +10 -0
  436. package/ts_build/tests/tree-sitter/test-files/mismatched-parens.js +38 -0
  437. package/ts_build/tests/tree-sitter/test-files/mismatched-parens.js.map +1 -0
  438. package/ts_build/tests/tree-sitter/test-files/missing-semicolon.d.ts +8 -0
  439. package/ts_build/tests/tree-sitter/test-files/missing-semicolon.js +38 -0
  440. package/ts_build/tests/tree-sitter/test-files/missing-semicolon.js.map +1 -0
  441. package/ts_build/tests/tree-sitter/test-files/partially-broken.d.ts +6 -0
  442. package/ts_build/tests/tree-sitter/test-files/partially-broken.js +20 -0
  443. package/ts_build/tests/tree-sitter/test-files/partially-broken.js.map +1 -0
  444. package/ts_build/tests/tree-sitter/test-files/specific-errors.d.ts +7 -0
  445. package/ts_build/tests/tree-sitter/test-files/specific-errors.js +14 -0
  446. package/ts_build/tests/tree-sitter/test-files/specific-errors.js.map +1 -0
  447. package/ts_build/tests/tree-sitter/test-files/unclosed-string.d.ts +8 -0
  448. package/ts_build/tests/tree-sitter/test-files/unclosed-string.js +38 -0
  449. package/ts_build/tests/tree-sitter/test-files/unclosed-string.js.map +1 -0
  450. package/ts_build/tests/tree-sitter/tree-sitter.test.d.ts +1 -0
  451. package/ts_build/tests/tree-sitter/tree-sitter.test.js +185 -0
  452. package/ts_build/tests/tree-sitter/tree-sitter.test.js.map +1 -0
  453. package/tsconfig.json +2 -1
  454. package/tests/languagePlugin.test.ts +0 -74
  455. /package/src/chat/modules/{index.js → index.ts} +0 -0
  456. /package/tests/{integration → manual/file-edits}/patching/input.txt +0 -0
  457. /package/tests/{integration → manual/file-edits}/patching/output.txt +0 -0
  458. /package/tests/{integration → manual/file-edits}/patching/patch.txt +0 -0
  459. /package/tests/{integration → manual/file-edits}/patching/unseen.txt +0 -0
@@ -0,0 +1,430 @@
1
+ import { Message } from "../../src/clients/types";
2
+ import { CustomVariables } from "../../src/processors/CustomVariables";
3
+ import { ToolsService } from "../../src/services";
4
+
5
+ describe("CustomVariables", () => {
6
+ let customVariables: CustomVariables;
7
+ let mockToolsService: jest.Mocked<ToolsService>;
8
+
9
+ beforeEach(() => {
10
+ mockToolsService = {
11
+ addTool: jest.fn(),
12
+ addFunctions: jest.fn(),
13
+ getTool: jest.fn().mockReturnValue(undefined),
14
+ callTool: jest.fn(),
15
+ } as any;
16
+
17
+ customVariables = new CustomVariables(mockToolsService);
18
+ });
19
+
20
+ afterEach(() => {
21
+ customVariables.clearVariables();
22
+ });
23
+
24
+ describe("constructor", () => {
25
+ it("should register all variable tools with ToolsService", () => {
26
+ expect(mockToolsService.addTool).toHaveBeenCalledTimes(5);
27
+ expect(mockToolsService.addFunctions).toHaveBeenCalledTimes(5);
28
+
29
+ // Verify all tools are registered
30
+ const addToolCalls = mockToolsService.addTool.mock.calls;
31
+ const toolNames = addToolCalls.map(call => call[0].function.name);
32
+
33
+ expect(toolNames).toContain("setVariable");
34
+ expect(toolNames).toContain("getVariable");
35
+ expect(toolNames).toContain("storeToolCallToVariable");
36
+ expect(toolNames).toContain("listVariables");
37
+ expect(toolNames).toContain("deleteVariable");
38
+ });
39
+
40
+ it("should not register tools if they already exist", () => {
41
+ mockToolsService.getTool.mockReturnValue({ type: "function", function: { name: "setVariable" } } as any);
42
+ const newCustomVariables = new CustomVariables(mockToolsService);
43
+
44
+ // Should still be called only from the first instance (5 times)
45
+ expect(mockToolsService.addTool).toHaveBeenCalledTimes(5);
46
+ });
47
+ });
48
+
49
+ describe("variable name validation", () => {
50
+ let setVariableFunction: (name: string, contents: any) => string;
51
+
52
+ beforeEach(() => {
53
+ const addFunctionsCalls = mockToolsService.addFunctions.mock.calls;
54
+ const setVariableCall = addFunctionsCalls.find(call => call[0].setVariable);
55
+ setVariableFunction = setVariableCall[0].setVariable;
56
+ });
57
+
58
+ it("should accept valid variable names", () => {
59
+ const result = setVariableFunction("validName123", "test");
60
+ expect(result).toContain("successfully");
61
+ });
62
+
63
+ it("should accept underscores in variable names", () => {
64
+ const result = setVariableFunction("valid_name_123", "test");
65
+ expect(result).toContain("successfully");
66
+ });
67
+
68
+ it("should reject variable names with special characters", () => {
69
+ const result = setVariableFunction("invalid-name", "test");
70
+ expect(result).toContain("Error: Invalid variable name");
71
+ });
72
+
73
+ it("should reject variable names with spaces", () => {
74
+ const result = setVariableFunction("invalid name", "test");
75
+ expect(result).toContain("Error: Invalid variable name");
76
+ });
77
+
78
+ it("should reject empty variable names", () => {
79
+ const result = setVariableFunction("", "test");
80
+ expect(result).toContain("Error: Invalid variable name");
81
+ });
82
+ });
83
+
84
+ describe("setVariable functionality", () => {
85
+ let setVariableFunction: (name: string, contents: any) => string;
86
+
87
+ beforeEach(() => {
88
+ const addFunctionsCalls = mockToolsService.addFunctions.mock.calls;
89
+ const setVariableCall = addFunctionsCalls.find(call => call[0].setVariable);
90
+ setVariableFunction = setVariableCall[0].setVariable;
91
+ });
92
+
93
+ it("should store string variables", () => {
94
+ const result = setVariableFunction("testVar", "test value");
95
+ expect(result).toContain('Variable "testVar" has been set successfully');
96
+ expect(customVariables.getVariableNames()).toContain("testVar");
97
+ });
98
+
99
+ it("should store numeric variables", () => {
100
+ const result = setVariableFunction("numVar", 42);
101
+ expect(result).toContain("successfully");
102
+ expect(customVariables.getVariableNames()).toContain("numVar");
103
+ });
104
+
105
+ it("should store object variables", () => {
106
+ const testObj = { key: "value", nested: { data: "test" } };
107
+ const result = setVariableFunction("objVar", testObj);
108
+ expect(result).toContain("successfully");
109
+ });
110
+
111
+ it("should overwrite existing variables", () => {
112
+ setVariableFunction("testVar", "first value");
113
+ const result = setVariableFunction("testVar", "second value");
114
+ expect(result).toContain("successfully");
115
+ expect(customVariables.getVariableCount()).toBe(1);
116
+ });
117
+ });
118
+
119
+ describe("getVariable functionality", () => {
120
+ let setVariableFunction: (name: string, contents: any) => string;
121
+ let getVariableFunction: (varName: string) => string;
122
+
123
+ beforeEach(() => {
124
+ const addFunctionsCalls = mockToolsService.addFunctions.mock.calls;
125
+ const setVariableCall = addFunctionsCalls.find(call => call[0].setVariable);
126
+ const getVariableCall = addFunctionsCalls.find(call => call[0].getVariable);
127
+ setVariableFunction = setVariableCall[0].setVariable;
128
+ getVariableFunction = getVariableCall[0].getVariable;
129
+ });
130
+
131
+ it("should retrieve string variables", () => {
132
+ setVariableFunction("testVar", "test value");
133
+ const result = getVariableFunction("testVar");
134
+ expect(result).toBe("test value");
135
+ });
136
+
137
+ it("should return JSON for object variables", () => {
138
+ const testObj = { key: "value", number: 42 };
139
+ setVariableFunction("objVar", testObj);
140
+ const result = getVariableFunction("objVar");
141
+ expect(result).toContain('"key": "value"');
142
+ expect(result).toContain('"number": 42');
143
+ });
144
+
145
+ it("should return error for undefined variables", () => {
146
+ const result = getVariableFunction("undefinedVar");
147
+ expect(result).toContain('Error: Variable "undefinedVar" is not defined');
148
+ expect(result).toContain("Available variables:");
149
+ });
150
+
151
+ it("should return error for invalid variable names", () => {
152
+ const result = getVariableFunction("invalid-name");
153
+ expect(result).toContain("Error: Invalid variable name");
154
+ });
155
+
156
+ it("should list available variables in error message", () => {
157
+ setVariableFunction("var1", "value1");
158
+ setVariableFunction("var2", "value2");
159
+ const result = getVariableFunction("undefinedVar");
160
+ expect(result).toContain("var1, var2");
161
+ });
162
+ });
163
+ describe("listVariables functionality", () => {
164
+ let setVariableFunction: (name: string, contents: any) => string;
165
+ let listVariablesFunction: () => string;
166
+
167
+ beforeEach(() => {
168
+ const addFunctionsCalls = mockToolsService.addFunctions.mock.calls;
169
+ const setVariableCall = addFunctionsCalls.find(call => call[0].setVariable);
170
+ const listVariablesCall = addFunctionsCalls.find(call => call[0].listVariables);
171
+ setVariableFunction = setVariableCall[0].setVariable;
172
+ listVariablesFunction = listVariablesCall[0].listVariables;
173
+ });
174
+
175
+ it("should return message when no variables exist", () => {
176
+ const result = listVariablesFunction();
177
+ expect(result).toBe("No variables are currently stored.");
178
+ });
179
+
180
+ it("should list all variables with previews", () => {
181
+ setVariableFunction("var1", "short value");
182
+ setVariableFunction("var2", "x".repeat(100)); // Long value
183
+ setVariableFunction("objVar", { key: "value" });
184
+
185
+ const result = listVariablesFunction();
186
+ expect(result).toContain("Currently stored variables (3):");
187
+ expect(result).toContain("var1: short value");
188
+ expect(result).toContain("var2: " + "x".repeat(50) + "...");
189
+ expect(result).toContain("objVar:");
190
+ });
191
+
192
+ it("should truncate long variable previews", () => {
193
+ const longValue = "x".repeat(100);
194
+ setVariableFunction("longVar", longValue);
195
+
196
+ const result = listVariablesFunction();
197
+ expect(result).toContain("longVar: " + "x".repeat(50) + "...");
198
+ });
199
+ });
200
+
201
+ describe("deleteVariable functionality", () => {
202
+ let setVariableFunction: (name: string, contents: any) => string;
203
+ let deleteVariableFunction: (varName: string) => string;
204
+
205
+ beforeEach(() => {
206
+ const addFunctionsCalls = mockToolsService.addFunctions.mock.calls;
207
+ const setVariableCall = addFunctionsCalls.find(call => call[0].setVariable);
208
+ const deleteVariableCall = addFunctionsCalls.find(call => call[0].deleteVariable);
209
+ setVariableFunction = setVariableCall[0].setVariable;
210
+ deleteVariableFunction = deleteVariableCall[0].deleteVariable;
211
+ });
212
+
213
+ it("should delete existing variables", () => {
214
+ setVariableFunction("testVar", "test value");
215
+ const result = deleteVariableFunction("testVar");
216
+ expect(result).toContain('Variable "testVar" has been deleted successfully');
217
+ expect(customVariables.getVariableNames()).not.toContain("testVar");
218
+ });
219
+
220
+ it("should return error for non-existent variables", () => {
221
+ const result = deleteVariableFunction("nonExistent");
222
+ expect(result).toContain('Error: Variable "nonExistent" is not defined');
223
+ });
224
+
225
+ it("should return error for invalid variable names", () => {
226
+ const result = deleteVariableFunction("invalid-name");
227
+ expect(result).toContain("Error: Invalid variable name");
228
+ });
229
+ });
230
+
231
+ describe("storeToolCallToVariable functionality", () => {
232
+ let storeToolCallFunction: (varName: string, toolName: string, toolArgs: string) => Promise<string>;
233
+
234
+ beforeEach(() => {
235
+ const addFunctionsCalls = mockToolsService.addFunctions.mock.calls;
236
+ const storeToolCallCall = addFunctionsCalls.find(call => call[0].storeToolCallToVariable);
237
+ storeToolCallFunction = storeToolCallCall[0].storeToolCallToVariable;
238
+ });
239
+
240
+ it("should execute tool call and store result", async () => {
241
+ const mockResult = {
242
+ toolMessages: [],
243
+ toolCallId: "test-call-id",
244
+ functionName: "testTool",
245
+ functionArgs: { param1: "value1" },
246
+ functionResp: { success: true, data: "test data" }
247
+ };
248
+ mockToolsService.callTool.mockResolvedValue(mockResult);
249
+
250
+ const result = await storeToolCallFunction("resultVar", "testTool", '{"param1": "value1"}');
251
+
252
+ expect(result).toContain('Tool call result for "testTool" has been stored in variable "resultVar"');
253
+ expect(mockToolsService.callTool).toHaveBeenCalledWith({
254
+ id: expect.any(String),
255
+ type: "function",
256
+ function: {
257
+ name: "testTool",
258
+ arguments: { param1: "value1" }
259
+ }
260
+ });
261
+ });
262
+
263
+ it("should return error for invalid JSON arguments", async () => {
264
+ const result = await storeToolCallFunction("resultVar", "testTool", "invalid json");
265
+ expect(result).toContain("Error: Invalid JSON in toolArgs parameter");
266
+ });
267
+
268
+ it("should return error for invalid variable names", async () => {
269
+ const result = await storeToolCallFunction("invalid-name", "testTool", "{}");
270
+ expect(result).toContain("Error: Invalid variable name");
271
+ });
272
+
273
+ it("should handle tool execution errors", async () => {
274
+ mockToolsService.callTool.mockRejectedValue(new Error("Tool execution failed"));
275
+
276
+ const result = await storeToolCallFunction("resultVar", "testTool", "{}");
277
+ expect(result).toContain("Error storing tool call result: Tool execution failed");
278
+ });
279
+ });
280
+
281
+ describe("variable substitution in messages", () => {
282
+ let setVariableFunction: (name: string, contents: any) => string;
283
+
284
+ beforeEach(() => {
285
+ const addFunctionsCalls = mockToolsService.addFunctions.mock.calls;
286
+ const setVariableCall = addFunctionsCalls.find(call => call[0].setVariable);
287
+ setVariableFunction = setVariableCall[0].setVariable;
288
+ });
289
+
290
+ it("should substitute variables in message content", async () => {
291
+ setVariableFunction("userName", "Alice");
292
+ setVariableFunction("greeting", "Hello");
293
+
294
+ const messages = [
295
+ {
296
+ role: "user" as const,
297
+ content: "{{greeting}} {{userName}}, how are you today?"
298
+ }
299
+ ];
300
+
301
+ const processor = customVariables.createProcessor();
302
+ const modifiedMessages = [...messages];
303
+ await processor(messages, modifiedMessages);
304
+ expect(modifiedMessages[0].content).toBe("Hello Alice, how are you today?");
305
+ });
306
+
307
+ it("should handle multiple substitutions in single message", async () => {
308
+ setVariableFunction("var1", "first");
309
+ setVariableFunction("var2", "second");
310
+ setVariableFunction("var3", "third");
311
+
312
+ const messages = [
313
+ {
314
+ role: "user" as const,
315
+ content: "{{var1}} and {{var2}} and {{var3}}"
316
+ }
317
+ ];
318
+
319
+ const processor = customVariables.createProcessor();
320
+ const modifiedMessages = [...messages];
321
+ await processor(messages, modifiedMessages);
322
+ expect(modifiedMessages[0].content).toBe("first and second and third");
323
+ });
324
+
325
+ it("should handle object variables with JSON serialization", async () => {
326
+ setVariableFunction("config", { api: "v1", timeout: 5000 });
327
+
328
+ const messages = [
329
+ {
330
+ role: "user" as const,
331
+ content: "Configuration: {{config}}"
332
+ }
333
+ ];
334
+
335
+ const processor = customVariables.createProcessor();
336
+ const modifiedMessages = [...messages];
337
+ await processor(messages, modifiedMessages);
338
+
339
+ expect(modifiedMessages[0].content).toBe('Configuration: {"api":"v1","timeout":5000}');
340
+ });
341
+
342
+ it("should return error for undefined variables", async () => {
343
+ const messages = [
344
+ {
345
+ role: "user" as const,
346
+ content: "Hello {{undefinedVar}}"
347
+ }
348
+ ];
349
+
350
+ const processor = customVariables.createProcessor();
351
+ const modifiedMessages = [...messages];
352
+ await processor(messages, modifiedMessages);
353
+
354
+ expect(modifiedMessages[0].content).toBe('{{ERROR: Variable "undefinedVar" is not defined}}');
355
+ });
356
+
357
+ it("should handle partial substitutions with mixed defined/undefined vars", async () => {
358
+ setVariableFunction("defined", "value");
359
+
360
+ const messages = [
361
+ {
362
+ role: "user" as const,
363
+ content: "{{defined}} and {{undefined}}"
364
+ }
365
+ ];
366
+
367
+ const processor = customVariables.createProcessor();
368
+ const modifiedMessages = [...messages];
369
+ await processor(messages, modifiedMessages);
370
+
371
+ expect(modifiedMessages[0].content).toBe('value and {{ERROR: Variable "undefined" is not defined}}');
372
+ });
373
+
374
+ it("should preserve message structure while substituting content", async () => {
375
+ setVariableFunction("test", "replaced");
376
+
377
+ const messages = [
378
+ {
379
+ role: "assistant" as const,
380
+ content: "Original {{test}} content",
381
+ metadata: { id: "test-id" }
382
+ }
383
+ ];
384
+
385
+ const processor = customVariables.createProcessor();
386
+ const modifiedMessages = [...messages];
387
+ await processor(messages, modifiedMessages);
388
+
389
+ expect(modifiedMessages[0]).toEqual({
390
+ role: "assistant",
391
+ content: "Original replaced content",
392
+ metadata: { id: "test-id" }
393
+ });
394
+ });
395
+
396
+ it("should handle nested variable references", async () => {
397
+ setVariableFunction("innerVar", "inner");
398
+ setVariableFunction("outerVar", "{{innerVar}}");
399
+
400
+ const messages = [
401
+ {
402
+ role: "user" as const,
403
+ content: "{{outerVar}} value"
404
+ }
405
+ ];
406
+
407
+ const processor = customVariables.createProcessor();
408
+ const modifiedMessages = [...messages];
409
+ await processor(messages, modifiedMessages);
410
+ expect(modifiedMessages[0].content).toBe("{{innerVar}} value"); // Only one level of substitution
411
+ });
412
+
413
+ it("should handle empty and whitespace variables", async () => {
414
+ setVariableFunction("empty", "");
415
+ setVariableFunction("spaces", " ");
416
+
417
+ const messages = [
418
+ {
419
+ role: "user" as const,
420
+ content: "Empty: '{{empty}}' Spaces: '{{spaces}}'"
421
+ }
422
+ ];
423
+
424
+ const processor = customVariables.createProcessor();
425
+ const modifiedMessages = [...messages];
426
+ await processor(messages, modifiedMessages);
427
+ expect(modifiedMessages[0].content).toBe("Empty: '' Spaces: ' '");
428
+ });
429
+ });
430
+ });