@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,118 @@
1
+ import {
2
+ GenericClient,
3
+ CompletionOptions,
4
+ CompletionResponse,
5
+ EmbeddingOptions,
6
+ EmbeddingResponse,
7
+ } from "./types";
8
+ import { McpService } from "../services/Mcp";
9
+
10
+ /*
11
+ *
12
+ * If an MCP supports the following methods, then we can use it as a generic client.
13
+ * Once it's a generic client, it can be used by agents, or any other part of the system that leverages Clients
14
+ */
15
+ export class KnowhowMcpClient implements GenericClient {
16
+ private mcpService: McpService;
17
+
18
+ constructor(mcpService: McpService, private handlesConnection = false) {
19
+ this.mcpService = mcpService;
20
+ }
21
+
22
+ setKey(key: string) {
23
+ return;
24
+ }
25
+
26
+ async connect(): Promise<void> {
27
+ if (this.handlesConnection) {
28
+ await this.mcpService.connectAll();
29
+ }
30
+ }
31
+
32
+ async disconnect(): Promise<void> {
33
+ if (this.handlesConnection) {
34
+ await this.mcpService.closeTransports();
35
+ }
36
+ }
37
+
38
+ async callFunction<T>(
39
+ toolName: string,
40
+ args: Record<string, any>
41
+ ): Promise<T> {
42
+ try {
43
+ await this.connect();
44
+ const result = await this.mcpService.callFunction<T>(toolName, args);
45
+ return result as T;
46
+ } catch (error) {
47
+ console.error("Error calling MCP function:", toolName, args);
48
+ console.error(error);
49
+ } finally {
50
+ await this.disconnect();
51
+ }
52
+ }
53
+
54
+ async createChatCompletion(
55
+ options: CompletionOptions & { provider: string }
56
+ ): Promise<CompletionResponse> {
57
+ const data = await this.callFunction<CompletionResponse>(
58
+ "createAiCompletion",
59
+ {
60
+ provider: options.provider || "",
61
+ options: {
62
+ ...options,
63
+ max_tokens: options.max_tokens || 3000,
64
+
65
+ ...(options.tools && {
66
+ tools: options.tools,
67
+ tool_choice: "auto",
68
+ }),
69
+ },
70
+ }
71
+ );
72
+
73
+ console.log("Completion Response:", JSON.stringify(data, null, 2));
74
+
75
+ return data;
76
+ }
77
+
78
+ async createEmbedding(
79
+ options: EmbeddingOptions & { provider: string }
80
+ ): Promise<EmbeddingResponse> {
81
+ return this.callFunction<EmbeddingResponse>("createEmbedding", {
82
+ provider: options.provider || "",
83
+ options: {
84
+ ...options,
85
+ },
86
+ });
87
+ }
88
+
89
+ async getModels(): Promise<{ id: string }[]> {
90
+ try {
91
+ const parsedResult = await this.callFunction<any>("listAllModels", {});
92
+ // Convert the models object to the expected format
93
+ if (typeof parsedResult === "object") {
94
+ const models: { id: string }[] = [];
95
+
96
+ // Handle case where result is already an array of {id: string}
97
+ if (Array.isArray(parsedResult)) {
98
+ return parsedResult;
99
+ }
100
+
101
+ // Handle case where result is {provider: [model1, model2]}
102
+ for (const [provider, modelList] of Object.entries(parsedResult)) {
103
+ if (Array.isArray(modelList)) {
104
+ for (const model of modelList) {
105
+ models.push({ id: `${provider}/${model}` });
106
+ }
107
+ }
108
+ }
109
+
110
+ return models;
111
+ }
112
+
113
+ throw new Error("Invalid response format from MCP service");
114
+ } catch (error) {
115
+ throw new Error(`Failed to get models via MCP: ${error.message}`);
116
+ }
117
+ }
118
+ }
@@ -17,10 +17,18 @@ import { EmbeddingModels, Models, OpenAiReasoningModels } from "../types";
17
17
 
18
18
  const config = getConfigSync();
19
19
 
20
- export class GenericOpenAiClient extends OpenAI implements GenericClient {
21
- constructor() {
22
- super({
23
- apiKey: process.env.OPENAI_KEY,
20
+ export class GenericOpenAiClient implements GenericClient {
21
+ client: OpenAI;
22
+ apiKey?: string;
23
+
24
+ constructor(apiKey = process.env.OPENAI_KEY) {
25
+ this.setKey(apiKey);
26
+ }
27
+
28
+ setKey(apiKey: string) {
29
+ this.apiKey = apiKey;
30
+ this.client = new OpenAI({
31
+ apiKey,
24
32
  ...(config.openaiBaseUrl && { baseURL: config.openaiBaseUrl }),
25
33
  });
26
34
  }
@@ -40,13 +48,14 @@ export class GenericOpenAiClient extends OpenAI implements GenericClient {
40
48
  return msg as ChatCompletionMessageParam;
41
49
  });
42
50
 
43
- const response = await this.chat.completions.create({
51
+ const response = await this.client.chat.completions.create({
44
52
  model: options.model,
45
53
  messages: openaiMessages,
46
54
  max_tokens: options.max_tokens,
47
55
  ...(OpenAiReasoningModels.includes(options.model) && {
48
56
  max_tokens: undefined,
49
- max_completion_tokens: options.max_tokens,
57
+ max_completion_tokens: Math.max(options.max_tokens, 100),
58
+ // Health check requires some thoughts
50
59
  }),
51
60
 
52
61
  ...(options.tools && {
@@ -166,6 +175,21 @@ export class GenericOpenAiClient extends OpenAI implements GenericClient {
166
175
  cached_input: 0,
167
176
  output: 10.0,
168
177
  },
178
+ [Models.openai.GPT_5]: {
179
+ input: 1.25,
180
+ cached_input: 0.125,
181
+ output: 10,
182
+ },
183
+ [Models.openai.GPT_5_Mini]: {
184
+ input: 0.25,
185
+ cached_input: 0.025,
186
+ output: 2,
187
+ },
188
+ [Models.openai.GPT_5_Nano]: {
189
+ input: 0.05,
190
+ cached_input: 0.005,
191
+ output: 0.4,
192
+ },
169
193
  /*
170
194
  *[Models.openai.Computer_Use]: {
171
195
  * input: 3.0,
@@ -226,7 +250,7 @@ export class GenericOpenAiClient extends OpenAI implements GenericClient {
226
250
  }
227
251
 
228
252
  async getModels() {
229
- const models = await this.models.list();
253
+ const models = await this.client.models.list();
230
254
  return models.data.map((m) => {
231
255
  return {
232
256
  id: m.id,
@@ -237,7 +261,7 @@ export class GenericOpenAiClient extends OpenAI implements GenericClient {
237
261
  }
238
262
 
239
263
  async createEmbedding(options: EmbeddingOptions): Promise<EmbeddingResponse> {
240
- const openAiEmbedding = await this.embeddings.create({
264
+ const openAiEmbedding = await this.client.embeddings.create({
241
265
  input: options.input,
242
266
  model: options.model,
243
267
  });
@@ -85,6 +85,7 @@ export interface EmbeddingResponse {
85
85
  }
86
86
 
87
87
  export interface GenericClient {
88
+ setKey(key: string): void;
88
89
  createChatCompletion(options: CompletionOptions): Promise<CompletionResponse>;
89
90
  createEmbedding(options: EmbeddingOptions): Promise<EmbeddingResponse>;
90
91
  getModels(): Promise<{ id: string }[]>;
@@ -16,10 +16,22 @@ import { Models } from "../types";
16
16
 
17
17
  const config = getConfigSync();
18
18
 
19
- export class GenericXAIClient extends OpenAI implements GenericClient {
20
- constructor() {
21
- super({
22
- apiKey: process.env.XAI_API_KEY,
19
+ export class GenericXAIClient implements GenericClient {
20
+ private client: OpenAI;
21
+ private apiKey: string;
22
+
23
+ constructor(apiKey = process.env.XAI_API_KEY) {
24
+ this.apiKey = apiKey || "";
25
+ this.client = new OpenAI({
26
+ apiKey: apiKey || process.env.XAI_API_KEY,
27
+ baseURL: "https://api.x.ai/v1",
28
+ });
29
+ }
30
+
31
+ setKey(apiKey: string) {
32
+ this.apiKey = apiKey;
33
+ this.client = new OpenAI({
34
+ apiKey,
23
35
  baseURL: "https://api.x.ai/v1",
24
36
  });
25
37
  }
@@ -39,7 +51,7 @@ export class GenericXAIClient extends OpenAI implements GenericClient {
39
51
  return msg as ChatCompletionMessageParam;
40
52
  });
41
53
 
42
- const response = await this.chat.completions.create({
54
+ const response = await this.client.chat.completions.create({
43
55
  model: options.model,
44
56
  messages: xaiMessages,
45
57
  max_tokens: options.max_tokens,
package/src/config.ts CHANGED
@@ -73,6 +73,14 @@ const defaultConfig = {
73
73
  ],
74
74
 
75
75
  modelProviders: [{ url: "http://localhost:1234", provider: "lms" }],
76
+
77
+ ycmd: {
78
+ enabled: false,
79
+ installPath: undefined, // Will default to ~/.knowhow/ycmd
80
+ port: 0, // 0 for auto-assign
81
+ logLevel: "info",
82
+ completionTimeout: 5000,
83
+ },
76
84
  } as Config;
77
85
 
78
86
  const defaultLanguage = {
@@ -148,6 +156,14 @@ export async function updateLanguageConfig(language: Language) {
148
156
  }
149
157
 
150
158
  export async function updateConfig(config: Config) {
159
+ if (!config || typeof config !== "object") {
160
+ throw new Error("Invalid config object");
161
+ }
162
+
163
+ await fs.promises.copyFile(
164
+ ".knowhow/knowhow.json",
165
+ ".knowhow/knowhow.json.bak"
166
+ );
151
167
  await writeFile(".knowhow/knowhow.json", JSON.stringify(config, null, 2));
152
168
  }
153
169
 
@@ -185,15 +201,24 @@ export function getConfigSync() {
185
201
  }
186
202
  }
187
203
 
204
+ let loggedWarning = false;
188
205
  export async function getConfig() {
189
206
  if (!fs.existsSync(".knowhow/knowhow.json")) {
190
- console.warn(
191
- "KnowHow config file not found. Please run `knowhow init` to create it."
192
- );
207
+ if (!loggedWarning) {
208
+ loggedWarning = true;
209
+ console.warn(
210
+ "KnowHow config file not found. Please run `knowhow init` to create it."
211
+ );
212
+ }
193
213
  return {} as Config;
194
214
  }
195
- const config = JSON.parse(await readFile(".knowhow/knowhow.json", "utf8"));
196
- return config as Config;
215
+ try {
216
+ const config = await readFile(".knowhow/knowhow.json", "utf8");
217
+ return JSON.parse(config) as Config;
218
+ } catch (error) {
219
+ console.error("Error reading .knowhow/knowhow.json:", error);
220
+ throw new Error("Failed to load KnowHow configuration.");
221
+ }
197
222
  }
198
223
 
199
224
  export async function loadPrompt(promptName: string) {
package/src/conversion.ts CHANGED
@@ -2,7 +2,7 @@ import pdf from "pdf-parse";
2
2
  import * as fs from "fs";
3
3
  import * as path from "path";
4
4
  import { readFile, fileExists } from "./utils";
5
- import { Downloader } from "./plugins/downloader/downloader";
5
+ import { services } from "./services";
6
6
 
7
7
  export async function processAudio(
8
8
  filePath: string,
@@ -21,6 +21,7 @@ export async function processAudio(
21
21
  : JSON.parse(fileContent);
22
22
  }
23
23
 
24
+ const { Downloader } = services();
24
25
  const chunks = await Downloader.chunk(
25
26
  filePath,
26
27
  parsed.dir,
@@ -73,9 +74,11 @@ export async function processVideo(
73
74
  );
74
75
 
75
76
  console.log("Extracting keyframes...");
77
+ const { Downloader } = services();
76
78
  const videoAnalysis = await Downloader.extractKeyframes(
77
79
  filePath,
78
80
  outputPath,
81
+ reusePreviousTranscript,
79
82
  chunkTime
80
83
  );
81
84
 
package/src/embeddings.ts CHANGED
@@ -71,6 +71,46 @@ function getChunkId(id: string, index: number, chunkSize: number) {
71
71
  return chunkSize ? `${id}-${index}` : id;
72
72
  }
73
73
 
74
+ function parseIdFromChunk(chunkName: string) {
75
+ const split = chunkName.split("-");
76
+ if (
77
+ split.length > 1 &&
78
+ Number.isInteger(parseInt(split[split.length - 1], 10))
79
+ ) {
80
+ // already has chunkId
81
+ return split.slice(0, -1).join("-");
82
+ }
83
+ return chunkName;
84
+ }
85
+
86
+ export async function detectDeletedEmbeddingFiles(
87
+ source: Config["embedSources"][0],
88
+ ignorePattern: string[],
89
+ embeddings: Embeddable[]
90
+ ) {
91
+ if (source.kind !== "file") {
92
+ return;
93
+ }
94
+ const inputs = (await glob.sync(source.input, {
95
+ ignore: ignorePattern,
96
+ })) as string[];
97
+
98
+ for (const embedding of embeddings) {
99
+ const id = parseIdFromChunk(embedding.id);
100
+ const dirName = path.dirname(id);
101
+ const exists = await fileExists(path.resolve(id));
102
+
103
+ const hasSomeFilesInDir = inputs.some((input) => input.startsWith(dirName));
104
+ if (hasSomeFilesInDir && !exists) {
105
+ console.log("Detected deleted embedding file", embedding.id);
106
+ const index = embeddings.findIndex((e) => e.id === embedding.id);
107
+ if (index !== -1) {
108
+ embeddings.splice(index, 1);
109
+ }
110
+ }
111
+ }
112
+ }
113
+
74
114
  export async function embedSource(
75
115
  model: Config["embeddingModel"],
76
116
  source: Config["embedSources"][0],
@@ -97,10 +137,8 @@ export async function embedSource(
97
137
  }
98
138
 
99
139
  console.log(`Found ${inputs.length} files`);
100
- if (inputs.length > 100) {
101
- console.error(
102
- "woah there, that's a lot of files. I'm not going to embed that many"
103
- );
140
+ if (inputs.length > 1000) {
141
+ console.error("Large number of files detected. This may take a while");
104
142
  }
105
143
  console.log(inputs);
106
144
  const embeddings: Embeddable[] = await loadEmbedding(source.output);
@@ -108,18 +146,20 @@ export async function embedSource(
108
146
  let index = 0;
109
147
  for (const file of inputs) {
110
148
  index++;
111
- const shouldSave = batch.length > 20 || index === inputs.length;
149
+ const shouldSave = batch.length > 20;
112
150
  if (shouldSave) {
113
151
  await Promise.all(batch);
152
+ await saveEmbedding(source.output, embeddings);
114
153
  batch = [];
115
154
  }
116
- batch.push(embedKind(model, file, source, embeddings, shouldSave));
155
+ batch.push(embedKind(model, file, source, embeddings));
117
156
  }
118
157
  if (batch.length > 0) {
119
158
  await Promise.all(batch);
120
159
  }
121
160
 
122
161
  // Save one last time just in case
162
+ await detectDeletedEmbeddingFiles(source, ignorePattern, embeddings);
123
163
  await saveEmbedding(source.output, embeddings);
124
164
  }
125
165
 
@@ -165,9 +205,31 @@ export async function embed(
165
205
  }
166
206
 
167
207
  dontPrune.push(chunkId);
168
- const alreadyEmbedded = embeddings.find(
169
- (e) => e.id === chunkId && e.text === textOfChunk
170
- );
208
+ const foundMany = embeddings.filter((e) => e.id === chunkId);
209
+ const found = foundMany.length > 0 ? foundMany[0] : null;
210
+ const alreadyEmbedded = found && found.text === textOfChunk;
211
+
212
+ if (foundMany.length > 1) {
213
+ // We have duplicates, so we need to remove them
214
+ console.log(`Removing ${foundMany.length} duplicates for`, chunkId);
215
+
216
+ let toDelete = embeddings.findIndex((e) => e.id === chunkId);
217
+ while (toDelete !== -1) {
218
+ // Keep removing until we find no more duplicates
219
+ embeddings.splice(toDelete, 1);
220
+ toDelete = embeddings.findIndex((e) => e.id === chunkId);
221
+ }
222
+
223
+ if (alreadyEmbedded) {
224
+ // Put back the exact match of the current chunk
225
+ // if this doesn't happen, we need to generate a new embedding
226
+ embeddings.push({
227
+ ...found,
228
+ });
229
+ updates.push(chunkId);
230
+ }
231
+ }
232
+
171
233
  if (alreadyEmbedded) {
172
234
  console.log("Skipping", chunkId);
173
235
  continue;
@@ -235,7 +297,7 @@ export async function embedJson(
235
297
  ) as Embeddable[];
236
298
 
237
299
  const embeddings: Embeddable[] = await loadEmbedding(output);
238
- let updates = [];
300
+ const updates = [];
239
301
  let batch = [];
240
302
 
241
303
  for (const row of sourceJson) {
@@ -264,24 +326,17 @@ export async function embedJson(
264
326
  batch = [];
265
327
  }
266
328
  updates.push(...embedded);
267
-
268
- if (updates.length > 20) {
269
- await saveEmbedding(output, embeddings);
270
- updates = [];
271
- }
272
329
  }
273
330
 
274
331
  // save in case we missed some
275
332
  await Promise.all(batch);
276
- await saveEmbedding(output, embeddings);
277
333
  }
278
334
 
279
335
  export async function embedKind(
280
336
  model: Config["embeddingModel"],
281
337
  id: string,
282
338
  source: Config["embedSources"][0],
283
- embeddings = [] as Embeddable[],
284
- save = true
339
+ embeddings = [] as Embeddable[]
285
340
  ) {
286
341
  const { prompt, output, uploadMode, chunkSize } = source;
287
342
 
@@ -312,10 +367,6 @@ export async function embedKind(
312
367
  );
313
368
  updates.push(...embedded);
314
369
  }
315
-
316
- if (save && updates.length > 0) {
317
- await saveEmbedding(output, embeddings);
318
- }
319
370
  }
320
371
 
321
372
  async function handleFileKind(filePath: string) {
@@ -367,7 +418,12 @@ export async function handleAllKinds(
367
418
 
368
419
  export async function saveEmbedding(output: string, embeddings: Embeddable[]) {
369
420
  const fileString =
370
- "[" + embeddings.map((e) => JSON.stringify(e)).join(",") + "]";
421
+ "[" +
422
+ embeddings
423
+ .sort((a, b) => (a.id < b.id ? -1 : 1))
424
+ .map((e) => JSON.stringify(e))
425
+ .join(",") +
426
+ "]";
371
427
  await writeFile(output, fileString);
372
428
  }
373
429
 
package/src/login.ts CHANGED
@@ -3,22 +3,20 @@ import fs from "fs";
3
3
  import path from "path";
4
4
  import { chmod } from "fs/promises";
5
5
  import { ask } from "./utils";
6
+ import { getConfig, updateConfig } from "./config";
7
+ import { KNOWHOW_API_URL } from "./services/KnowhowClient";
6
8
 
7
- const API_URL = process.env.KNOWHOW_API_URL;
8
-
9
- export async function login(): Promise<void> {
10
- if (!API_URL) {
9
+ export async function login(jwtFlag?: string): Promise<void> {
10
+ if (!KNOWHOW_API_URL) {
11
11
  throw new Error("Error: KNOWHOW_API_URL environment variable not set.");
12
12
  }
13
13
 
14
- const [flag] = process.argv.slice(3);
15
-
16
- if (flag === "--jwt") {
14
+ if (jwtFlag) {
17
15
  const jwt = await ask("Enter your JWT: ");
18
16
 
19
17
  // Update the JWT file
20
18
  const configDir = path.join(process.cwd(), ".knowhow");
21
- const jwtFile = path.join(configDir, ".jwt");
19
+ const jwtFile = path.join(process.cwd(), ".knowhow", ".jwt");
22
20
 
23
21
  if (!fs.existsSync(configDir)) {
24
22
  fs.mkdirSync(configDir, { recursive: true });
@@ -31,7 +29,7 @@ export async function login(): Promise<void> {
31
29
  // Get current user/org information
32
30
  try {
33
31
  const storedJwt = await loadJwt();
34
- const response = await axios.get(`${API_URL}/api/users/me`, {
32
+ const response = await axios.get(`${KNOWHOW_API_URL}/api/users/me`, {
35
33
  headers: {
36
34
  Authorization: `Bearer ${storedJwt}`,
37
35
  },
@@ -47,6 +45,25 @@ export async function login(): Promise<void> {
47
45
  console.log(
48
46
  `Current user: ${user.email}, \nOrganization: ${currentOrg?.organization?.name} - ${orgId}`
49
47
  );
48
+
49
+ const config = await getConfig();
50
+ const proxyUrl = KNOWHOW_API_URL + "/api/proxy";
51
+ const hasProvider = config.modelProviders.find(
52
+ (provider) => provider.provider === "knowhow" && provider.url === proxyUrl
53
+ );
54
+ if (!hasProvider) {
55
+ if (!config.modelProviders) {
56
+ config.modelProviders = [];
57
+ }
58
+
59
+ config.modelProviders.push({
60
+ provider: "knowhow",
61
+ url: proxyUrl,
62
+ jwtFile: ".knowhow/.jwt",
63
+ });
64
+
65
+ await updateConfig(config);
66
+ }
50
67
  } catch (error) {
51
68
  if (axios.isAxiosError(error) && error.response) {
52
69
  throw new Error(
package/src/microphone.ts CHANGED
@@ -3,7 +3,6 @@ import * as fs from "fs";
3
3
  import * as path from "path";
4
4
  import { openai } from "./ai";
5
5
  import { execAsync, ask } from "./utils";
6
- import { Downloader } from "./plugins/downloader/downloader";
7
6
  import { convertToText, convertAudioToText } from "./conversion";
8
7
 
9
8
  interface MicrophoneConfig {