@tyvm/knowhow 0.0.32 → 0.0.34

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 (508) hide show
  1. package/autodoc/plugins/downloader/downloader.mdx +2 -2
  2. package/benchmarks/.dockerignore +7 -0
  3. package/benchmarks/README.md +166 -0
  4. package/benchmarks/docker/Dockerfile +68 -0
  5. package/benchmarks/example-config.yml +27 -0
  6. package/benchmarks/jest.config.js +13 -0
  7. package/benchmarks/package-lock.json +4297 -0
  8. package/benchmarks/package.json +39 -0
  9. package/benchmarks/results/4542435/2025-08-05/lms/lms-openai-gpt-oss-20b.json +2814 -0
  10. package/benchmarks/results/4542435/2025-08-05/lms/lms-qwen-qwen3-30b-a3b-2507.json +2014 -0
  11. package/benchmarks/results/4fb9125/2025-08-07/anthropic/anthropic-claude-sonnet-4-20250514.json +3121 -0
  12. package/benchmarks/results/5766aee/2025-08-02/lms-qwen/qwen3-coder-30b.json +98 -0
  13. package/benchmarks/results/6d73808/2025-08-07/openai/openai-gpt-5.json +3256 -0
  14. package/benchmarks/results/77bf0a6/2025-08-02/lms-qwen/qwen3-30b-a3b-2507.json +4298 -0
  15. package/benchmarks/results/8c0d445/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +3031 -0
  16. package/benchmarks/results/8c0d445/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +2990 -0
  17. package/benchmarks/results/ac6b2ab/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +3256 -0
  18. package/benchmarks/results/ac6b2ab/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +3007 -0
  19. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +3256 -0
  20. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-mini-2025-04-14.json +3036 -0
  21. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-nano-2025-04-14.json +3280 -0
  22. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-30b-a3b-2507.json +1920 -0
  23. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-coder-30b.json +3281 -0
  24. package/benchmarks/results/b502ed9/2025-08-03/lms-qwen/qwen3-coder-30b.json +2896 -0
  25. package/benchmarks/results/d1a8129/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +3011 -0
  26. package/benchmarks/results/e60471c/2025-08-03/lms/qwen3-30b-a3b-2507.json +3003 -0
  27. package/benchmarks/scripts/build-and-run.sh +47 -0
  28. package/benchmarks/scripts/clone-exercism.sh +92 -0
  29. package/benchmarks/scripts/validate.sh +48 -0
  30. package/benchmarks/src/__tests__/runner.test.ts +27 -0
  31. package/benchmarks/src/cli.ts +90 -0
  32. package/benchmarks/src/evaluators/EvaluatorRegistry.ts +64 -0
  33. package/benchmarks/src/evaluators/JavaScriptEvaluator.ts +183 -0
  34. package/benchmarks/src/evaluators/index.ts +3 -0
  35. package/benchmarks/src/evaluators/types.ts +22 -0
  36. package/benchmarks/src/index.ts +3 -0
  37. package/benchmarks/src/providers.ts +13 -0
  38. package/benchmarks/src/runner.ts +824 -0
  39. package/benchmarks/src/types.ts +63 -0
  40. package/benchmarks/tsconfig.json +19 -0
  41. package/jest.config.js +2 -1
  42. package/leaderboard/README.md +148 -0
  43. package/leaderboard/app/api/benchmark-data/route.ts +131 -0
  44. package/leaderboard/app/api/benchmark-detail/route.ts +172 -0
  45. package/leaderboard/app/details/[model]/[provider]/[language]/page.tsx +501 -0
  46. package/leaderboard/app/exercise/[model]/[provider]/[language]/[exercise]/page.tsx +375 -0
  47. package/leaderboard/app/globals.css +27 -0
  48. package/leaderboard/app/layout.tsx +21 -0
  49. package/leaderboard/app/page.tsx +170 -0
  50. package/leaderboard/components/LeaderboardTable.tsx +168 -0
  51. package/leaderboard/components/PerformanceChart.tsx +109 -0
  52. package/leaderboard/next-env.d.ts +5 -0
  53. package/leaderboard/next.config.js +4 -0
  54. package/leaderboard/package-lock.json +6363 -0
  55. package/leaderboard/package.json +28 -0
  56. package/leaderboard/postcss.config.js +6 -0
  57. package/leaderboard/tailwind.config.js +17 -0
  58. package/leaderboard/tsconfig.json +28 -0
  59. package/leaderboard/types/benchmark.ts +67 -0
  60. package/leaderboard/utils/dataProcessor.ts +33 -0
  61. package/package.json +2 -1
  62. package/src/agents/base/base.ts +147 -21
  63. package/src/agents/base/prompt.ts +28 -0
  64. package/src/agents/index.ts +3 -0
  65. package/src/agents/patcher/patcher.ts +6 -4
  66. package/src/agents/setup/setup.ts +56 -0
  67. package/src/agents/tools/agentCall.ts +6 -2
  68. package/src/agents/tools/aiClient.ts +74 -8
  69. package/src/agents/tools/execCommand.ts +13 -14
  70. package/src/agents/tools/executeScript/README.md +16 -0
  71. package/src/agents/tools/index.ts +2 -0
  72. package/src/agents/tools/list.ts +73 -16
  73. package/src/agents/tools/startAgentTask.ts +109 -0
  74. package/src/agents/tools/textSearch.ts +1 -1
  75. package/src/agents/tools/visionTool.ts +31 -2
  76. package/src/agents/tools/ycmd/client.ts +608 -0
  77. package/src/agents/tools/ycmd/definitions.ts +294 -0
  78. package/src/agents/tools/ycmd/detection.ts +211 -0
  79. package/src/agents/tools/ycmd/index.ts +11 -0
  80. package/src/agents/tools/ycmd/installer.ts +251 -0
  81. package/src/agents/tools/ycmd/server.ts +535 -0
  82. package/src/agents/tools/ycmd/serverManager.ts +316 -0
  83. package/src/agents/tools/ycmd/tools/completion.ts +113 -0
  84. package/src/agents/tools/ycmd/tools/diagnostics.ts +155 -0
  85. package/src/agents/tools/ycmd/tools/getLocations.ts +173 -0
  86. package/src/agents/tools/ycmd/tools/goto.ts +169 -0
  87. package/src/agents/tools/ycmd/tools/refactor.ts +204 -0
  88. package/src/agents/tools/ycmd/tools/signature.ts +174 -0
  89. package/src/agents/tools/ycmd/tools/start.ts +95 -0
  90. package/src/agents/tools/ycmd/utils/pathUtils.ts +59 -0
  91. package/src/ai.ts +15 -0
  92. package/src/chat/CliChatService.ts +277 -0
  93. package/src/chat/modules/AgentModule.ts +980 -0
  94. package/src/chat/modules/AskModule.ts +98 -0
  95. package/src/chat/modules/BaseChatModule.ts +66 -0
  96. package/src/chat/modules/InternalChatModule.ts +174 -0
  97. package/src/chat/modules/SearchModule.ts +166 -0
  98. package/src/chat/modules/SetupModule.ts +185 -0
  99. package/src/chat/modules/SystemModule.ts +120 -0
  100. package/src/chat/modules/VoiceModule.ts +70 -0
  101. package/src/chat/modules/index.js +5 -0
  102. package/src/chat/types.ts +97 -0
  103. package/src/chat.ts +9 -1
  104. package/src/chat2.ts +62 -0
  105. package/src/cli.ts +264 -35
  106. package/src/clients/anthropic.ts +14 -7
  107. package/src/clients/gemini.ts +15 -7
  108. package/src/clients/http.ts +17 -7
  109. package/src/clients/index.ts +117 -4
  110. package/src/clients/knowhow.ts +7 -2
  111. package/src/clients/knowhowMcp.ts +118 -0
  112. package/src/clients/openai.ts +32 -8
  113. package/src/clients/types.ts +1 -0
  114. package/src/clients/xai.ts +17 -5
  115. package/src/config.ts +30 -5
  116. package/src/conversion.ts +4 -1
  117. package/src/embeddings.ts +79 -23
  118. package/src/login.ts +26 -9
  119. package/src/microphone.ts +0 -1
  120. package/src/plugins/downloader/downloader.ts +72 -24
  121. package/src/plugins/downloader/plugin.ts +3 -1
  122. package/src/plugins/plugins.ts +3 -0
  123. package/src/processors/CustomVariables.ts +425 -0
  124. package/src/processors/HarmonyToolProcessor.ts +264 -0
  125. package/src/processors/XmlToolCallProcessor.ts +533 -0
  126. package/src/processors/index.ts +3 -0
  127. package/src/prompts/KnowhowConfigExamples.ts +376 -0
  128. package/src/services/KnowhowClient.ts +49 -3
  129. package/src/services/Mcp.ts +42 -3
  130. package/src/services/McpServer.ts +14 -4
  131. package/src/services/McpWebsocketTransport.ts +21 -7
  132. package/src/services/MessageProcessor.ts +10 -5
  133. package/src/services/index.ts +5 -0
  134. package/src/services/script-execution/ScriptExecutor.ts +34 -1
  135. package/src/services/types.ts +17 -14
  136. package/src/types.ts +17 -0
  137. package/src/utils/index.ts +138 -0
  138. package/tests/XmlToolCallProcessor.test.ts +468 -0
  139. package/tests/manual/ycmd/debug_diagnostics_test.ts +127 -0
  140. package/tests/manual/ycmd/fixtures/debug_diagnostics.ts +26 -0
  141. package/tests/manual/ycmd/fixtures/file_change_test.ts +17 -0
  142. package/tests/manual/ycmd/minimal_advanced_test.ts +108 -0
  143. package/tests/manual/ycmd/simple_diagnostics_test.ts +61 -0
  144. package/tests/manual/ycmd/simple_test.ts +74 -0
  145. package/tests/manual/ycmd/test-typescript-sample.ts +34 -0
  146. package/tests/manual/ycmd/test_advanced_features.ts +407 -0
  147. package/tests/manual/ycmd/test_advanced_with_tools.ts +320 -0
  148. package/tests/manual/ycmd/test_comprehensive_typescript.ts +179 -0
  149. package/tests/manual/ycmd/test_diagnostics_file_changes.ts +249 -0
  150. package/tests/manual/ycmd/test_diagnostics_fix.ts +99 -0
  151. package/tests/manual/ycmd/test_diagnostics_simple.ts +100 -0
  152. package/tests/manual/ycmd/test_diagnostics_timing.ts +120 -0
  153. package/tests/manual/ycmd/test_discover_commands.ts +310 -0
  154. package/tests/manual/ycmd/test_endpoints.ts +115 -0
  155. package/tests/manual/ycmd/test_final_comprehensive.ts +218 -0
  156. package/tests/manual/ycmd/test_final_validation.ts +150 -0
  157. package/tests/manual/ycmd/test_implementation.js +42 -0
  158. package/tests/manual/ycmd/test_individual_ycmd_tool.ts +39 -0
  159. package/tests/manual/ycmd/test_server_manager.ts +52 -0
  160. package/tests/manual/ycmd/test_simple_debug.ts +86 -0
  161. package/tests/manual/ycmd/test_tsserver_workflow.js +83 -0
  162. package/tests/manual/ycmd/test_tsserver_workflow.ts +122 -0
  163. package/tests/manual/ycmd/test_typescript_simple.ts +48 -0
  164. package/tests/manual/ycmd/test_typescript_ycmd.ts +105 -0
  165. package/tests/manual/ycmd/test_workspace_config.ts +90 -0
  166. package/tests/manual/ycmd/test_ycmd_auto_start.ts +137 -0
  167. package/tests/manual/ycmd/test_ycmd_comprehensive.ts +73 -0
  168. package/tests/manual/ycmd/test_ycmd_connection.py +10 -0
  169. package/tests/manual/ycmd/test_ycmd_direct.ts +142 -0
  170. package/tests/manual/ycmd/test_ycmd_experiment.ts +48 -0
  171. package/tests/manual/ycmd/test_ycmd_final.ts +200 -0
  172. package/tests/manual/ycmd/test_ycmd_fixed.py +18 -0
  173. package/tests/manual/ycmd/test_ycmd_integration.ts +112 -0
  174. package/tests/manual/ycmd/test_ycmd_simple.ts +45 -0
  175. package/tests/manual/ycmd/test_ycmd_usage.py +27 -0
  176. package/tests/manual/ycmd/working_simple_test.ts +134 -0
  177. package/ts_build/src/agents/base/base.d.ts +14 -1
  178. package/ts_build/src/agents/base/base.js +91 -17
  179. package/ts_build/src/agents/base/base.js.map +1 -1
  180. package/ts_build/src/agents/base/prompt.d.ts +1 -1
  181. package/ts_build/src/agents/base/prompt.js +28 -0
  182. package/ts_build/src/agents/base/prompt.js.map +1 -1
  183. package/ts_build/src/agents/index.d.ts +2 -0
  184. package/ts_build/src/agents/index.js +2 -0
  185. package/ts_build/src/agents/index.js.map +1 -1
  186. package/ts_build/src/agents/patcher/patcher.js +6 -3
  187. package/ts_build/src/agents/patcher/patcher.js.map +1 -1
  188. package/ts_build/src/agents/setup/setup.d.ts +8 -0
  189. package/ts_build/src/agents/setup/setup.js +59 -0
  190. package/ts_build/src/agents/setup/setup.js.map +1 -0
  191. package/ts_build/src/agents/tools/agentCall.js +5 -2
  192. package/ts_build/src/agents/tools/agentCall.js.map +1 -1
  193. package/ts_build/src/agents/tools/aiClient.d.ts +6 -5
  194. package/ts_build/src/agents/tools/aiClient.js +37 -6
  195. package/ts_build/src/agents/tools/aiClient.js.map +1 -1
  196. package/ts_build/src/agents/tools/execCommand.d.ts +2 -2
  197. package/ts_build/src/agents/tools/execCommand.js +5 -6
  198. package/ts_build/src/agents/tools/execCommand.js.map +1 -1
  199. package/ts_build/src/agents/tools/executeScript/index.d.ts +1 -1
  200. package/ts_build/src/agents/tools/index.d.ts +2 -0
  201. package/ts_build/src/agents/tools/index.js +2 -0
  202. package/ts_build/src/agents/tools/index.js.map +1 -1
  203. package/ts_build/src/agents/tools/list.js +66 -16
  204. package/ts_build/src/agents/tools/list.js.map +1 -1
  205. package/ts_build/src/agents/tools/startAgentTask.d.ts +13 -0
  206. package/ts_build/src/agents/tools/startAgentTask.js +74 -0
  207. package/ts_build/src/agents/tools/startAgentTask.js.map +1 -0
  208. package/ts_build/src/agents/tools/startChatTask.d.ts +13 -0
  209. package/ts_build/src/agents/tools/startChatTask.js +73 -0
  210. package/ts_build/src/agents/tools/startChatTask.js.map +1 -0
  211. package/ts_build/src/agents/tools/textSearch.js +1 -1
  212. package/ts_build/src/agents/tools/textSearch.js.map +1 -1
  213. package/ts_build/src/agents/tools/visionTool.d.ts +1 -1
  214. package/ts_build/src/agents/tools/visionTool.js +23 -3
  215. package/ts_build/src/agents/tools/visionTool.js.map +1 -1
  216. package/ts_build/src/agents/tools/ycmd/client.d.ts +93 -0
  217. package/ts_build/src/agents/tools/ycmd/client.js +355 -0
  218. package/ts_build/src/agents/tools/ycmd/client.js.map +1 -0
  219. package/ts_build/src/agents/tools/ycmd/definitions.d.ts +345 -0
  220. package/ts_build/src/agents/tools/ycmd/definitions.js +298 -0
  221. package/ts_build/src/agents/tools/ycmd/definitions.js.map +1 -0
  222. package/ts_build/src/agents/tools/ycmd/detection.d.ts +11 -0
  223. package/ts_build/src/agents/tools/ycmd/detection.js +175 -0
  224. package/ts_build/src/agents/tools/ycmd/detection.js.map +1 -0
  225. package/ts_build/src/agents/tools/ycmd/index.d.ts +8 -0
  226. package/ts_build/src/agents/tools/ycmd/index.js +20 -0
  227. package/ts_build/src/agents/tools/ycmd/index.js.map +1 -0
  228. package/ts_build/src/agents/tools/ycmd/installer.d.ts +19 -0
  229. package/ts_build/src/agents/tools/ycmd/installer.js +196 -0
  230. package/ts_build/src/agents/tools/ycmd/installer.js.map +1 -0
  231. package/ts_build/src/agents/tools/ycmd/server.d.ts +35 -0
  232. package/ts_build/src/agents/tools/ycmd/server.js +363 -0
  233. package/ts_build/src/agents/tools/ycmd/server.js.map +1 -0
  234. package/ts_build/src/agents/tools/ycmd/serverManager.d.ts +39 -0
  235. package/ts_build/src/agents/tools/ycmd/serverManager.js +210 -0
  236. package/ts_build/src/agents/tools/ycmd/serverManager.js.map +1 -0
  237. package/ts_build/src/agents/tools/ycmd/tools/completion.d.ts +22 -0
  238. package/ts_build/src/agents/tools/ycmd/tools/completion.js +72 -0
  239. package/ts_build/src/agents/tools/ycmd/tools/completion.js.map +1 -0
  240. package/ts_build/src/agents/tools/ycmd/tools/diagnostics.d.ts +42 -0
  241. package/ts_build/src/agents/tools/ycmd/tools/diagnostics.js +88 -0
  242. package/ts_build/src/agents/tools/ycmd/tools/diagnostics.js.map +1 -0
  243. package/ts_build/src/agents/tools/ycmd/tools/getLocations.d.ts +22 -0
  244. package/ts_build/src/agents/tools/ycmd/tools/getLocations.js +142 -0
  245. package/ts_build/src/agents/tools/ycmd/tools/getLocations.js.map +1 -0
  246. package/ts_build/src/agents/tools/ycmd/tools/goto.d.ts +20 -0
  247. package/ts_build/src/agents/tools/ycmd/tools/goto.js +101 -0
  248. package/ts_build/src/agents/tools/ycmd/tools/goto.js.map +1 -0
  249. package/ts_build/src/agents/tools/ycmd/tools/refactor.d.ts +32 -0
  250. package/ts_build/src/agents/tools/ycmd/tools/refactor.js +123 -0
  251. package/ts_build/src/agents/tools/ycmd/tools/refactor.js.map +1 -0
  252. package/ts_build/src/agents/tools/ycmd/tools/signature.d.ts +25 -0
  253. package/ts_build/src/agents/tools/ycmd/tools/signature.js +110 -0
  254. package/ts_build/src/agents/tools/ycmd/tools/signature.js.map +1 -0
  255. package/ts_build/src/agents/tools/ycmd/tools/start.d.ts +17 -0
  256. package/ts_build/src/agents/tools/ycmd/tools/start.js +65 -0
  257. package/ts_build/src/agents/tools/ycmd/tools/start.js.map +1 -0
  258. package/ts_build/src/agents/tools/ycmd/utils/pathUtils.d.ts +4 -0
  259. package/ts_build/src/agents/tools/ycmd/utils/pathUtils.js +67 -0
  260. package/ts_build/src/agents/tools/ycmd/utils/pathUtils.js.map +1 -0
  261. package/ts_build/src/ai.d.ts +1 -0
  262. package/ts_build/src/ai.js +40 -1
  263. package/ts_build/src/ai.js.map +1 -1
  264. package/ts_build/src/chat/ChatCommandHandler.d.ts +36 -0
  265. package/ts_build/src/chat/ChatCommandHandler.js +268 -0
  266. package/ts_build/src/chat/ChatCommandHandler.js.map +1 -0
  267. package/ts_build/src/chat/ChatInputManager.d.ts +22 -0
  268. package/ts_build/src/chat/ChatInputManager.js +85 -0
  269. package/ts_build/src/chat/ChatInputManager.js.map +1 -0
  270. package/ts_build/src/chat/ChatManager.d.ts +49 -0
  271. package/ts_build/src/chat/ChatManager.js +271 -0
  272. package/ts_build/src/chat/ChatManager.js.map +1 -0
  273. package/ts_build/src/chat/ChatSession.d.ts +32 -0
  274. package/ts_build/src/chat/ChatSession.js +3 -0
  275. package/ts_build/src/chat/ChatSession.js.map +1 -0
  276. package/ts_build/src/chat/ChatSessionManager.d.ts +19 -0
  277. package/ts_build/src/chat/ChatSessionManager.js +188 -0
  278. package/ts_build/src/chat/ChatSessionManager.js.map +1 -0
  279. package/ts_build/src/chat/ChatStateManager.d.ts +58 -0
  280. package/ts_build/src/chat/ChatStateManager.js +156 -0
  281. package/ts_build/src/chat/ChatStateManager.js.map +1 -0
  282. package/ts_build/src/chat/CliChatService.d.ts +35 -0
  283. package/ts_build/src/chat/CliChatService.js +201 -0
  284. package/ts_build/src/chat/CliChatService.js.map +1 -0
  285. package/ts_build/src/chat/InterruptibleInput.d.ts +20 -0
  286. package/ts_build/src/chat/InterruptibleInput.js +109 -0
  287. package/ts_build/src/chat/InterruptibleInput.js.map +1 -0
  288. package/ts_build/src/chat/interfaces/ChatModule.d.ts +6 -0
  289. package/ts_build/src/chat/interfaces/ChatModule.js +3 -0
  290. package/ts_build/src/chat/interfaces/ChatModule.js.map +1 -0
  291. package/ts_build/src/chat/modules/AgentModule.d.ts +56 -0
  292. package/ts_build/src/chat/modules/AgentModule.js +705 -0
  293. package/ts_build/src/chat/modules/AgentModule.js.map +1 -0
  294. package/ts_build/src/chat/modules/AskModule.d.ts +10 -0
  295. package/ts_build/src/chat/modules/AskModule.js +63 -0
  296. package/ts_build/src/chat/modules/AskModule.js.map +1 -0
  297. package/ts_build/src/chat/modules/BaseChatModule.d.ts +14 -0
  298. package/ts_build/src/chat/modules/BaseChatModule.js +32 -0
  299. package/ts_build/src/chat/modules/BaseChatModule.js.map +1 -0
  300. package/ts_build/src/chat/modules/InternalChatModule.d.ts +24 -0
  301. package/ts_build/src/chat/modules/InternalChatModule.js +127 -0
  302. package/ts_build/src/chat/modules/InternalChatModule.js.map +1 -0
  303. package/ts_build/src/chat/modules/SearchModule.d.ts +12 -0
  304. package/ts_build/src/chat/modules/SearchModule.js +119 -0
  305. package/ts_build/src/chat/modules/SearchModule.js.map +1 -0
  306. package/ts_build/src/chat/modules/SetupModule.d.ts +15 -0
  307. package/ts_build/src/chat/modules/SetupModule.js +147 -0
  308. package/ts_build/src/chat/modules/SetupModule.js.map +1 -0
  309. package/ts_build/src/chat/modules/SystemModule.d.ts +14 -0
  310. package/ts_build/src/chat/modules/SystemModule.js +90 -0
  311. package/ts_build/src/chat/modules/SystemModule.js.map +1 -0
  312. package/ts_build/src/chat/modules/VoiceModule.d.ts +11 -0
  313. package/ts_build/src/chat/modules/VoiceModule.js +57 -0
  314. package/ts_build/src/chat/modules/VoiceModule.js.map +1 -0
  315. package/ts_build/src/chat/types.d.ts +83 -0
  316. package/ts_build/src/chat/types.js +3 -0
  317. package/ts_build/src/chat/types.js.map +1 -0
  318. package/ts_build/src/chat.js +7 -1
  319. package/ts_build/src/chat.js.map +1 -1
  320. package/ts_build/src/chat2.d.ts +3 -0
  321. package/ts_build/src/chat2.js +47 -0
  322. package/ts_build/src/chat2.js.map +1 -0
  323. package/ts_build/src/cli.js +218 -37
  324. package/ts_build/src/cli.js.map +1 -1
  325. package/ts_build/src/clients/anthropic.d.ts +5 -2
  326. package/ts_build/src/clients/anthropic.js +12 -7
  327. package/ts_build/src/clients/anthropic.js.map +1 -1
  328. package/ts_build/src/clients/gemini.d.ts +6 -3
  329. package/ts_build/src/clients/gemini.js +13 -7
  330. package/ts_build/src/clients/gemini.js.map +1 -1
  331. package/ts_build/src/clients/http.d.ts +1 -0
  332. package/ts_build/src/clients/http.js +12 -5
  333. package/ts_build/src/clients/http.js.map +1 -1
  334. package/ts_build/src/clients/index.d.ts +10 -0
  335. package/ts_build/src/clients/index.js +74 -4
  336. package/ts_build/src/clients/index.js.map +1 -1
  337. package/ts_build/src/clients/knowhow.d.ts +3 -1
  338. package/ts_build/src/clients/knowhow.js +8 -2
  339. package/ts_build/src/clients/knowhow.js.map +1 -1
  340. package/ts_build/src/clients/knowhowMcp.d.ts +20 -0
  341. package/ts_build/src/clients/knowhowMcp.js +86 -0
  342. package/ts_build/src/clients/knowhowMcp.js.map +1 -0
  343. package/ts_build/src/clients/openai.d.ts +5 -2
  344. package/ts_build/src/clients/openai.js +29 -8
  345. package/ts_build/src/clients/openai.js.map +1 -1
  346. package/ts_build/src/clients/types.d.ts +1 -0
  347. package/ts_build/src/clients/xai.d.ts +5 -2
  348. package/ts_build/src/clients/xai.js +15 -5
  349. package/ts_build/src/clients/xai.js.map +1 -1
  350. package/ts_build/src/config.js +24 -3
  351. package/ts_build/src/config.js.map +1 -1
  352. package/ts_build/src/conversion.js +6 -4
  353. package/ts_build/src/conversion.js.map +1 -1
  354. package/ts_build/src/embeddings.d.ts +2 -1
  355. package/ts_build/src/embeddings.js +62 -17
  356. package/ts_build/src/embeddings.js.map +1 -1
  357. package/ts_build/src/login.d.ts +1 -1
  358. package/ts_build/src/login.js +21 -7
  359. package/ts_build/src/login.js.map +1 -1
  360. package/ts_build/src/microphone.js.map +1 -1
  361. package/ts_build/src/plugins/downloader/downloader.d.ts +4 -5
  362. package/ts_build/src/plugins/downloader/downloader.js +55 -26
  363. package/ts_build/src/plugins/downloader/downloader.js.map +1 -1
  364. package/ts_build/src/plugins/downloader/plugin.js +5 -3
  365. package/ts_build/src/plugins/downloader/plugin.js.map +1 -1
  366. package/ts_build/src/plugins/plugins.js +3 -0
  367. package/ts_build/src/plugins/plugins.js.map +1 -1
  368. package/ts_build/src/processors/CustomVariables.d.ts +32 -0
  369. package/ts_build/src/processors/CustomVariables.js +297 -0
  370. package/ts_build/src/processors/CustomVariables.js.map +1 -0
  371. package/ts_build/src/processors/HarmonyToolProcessor.d.ts +15 -0
  372. package/ts_build/src/processors/HarmonyToolProcessor.js +154 -0
  373. package/ts_build/src/processors/HarmonyToolProcessor.js.map +1 -0
  374. package/ts_build/src/processors/XmlToolCallProcessor.d.ts +14 -0
  375. package/ts_build/src/processors/XmlToolCallProcessor.js +357 -0
  376. package/ts_build/src/processors/XmlToolCallProcessor.js.map +1 -0
  377. package/ts_build/src/processors/index.d.ts +3 -0
  378. package/ts_build/src/processors/index.js +7 -1
  379. package/ts_build/src/processors/index.js.map +1 -1
  380. package/ts_build/src/prompts/KnowhowConfigExamples.d.ts +2 -0
  381. package/ts_build/src/prompts/KnowhowConfigExamples.js +379 -0
  382. package/ts_build/src/prompts/KnowhowConfigExamples.js.map +1 -0
  383. package/ts_build/src/services/KnowhowClient.d.ts +22 -0
  384. package/ts_build/src/services/KnowhowClient.js +14 -2
  385. package/ts_build/src/services/KnowhowClient.js.map +1 -1
  386. package/ts_build/src/services/Mcp.d.ts +1 -0
  387. package/ts_build/src/services/Mcp.js +20 -3
  388. package/ts_build/src/services/Mcp.js.map +1 -1
  389. package/ts_build/src/services/McpServer.d.ts +1 -1
  390. package/ts_build/src/services/McpServer.js +8 -4
  391. package/ts_build/src/services/McpServer.js.map +1 -1
  392. package/ts_build/src/services/McpWebsocketTransport.js +17 -7
  393. package/ts_build/src/services/McpWebsocketTransport.js.map +1 -1
  394. package/ts_build/src/services/MessageProcessor.d.ts +1 -1
  395. package/ts_build/src/services/MessageProcessor.js +4 -4
  396. package/ts_build/src/services/MessageProcessor.js.map +1 -1
  397. package/ts_build/src/services/index.d.ts +2 -0
  398. package/ts_build/src/services/index.js +4 -0
  399. package/ts_build/src/services/index.js.map +1 -1
  400. package/ts_build/src/services/script-execution/ScriptExecutor.d.ts +1 -0
  401. package/ts_build/src/services/script-execution/ScriptExecutor.js +23 -0
  402. package/ts_build/src/services/script-execution/ScriptExecutor.js.map +1 -1
  403. package/ts_build/src/services/types.d.ts +2 -6
  404. package/ts_build/src/services/types.js +4 -4
  405. package/ts_build/src/services/types.js.map +1 -1
  406. package/ts_build/src/types.d.ts +11 -0
  407. package/ts_build/src/types.js +8 -0
  408. package/ts_build/src/types.js.map +1 -1
  409. package/ts_build/src/utils/index.d.ts +2 -0
  410. package/ts_build/src/utils/index.js +102 -1
  411. package/ts_build/src/utils/index.js.map +1 -1
  412. package/ts_build/tests/XmlToolCallProcessor.test.d.ts +1 -0
  413. package/ts_build/tests/XmlToolCallProcessor.test.js +376 -0
  414. package/ts_build/tests/XmlToolCallProcessor.test.js.map +1 -0
  415. package/ts_build/tests/manual/ycmd/debug_diagnostics_test.d.ts +1 -0
  416. package/ts_build/tests/manual/ycmd/debug_diagnostics_test.js +114 -0
  417. package/ts_build/tests/manual/ycmd/debug_diagnostics_test.js.map +1 -0
  418. package/ts_build/tests/manual/ycmd/minimal_advanced_test.d.ts +2 -0
  419. package/ts_build/tests/manual/ycmd/minimal_advanced_test.js +104 -0
  420. package/ts_build/tests/manual/ycmd/minimal_advanced_test.js.map +1 -0
  421. package/ts_build/tests/manual/ycmd/simple_diagnostics_test.d.ts +1 -0
  422. package/ts_build/tests/manual/ycmd/simple_diagnostics_test.js +74 -0
  423. package/ts_build/tests/manual/ycmd/simple_diagnostics_test.js.map +1 -0
  424. package/ts_build/tests/manual/ycmd/simple_test.d.ts +2 -0
  425. package/ts_build/tests/manual/ycmd/simple_test.js +82 -0
  426. package/ts_build/tests/manual/ycmd/simple_test.js.map +1 -0
  427. package/ts_build/tests/manual/ycmd/test-typescript-sample.d.ts +14 -0
  428. package/ts_build/tests/manual/ycmd/test-typescript-sample.js +20 -0
  429. package/ts_build/tests/manual/ycmd/test-typescript-sample.js.map +1 -0
  430. package/ts_build/tests/manual/ycmd/test_advanced_features.d.ts +2 -0
  431. package/ts_build/tests/manual/ycmd/test_advanced_features.js +297 -0
  432. package/ts_build/tests/manual/ycmd/test_advanced_features.js.map +1 -0
  433. package/ts_build/tests/manual/ycmd/test_advanced_with_tools.d.ts +3 -0
  434. package/ts_build/tests/manual/ycmd/test_advanced_with_tools.js +262 -0
  435. package/ts_build/tests/manual/ycmd/test_advanced_with_tools.js.map +1 -0
  436. package/ts_build/tests/manual/ycmd/test_comprehensive_typescript.d.ts +2 -0
  437. package/ts_build/tests/manual/ycmd/test_comprehensive_typescript.js +186 -0
  438. package/ts_build/tests/manual/ycmd/test_comprehensive_typescript.js.map +1 -0
  439. package/ts_build/tests/manual/ycmd/test_diagnostics_file_changes.d.ts +1 -0
  440. package/ts_build/tests/manual/ycmd/test_diagnostics_file_changes.js +174 -0
  441. package/ts_build/tests/manual/ycmd/test_diagnostics_file_changes.js.map +1 -0
  442. package/ts_build/tests/manual/ycmd/test_diagnostics_fix.d.ts +2 -0
  443. package/ts_build/tests/manual/ycmd/test_diagnostics_fix.js +106 -0
  444. package/ts_build/tests/manual/ycmd/test_diagnostics_fix.js.map +1 -0
  445. package/ts_build/tests/manual/ycmd/test_diagnostics_simple.d.ts +1 -0
  446. package/ts_build/tests/manual/ycmd/test_diagnostics_simple.js +104 -0
  447. package/ts_build/tests/manual/ycmd/test_diagnostics_simple.js.map +1 -0
  448. package/ts_build/tests/manual/ycmd/test_diagnostics_timing.d.ts +1 -0
  449. package/ts_build/tests/manual/ycmd/test_diagnostics_timing.js +119 -0
  450. package/ts_build/tests/manual/ycmd/test_diagnostics_timing.js.map +1 -0
  451. package/ts_build/tests/manual/ycmd/test_discover_commands.d.ts +2 -0
  452. package/ts_build/tests/manual/ycmd/test_discover_commands.js +243 -0
  453. package/ts_build/tests/manual/ycmd/test_discover_commands.js.map +1 -0
  454. package/ts_build/tests/manual/ycmd/test_endpoints.d.ts +2 -0
  455. package/ts_build/tests/manual/ycmd/test_endpoints.js +120 -0
  456. package/ts_build/tests/manual/ycmd/test_endpoints.js.map +1 -0
  457. package/ts_build/tests/manual/ycmd/test_final_comprehensive.d.ts +2 -0
  458. package/ts_build/tests/manual/ycmd/test_final_comprehensive.js +221 -0
  459. package/ts_build/tests/manual/ycmd/test_final_comprehensive.js.map +1 -0
  460. package/ts_build/tests/manual/ycmd/test_final_validation.d.ts +2 -0
  461. package/ts_build/tests/manual/ycmd/test_final_validation.js +160 -0
  462. package/ts_build/tests/manual/ycmd/test_final_validation.js.map +1 -0
  463. package/ts_build/tests/manual/ycmd/test_individual_ycmd_tool.d.ts +2 -0
  464. package/ts_build/tests/manual/ycmd/test_individual_ycmd_tool.js +37 -0
  465. package/ts_build/tests/manual/ycmd/test_individual_ycmd_tool.js.map +1 -0
  466. package/ts_build/tests/manual/ycmd/test_server_manager.d.ts +1 -0
  467. package/ts_build/tests/manual/ycmd/test_server_manager.js +38 -0
  468. package/ts_build/tests/manual/ycmd/test_server_manager.js.map +1 -0
  469. package/ts_build/tests/manual/ycmd/test_simple_debug.d.ts +2 -0
  470. package/ts_build/tests/manual/ycmd/test_simple_debug.js +99 -0
  471. package/ts_build/tests/manual/ycmd/test_simple_debug.js.map +1 -0
  472. package/ts_build/tests/manual/ycmd/test_tsserver_workflow.d.ts +1 -0
  473. package/ts_build/tests/manual/ycmd/test_tsserver_workflow.js +128 -0
  474. package/ts_build/tests/manual/ycmd/test_tsserver_workflow.js.map +1 -0
  475. package/ts_build/tests/manual/ycmd/test_typescript_simple.d.ts +1 -0
  476. package/ts_build/tests/manual/ycmd/test_typescript_simple.js +66 -0
  477. package/ts_build/tests/manual/ycmd/test_typescript_simple.js.map +1 -0
  478. package/ts_build/tests/manual/ycmd/test_typescript_ycmd.d.ts +1 -0
  479. package/ts_build/tests/manual/ycmd/test_typescript_ycmd.js +105 -0
  480. package/ts_build/tests/manual/ycmd/test_typescript_ycmd.js.map +1 -0
  481. package/ts_build/tests/manual/ycmd/test_workspace_config.d.ts +1 -0
  482. package/ts_build/tests/manual/ycmd/test_workspace_config.js +89 -0
  483. package/ts_build/tests/manual/ycmd/test_workspace_config.js.map +1 -0
  484. package/ts_build/tests/manual/ycmd/test_ycmd_auto_start.d.ts +2 -0
  485. package/ts_build/tests/manual/ycmd/test_ycmd_auto_start.js +130 -0
  486. package/ts_build/tests/manual/ycmd/test_ycmd_auto_start.js.map +1 -0
  487. package/ts_build/tests/manual/ycmd/test_ycmd_comprehensive.d.ts +1 -0
  488. package/ts_build/tests/manual/ycmd/test_ycmd_comprehensive.js +83 -0
  489. package/ts_build/tests/manual/ycmd/test_ycmd_comprehensive.js.map +1 -0
  490. package/ts_build/tests/manual/ycmd/test_ycmd_direct.d.ts +2 -0
  491. package/ts_build/tests/manual/ycmd/test_ycmd_direct.js +149 -0
  492. package/ts_build/tests/manual/ycmd/test_ycmd_direct.js.map +1 -0
  493. package/ts_build/tests/manual/ycmd/test_ycmd_experiment.d.ts +15 -0
  494. package/ts_build/tests/manual/ycmd/test_ycmd_experiment.js +58 -0
  495. package/ts_build/tests/manual/ycmd/test_ycmd_experiment.js.map +1 -0
  496. package/ts_build/tests/manual/ycmd/test_ycmd_final.d.ts +2 -0
  497. package/ts_build/tests/manual/ycmd/test_ycmd_final.js +195 -0
  498. package/ts_build/tests/manual/ycmd/test_ycmd_final.js.map +1 -0
  499. package/ts_build/tests/manual/ycmd/test_ycmd_integration.d.ts +3 -0
  500. package/ts_build/tests/manual/ycmd/test_ycmd_integration.js +110 -0
  501. package/ts_build/tests/manual/ycmd/test_ycmd_integration.js.map +1 -0
  502. package/ts_build/tests/manual/ycmd/test_ycmd_simple.d.ts +2 -0
  503. package/ts_build/tests/manual/ycmd/test_ycmd_simple.js +36 -0
  504. package/ts_build/tests/manual/ycmd/test_ycmd_simple.js.map +1 -0
  505. package/ts_build/tests/manual/ycmd/working_simple_test.d.ts +2 -0
  506. package/ts_build/tests/manual/ycmd/working_simple_test.js +134 -0
  507. package/ts_build/tests/manual/ycmd/working_simple_test.js.map +1 -0
  508. package/tsconfig.json +3 -1
@@ -0,0 +1,425 @@
1
+ import { Message } from "../clients/types";
2
+ import { MessageProcessorFunction } from "../services/MessageProcessor";
3
+ import { ToolsService } from "../services";
4
+ import { Tool } from "../clients";
5
+
6
+ interface VariableStorage {
7
+ [name: string]: any;
8
+ }
9
+
10
+ export class CustomVariables {
11
+ private variables: VariableStorage = {};
12
+ private setVariableToolName = "setVariable";
13
+ private getVariableToolName = "getVariable";
14
+ private storeToolCallToolName = "storeToolCallToVariable";
15
+ private listVariablesToolName = "listVariables";
16
+ private deleteVariableToolName = "deleteVariable";
17
+
18
+ constructor(private toolsService: ToolsService) {
19
+ this.registerTools(toolsService);
20
+ }
21
+
22
+ /**
23
+ * Validates variable names - alphanumeric and underscore allowed
24
+ */
25
+ private isValidVariableName(name: string): boolean {
26
+ return /^[a-zA-Z0-9_]+$/.test(name);
27
+ }
28
+
29
+ /**
30
+ * Sets a variable value
31
+ */
32
+ private setVariable(name: string, contents: any): string {
33
+ if (!this.isValidVariableName(name)) {
34
+ return `Error: Invalid variable name "${name}". Only alphanumeric characters and underscores are allowed.`;
35
+ }
36
+
37
+ this.variables[name] = contents;
38
+ return `Variable "${name}" has been set successfully.`;
39
+ }
40
+
41
+ /**
42
+ * Gets a variable value
43
+ */
44
+ private getVariable(varName: string): string {
45
+ if (!this.isValidVariableName(varName)) {
46
+ return `Error: Invalid variable name "${varName}". Only alphanumeric characters and underscores are allowed.`;
47
+ }
48
+
49
+ if (!(varName in this.variables)) {
50
+ return `Error: Variable "${varName}" is not defined. Available variables: ${Object.keys(
51
+ this.variables
52
+ ).join(", ")}`;
53
+ }
54
+
55
+ const value = this.variables[varName];
56
+ if (typeof value === "string") {
57
+ return value;
58
+ }
59
+ return JSON.stringify(value, null, 2);
60
+ }
61
+
62
+ /**
63
+ * Stores the result of a tool call to a variable
64
+ */
65
+ private async storeToolCallToVariable(
66
+ varName: string,
67
+ toolName: string,
68
+ toolArgs: string
69
+ ): Promise<string> {
70
+ if (!this.isValidVariableName(varName)) {
71
+ return `Error: Invalid variable name "${varName}". Only alphanumeric characters and underscores are allowed.`;
72
+ }
73
+
74
+ try {
75
+ // Parse tool arguments
76
+ let parsedArgs: any;
77
+ try {
78
+ parsedArgs = JSON.parse(toolArgs);
79
+ } catch {
80
+ return `Error: Invalid JSON in toolArgs parameter: ${toolArgs}`;
81
+ }
82
+
83
+ const result = await this.toolsService.callTool({
84
+ id: `${toolName}-${Date.now()}`,
85
+ type: "function",
86
+ function: {
87
+ name: toolName,
88
+ arguments: parsedArgs,
89
+ },
90
+ });
91
+ this.variables[varName] = result;
92
+
93
+ return `Tool call result for "${toolName}" has been stored in variable "${varName}".`;
94
+ } catch (error: any) {
95
+ return `Error storing tool call result: ${error.message}`;
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Lists all stored variables with their values
101
+ */
102
+ private listVariables(): string {
103
+ const variableNames = Object.keys(this.variables);
104
+
105
+ if (variableNames.length === 0) {
106
+ return "No variables are currently stored.";
107
+ }
108
+
109
+ const variableList = variableNames.map(name => {
110
+ const value = this.variables[name];
111
+ const preview = typeof value === "string"
112
+ ? (value.length > 50 ? value.substring(0, 50) + "..." : value)
113
+ : JSON.stringify(value).substring(0, 50) + (JSON.stringify(value).length > 50 ? "..." : "");
114
+ return `- ${name}: ${preview}`;
115
+ }).join("\n");
116
+
117
+ return `Currently stored variables (${variableNames.length}):\n${variableList}`;
118
+ }
119
+
120
+ /**
121
+ * Deletes a specific variable
122
+ */
123
+ private deleteVariable(varName: string): string {
124
+ if (!this.isValidVariableName(varName)) {
125
+ return `Error: Invalid variable name "${varName}". Only alphanumeric characters and underscores are allowed.`;
126
+ }
127
+
128
+ if (!(varName in this.variables)) {
129
+ return `Error: Variable "${varName}" is not defined. Available variables: ${Object.keys(
130
+ this.variables
131
+ ).join(", ")}`;
132
+ }
133
+
134
+ delete this.variables[varName];
135
+ return `Variable "${varName}" has been deleted successfully.`;
136
+ }
137
+
138
+ /**
139
+ * Recursively processes a value to substitute {{variable}} patterns
140
+ */
141
+ private substituteVariables(
142
+ value: any,
143
+ processedVars: Set<string> = new Set()
144
+ ): any {
145
+ if (typeof value === "string") {
146
+ // Find all {{variable}} patterns
147
+ return value.replace(/\{\{([a-zA-Z0-9_]+)\}\}/g, (match, varName) => {
148
+ // Prevent infinite recursion
149
+ if (processedVars.has(varName)) {
150
+ return `{{ERROR: Circular reference detected for variable "${varName}"}}`;
151
+ }
152
+
153
+ if (!(varName in this.variables)) {
154
+ return `{{ERROR: Variable "${varName}" is not defined}}`;
155
+ }
156
+
157
+ const varValue = this.variables[varName];
158
+
159
+ // If the variable value is a string, recursively process it
160
+ if (typeof varValue === "string") {
161
+ const newProcessedVars = new Set(processedVars);
162
+ newProcessedVars.add(varName);
163
+ return this.substituteVariables(varValue, newProcessedVars);
164
+ }
165
+
166
+ // For non-string values, convert to JSON
167
+ return JSON.stringify(varValue);
168
+ });
169
+ }
170
+
171
+ if (Array.isArray(value)) {
172
+ return value.map((item) => this.substituteVariables(item, processedVars));
173
+ }
174
+
175
+ if (value && typeof value === "object") {
176
+ const result: any = {};
177
+ for (const [key, val] of Object.entries(value)) {
178
+ result[key] = this.substituteVariables(val, processedVars);
179
+ }
180
+ return result;
181
+ }
182
+
183
+ return value;
184
+ }
185
+
186
+ /**
187
+ * Processes messages to substitute variables in content and tool call arguments
188
+ */
189
+ private processMessage(message: Message): Message {
190
+ // Create a copy of the message to avoid mutating the original
191
+ const processedMessage: Message = { ...message };
192
+
193
+ // Process message content
194
+ if (typeof processedMessage.content === "string") {
195
+ processedMessage.content = this.substituteVariables(
196
+ processedMessage.content
197
+ );
198
+ }
199
+
200
+ // Process tool calls if they exist
201
+ if (processedMessage.tool_calls) {
202
+ processedMessage.tool_calls = processedMessage.tool_calls.map(
203
+ (toolCall) => ({
204
+ ...toolCall,
205
+ function: {
206
+ ...toolCall.function,
207
+ arguments: this.substituteVariables(toolCall.function.arguments),
208
+ },
209
+ })
210
+ );
211
+ }
212
+
213
+ return processedMessage;
214
+ }
215
+
216
+ /**
217
+ * Creates a message processor function that substitutes variables in messages
218
+ */
219
+ createProcessor(
220
+ filterFn?: (msg: Message) => boolean
221
+ ): MessageProcessorFunction {
222
+ return async (originalMessages: Message[], modifiedMessages: Message[]) => {
223
+ // Process messages in place - substitute variables before tool calls are executed
224
+ for (let i = 0; i < modifiedMessages.length; i++) {
225
+ const message = modifiedMessages[i];
226
+
227
+ if (filterFn && !filterFn(message)) {
228
+ continue;
229
+ }
230
+
231
+ // Apply variable substitution
232
+ modifiedMessages[i] = this.processMessage(message);
233
+ }
234
+ };
235
+ }
236
+
237
+ /**
238
+ * Registers all custom variable tools with the ToolsService
239
+ */
240
+ private registerTools(toolsService: ToolsService): void {
241
+ // Register setVariable tool
242
+ if (!toolsService.getTool(this.setVariableToolName)) {
243
+ toolsService.addTool(setVariableToolDefinition);
244
+ toolsService.addFunctions({
245
+ [this.setVariableToolName]: (name: string, contents: any) => {
246
+ return this.setVariable(name, contents);
247
+ },
248
+ });
249
+ }
250
+
251
+ // Register getVariable tool
252
+ if (!toolsService.getTool(this.getVariableToolName)) {
253
+ toolsService.addTool(getVariableToolDefinition);
254
+ toolsService.addFunctions({
255
+ [this.getVariableToolName]: (varName: string) => {
256
+ return this.getVariable(varName);
257
+ },
258
+ });
259
+ }
260
+
261
+ // Register storeToolCallToVariable tool
262
+ if (!toolsService.getTool(this.storeToolCallToolName)) {
263
+ toolsService.addTool(storeToolCallToVariableDefinition);
264
+ toolsService.addFunctions({
265
+ [this.storeToolCallToolName]: async (
266
+ varName: string,
267
+ toolName: string,
268
+ toolArgs: string
269
+ ) => {
270
+ return await this.storeToolCallToVariable(
271
+ varName,
272
+ toolName,
273
+ toolArgs
274
+ );
275
+ },
276
+ });
277
+ }
278
+
279
+ // Register listVariables tool
280
+ if (!toolsService.getTool(this.listVariablesToolName)) {
281
+ toolsService.addTool(listVariablesToolDefinition);
282
+ toolsService.addFunctions({
283
+ [this.listVariablesToolName]: () => {
284
+ return this.listVariables();
285
+ },
286
+ });
287
+ }
288
+
289
+ // Register deleteVariable tool
290
+ if (!toolsService.getTool(this.deleteVariableToolName)) {
291
+ toolsService.addTool(deleteVariableToolDefinition);
292
+ toolsService.addFunctions({
293
+ [this.deleteVariableToolName]: (varName: string) => {
294
+ return this.deleteVariable(varName);
295
+ },
296
+ });
297
+ }
298
+ }
299
+
300
+ /**
301
+ * Gets all variable names
302
+ */
303
+ getVariableNames(): string[] {
304
+ return Object.keys(this.variables);
305
+ }
306
+
307
+ /**
308
+ * Clears all variables
309
+ */
310
+ clearVariables(): void {
311
+ this.variables = {};
312
+ }
313
+
314
+ /**
315
+ * Gets the number of stored variables
316
+ */
317
+ getVariableCount(): number {
318
+ return Object.keys(this.variables).length;
319
+ }
320
+ }
321
+
322
+ export const setVariableToolDefinition: Tool = {
323
+ type: "function",
324
+ function: {
325
+ name: "setVariable",
326
+ description:
327
+ "Store a value in a variable for later use. The variable can then be referenced using {{variableName}} syntax in messages or tool calls.",
328
+ parameters: {
329
+ type: "object",
330
+ positional: true,
331
+ properties: {
332
+ name: {
333
+ type: "string",
334
+ description:
335
+ "The name of the variable (alphanumeric and underscore only)",
336
+ },
337
+ contents: {
338
+ type: "string",
339
+ description: "The value to store in the variable",
340
+ },
341
+ },
342
+ required: ["name", "contents"],
343
+ },
344
+ },
345
+ };
346
+
347
+ export const getVariableToolDefinition: Tool = {
348
+ type: "function",
349
+ function: {
350
+ name: "getVariable",
351
+ description: "Retrieve the value of a previously stored variable.",
352
+ parameters: {
353
+ type: "object",
354
+ positional: true,
355
+ properties: {
356
+ varName: {
357
+ type: "string",
358
+ description: "The name of the variable to retrieve",
359
+ },
360
+ },
361
+ required: ["varName"],
362
+ },
363
+ },
364
+ };
365
+
366
+ export const storeToolCallToVariableDefinition: Tool = {
367
+ type: "function",
368
+ function: {
369
+ name: "storeToolCallToVariable",
370
+ description:
371
+ "Execute a tool call and store its result in a variable for later use.",
372
+ parameters: {
373
+ type: "object",
374
+ positional: true,
375
+ properties: {
376
+ varName: {
377
+ type: "string",
378
+ description: "The name of the variable to store the result in",
379
+ },
380
+ toolName: {
381
+ type: "string",
382
+ description: "The name of the tool to call",
383
+ },
384
+ toolArgs: {
385
+ type: "string",
386
+ description: "The arguments for the tool call as a JSON string",
387
+ },
388
+ },
389
+ required: ["varName", "toolName", "toolArgs"],
390
+ },
391
+ },
392
+ };
393
+
394
+ export const listVariablesToolDefinition: Tool = {
395
+ type: "function",
396
+ function: {
397
+ name: "listVariables",
398
+ description: "List all currently stored variables with their values.",
399
+ parameters: {
400
+ type: "object",
401
+ positional: false,
402
+ properties: {},
403
+ required: [],
404
+ },
405
+ },
406
+ };
407
+
408
+ export const deleteVariableToolDefinition: Tool = {
409
+ type: "function",
410
+ function: {
411
+ name: "deleteVariable",
412
+ description: "Delete a specific variable from storage.",
413
+ parameters: {
414
+ type: "object",
415
+ positional: true,
416
+ properties: {
417
+ varName: {
418
+ type: "string",
419
+ description: "The name of the variable to delete",
420
+ },
421
+ },
422
+ required: ["varName"],
423
+ },
424
+ },
425
+ };
@@ -0,0 +1,264 @@
1
+ import { Message, ToolCall } from "../clients/types";
2
+ import { MessageProcessorFunction } from "../services/MessageProcessor";
3
+
4
+ export class HarmonyToolProcessor {
5
+ private static instance: HarmonyToolProcessor;
6
+
7
+ /**
8
+ * Get singleton instance
9
+ */
10
+ static getInstance(): HarmonyToolProcessor {
11
+ if (!HarmonyToolProcessor.instance) {
12
+ HarmonyToolProcessor.instance = new HarmonyToolProcessor();
13
+ }
14
+ return HarmonyToolProcessor.instance;
15
+ }
16
+
17
+ /**
18
+ * Detects Harmony tool call patterns in text content
19
+ * Looks for patterns like: <|channel|>commentary to=functions.toolName <|constrain|>json<|message|>{"args":"value"}
20
+ */
21
+ private detectHarmonyToolCalls(
22
+ content: string
23
+ ): { toolName: string; arguments: string; fullMatch: string }[] {
24
+ const toolCalls: {
25
+ toolName: string;
26
+ arguments: string;
27
+ fullMatch: string;
28
+ }[] = [];
29
+
30
+ // Pattern to match Harmony tool calls:
31
+ // <|channel|>commentary to=functions.toolName <|constrain|>json<|message|>{"args":"value"}
32
+ // Updated to handle multiline JSON with balanced braces
33
+ const harmonyPattern =
34
+ /<\|channel\|>commentary\s+to=functions\.([a-zA-Z_][a-zA-Z0-9_]*)\s*<\|constrain\|>json<\|message\|>([\s\S]*?)(?=<\|(?!message\|)|$)/g;
35
+
36
+ let match;
37
+ while ((match = harmonyPattern.exec(content)) !== null) {
38
+ const [fullMatch, toolName, potentialJson] = match;
39
+
40
+ // Extract JSON from the potential content
41
+ const jsonArgs = this.extractJsonFromContent(potentialJson.trim());
42
+
43
+ // Validate that we have both tool name and valid JSON arguments
44
+ if (toolName && jsonArgs) {
45
+ toolCalls.push({
46
+ toolName: toolName.trim(),
47
+ arguments: jsonArgs,
48
+ fullMatch,
49
+ });
50
+ }
51
+ }
52
+
53
+ return toolCalls;
54
+ }
55
+
56
+ /**
57
+ * Detects Harmony final patterns in text content
58
+ * Looks for patterns like: <|channel|>final<|message|>content or <|final|>
59
+ */
60
+ private detectHarmonyFinalCalls(
61
+ content: string
62
+ ): { toolName: string; arguments: string; fullMatch: string }[] {
63
+ const toolCalls: {
64
+ toolName: string;
65
+ arguments: string;
66
+ fullMatch: string;
67
+ }[] = [];
68
+
69
+ // Pattern 1: <|channel|>final<|message|>content
70
+ const finalChannelPattern = /<\|channel\|>final<\|message\|>([\s\S]*?)(?=<\||$)/g;
71
+ let match;
72
+ while ((match = finalChannelPattern.exec(content)) !== null) {
73
+ const [fullMatch, messageContent] = match;
74
+ toolCalls.push({
75
+ toolName: "finalAnswer",
76
+ arguments: JSON.stringify({ answer: messageContent.trim() }),
77
+ fullMatch,
78
+ });
79
+ }
80
+
81
+ // Pattern 2: <|final|> (use remaining content as answer)
82
+ const finalTokenPattern = /<\|final\|>([\s\S]*?)(?=<\||$)/g;
83
+ while ((match = finalTokenPattern.exec(content)) !== null) {
84
+ const [fullMatch, messageContent] = match;
85
+ toolCalls.push({
86
+ toolName: "finalAnswer",
87
+ arguments: JSON.stringify({ answer: messageContent.trim() || "Done" }),
88
+ fullMatch,
89
+ });
90
+ }
91
+
92
+ return toolCalls;
93
+ }
94
+
95
+ /**
96
+ * Extracts JSON from content that may contain JSON along with other text
97
+ */
98
+ private extractJsonFromContent(content: string): string | null {
99
+ // Try to find the JSON object boundaries
100
+ const jsonMatch = content.match(/(\{[\s\S]*\})/);
101
+ if (jsonMatch) {
102
+ const jsonCandidate = jsonMatch[1].trim();
103
+
104
+ // Validate it's proper JSON
105
+ try {
106
+ JSON.parse(jsonCandidate);
107
+ return jsonCandidate;
108
+ } catch (error) {
109
+ // If invalid, return null so it gets skipped
110
+ return null;
111
+ }
112
+ }
113
+ return null;
114
+ }
115
+
116
+ /**
117
+ * Validates and cleans JSON arguments
118
+ */
119
+ private validateAndCleanArguments(jsonString: string): string {
120
+ try {
121
+ // Parse and re-stringify to ensure valid JSON
122
+ const parsed = JSON.parse(jsonString);
123
+ return JSON.stringify(parsed);
124
+ } catch (error) {
125
+ // If JSON is invalid, try to fix common issues
126
+ try {
127
+ // Remove trailing commas
128
+ let cleaned = jsonString.replace(/,(\s*[}\]])/g, "$1");
129
+
130
+ // Fix unquoted keys
131
+ cleaned = cleaned.replace(
132
+ /([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g,
133
+ '$1"$2":'
134
+ );
135
+
136
+ const parsed = JSON.parse(cleaned);
137
+ return JSON.stringify(parsed);
138
+ } catch (secondError) {
139
+ // If all else fails, wrap in a generic structure
140
+ return JSON.stringify({ input: jsonString });
141
+ }
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Generates a unique tool call ID
147
+ */
148
+ private generateToolCallId(): string {
149
+ return `harmony_call_${Date.now()}_${Math.random()
150
+ .toString(36)
151
+ .substr(2, 9)}`;
152
+ }
153
+
154
+ /**
155
+ * Converts Harmony tool call matches to proper ToolCall objects
156
+ */
157
+ private convertHarmonyToToolCalls(
158
+ matches: { toolName: string; arguments: string; fullMatch: string }[]
159
+ ): ToolCall[] {
160
+ const toolCalls: ToolCall[] = [];
161
+
162
+ for (const match of matches) {
163
+ const { toolName, arguments: jsonArgs } = match;
164
+
165
+ if (!toolName) continue;
166
+
167
+ const toolCall: ToolCall = {
168
+ id: this.generateToolCallId(),
169
+ type: "function",
170
+ function: {
171
+ name: toolName,
172
+ arguments: this.validateAndCleanArguments(jsonArgs),
173
+ },
174
+ };
175
+
176
+ toolCalls.push(toolCall);
177
+ }
178
+
179
+ return toolCalls;
180
+ }
181
+
182
+ /**
183
+ * Checks if content contains Harmony format patterns
184
+ */
185
+ private isHarmonyFormat(content: string): boolean {
186
+ // Look for key Harmony format indicators
187
+ return (
188
+ (content.includes("<|channel|>") &&
189
+ content.includes("to=functions.") &&
190
+ content.includes("<|constrain|>json<|message|>")) ||
191
+ // Also detect final patterns
192
+ content.includes("<|channel|>final<|message|>") ||
193
+ content.includes("<|final|>") ||
194
+ // Also detect finalAnswer channel pattern
195
+ content.includes("<|channel|>finalAnswer<|message|>")
196
+ );
197
+ }
198
+
199
+ /**
200
+ * Processes a single message to detect and transform Harmony tool calls
201
+ */
202
+ private processMessage(message: Message): void {
203
+ // Only process assistant messages that might contain Harmony tool calls
204
+ if (message.role !== "assistant") {
205
+ return;
206
+ }
207
+
208
+ // Only process string content
209
+ if (typeof message.content !== "string") {
210
+ return;
211
+ }
212
+
213
+ // Skip if message already has tool calls
214
+ if (message?.tool_calls?.length) {
215
+ return;
216
+ }
217
+
218
+ // Skip if this doesn't look like Harmony format
219
+ if (!this.isHarmonyFormat(message.content)) {
220
+ return;
221
+ }
222
+
223
+ const matches = this.detectHarmonyToolCalls(message.content);
224
+
225
+ // Also check for final patterns
226
+ const finalMatches = this.detectHarmonyFinalCalls(message.content);
227
+
228
+ // Combine all matches
229
+ const allMatches = [...matches, ...finalMatches];
230
+
231
+ if (allMatches.length === 0) {
232
+ return;
233
+ }
234
+
235
+ // Convert matches to proper tool calls
236
+ const toolCalls = this.convertHarmonyToToolCalls(allMatches);
237
+
238
+ if (allMatches.length === 0) {
239
+ return;
240
+ }
241
+
242
+ // Add tool calls to the message (merge with existing if any)
243
+ if (message.tool_calls) {
244
+ message.tool_calls.push(...toolCalls);
245
+ } else {
246
+ message.tool_calls = toolCalls;
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Creates a message processor function for post_call processing
252
+ */
253
+ createProcessor(): MessageProcessorFunction {
254
+ return (originalMessages: Message[], modifiedMessages: Message[]): void => {
255
+ // Process each message in the modified messages array
256
+ for (const message of modifiedMessages) {
257
+ this.processMessage(message);
258
+ }
259
+ };
260
+ }
261
+ }
262
+
263
+ // Global instance for easy access
264
+ export const globalHarmonyToolProcessor = new HarmonyToolProcessor();