@anh3d0nic/qwen-code-termux-ice 21.0.1 → 21.2.0

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 (1281) hide show
  1. package/bin/qwen-ice +127 -331
  2. package/core/ice-core.js +101 -0
  3. package/core-dist/index.d.ts +6 -0
  4. package/core-dist/index.js +7 -0
  5. package/core-dist/index.js.map +1 -0
  6. package/core-dist/src/__mocks__/fs/promises.d.ts +11 -0
  7. package/core-dist/src/__mocks__/fs/promises.js +17 -0
  8. package/core-dist/src/__mocks__/fs/promises.js.map +1 -0
  9. package/core-dist/src/config/config.d.ts +648 -0
  10. package/core-dist/src/config/config.js +1374 -0
  11. package/core-dist/src/config/config.js.map +1 -0
  12. package/core-dist/src/config/config.test.d.ts +6 -0
  13. package/core-dist/src/config/config.test.js +1116 -0
  14. package/core-dist/src/config/config.test.js.map +1 -0
  15. package/core-dist/src/config/constants.d.ts +11 -0
  16. package/core-dist/src/config/constants.js +16 -0
  17. package/core-dist/src/config/constants.js.map +1 -0
  18. package/core-dist/src/config/models.d.ts +9 -0
  19. package/core-dist/src/config/models.js +10 -0
  20. package/core-dist/src/config/models.js.map +1 -0
  21. package/core-dist/src/config/storage.d.ts +38 -0
  22. package/core-dist/src/config/storage.js +114 -0
  23. package/core-dist/src/config/storage.js.map +1 -0
  24. package/core-dist/src/config/storage.test.d.ts +6 -0
  25. package/core-dist/src/config/storage.test.js +36 -0
  26. package/core-dist/src/config/storage.test.js.map +1 -0
  27. package/core-dist/src/confirmation-bus/message-bus.d.ts +22 -0
  28. package/core-dist/src/confirmation-bus/message-bus.js +98 -0
  29. package/core-dist/src/confirmation-bus/message-bus.js.map +1 -0
  30. package/core-dist/src/confirmation-bus/types.d.ts +104 -0
  31. package/core-dist/src/confirmation-bus/types.js +16 -0
  32. package/core-dist/src/confirmation-bus/types.js.map +1 -0
  33. package/core-dist/src/core/__tests__/openaiTimeoutHandling.test.d.ts +6 -0
  34. package/core-dist/src/core/__tests__/openaiTimeoutHandling.test.js +298 -0
  35. package/core-dist/src/core/__tests__/openaiTimeoutHandling.test.js.map +1 -0
  36. package/core-dist/src/core/__tests__/orphanedToolCallsTest.d.ts +64 -0
  37. package/core-dist/src/core/__tests__/orphanedToolCallsTest.js +122 -0
  38. package/core-dist/src/core/__tests__/orphanedToolCallsTest.js.map +1 -0
  39. package/core-dist/src/core/anthropicContentGenerator/anthropicContentGenerator.d.ts +28 -0
  40. package/core-dist/src/core/anthropicContentGenerator/anthropicContentGenerator.js +349 -0
  41. package/core-dist/src/core/anthropicContentGenerator/anthropicContentGenerator.js.map +1 -0
  42. package/core-dist/src/core/anthropicContentGenerator/anthropicContentGenerator.test.d.ts +6 -0
  43. package/core-dist/src/core/anthropicContentGenerator/anthropicContentGenerator.test.js +396 -0
  44. package/core-dist/src/core/anthropicContentGenerator/anthropicContentGenerator.test.js.map +1 -0
  45. package/core-dist/src/core/anthropicContentGenerator/converter.d.ts +48 -0
  46. package/core-dist/src/core/anthropicContentGenerator/converter.js +449 -0
  47. package/core-dist/src/core/anthropicContentGenerator/converter.js.map +1 -0
  48. package/core-dist/src/core/anthropicContentGenerator/converter.test.d.ts +6 -0
  49. package/core-dist/src/core/anthropicContentGenerator/converter.test.js +843 -0
  50. package/core-dist/src/core/anthropicContentGenerator/converter.test.js.map +1 -0
  51. package/core-dist/src/core/anthropicContentGenerator/index.d.ts +9 -0
  52. package/core-dist/src/core/anthropicContentGenerator/index.js +11 -0
  53. package/core-dist/src/core/anthropicContentGenerator/index.js.map +1 -0
  54. package/core-dist/src/core/baseLlmClient.d.ts +48 -0
  55. package/core-dist/src/core/baseLlmClient.js +98 -0
  56. package/core-dist/src/core/baseLlmClient.js.map +1 -0
  57. package/core-dist/src/core/baseLlmClient.test.d.ts +6 -0
  58. package/core-dist/src/core/baseLlmClient.test.js +319 -0
  59. package/core-dist/src/core/baseLlmClient.test.js.map +1 -0
  60. package/core-dist/src/core/client.d.ts +48 -0
  61. package/core-dist/src/core/client.js +547 -0
  62. package/core-dist/src/core/client.js.map +1 -0
  63. package/core-dist/src/core/client.test.d.ts +6 -0
  64. package/core-dist/src/core/client.test.js +1885 -0
  65. package/core-dist/src/core/client.test.js.map +1 -0
  66. package/core-dist/src/core/contentGenerator.d.ts +100 -0
  67. package/core-dist/src/core/contentGenerator.js +162 -0
  68. package/core-dist/src/core/contentGenerator.js.map +1 -0
  69. package/core-dist/src/core/contentGenerator.test.d.ts +6 -0
  70. package/core-dist/src/core/contentGenerator.test.js +95 -0
  71. package/core-dist/src/core/contentGenerator.test.js.map +1 -0
  72. package/core-dist/src/core/coreToolScheduler.d.ts +142 -0
  73. package/core-dist/src/core/coreToolScheduler.js +872 -0
  74. package/core-dist/src/core/coreToolScheduler.js.map +1 -0
  75. package/core-dist/src/core/coreToolScheduler.test.d.ts +6 -0
  76. package/core-dist/src/core/coreToolScheduler.test.js +2221 -0
  77. package/core-dist/src/core/coreToolScheduler.test.js.map +1 -0
  78. package/core-dist/src/core/geminiChat.d.ts +122 -0
  79. package/core-dist/src/core/geminiChat.js +571 -0
  80. package/core-dist/src/core/geminiChat.js.map +1 -0
  81. package/core-dist/src/core/geminiChat.test.d.ts +6 -0
  82. package/core-dist/src/core/geminiChat.test.js +1276 -0
  83. package/core-dist/src/core/geminiChat.test.js.map +1 -0
  84. package/core-dist/src/core/geminiContentGenerator/geminiContentGenerator.d.ts +38 -0
  85. package/core-dist/src/core/geminiContentGenerator/geminiContentGenerator.js +193 -0
  86. package/core-dist/src/core/geminiContentGenerator/geminiContentGenerator.js.map +1 -0
  87. package/core-dist/src/core/geminiContentGenerator/geminiContentGenerator.test.d.ts +6 -0
  88. package/core-dist/src/core/geminiContentGenerator/geminiContentGenerator.test.js +304 -0
  89. package/core-dist/src/core/geminiContentGenerator/geminiContentGenerator.test.js.map +1 -0
  90. package/core-dist/src/core/geminiContentGenerator/index.d.ts +12 -0
  91. package/core-dist/src/core/geminiContentGenerator/index.js +36 -0
  92. package/core-dist/src/core/geminiContentGenerator/index.js.map +1 -0
  93. package/core-dist/src/core/geminiContentGenerator/index.test.d.ts +6 -0
  94. package/core-dist/src/core/geminiContentGenerator/index.test.js +34 -0
  95. package/core-dist/src/core/geminiContentGenerator/index.test.js.map +1 -0
  96. package/core-dist/src/core/geminiRequest.d.ts +13 -0
  97. package/core-dist/src/core/geminiRequest.js +11 -0
  98. package/core-dist/src/core/geminiRequest.js.map +1 -0
  99. package/core-dist/src/core/geminiRequest.test.d.ts +6 -0
  100. package/core-dist/src/core/geminiRequest.test.js +73 -0
  101. package/core-dist/src/core/geminiRequest.test.js.map +1 -0
  102. package/core-dist/src/core/logger.d.ts +68 -0
  103. package/core-dist/src/core/logger.js +364 -0
  104. package/core-dist/src/core/logger.js.map +1 -0
  105. package/core-dist/src/core/logger.test.d.ts +6 -0
  106. package/core-dist/src/core/logger.test.js +520 -0
  107. package/core-dist/src/core/logger.test.js.map +1 -0
  108. package/core-dist/src/core/loggingContentGenerator/index.d.ts +6 -0
  109. package/core-dist/src/core/loggingContentGenerator/index.js +7 -0
  110. package/core-dist/src/core/loggingContentGenerator/index.js.map +1 -0
  111. package/core-dist/src/core/loggingContentGenerator/loggingContentGenerator.d.ts +36 -0
  112. package/core-dist/src/core/loggingContentGenerator/loggingContentGenerator.js +321 -0
  113. package/core-dist/src/core/loggingContentGenerator/loggingContentGenerator.js.map +1 -0
  114. package/core-dist/src/core/loggingContentGenerator/loggingContentGenerator.test.d.ts +6 -0
  115. package/core-dist/src/core/loggingContentGenerator/loggingContentGenerator.test.js +287 -0
  116. package/core-dist/src/core/loggingContentGenerator/loggingContentGenerator.test.js.map +1 -0
  117. package/core-dist/src/core/modalityDefaults.d.ts +14 -0
  118. package/core-dist/src/core/modalityDefaults.js +81 -0
  119. package/core-dist/src/core/modalityDefaults.js.map +1 -0
  120. package/core-dist/src/core/modalityDefaults.test.d.ts +6 -0
  121. package/core-dist/src/core/modalityDefaults.test.js +181 -0
  122. package/core-dist/src/core/modalityDefaults.test.js.map +1 -0
  123. package/core-dist/src/core/nonInteractiveToolExecutor.d.ts +16 -0
  124. package/core-dist/src/core/nonInteractiveToolExecutor.js +30 -0
  125. package/core-dist/src/core/nonInteractiveToolExecutor.js.map +1 -0
  126. package/core-dist/src/core/nonInteractiveToolExecutor.test.d.ts +6 -0
  127. package/core-dist/src/core/nonInteractiveToolExecutor.test.js +296 -0
  128. package/core-dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -0
  129. package/core-dist/src/core/openaiContentGenerator/constants.d.ts +6 -0
  130. package/core-dist/src/core/openaiContentGenerator/constants.js +7 -0
  131. package/core-dist/src/core/openaiContentGenerator/constants.js.map +1 -0
  132. package/core-dist/src/core/openaiContentGenerator/converter.d.ts +133 -0
  133. package/core-dist/src/core/openaiContentGenerator/converter.js +1020 -0
  134. package/core-dist/src/core/openaiContentGenerator/converter.js.map +1 -0
  135. package/core-dist/src/core/openaiContentGenerator/converter.test.d.ts +6 -0
  136. package/core-dist/src/core/openaiContentGenerator/converter.test.js +1966 -0
  137. package/core-dist/src/core/openaiContentGenerator/converter.test.js.map +1 -0
  138. package/core-dist/src/core/openaiContentGenerator/errorHandler.d.ts +27 -0
  139. package/core-dist/src/core/openaiContentGenerator/errorHandler.js +84 -0
  140. package/core-dist/src/core/openaiContentGenerator/errorHandler.js.map +1 -0
  141. package/core-dist/src/core/openaiContentGenerator/errorHandler.test.d.ts +6 -0
  142. package/core-dist/src/core/openaiContentGenerator/errorHandler.test.js +267 -0
  143. package/core-dist/src/core/openaiContentGenerator/errorHandler.test.js.map +1 -0
  144. package/core-dist/src/core/openaiContentGenerator/index.d.ts +21 -0
  145. package/core-dist/src/core/openaiContentGenerator/index.js +43 -0
  146. package/core-dist/src/core/openaiContentGenerator/index.js.map +1 -0
  147. package/core-dist/src/core/openaiContentGenerator/openaiContentGenerator.d.ts +22 -0
  148. package/core-dist/src/core/openaiContentGenerator/openaiContentGenerator.js +117 -0
  149. package/core-dist/src/core/openaiContentGenerator/openaiContentGenerator.js.map +1 -0
  150. package/core-dist/src/core/openaiContentGenerator/openaiContentGenerator.test.d.ts +6 -0
  151. package/core-dist/src/core/openaiContentGenerator/openaiContentGenerator.test.js +298 -0
  152. package/core-dist/src/core/openaiContentGenerator/openaiContentGenerator.test.js.map +1 -0
  153. package/core-dist/src/core/openaiContentGenerator/pipeline.d.ts +74 -0
  154. package/core-dist/src/core/openaiContentGenerator/pipeline.js +327 -0
  155. package/core-dist/src/core/openaiContentGenerator/pipeline.js.map +1 -0
  156. package/core-dist/src/core/openaiContentGenerator/pipeline.test.d.ts +6 -0
  157. package/core-dist/src/core/openaiContentGenerator/pipeline.test.js +1143 -0
  158. package/core-dist/src/core/openaiContentGenerator/pipeline.test.js.map +1 -0
  159. package/core-dist/src/core/openaiContentGenerator/provider/README.md +61 -0
  160. package/core-dist/src/core/openaiContentGenerator/provider/dashscope.d.ts +70 -0
  161. package/core-dist/src/core/openaiContentGenerator/provider/dashscope.js +258 -0
  162. package/core-dist/src/core/openaiContentGenerator/provider/dashscope.js.map +1 -0
  163. package/core-dist/src/core/openaiContentGenerator/provider/dashscope.test.d.ts +6 -0
  164. package/core-dist/src/core/openaiContentGenerator/provider/dashscope.test.js +781 -0
  165. package/core-dist/src/core/openaiContentGenerator/provider/dashscope.test.js.map +1 -0
  166. package/core-dist/src/core/openaiContentGenerator/provider/deepseek.d.ts +14 -0
  167. package/core-dist/src/core/openaiContentGenerator/provider/deepseek.js +21 -0
  168. package/core-dist/src/core/openaiContentGenerator/provider/deepseek.js.map +1 -0
  169. package/core-dist/src/core/openaiContentGenerator/provider/deepseek.test.d.ts +6 -0
  170. package/core-dist/src/core/openaiContentGenerator/provider/deepseek.test.js +51 -0
  171. package/core-dist/src/core/openaiContentGenerator/provider/deepseek.test.js.map +1 -0
  172. package/core-dist/src/core/openaiContentGenerator/provider/default.d.ts +17 -0
  173. package/core-dist/src/core/openaiContentGenerator/provider/default.js +52 -0
  174. package/core-dist/src/core/openaiContentGenerator/provider/default.js.map +1 -0
  175. package/core-dist/src/core/openaiContentGenerator/provider/default.test.d.ts +6 -0
  176. package/core-dist/src/core/openaiContentGenerator/provider/default.test.js +227 -0
  177. package/core-dist/src/core/openaiContentGenerator/provider/default.test.js.map +1 -0
  178. package/core-dist/src/core/openaiContentGenerator/provider/index.d.ts +6 -0
  179. package/core-dist/src/core/openaiContentGenerator/provider/index.js +6 -0
  180. package/core-dist/src/core/openaiContentGenerator/provider/index.js.map +1 -0
  181. package/core-dist/src/core/openaiContentGenerator/provider/modelscope.d.ts +17 -0
  182. package/core-dist/src/core/openaiContentGenerator/provider/modelscope.js +25 -0
  183. package/core-dist/src/core/openaiContentGenerator/provider/modelscope.js.map +1 -0
  184. package/core-dist/src/core/openaiContentGenerator/provider/modelscope.test.d.ts +6 -0
  185. package/core-dist/src/core/openaiContentGenerator/provider/modelscope.test.js +66 -0
  186. package/core-dist/src/core/openaiContentGenerator/provider/modelscope.test.js.map +1 -0
  187. package/core-dist/src/core/openaiContentGenerator/provider/openrouter.d.ts +8 -0
  188. package/core-dist/src/core/openaiContentGenerator/provider/openrouter.js +21 -0
  189. package/core-dist/src/core/openaiContentGenerator/provider/openrouter.js.map +1 -0
  190. package/core-dist/src/core/openaiContentGenerator/provider/openrouter.test.d.ts +6 -0
  191. package/core-dist/src/core/openaiContentGenerator/provider/openrouter.test.js +152 -0
  192. package/core-dist/src/core/openaiContentGenerator/provider/openrouter.test.js.map +1 -0
  193. package/core-dist/src/core/openaiContentGenerator/provider/types.d.ts +26 -0
  194. package/core-dist/src/core/openaiContentGenerator/provider/types.js +2 -0
  195. package/core-dist/src/core/openaiContentGenerator/provider/types.js.map +1 -0
  196. package/core-dist/src/core/openaiContentGenerator/streamingToolCallParser.d.ts +157 -0
  197. package/core-dist/src/core/openaiContentGenerator/streamingToolCallParser.js +390 -0
  198. package/core-dist/src/core/openaiContentGenerator/streamingToolCallParser.js.map +1 -0
  199. package/core-dist/src/core/openaiContentGenerator/streamingToolCallParser.test.d.ts +6 -0
  200. package/core-dist/src/core/openaiContentGenerator/streamingToolCallParser.test.js +585 -0
  201. package/core-dist/src/core/openaiContentGenerator/streamingToolCallParser.test.js.map +1 -0
  202. package/core-dist/src/core/prompts.d.ts +81 -0
  203. package/core-dist/src/core/prompts.js +996 -0
  204. package/core-dist/src/core/prompts.js.map +1 -0
  205. package/core-dist/src/core/prompts.test.d.ts +6 -0
  206. package/core-dist/src/core/prompts.test.js +485 -0
  207. package/core-dist/src/core/prompts.test.js.map +1 -0
  208. package/core-dist/src/core/tokenLimits.d.ts +29 -0
  209. package/core-dist/src/core/tokenLimits.js +171 -0
  210. package/core-dist/src/core/tokenLimits.js.map +1 -0
  211. package/core-dist/src/core/tokenLimits.test.d.ts +1 -0
  212. package/core-dist/src/core/tokenLimits.test.js +270 -0
  213. package/core-dist/src/core/tokenLimits.test.js.map +1 -0
  214. package/core-dist/src/core/turn.d.ts +161 -0
  215. package/core-dist/src/core/turn.js +197 -0
  216. package/core-dist/src/core/turn.js.map +1 -0
  217. package/core-dist/src/core/turn.test.d.ts +6 -0
  218. package/core-dist/src/core/turn.test.js +817 -0
  219. package/core-dist/src/core/turn.test.js.map +1 -0
  220. package/core-dist/src/extension/claude-converter.d.ts +121 -0
  221. package/core-dist/src/extension/claude-converter.js +572 -0
  222. package/core-dist/src/extension/claude-converter.js.map +1 -0
  223. package/core-dist/src/extension/claude-converter.test.d.ts +6 -0
  224. package/core-dist/src/extension/claude-converter.test.js +305 -0
  225. package/core-dist/src/extension/claude-converter.test.js.map +1 -0
  226. package/core-dist/src/extension/extensionManager.d.ts +159 -0
  227. package/core-dist/src/extension/extensionManager.js +829 -0
  228. package/core-dist/src/extension/extensionManager.js.map +1 -0
  229. package/core-dist/src/extension/extensionManager.test.d.ts +6 -0
  230. package/core-dist/src/extension/extensionManager.test.js +598 -0
  231. package/core-dist/src/extension/extensionManager.test.js.map +1 -0
  232. package/core-dist/src/extension/extensionSettings.d.ts +33 -0
  233. package/core-dist/src/extension/extensionSettings.js +186 -0
  234. package/core-dist/src/extension/extensionSettings.js.map +1 -0
  235. package/core-dist/src/extension/extensionSettings.test.d.ts +1 -0
  236. package/core-dist/src/extension/extensionSettings.test.js +488 -0
  237. package/core-dist/src/extension/extensionSettings.test.js.map +1 -0
  238. package/core-dist/src/extension/gemini-converter.d.ts +47 -0
  239. package/core-dist/src/extension/gemini-converter.js +185 -0
  240. package/core-dist/src/extension/gemini-converter.js.map +1 -0
  241. package/core-dist/src/extension/gemini-converter.test.d.ts +6 -0
  242. package/core-dist/src/extension/gemini-converter.test.js +128 -0
  243. package/core-dist/src/extension/gemini-converter.test.js.map +1 -0
  244. package/core-dist/src/extension/github.d.ts +30 -0
  245. package/core-dist/src/extension/github.js +330 -0
  246. package/core-dist/src/extension/github.js.map +1 -0
  247. package/core-dist/src/extension/github.test.d.ts +6 -0
  248. package/core-dist/src/extension/github.test.js +376 -0
  249. package/core-dist/src/extension/github.test.js.map +1 -0
  250. package/core-dist/src/extension/index.d.ts +6 -0
  251. package/core-dist/src/extension/index.js +7 -0
  252. package/core-dist/src/extension/index.js.map +1 -0
  253. package/core-dist/src/extension/marketplace.d.ts +19 -0
  254. package/core-dist/src/extension/marketplace.js +222 -0
  255. package/core-dist/src/extension/marketplace.js.map +1 -0
  256. package/core-dist/src/extension/marketplace.test.d.ts +6 -0
  257. package/core-dist/src/extension/marketplace.test.js +215 -0
  258. package/core-dist/src/extension/marketplace.test.js.map +1 -0
  259. package/core-dist/src/extension/override.d.ts +25 -0
  260. package/core-dist/src/extension/override.js +82 -0
  261. package/core-dist/src/extension/override.js.map +1 -0
  262. package/core-dist/src/extension/override.test.d.ts +6 -0
  263. package/core-dist/src/extension/override.test.js +94 -0
  264. package/core-dist/src/extension/override.test.js.map +1 -0
  265. package/core-dist/src/extension/settings.d.ts +39 -0
  266. package/core-dist/src/extension/settings.js +116 -0
  267. package/core-dist/src/extension/settings.js.map +1 -0
  268. package/core-dist/src/extension/settings.test.d.ts +6 -0
  269. package/core-dist/src/extension/settings.test.js +125 -0
  270. package/core-dist/src/extension/settings.test.js.map +1 -0
  271. package/core-dist/src/extension/storage.d.ts +9 -0
  272. package/core-dist/src/extension/storage.js +38 -0
  273. package/core-dist/src/extension/storage.js.map +1 -0
  274. package/core-dist/src/extension/storage.test.d.ts +6 -0
  275. package/core-dist/src/extension/storage.test.js +64 -0
  276. package/core-dist/src/extension/storage.test.js.map +1 -0
  277. package/core-dist/src/extension/variableSchema.d.ts +40 -0
  278. package/core-dist/src/extension/variableSchema.js +26 -0
  279. package/core-dist/src/extension/variableSchema.js.map +1 -0
  280. package/core-dist/src/extension/variables.d.ts +21 -0
  281. package/core-dist/src/extension/variables.js +46 -0
  282. package/core-dist/src/extension/variables.js.map +1 -0
  283. package/core-dist/src/extension/variables.test.d.ts +6 -0
  284. package/core-dist/src/extension/variables.test.js +17 -0
  285. package/core-dist/src/extension/variables.test.js.map +1 -0
  286. package/core-dist/src/hooks/hookAggregator.d.ts +66 -0
  287. package/core-dist/src/hooks/hookAggregator.js +280 -0
  288. package/core-dist/src/hooks/hookAggregator.js.map +1 -0
  289. package/core-dist/src/hooks/hookAggregator.test.d.ts +6 -0
  290. package/core-dist/src/hooks/hookAggregator.test.js +449 -0
  291. package/core-dist/src/hooks/hookAggregator.test.js.map +1 -0
  292. package/core-dist/src/hooks/hookEventHandler.d.ts +42 -0
  293. package/core-dist/src/hooks/hookEventHandler.js +127 -0
  294. package/core-dist/src/hooks/hookEventHandler.js.map +1 -0
  295. package/core-dist/src/hooks/hookEventHandler.test.d.ts +6 -0
  296. package/core-dist/src/hooks/hookEventHandler.test.js +183 -0
  297. package/core-dist/src/hooks/hookEventHandler.test.js.map +1 -0
  298. package/core-dist/src/hooks/hookPlanner.d.ts +42 -0
  299. package/core-dist/src/hooks/hookPlanner.js +101 -0
  300. package/core-dist/src/hooks/hookPlanner.js.map +1 -0
  301. package/core-dist/src/hooks/hookPlanner.test.d.ts +6 -0
  302. package/core-dist/src/hooks/hookPlanner.test.js +303 -0
  303. package/core-dist/src/hooks/hookPlanner.test.js.map +1 -0
  304. package/core-dist/src/hooks/hookRegistry.d.ts +106 -0
  305. package/core-dist/src/hooks/hookRegistry.js +225 -0
  306. package/core-dist/src/hooks/hookRegistry.js.map +1 -0
  307. package/core-dist/src/hooks/hookRegistry.test.d.ts +6 -0
  308. package/core-dist/src/hooks/hookRegistry.test.js +539 -0
  309. package/core-dist/src/hooks/hookRegistry.test.js.map +1 -0
  310. package/core-dist/src/hooks/hookRunner.d.ts +40 -0
  311. package/core-dist/src/hooks/hookRunner.js +318 -0
  312. package/core-dist/src/hooks/hookRunner.js.map +1 -0
  313. package/core-dist/src/hooks/hookRunner.test.d.ts +6 -0
  314. package/core-dist/src/hooks/hookRunner.test.js +466 -0
  315. package/core-dist/src/hooks/hookRunner.test.js.map +1 -0
  316. package/core-dist/src/hooks/hookSystem.d.ts +43 -0
  317. package/core-dist/src/hooks/hookSystem.js +75 -0
  318. package/core-dist/src/hooks/hookSystem.js.map +1 -0
  319. package/core-dist/src/hooks/hookSystem.test.d.ts +6 -0
  320. package/core-dist/src/hooks/hookSystem.test.js +237 -0
  321. package/core-dist/src/hooks/hookSystem.test.js.map +1 -0
  322. package/core-dist/src/hooks/index.d.ts +16 -0
  323. package/core-dist/src/hooks/index.js +16 -0
  324. package/core-dist/src/hooks/index.js.map +1 -0
  325. package/core-dist/src/hooks/trustedHooks.d.ts +28 -0
  326. package/core-dist/src/hooks/trustedHooks.js +91 -0
  327. package/core-dist/src/hooks/trustedHooks.js.map +1 -0
  328. package/core-dist/src/hooks/types.d.ts +498 -0
  329. package/core-dist/src/hooks/types.js +292 -0
  330. package/core-dist/src/hooks/types.js.map +1 -0
  331. package/core-dist/src/ide/constants.d.ts +9 -0
  332. package/core-dist/src/ide/constants.js +10 -0
  333. package/core-dist/src/ide/constants.js.map +1 -0
  334. package/core-dist/src/ide/detect-ide.d.ts +56 -0
  335. package/core-dist/src/ide/detect-ide.js +68 -0
  336. package/core-dist/src/ide/detect-ide.js.map +1 -0
  337. package/core-dist/src/ide/detect-ide.test.d.ts +6 -0
  338. package/core-dist/src/ide/detect-ide.test.js +113 -0
  339. package/core-dist/src/ide/detect-ide.test.js.map +1 -0
  340. package/core-dist/src/ide/ide-client.d.ts +132 -0
  341. package/core-dist/src/ide/ide-client.js +750 -0
  342. package/core-dist/src/ide/ide-client.js.map +1 -0
  343. package/core-dist/src/ide/ide-client.test.d.ts +6 -0
  344. package/core-dist/src/ide/ide-client.test.js +463 -0
  345. package/core-dist/src/ide/ide-client.test.js.map +1 -0
  346. package/core-dist/src/ide/ide-installer.d.ts +14 -0
  347. package/core-dist/src/ide/ide-installer.js +112 -0
  348. package/core-dist/src/ide/ide-installer.js.map +1 -0
  349. package/core-dist/src/ide/ide-installer.test.d.ts +6 -0
  350. package/core-dist/src/ide/ide-installer.test.js +134 -0
  351. package/core-dist/src/ide/ide-installer.test.js.map +1 -0
  352. package/core-dist/src/ide/ideContext.d.ts +44 -0
  353. package/core-dist/src/ide/ideContext.js +101 -0
  354. package/core-dist/src/ide/ideContext.js.map +1 -0
  355. package/core-dist/src/ide/ideContext.test.d.ts +6 -0
  356. package/core-dist/src/ide/ideContext.test.js +393 -0
  357. package/core-dist/src/ide/ideContext.test.js.map +1 -0
  358. package/core-dist/src/ide/process-utils.d.ts +21 -0
  359. package/core-dist/src/ide/process-utils.js +170 -0
  360. package/core-dist/src/ide/process-utils.js.map +1 -0
  361. package/core-dist/src/ide/process-utils.test.d.ts +6 -0
  362. package/core-dist/src/ide/process-utils.test.js +130 -0
  363. package/core-dist/src/ide/process-utils.test.js.map +1 -0
  364. package/core-dist/src/ide/types.d.ts +486 -0
  365. package/core-dist/src/ide/types.js +138 -0
  366. package/core-dist/src/ide/types.js.map +1 -0
  367. package/core-dist/src/index.d.ts +179 -0
  368. package/core-dist/src/index.js +225 -0
  369. package/core-dist/src/index.js.map +1 -0
  370. package/core-dist/src/index.test.d.ts +6 -0
  371. package/core-dist/src/index.test.js +12 -0
  372. package/core-dist/src/index.test.js.map +1 -0
  373. package/core-dist/src/lsp/LspConfigLoader.d.ts +46 -0
  374. package/core-dist/src/lsp/LspConfigLoader.js +381 -0
  375. package/core-dist/src/lsp/LspConfigLoader.js.map +1 -0
  376. package/core-dist/src/lsp/LspConfigLoader.test.d.ts +6 -0
  377. package/core-dist/src/lsp/LspConfigLoader.test.js +80 -0
  378. package/core-dist/src/lsp/LspConfigLoader.test.js.map +1 -0
  379. package/core-dist/src/lsp/LspConnectionFactory.d.ts +62 -0
  380. package/core-dist/src/lsp/LspConnectionFactory.js +305 -0
  381. package/core-dist/src/lsp/LspConnectionFactory.js.map +1 -0
  382. package/core-dist/src/lsp/LspLanguageDetector.d.ts +39 -0
  383. package/core-dist/src/lsp/LspLanguageDetector.js +199 -0
  384. package/core-dist/src/lsp/LspLanguageDetector.js.map +1 -0
  385. package/core-dist/src/lsp/LspResponseNormalizer.d.ts +122 -0
  386. package/core-dist/src/lsp/LspResponseNormalizer.js +710 -0
  387. package/core-dist/src/lsp/LspResponseNormalizer.js.map +1 -0
  388. package/core-dist/src/lsp/LspServerManager.d.ts +87 -0
  389. package/core-dist/src/lsp/LspServerManager.js +563 -0
  390. package/core-dist/src/lsp/LspServerManager.js.map +1 -0
  391. package/core-dist/src/lsp/NativeLspClient.d.ts +149 -0
  392. package/core-dist/src/lsp/NativeLspClient.js +169 -0
  393. package/core-dist/src/lsp/NativeLspClient.js.map +1 -0
  394. package/core-dist/src/lsp/NativeLspService.d.ts +106 -0
  395. package/core-dist/src/lsp/NativeLspService.integration.test.d.ts +6 -0
  396. package/core-dist/src/lsp/NativeLspService.integration.test.js +663 -0
  397. package/core-dist/src/lsp/NativeLspService.integration.test.js.map +1 -0
  398. package/core-dist/src/lsp/NativeLspService.js +623 -0
  399. package/core-dist/src/lsp/NativeLspService.js.map +1 -0
  400. package/core-dist/src/lsp/NativeLspService.test.d.ts +6 -0
  401. package/core-dist/src/lsp/NativeLspService.test.js +99 -0
  402. package/core-dist/src/lsp/NativeLspService.test.js.map +1 -0
  403. package/core-dist/src/lsp/constants.d.ts +35 -0
  404. package/core-dist/src/lsp/constants.js +86 -0
  405. package/core-dist/src/lsp/constants.js.map +1 -0
  406. package/core-dist/src/lsp/types.d.ts +409 -0
  407. package/core-dist/src/lsp/types.js +7 -0
  408. package/core-dist/src/lsp/types.js.map +1 -0
  409. package/core-dist/src/mcp/constants.d.ts +22 -0
  410. package/core-dist/src/mcp/constants.js +23 -0
  411. package/core-dist/src/mcp/constants.js.map +1 -0
  412. package/core-dist/src/mcp/google-auth-provider.d.ts +23 -0
  413. package/core-dist/src/mcp/google-auth-provider.js +75 -0
  414. package/core-dist/src/mcp/google-auth-provider.js.map +1 -0
  415. package/core-dist/src/mcp/google-auth-provider.test.d.ts +6 -0
  416. package/core-dist/src/mcp/google-auth-provider.test.js +89 -0
  417. package/core-dist/src/mcp/google-auth-provider.test.js.map +1 -0
  418. package/core-dist/src/mcp/oauth-provider.d.ts +150 -0
  419. package/core-dist/src/mcp/oauth-provider.js +617 -0
  420. package/core-dist/src/mcp/oauth-provider.js.map +1 -0
  421. package/core-dist/src/mcp/oauth-provider.test.d.ts +6 -0
  422. package/core-dist/src/mcp/oauth-provider.test.js +917 -0
  423. package/core-dist/src/mcp/oauth-provider.test.js.map +1 -0
  424. package/core-dist/src/mcp/oauth-token-storage.d.ts +65 -0
  425. package/core-dist/src/mcp/oauth-token-storage.js +182 -0
  426. package/core-dist/src/mcp/oauth-token-storage.js.map +1 -0
  427. package/core-dist/src/mcp/oauth-token-storage.test.d.ts +6 -0
  428. package/core-dist/src/mcp/oauth-token-storage.test.js +307 -0
  429. package/core-dist/src/mcp/oauth-token-storage.test.js.map +1 -0
  430. package/core-dist/src/mcp/oauth-utils.d.ts +124 -0
  431. package/core-dist/src/mcp/oauth-utils.js +252 -0
  432. package/core-dist/src/mcp/oauth-utils.js.map +1 -0
  433. package/core-dist/src/mcp/oauth-utils.test.d.ts +6 -0
  434. package/core-dist/src/mcp/oauth-utils.test.js +220 -0
  435. package/core-dist/src/mcp/oauth-utils.test.js.map +1 -0
  436. package/core-dist/src/mcp/sa-impersonation-provider.d.ts +33 -0
  437. package/core-dist/src/mcp/sa-impersonation-provider.js +133 -0
  438. package/core-dist/src/mcp/sa-impersonation-provider.js.map +1 -0
  439. package/core-dist/src/mcp/sa-impersonation-provider.test.d.ts +6 -0
  440. package/core-dist/src/mcp/sa-impersonation-provider.test.js +117 -0
  441. package/core-dist/src/mcp/sa-impersonation-provider.test.js.map +1 -0
  442. package/core-dist/src/mcp/token-storage/base-token-storage.d.ts +19 -0
  443. package/core-dist/src/mcp/token-storage/base-token-storage.js +36 -0
  444. package/core-dist/src/mcp/token-storage/base-token-storage.js.map +1 -0
  445. package/core-dist/src/mcp/token-storage/base-token-storage.test.d.ts +6 -0
  446. package/core-dist/src/mcp/token-storage/base-token-storage.test.js +160 -0
  447. package/core-dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -0
  448. package/core-dist/src/mcp/token-storage/file-token-storage.d.ts +24 -0
  449. package/core-dist/src/mcp/token-storage/file-token-storage.js +144 -0
  450. package/core-dist/src/mcp/token-storage/file-token-storage.js.map +1 -0
  451. package/core-dist/src/mcp/token-storage/file-token-storage.test.d.ts +6 -0
  452. package/core-dist/src/mcp/token-storage/file-token-storage.test.js +235 -0
  453. package/core-dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -0
  454. package/core-dist/src/mcp/token-storage/hybrid-token-storage.d.ts +23 -0
  455. package/core-dist/src/mcp/token-storage/hybrid-token-storage.js +78 -0
  456. package/core-dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -0
  457. package/core-dist/src/mcp/token-storage/hybrid-token-storage.test.d.ts +6 -0
  458. package/core-dist/src/mcp/token-storage/hybrid-token-storage.test.js +193 -0
  459. package/core-dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -0
  460. package/core-dist/src/mcp/token-storage/index.d.ts +11 -0
  461. package/core-dist/src/mcp/token-storage/index.js +12 -0
  462. package/core-dist/src/mcp/token-storage/index.js.map +1 -0
  463. package/core-dist/src/mcp/token-storage/keychain-token-storage.d.ts +35 -0
  464. package/core-dist/src/mcp/token-storage/keychain-token-storage.js +248 -0
  465. package/core-dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -0
  466. package/core-dist/src/mcp/token-storage/keychain-token-storage.test.d.ts +6 -0
  467. package/core-dist/src/mcp/token-storage/keychain-token-storage.test.js +254 -0
  468. package/core-dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -0
  469. package/core-dist/src/mcp/token-storage/types.d.ts +38 -0
  470. package/core-dist/src/mcp/token-storage/types.js +11 -0
  471. package/core-dist/src/mcp/token-storage/types.js.map +1 -0
  472. package/core-dist/src/mocks/msw.d.ts +6 -0
  473. package/core-dist/src/mocks/msw.js +8 -0
  474. package/core-dist/src/mocks/msw.js.map +1 -0
  475. package/core-dist/src/models/constants.d.ts +71 -0
  476. package/core-dist/src/models/constants.js +92 -0
  477. package/core-dist/src/models/constants.js.map +1 -0
  478. package/core-dist/src/models/index.d.ts +10 -0
  479. package/core-dist/src/models/index.js +12 -0
  480. package/core-dist/src/models/index.js.map +1 -0
  481. package/core-dist/src/models/modelConfigErrors.d.ts +46 -0
  482. package/core-dist/src/models/modelConfigErrors.js +87 -0
  483. package/core-dist/src/models/modelConfigErrors.js.map +1 -0
  484. package/core-dist/src/models/modelConfigResolver.d.ts +84 -0
  485. package/core-dist/src/models/modelConfigResolver.js +204 -0
  486. package/core-dist/src/models/modelConfigResolver.js.map +1 -0
  487. package/core-dist/src/models/modelConfigResolver.test.d.ts +6 -0
  488. package/core-dist/src/models/modelConfigResolver.test.js +302 -0
  489. package/core-dist/src/models/modelConfigResolver.test.js.map +1 -0
  490. package/core-dist/src/models/modelRegistry.d.ts +55 -0
  491. package/core-dist/src/models/modelRegistry.js +182 -0
  492. package/core-dist/src/models/modelRegistry.js.map +1 -0
  493. package/core-dist/src/models/modelRegistry.test.d.ts +6 -0
  494. package/core-dist/src/models/modelRegistry.test.js +408 -0
  495. package/core-dist/src/models/modelRegistry.test.js.map +1 -0
  496. package/core-dist/src/models/modelsConfig.d.ts +343 -0
  497. package/core-dist/src/models/modelsConfig.js +957 -0
  498. package/core-dist/src/models/modelsConfig.js.map +1 -0
  499. package/core-dist/src/models/modelsConfig.test.d.ts +6 -0
  500. package/core-dist/src/models/modelsConfig.test.js +1242 -0
  501. package/core-dist/src/models/modelsConfig.test.js.map +1 -0
  502. package/core-dist/src/models/types.d.ts +114 -0
  503. package/core-dist/src/models/types.js +7 -0
  504. package/core-dist/src/models/types.js.map +1 -0
  505. package/core-dist/src/output/json-formatter.d.ts +11 -0
  506. package/core-dist/src/output/json-formatter.js +30 -0
  507. package/core-dist/src/output/json-formatter.js.map +1 -0
  508. package/core-dist/src/output/json-formatter.test.d.ts +6 -0
  509. package/core-dist/src/output/json-formatter.test.js +266 -0
  510. package/core-dist/src/output/json-formatter.test.js.map +1 -0
  511. package/core-dist/src/output/types.d.ts +25 -0
  512. package/core-dist/src/output/types.js +17 -0
  513. package/core-dist/src/output/types.js.map +1 -0
  514. package/core-dist/src/prompts/mcp-prompts.d.ts +8 -0
  515. package/core-dist/src/prompts/mcp-prompts.js +13 -0
  516. package/core-dist/src/prompts/mcp-prompts.js.map +1 -0
  517. package/core-dist/src/prompts/prompt-registry.d.ts +34 -0
  518. package/core-dist/src/prompts/prompt-registry.js +65 -0
  519. package/core-dist/src/prompts/prompt-registry.js.map +1 -0
  520. package/core-dist/src/qwen/qwenContentGenerator.d.ts +71 -0
  521. package/core-dist/src/qwen/qwenContentGenerator.js +182 -0
  522. package/core-dist/src/qwen/qwenContentGenerator.js.map +1 -0
  523. package/core-dist/src/qwen/qwenContentGenerator.test.d.ts +6 -0
  524. package/core-dist/src/qwen/qwenContentGenerator.test.js +1175 -0
  525. package/core-dist/src/qwen/qwenContentGenerator.test.js.map +1 -0
  526. package/core-dist/src/qwen/qwenOAuth2.d.ts +195 -0
  527. package/core-dist/src/qwen/qwenOAuth2.js +677 -0
  528. package/core-dist/src/qwen/qwenOAuth2.js.map +1 -0
  529. package/core-dist/src/qwen/qwenOAuth2.test.d.ts +6 -0
  530. package/core-dist/src/qwen/qwenOAuth2.test.js +1621 -0
  531. package/core-dist/src/qwen/qwenOAuth2.test.js.map +1 -0
  532. package/core-dist/src/qwen/sharedTokenManager.d.ts +196 -0
  533. package/core-dist/src/qwen/sharedTokenManager.js +649 -0
  534. package/core-dist/src/qwen/sharedTokenManager.js.map +1 -0
  535. package/core-dist/src/qwen/sharedTokenManager.test.d.ts +7 -0
  536. package/core-dist/src/qwen/sharedTokenManager.test.js +662 -0
  537. package/core-dist/src/qwen/sharedTokenManager.test.js.map +1 -0
  538. package/core-dist/src/services/chatCompressionService.d.ts +32 -0
  539. package/core-dist/src/services/chatCompressionService.js +213 -0
  540. package/core-dist/src/services/chatCompressionService.js.map +1 -0
  541. package/core-dist/src/services/chatCompressionService.test.d.ts +6 -0
  542. package/core-dist/src/services/chatCompressionService.test.js +343 -0
  543. package/core-dist/src/services/chatCompressionService.test.js.map +1 -0
  544. package/core-dist/src/services/chatRecordingService.d.ts +215 -0
  545. package/core-dist/src/services/chatRecordingService.js +285 -0
  546. package/core-dist/src/services/chatRecordingService.js.map +1 -0
  547. package/core-dist/src/services/chatRecordingService.test.d.ts +6 -0
  548. package/core-dist/src/services/chatRecordingService.test.js +299 -0
  549. package/core-dist/src/services/chatRecordingService.test.js.map +1 -0
  550. package/core-dist/src/services/fileDiscoveryService.d.ts +45 -0
  551. package/core-dist/src/services/fileDiscoveryService.js +104 -0
  552. package/core-dist/src/services/fileDiscoveryService.js.map +1 -0
  553. package/core-dist/src/services/fileDiscoveryService.test.d.ts +6 -0
  554. package/core-dist/src/services/fileDiscoveryService.test.js +143 -0
  555. package/core-dist/src/services/fileDiscoveryService.test.js.map +1 -0
  556. package/core-dist/src/services/fileSystemService.d.ts +88 -0
  557. package/core-dist/src/services/fileSystemService.js +131 -0
  558. package/core-dist/src/services/fileSystemService.js.map +1 -0
  559. package/core-dist/src/services/fileSystemService.test.d.ts +6 -0
  560. package/core-dist/src/services/fileSystemService.test.js +216 -0
  561. package/core-dist/src/services/fileSystemService.test.js.map +1 -0
  562. package/core-dist/src/services/gitService.d.ts +22 -0
  563. package/core-dist/src/services/gitService.js +98 -0
  564. package/core-dist/src/services/gitService.js.map +1 -0
  565. package/core-dist/src/services/gitService.test.d.ts +6 -0
  566. package/core-dist/src/services/gitService.test.js +187 -0
  567. package/core-dist/src/services/gitService.test.js.map +1 -0
  568. package/core-dist/src/services/loopDetectionService.d.ts +86 -0
  569. package/core-dist/src/services/loopDetectionService.js +239 -0
  570. package/core-dist/src/services/loopDetectionService.js.map +1 -0
  571. package/core-dist/src/services/loopDetectionService.test.d.ts +6 -0
  572. package/core-dist/src/services/loopDetectionService.test.js +478 -0
  573. package/core-dist/src/services/loopDetectionService.test.js.map +1 -0
  574. package/core-dist/src/services/sessionService.d.ts +200 -0
  575. package/core-dist/src/services/sessionService.js +527 -0
  576. package/core-dist/src/services/sessionService.js.map +1 -0
  577. package/core-dist/src/services/sessionService.test.d.ts +6 -0
  578. package/core-dist/src/services/sessionService.test.js +576 -0
  579. package/core-dist/src/services/sessionService.test.js.map +1 -0
  580. package/core-dist/src/services/shellExecutionService.d.ts +104 -0
  581. package/core-dist/src/services/shellExecutionService.js +626 -0
  582. package/core-dist/src/services/shellExecutionService.js.map +1 -0
  583. package/core-dist/src/services/shellExecutionService.test.d.ts +6 -0
  584. package/core-dist/src/services/shellExecutionService.test.js +684 -0
  585. package/core-dist/src/services/shellExecutionService.test.js.map +1 -0
  586. package/core-dist/src/skills/index.d.ts +19 -0
  587. package/core-dist/src/skills/index.js +9 -0
  588. package/core-dist/src/skills/index.js.map +1 -0
  589. package/core-dist/src/skills/skill-load.d.ts +4 -0
  590. package/core-dist/src/skills/skill-load.js +137 -0
  591. package/core-dist/src/skills/skill-load.js.map +1 -0
  592. package/core-dist/src/skills/skill-load.test.d.ts +6 -0
  593. package/core-dist/src/skills/skill-load.test.js +237 -0
  594. package/core-dist/src/skills/skill-load.test.js.map +1 -0
  595. package/core-dist/src/skills/skill-manager.d.ts +134 -0
  596. package/core-dist/src/skills/skill-manager.js +505 -0
  597. package/core-dist/src/skills/skill-manager.js.map +1 -0
  598. package/core-dist/src/skills/skill-manager.test.d.ts +6 -0
  599. package/core-dist/src/skills/skill-manager.test.js +527 -0
  600. package/core-dist/src/skills/skill-manager.test.js.map +1 -0
  601. package/core-dist/src/skills/types.d.ts +88 -0
  602. package/core-dist/src/skills/types.js +29 -0
  603. package/core-dist/src/skills/types.js.map +1 -0
  604. package/core-dist/src/subagents/builtin-agents.d.ts +35 -0
  605. package/core-dist/src/subagents/builtin-agents.js +85 -0
  606. package/core-dist/src/subagents/builtin-agents.js.map +1 -0
  607. package/core-dist/src/subagents/builtin-agents.test.d.ts +6 -0
  608. package/core-dist/src/subagents/builtin-agents.test.js +78 -0
  609. package/core-dist/src/subagents/builtin-agents.test.js.map +1 -0
  610. package/core-dist/src/subagents/index.d.ts +29 -0
  611. package/core-dist/src/subagents/index.js +15 -0
  612. package/core-dist/src/subagents/index.js.map +1 -0
  613. package/core-dist/src/subagents/subagent-events.d.ts +105 -0
  614. package/core-dist/src/subagents/subagent-events.js +32 -0
  615. package/core-dist/src/subagents/subagent-events.js.map +1 -0
  616. package/core-dist/src/subagents/subagent-hooks.d.ts +29 -0
  617. package/core-dist/src/subagents/subagent-hooks.js +7 -0
  618. package/core-dist/src/subagents/subagent-hooks.js.map +1 -0
  619. package/core-dist/src/subagents/subagent-manager.d.ts +178 -0
  620. package/core-dist/src/subagents/subagent-manager.js +711 -0
  621. package/core-dist/src/subagents/subagent-manager.js.map +1 -0
  622. package/core-dist/src/subagents/subagent-manager.test.d.ts +6 -0
  623. package/core-dist/src/subagents/subagent-manager.test.js +829 -0
  624. package/core-dist/src/subagents/subagent-manager.test.js.map +1 -0
  625. package/core-dist/src/subagents/subagent-statistics.d.ts +50 -0
  626. package/core-dist/src/subagents/subagent-statistics.js +210 -0
  627. package/core-dist/src/subagents/subagent-statistics.js.map +1 -0
  628. package/core-dist/src/subagents/subagent-statistics.test.d.ts +6 -0
  629. package/core-dist/src/subagents/subagent-statistics.test.js +238 -0
  630. package/core-dist/src/subagents/subagent-statistics.test.js.map +1 -0
  631. package/core-dist/src/subagents/subagent.d.ts +167 -0
  632. package/core-dist/src/subagents/subagent.js +758 -0
  633. package/core-dist/src/subagents/subagent.js.map +1 -0
  634. package/core-dist/src/subagents/subagent.test.d.ts +6 -0
  635. package/core-dist/src/subagents/subagent.test.js +819 -0
  636. package/core-dist/src/subagents/subagent.test.js.map +1 -0
  637. package/core-dist/src/subagents/types.d.ts +224 -0
  638. package/core-dist/src/subagents/types.js +58 -0
  639. package/core-dist/src/subagents/types.js.map +1 -0
  640. package/core-dist/src/subagents/types.test.d.ts +6 -0
  641. package/core-dist/src/subagents/types.test.js +31 -0
  642. package/core-dist/src/subagents/types.test.js.map +1 -0
  643. package/core-dist/src/subagents/validation.d.ts +63 -0
  644. package/core-dist/src/subagents/validation.js +293 -0
  645. package/core-dist/src/subagents/validation.js.map +1 -0
  646. package/core-dist/src/subagents/validation.test.d.ts +6 -0
  647. package/core-dist/src/subagents/validation.test.js +330 -0
  648. package/core-dist/src/subagents/validation.test.js.map +1 -0
  649. package/core-dist/src/telemetry/config.d.ts +31 -0
  650. package/core-dist/src/telemetry/config.js +74 -0
  651. package/core-dist/src/telemetry/config.js.map +1 -0
  652. package/core-dist/src/telemetry/config.test.d.ts +6 -0
  653. package/core-dist/src/telemetry/config.test.js +124 -0
  654. package/core-dist/src/telemetry/config.test.js.map +1 -0
  655. package/core-dist/src/telemetry/constants.d.ts +39 -0
  656. package/core-dist/src/telemetry/constants.js +41 -0
  657. package/core-dist/src/telemetry/constants.js.map +1 -0
  658. package/core-dist/src/telemetry/file-exporters.d.ts +29 -0
  659. package/core-dist/src/telemetry/file-exporters.js +62 -0
  660. package/core-dist/src/telemetry/file-exporters.js.map +1 -0
  661. package/core-dist/src/telemetry/index.d.ts +25 -0
  662. package/core-dist/src/telemetry/index.js +31 -0
  663. package/core-dist/src/telemetry/index.js.map +1 -0
  664. package/core-dist/src/telemetry/integration.test.circular.d.ts +6 -0
  665. package/core-dist/src/telemetry/integration.test.circular.js +95 -0
  666. package/core-dist/src/telemetry/integration.test.circular.js.map +1 -0
  667. package/core-dist/src/telemetry/loggers.d.ts +40 -0
  668. package/core-dist/src/telemetry/loggers.js +712 -0
  669. package/core-dist/src/telemetry/loggers.js.map +1 -0
  670. package/core-dist/src/telemetry/loggers.test.circular.d.ts +6 -0
  671. package/core-dist/src/telemetry/loggers.test.circular.js +107 -0
  672. package/core-dist/src/telemetry/loggers.test.circular.js.map +1 -0
  673. package/core-dist/src/telemetry/loggers.test.d.ts +6 -0
  674. package/core-dist/src/telemetry/loggers.test.js +961 -0
  675. package/core-dist/src/telemetry/loggers.test.js.map +1 -0
  676. package/core-dist/src/telemetry/metrics.d.ts +320 -0
  677. package/core-dist/src/telemetry/metrics.js +532 -0
  678. package/core-dist/src/telemetry/metrics.js.map +1 -0
  679. package/core-dist/src/telemetry/metrics.test.d.ts +6 -0
  680. package/core-dist/src/telemetry/metrics.test.js +746 -0
  681. package/core-dist/src/telemetry/metrics.test.js.map +1 -0
  682. package/core-dist/src/telemetry/qwen-logger/event-types.d.ts +89 -0
  683. package/core-dist/src/telemetry/qwen-logger/event-types.js +2 -0
  684. package/core-dist/src/telemetry/qwen-logger/event-types.js.map +1 -0
  685. package/core-dist/src/telemetry/qwen-logger/qwen-logger.d.ts +102 -0
  686. package/core-dist/src/telemetry/qwen-logger/qwen-logger.js +739 -0
  687. package/core-dist/src/telemetry/qwen-logger/qwen-logger.js.map +1 -0
  688. package/core-dist/src/telemetry/qwen-logger/qwen-logger.test.d.ts +6 -0
  689. package/core-dist/src/telemetry/qwen-logger/qwen-logger.test.js +380 -0
  690. package/core-dist/src/telemetry/qwen-logger/qwen-logger.test.js.map +1 -0
  691. package/core-dist/src/telemetry/sdk.d.ts +9 -0
  692. package/core-dist/src/telemetry/sdk.js +163 -0
  693. package/core-dist/src/telemetry/sdk.js.map +1 -0
  694. package/core-dist/src/telemetry/sdk.test.d.ts +6 -0
  695. package/core-dist/src/telemetry/sdk.test.js +116 -0
  696. package/core-dist/src/telemetry/sdk.test.js.map +1 -0
  697. package/core-dist/src/telemetry/telemetry-utils.d.ts +6 -0
  698. package/core-dist/src/telemetry/telemetry-utils.js +14 -0
  699. package/core-dist/src/telemetry/telemetry-utils.js.map +1 -0
  700. package/core-dist/src/telemetry/telemetry-utils.test.d.ts +6 -0
  701. package/core-dist/src/telemetry/telemetry-utils.test.js +40 -0
  702. package/core-dist/src/telemetry/telemetry-utils.test.js.map +1 -0
  703. package/core-dist/src/telemetry/telemetry.test.d.ts +6 -0
  704. package/core-dist/src/telemetry/telemetry.test.js +49 -0
  705. package/core-dist/src/telemetry/telemetry.test.js.map +1 -0
  706. package/core-dist/src/telemetry/tool-call-decision.d.ts +13 -0
  707. package/core-dist/src/telemetry/tool-call-decision.js +29 -0
  708. package/core-dist/src/telemetry/tool-call-decision.js.map +1 -0
  709. package/core-dist/src/telemetry/types.d.ts +363 -0
  710. package/core-dist/src/telemetry/types.js +635 -0
  711. package/core-dist/src/telemetry/types.js.map +1 -0
  712. package/core-dist/src/telemetry/uiTelemetry.d.ts +80 -0
  713. package/core-dist/src/telemetry/uiTelemetry.js +164 -0
  714. package/core-dist/src/telemetry/uiTelemetry.js.map +1 -0
  715. package/core-dist/src/telemetry/uiTelemetry.test.d.ts +6 -0
  716. package/core-dist/src/telemetry/uiTelemetry.test.js +625 -0
  717. package/core-dist/src/telemetry/uiTelemetry.test.js.map +1 -0
  718. package/core-dist/src/test-utils/config.d.ts +17 -0
  719. package/core-dist/src/test-utils/config.js +31 -0
  720. package/core-dist/src/test-utils/config.js.map +1 -0
  721. package/core-dist/src/test-utils/index.d.ts +6 -0
  722. package/core-dist/src/test-utils/index.js +7 -0
  723. package/core-dist/src/test-utils/index.js.map +1 -0
  724. package/core-dist/src/test-utils/mock-tool.d.ts +66 -0
  725. package/core-dist/src/test-utils/mock-tool.js +121 -0
  726. package/core-dist/src/test-utils/mock-tool.js.map +1 -0
  727. package/core-dist/src/test-utils/mockWorkspaceContext.d.ts +13 -0
  728. package/core-dist/src/test-utils/mockWorkspaceContext.js +24 -0
  729. package/core-dist/src/test-utils/mockWorkspaceContext.js.map +1 -0
  730. package/core-dist/src/tools/askUserQuestion.d.ts +41 -0
  731. package/core-dist/src/tools/askUserQuestion.js +247 -0
  732. package/core-dist/src/tools/askUserQuestion.js.map +1 -0
  733. package/core-dist/src/tools/askUserQuestion.test.d.ts +6 -0
  734. package/core-dist/src/tools/askUserQuestion.test.js +218 -0
  735. package/core-dist/src/tools/askUserQuestion.test.js.map +1 -0
  736. package/core-dist/src/tools/diffOptions.d.ts +9 -0
  737. package/core-dist/src/tools/diffOptions.js +46 -0
  738. package/core-dist/src/tools/diffOptions.js.map +1 -0
  739. package/core-dist/src/tools/diffOptions.test.d.ts +6 -0
  740. package/core-dist/src/tools/diffOptions.test.js +155 -0
  741. package/core-dist/src/tools/diffOptions.test.js.map +1 -0
  742. package/core-dist/src/tools/edit.d.ts +55 -0
  743. package/core-dist/src/tools/edit.js +446 -0
  744. package/core-dist/src/tools/edit.js.map +1 -0
  745. package/core-dist/src/tools/edit.test.d.ts +6 -0
  746. package/core-dist/src/tools/edit.test.js +742 -0
  747. package/core-dist/src/tools/edit.test.js.map +1 -0
  748. package/core-dist/src/tools/exitPlanMode.d.ts +28 -0
  749. package/core-dist/src/tools/exitPlanMode.js +144 -0
  750. package/core-dist/src/tools/exitPlanMode.js.map +1 -0
  751. package/core-dist/src/tools/exitPlanMode.test.d.ts +6 -0
  752. package/core-dist/src/tools/exitPlanMode.test.js +178 -0
  753. package/core-dist/src/tools/exitPlanMode.test.js.map +1 -0
  754. package/core-dist/src/tools/glob.d.ts +44 -0
  755. package/core-dist/src/tools/glob.js +195 -0
  756. package/core-dist/src/tools/glob.js.map +1 -0
  757. package/core-dist/src/tools/glob.test.d.ts +6 -0
  758. package/core-dist/src/tools/glob.test.js +481 -0
  759. package/core-dist/src/tools/glob.test.js.map +1 -0
  760. package/core-dist/src/tools/grep.d.ts +44 -0
  761. package/core-dist/src/tools/grep.js +427 -0
  762. package/core-dist/src/tools/grep.js.map +1 -0
  763. package/core-dist/src/tools/grep.test.d.ts +6 -0
  764. package/core-dist/src/tools/grep.test.js +360 -0
  765. package/core-dist/src/tools/grep.test.js.map +1 -0
  766. package/core-dist/src/tools/ls.d.ts +68 -0
  767. package/core-dist/src/tools/ls.js +221 -0
  768. package/core-dist/src/tools/ls.js.map +1 -0
  769. package/core-dist/src/tools/ls.test.d.ts +6 -0
  770. package/core-dist/src/tools/ls.test.js +246 -0
  771. package/core-dist/src/tools/ls.test.js.map +1 -0
  772. package/core-dist/src/tools/lsp.d.ts +66 -0
  773. package/core-dist/src/tools/lsp.js +894 -0
  774. package/core-dist/src/tools/lsp.js.map +1 -0
  775. package/core-dist/src/tools/lsp.test.d.ts +6 -0
  776. package/core-dist/src/tools/lsp.test.js +960 -0
  777. package/core-dist/src/tools/lsp.test.js.map +1 -0
  778. package/core-dist/src/tools/mcp-client-manager.d.ts +110 -0
  779. package/core-dist/src/tools/mcp-client-manager.js +381 -0
  780. package/core-dist/src/tools/mcp-client-manager.js.map +1 -0
  781. package/core-dist/src/tools/mcp-client-manager.test.d.ts +6 -0
  782. package/core-dist/src/tools/mcp-client-manager.test.js +207 -0
  783. package/core-dist/src/tools/mcp-client-manager.test.js.map +1 -0
  784. package/core-dist/src/tools/mcp-client.d.ts +199 -0
  785. package/core-dist/src/tools/mcp-client.js +1001 -0
  786. package/core-dist/src/tools/mcp-client.js.map +1 -0
  787. package/core-dist/src/tools/mcp-client.test.d.ts +6 -0
  788. package/core-dist/src/tools/mcp-client.test.js +307 -0
  789. package/core-dist/src/tools/mcp-client.test.js.map +1 -0
  790. package/core-dist/src/tools/mcp-tool.d.ts +69 -0
  791. package/core-dist/src/tools/mcp-tool.js +365 -0
  792. package/core-dist/src/tools/mcp-tool.js.map +1 -0
  793. package/core-dist/src/tools/mcp-tool.test.d.ts +6 -0
  794. package/core-dist/src/tools/mcp-tool.test.js +827 -0
  795. package/core-dist/src/tools/mcp-tool.test.js.map +1 -0
  796. package/core-dist/src/tools/memoryTool.d.ts +42 -0
  797. package/core-dist/src/tools/memoryTool.js +403 -0
  798. package/core-dist/src/tools/memoryTool.js.map +1 -0
  799. package/core-dist/src/tools/memoryTool.test.d.ts +6 -0
  800. package/core-dist/src/tools/memoryTool.test.js +416 -0
  801. package/core-dist/src/tools/memoryTool.test.js.map +1 -0
  802. package/core-dist/src/tools/modifiable-tool.d.ts +32 -0
  803. package/core-dist/src/tools/modifiable-tool.js +90 -0
  804. package/core-dist/src/tools/modifiable-tool.js.map +1 -0
  805. package/core-dist/src/tools/modifiable-tool.test.d.ts +6 -0
  806. package/core-dist/src/tools/modifiable-tool.test.js +188 -0
  807. package/core-dist/src/tools/modifiable-tool.test.js.map +1 -0
  808. package/core-dist/src/tools/read-file.d.ts +35 -0
  809. package/core-dist/src/tools/read-file.js +141 -0
  810. package/core-dist/src/tools/read-file.js.map +1 -0
  811. package/core-dist/src/tools/read-file.test.d.ts +6 -0
  812. package/core-dist/src/tools/read-file.test.js +333 -0
  813. package/core-dist/src/tools/read-file.test.js.map +1 -0
  814. package/core-dist/src/tools/ripGrep.d.ts +44 -0
  815. package/core-dist/src/tools/ripGrep.js +235 -0
  816. package/core-dist/src/tools/ripGrep.js.map +1 -0
  817. package/core-dist/src/tools/ripGrep.test.d.ts +6 -0
  818. package/core-dist/src/tools/ripGrep.test.js +529 -0
  819. package/core-dist/src/tools/ripGrep.test.js.map +1 -0
  820. package/core-dist/src/tools/sdk-control-client-transport.d.ts +67 -0
  821. package/core-dist/src/tools/sdk-control-client-transport.js +93 -0
  822. package/core-dist/src/tools/sdk-control-client-transport.js.map +1 -0
  823. package/core-dist/src/tools/shell.d.ts +34 -0
  824. package/core-dist/src/tools/shell.js +509 -0
  825. package/core-dist/src/tools/shell.js.map +1 -0
  826. package/core-dist/src/tools/shell.test.d.ts +6 -0
  827. package/core-dist/src/tools/shell.test.js +880 -0
  828. package/core-dist/src/tools/shell.test.js.map +1 -0
  829. package/core-dist/src/tools/skill.d.ts +45 -0
  830. package/core-dist/src/tools/skill.js +214 -0
  831. package/core-dist/src/tools/skill.js.map +1 -0
  832. package/core-dist/src/tools/skill.test.d.ts +6 -0
  833. package/core-dist/src/tools/skill.test.js +280 -0
  834. package/core-dist/src/tools/skill.test.js.map +1 -0
  835. package/core-dist/src/tools/task.d.ts +60 -0
  836. package/core-dist/src/tools/task.js +417 -0
  837. package/core-dist/src/tools/task.js.map +1 -0
  838. package/core-dist/src/tools/task.test.d.ts +6 -0
  839. package/core-dist/src/tools/task.test.js +367 -0
  840. package/core-dist/src/tools/task.test.js.map +1 -0
  841. package/core-dist/src/tools/todoWrite.d.ts +42 -0
  842. package/core-dist/src/tools/todoWrite.js +409 -0
  843. package/core-dist/src/tools/todoWrite.js.map +1 -0
  844. package/core-dist/src/tools/todoWrite.test.d.ts +6 -0
  845. package/core-dist/src/tools/todoWrite.test.js +234 -0
  846. package/core-dist/src/tools/todoWrite.test.js.map +1 -0
  847. package/core-dist/src/tools/tool-error.d.ts +45 -0
  848. package/core-dist/src/tools/tool-error.js +61 -0
  849. package/core-dist/src/tools/tool-error.js.map +1 -0
  850. package/core-dist/src/tools/tool-names.d.ts +60 -0
  851. package/core-dist/src/tools/tool-names.js +66 -0
  852. package/core-dist/src/tools/tool-names.js.map +1 -0
  853. package/core-dist/src/tools/tool-registry.d.ts +103 -0
  854. package/core-dist/src/tools/tool-registry.js +404 -0
  855. package/core-dist/src/tools/tool-registry.js.map +1 -0
  856. package/core-dist/src/tools/tool-registry.test.d.ts +6 -0
  857. package/core-dist/src/tools/tool-registry.test.js +331 -0
  858. package/core-dist/src/tools/tool-registry.test.js.map +1 -0
  859. package/core-dist/src/tools/tools.d.ts +364 -0
  860. package/core-dist/src/tools/tools.js +263 -0
  861. package/core-dist/src/tools/tools.js.map +1 -0
  862. package/core-dist/src/tools/tools.test.d.ts +6 -0
  863. package/core-dist/src/tools/tools.test.js +205 -0
  864. package/core-dist/src/tools/tools.test.js.map +1 -0
  865. package/core-dist/src/tools/web-fetch.d.ts +31 -0
  866. package/core-dist/src/tools/web-fetch.js +168 -0
  867. package/core-dist/src/tools/web-fetch.js.map +1 -0
  868. package/core-dist/src/tools/web-fetch.test.d.ts +6 -0
  869. package/core-dist/src/tools/web-fetch.test.js +134 -0
  870. package/core-dist/src/tools/web-fetch.test.js.map +1 -0
  871. package/core-dist/src/tools/web-search/base-provider.d.ts +31 -0
  872. package/core-dist/src/tools/web-search/base-provider.js +34 -0
  873. package/core-dist/src/tools/web-search/base-provider.js.map +1 -0
  874. package/core-dist/src/tools/web-search/index.d.ts +24 -0
  875. package/core-dist/src/tools/web-search/index.js +249 -0
  876. package/core-dist/src/tools/web-search/index.js.map +1 -0
  877. package/core-dist/src/tools/web-search/index.test.d.ts +6 -0
  878. package/core-dist/src/tools/web-search/index.test.js +237 -0
  879. package/core-dist/src/tools/web-search/index.test.js.map +1 -0
  880. package/core-dist/src/tools/web-search/providers/dashscope-provider.d.ts +23 -0
  881. package/core-dist/src/tools/web-search/providers/dashscope-provider.js +120 -0
  882. package/core-dist/src/tools/web-search/providers/dashscope-provider.js.map +1 -0
  883. package/core-dist/src/tools/web-search/providers/google-provider.d.ts +17 -0
  884. package/core-dist/src/tools/web-search/providers/google-provider.js +55 -0
  885. package/core-dist/src/tools/web-search/providers/google-provider.js.map +1 -0
  886. package/core-dist/src/tools/web-search/providers/tavily-provider.d.ts +17 -0
  887. package/core-dist/src/tools/web-search/providers/tavily-provider.js +54 -0
  888. package/core-dist/src/tools/web-search/providers/tavily-provider.js.map +1 -0
  889. package/core-dist/src/tools/web-search/types.d.ts +138 -0
  890. package/core-dist/src/tools/web-search/types.js +7 -0
  891. package/core-dist/src/tools/web-search/types.js.map +1 -0
  892. package/core-dist/src/tools/web-search/utils.d.ts +28 -0
  893. package/core-dist/src/tools/web-search/utils.js +35 -0
  894. package/core-dist/src/tools/web-search/utils.js.map +1 -0
  895. package/core-dist/src/tools/write-file.d.ts +52 -0
  896. package/core-dist/src/tools/write-file.js +316 -0
  897. package/core-dist/src/tools/write-file.js.map +1 -0
  898. package/core-dist/src/tools/write-file.test.d.ts +6 -0
  899. package/core-dist/src/tools/write-file.test.js +613 -0
  900. package/core-dist/src/tools/write-file.test.js.map +1 -0
  901. package/core-dist/src/utils/LruCache.d.ts +13 -0
  902. package/core-dist/src/utils/LruCache.js +38 -0
  903. package/core-dist/src/utils/LruCache.js.map +1 -0
  904. package/core-dist/src/utils/browser.d.ts +13 -0
  905. package/core-dist/src/utils/browser.js +50 -0
  906. package/core-dist/src/utils/browser.js.map +1 -0
  907. package/core-dist/src/utils/configResolver.d.ts +120 -0
  908. package/core-dist/src/utils/configResolver.js +125 -0
  909. package/core-dist/src/utils/configResolver.js.map +1 -0
  910. package/core-dist/src/utils/configResolver.test.d.ts +6 -0
  911. package/core-dist/src/utils/configResolver.test.js +99 -0
  912. package/core-dist/src/utils/configResolver.test.js.map +1 -0
  913. package/core-dist/src/utils/debugLogger.d.ts +46 -0
  914. package/core-dist/src/utils/debugLogger.js +159 -0
  915. package/core-dist/src/utils/debugLogger.js.map +1 -0
  916. package/core-dist/src/utils/debugLogger.test.d.ts +6 -0
  917. package/core-dist/src/utils/debugLogger.test.js +188 -0
  918. package/core-dist/src/utils/debugLogger.test.js.map +1 -0
  919. package/core-dist/src/utils/editHelper.d.ts +58 -0
  920. package/core-dist/src/utils/editHelper.js +342 -0
  921. package/core-dist/src/utils/editHelper.js.map +1 -0
  922. package/core-dist/src/utils/editHelper.test.d.ts +6 -0
  923. package/core-dist/src/utils/editHelper.test.js +127 -0
  924. package/core-dist/src/utils/editHelper.test.js.map +1 -0
  925. package/core-dist/src/utils/editor.d.ts +37 -0
  926. package/core-dist/src/utils/editor.js +179 -0
  927. package/core-dist/src/utils/editor.js.map +1 -0
  928. package/core-dist/src/utils/editor.test.d.ts +6 -0
  929. package/core-dist/src/utils/editor.test.js +434 -0
  930. package/core-dist/src/utils/editor.test.js.map +1 -0
  931. package/core-dist/src/utils/envVarResolver.d.ts +39 -0
  932. package/core-dist/src/utils/envVarResolver.js +100 -0
  933. package/core-dist/src/utils/envVarResolver.js.map +1 -0
  934. package/core-dist/src/utils/envVarResolver.test.d.ts +6 -0
  935. package/core-dist/src/utils/envVarResolver.test.js +221 -0
  936. package/core-dist/src/utils/envVarResolver.test.js.map +1 -0
  937. package/core-dist/src/utils/environmentContext.d.ts +21 -0
  938. package/core-dist/src/utils/environmentContext.js +73 -0
  939. package/core-dist/src/utils/environmentContext.js.map +1 -0
  940. package/core-dist/src/utils/environmentContext.test.d.ts +6 -0
  941. package/core-dist/src/utils/environmentContext.test.js +151 -0
  942. package/core-dist/src/utils/environmentContext.test.js.map +1 -0
  943. package/core-dist/src/utils/errorParsing.d.ts +7 -0
  944. package/core-dist/src/utils/errorParsing.js +72 -0
  945. package/core-dist/src/utils/errorParsing.js.map +1 -0
  946. package/core-dist/src/utils/errorParsing.test.d.ts +6 -0
  947. package/core-dist/src/utils/errorParsing.test.js +87 -0
  948. package/core-dist/src/utils/errorParsing.test.js.map +1 -0
  949. package/core-dist/src/utils/errorReporting.d.ts +14 -0
  950. package/core-dist/src/utils/errorReporting.js +56 -0
  951. package/core-dist/src/utils/errorReporting.js.map +1 -0
  952. package/core-dist/src/utils/errorReporting.test.d.ts +6 -0
  953. package/core-dist/src/utils/errorReporting.test.js +84 -0
  954. package/core-dist/src/utils/errorReporting.test.js.map +1 -0
  955. package/core-dist/src/utils/errors.d.ts +44 -0
  956. package/core-dist/src/utils/errors.js +114 -0
  957. package/core-dist/src/utils/errors.js.map +1 -0
  958. package/core-dist/src/utils/errors.test.d.ts +6 -0
  959. package/core-dist/src/utils/errors.test.js +70 -0
  960. package/core-dist/src/utils/errors.test.js.map +1 -0
  961. package/core-dist/src/utils/fetch.d.ts +14 -0
  962. package/core-dist/src/utils/fetch.js +152 -0
  963. package/core-dist/src/utils/fetch.js.map +1 -0
  964. package/core-dist/src/utils/fetch.test.d.ts +6 -0
  965. package/core-dist/src/utils/fetch.test.js +40 -0
  966. package/core-dist/src/utils/fetch.test.js.map +1 -0
  967. package/core-dist/src/utils/fileUtils.d.ts +102 -0
  968. package/core-dist/src/utils/fileUtils.js +584 -0
  969. package/core-dist/src/utils/fileUtils.js.map +1 -0
  970. package/core-dist/src/utils/fileUtils.test.d.ts +6 -0
  971. package/core-dist/src/utils/fileUtils.test.js +808 -0
  972. package/core-dist/src/utils/fileUtils.test.js.map +1 -0
  973. package/core-dist/src/utils/filesearch/crawlCache.d.ts +25 -0
  974. package/core-dist/src/utils/filesearch/crawlCache.js +57 -0
  975. package/core-dist/src/utils/filesearch/crawlCache.js.map +1 -0
  976. package/core-dist/src/utils/filesearch/crawlCache.test.d.ts +6 -0
  977. package/core-dist/src/utils/filesearch/crawlCache.test.js +103 -0
  978. package/core-dist/src/utils/filesearch/crawlCache.test.js.map +1 -0
  979. package/core-dist/src/utils/filesearch/crawler.d.ts +15 -0
  980. package/core-dist/src/utils/filesearch/crawler.js +50 -0
  981. package/core-dist/src/utils/filesearch/crawler.js.map +1 -0
  982. package/core-dist/src/utils/filesearch/crawler.test.d.ts +6 -0
  983. package/core-dist/src/utils/filesearch/crawler.test.js +468 -0
  984. package/core-dist/src/utils/filesearch/crawler.test.js.map +1 -0
  985. package/core-dist/src/utils/filesearch/fileSearch.d.ts +38 -0
  986. package/core-dist/src/utils/filesearch/fileSearch.js +194 -0
  987. package/core-dist/src/utils/filesearch/fileSearch.js.map +1 -0
  988. package/core-dist/src/utils/filesearch/fileSearch.test.d.ts +6 -0
  989. package/core-dist/src/utils/filesearch/fileSearch.test.js +642 -0
  990. package/core-dist/src/utils/filesearch/fileSearch.test.js.map +1 -0
  991. package/core-dist/src/utils/filesearch/ignore.d.ts +42 -0
  992. package/core-dist/src/utils/filesearch/ignore.js +106 -0
  993. package/core-dist/src/utils/filesearch/ignore.js.map +1 -0
  994. package/core-dist/src/utils/filesearch/ignore.test.d.ts +6 -0
  995. package/core-dist/src/utils/filesearch/ignore.test.js +144 -0
  996. package/core-dist/src/utils/filesearch/ignore.test.js.map +1 -0
  997. package/core-dist/src/utils/filesearch/result-cache.d.ts +33 -0
  998. package/core-dist/src/utils/filesearch/result-cache.js +59 -0
  999. package/core-dist/src/utils/filesearch/result-cache.js.map +1 -0
  1000. package/core-dist/src/utils/filesearch/result-cache.test.d.ts +6 -0
  1001. package/core-dist/src/utils/filesearch/result-cache.test.js +46 -0
  1002. package/core-dist/src/utils/filesearch/result-cache.test.js.map +1 -0
  1003. package/core-dist/src/utils/formatters.d.ts +6 -0
  1004. package/core-dist/src/utils/formatters.js +16 -0
  1005. package/core-dist/src/utils/formatters.js.map +1 -0
  1006. package/core-dist/src/utils/generateContentResponseUtilities.d.ts +13 -0
  1007. package/core-dist/src/utils/generateContentResponseUtilities.js +95 -0
  1008. package/core-dist/src/utils/generateContentResponseUtilities.js.map +1 -0
  1009. package/core-dist/src/utils/generateContentResponseUtilities.test.d.ts +6 -0
  1010. package/core-dist/src/utils/generateContentResponseUtilities.test.js +235 -0
  1011. package/core-dist/src/utils/generateContentResponseUtilities.test.js.map +1 -0
  1012. package/core-dist/src/utils/getFolderStructure.d.ts +31 -0
  1013. package/core-dist/src/utils/getFolderStructure.js +233 -0
  1014. package/core-dist/src/utils/getFolderStructure.js.map +1 -0
  1015. package/core-dist/src/utils/getFolderStructure.test.d.ts +6 -0
  1016. package/core-dist/src/utils/getFolderStructure.test.js +282 -0
  1017. package/core-dist/src/utils/getFolderStructure.test.js.map +1 -0
  1018. package/core-dist/src/utils/getPty.d.ts +7 -0
  1019. package/core-dist/src/utils/getPty.js +7 -0
  1020. package/core-dist/src/utils/getPty.js.map +1 -0
  1021. package/core-dist/src/utils/gitIgnoreParser.d.ts +16 -0
  1022. package/core-dist/src/utils/gitIgnoreParser.js +152 -0
  1023. package/core-dist/src/utils/gitIgnoreParser.js.map +1 -0
  1024. package/core-dist/src/utils/gitIgnoreParser.test.d.ts +6 -0
  1025. package/core-dist/src/utils/gitIgnoreParser.test.js +185 -0
  1026. package/core-dist/src/utils/gitIgnoreParser.test.js.map +1 -0
  1027. package/core-dist/src/utils/gitUtils.d.ts +21 -0
  1028. package/core-dist/src/utils/gitUtils.js +78 -0
  1029. package/core-dist/src/utils/gitUtils.js.map +1 -0
  1030. package/core-dist/src/utils/iconvHelper.d.ts +33 -0
  1031. package/core-dist/src/utils/iconvHelper.js +48 -0
  1032. package/core-dist/src/utils/iconvHelper.js.map +1 -0
  1033. package/core-dist/src/utils/ignorePatterns.d.ts +103 -0
  1034. package/core-dist/src/utils/ignorePatterns.js +222 -0
  1035. package/core-dist/src/utils/ignorePatterns.js.map +1 -0
  1036. package/core-dist/src/utils/ignorePatterns.test.d.ts +6 -0
  1037. package/core-dist/src/utils/ignorePatterns.test.js +255 -0
  1038. package/core-dist/src/utils/ignorePatterns.test.js.map +1 -0
  1039. package/core-dist/src/utils/installationManager.d.ts +16 -0
  1040. package/core-dist/src/utils/installationManager.js +52 -0
  1041. package/core-dist/src/utils/installationManager.js.map +1 -0
  1042. package/core-dist/src/utils/installationManager.test.d.ts +6 -0
  1043. package/core-dist/src/utils/installationManager.test.js +79 -0
  1044. package/core-dist/src/utils/installationManager.test.js.map +1 -0
  1045. package/core-dist/src/utils/jsonl-utils.d.ts +38 -0
  1046. package/core-dist/src/utils/jsonl-utils.js +176 -0
  1047. package/core-dist/src/utils/jsonl-utils.js.map +1 -0
  1048. package/core-dist/src/utils/language-detection.d.ts +6 -0
  1049. package/core-dist/src/utils/language-detection.js +101 -0
  1050. package/core-dist/src/utils/language-detection.js.map +1 -0
  1051. package/core-dist/src/utils/memoryDiscovery.d.ts +15 -0
  1052. package/core-dist/src/utils/memoryDiscovery.js +238 -0
  1053. package/core-dist/src/utils/memoryDiscovery.js.map +1 -0
  1054. package/core-dist/src/utils/memoryDiscovery.test.d.ts +6 -0
  1055. package/core-dist/src/utils/memoryDiscovery.test.js +212 -0
  1056. package/core-dist/src/utils/memoryDiscovery.test.js.map +1 -0
  1057. package/core-dist/src/utils/memoryImportProcessor.d.ts +41 -0
  1058. package/core-dist/src/utils/memoryImportProcessor.js +296 -0
  1059. package/core-dist/src/utils/memoryImportProcessor.js.map +1 -0
  1060. package/core-dist/src/utils/memoryImportProcessor.test.d.ts +6 -0
  1061. package/core-dist/src/utils/memoryImportProcessor.test.js +631 -0
  1062. package/core-dist/src/utils/memoryImportProcessor.test.js.map +1 -0
  1063. package/core-dist/src/utils/messageInspectors.d.ts +8 -0
  1064. package/core-dist/src/utils/messageInspectors.js +16 -0
  1065. package/core-dist/src/utils/messageInspectors.js.map +1 -0
  1066. package/core-dist/src/utils/nextSpeakerChecker.d.ts +12 -0
  1067. package/core-dist/src/utils/nextSpeakerChecker.js +99 -0
  1068. package/core-dist/src/utils/nextSpeakerChecker.js.map +1 -0
  1069. package/core-dist/src/utils/nextSpeakerChecker.test.d.ts +6 -0
  1070. package/core-dist/src/utils/nextSpeakerChecker.test.js +183 -0
  1071. package/core-dist/src/utils/nextSpeakerChecker.test.js.map +1 -0
  1072. package/core-dist/src/utils/openaiLogger.d.ts +42 -0
  1073. package/core-dist/src/utils/openaiLogger.js +140 -0
  1074. package/core-dist/src/utils/openaiLogger.js.map +1 -0
  1075. package/core-dist/src/utils/openaiLogger.test.d.ts +6 -0
  1076. package/core-dist/src/utils/openaiLogger.test.js +314 -0
  1077. package/core-dist/src/utils/openaiLogger.test.js.map +1 -0
  1078. package/core-dist/src/utils/partUtils.d.ts +35 -0
  1079. package/core-dist/src/utils/partUtils.js +133 -0
  1080. package/core-dist/src/utils/partUtils.js.map +1 -0
  1081. package/core-dist/src/utils/partUtils.test.d.ts +6 -0
  1082. package/core-dist/src/utils/partUtils.test.js +241 -0
  1083. package/core-dist/src/utils/partUtils.test.js.map +1 -0
  1084. package/core-dist/src/utils/pathReader.d.ts +17 -0
  1085. package/core-dist/src/utils/pathReader.js +92 -0
  1086. package/core-dist/src/utils/pathReader.js.map +1 -0
  1087. package/core-dist/src/utils/pathReader.test.d.ts +6 -0
  1088. package/core-dist/src/utils/pathReader.test.js +367 -0
  1089. package/core-dist/src/utils/pathReader.test.js.map +1 -0
  1090. package/core-dist/src/utils/paths.d.ts +110 -0
  1091. package/core-dist/src/utils/paths.js +269 -0
  1092. package/core-dist/src/utils/paths.js.map +1 -0
  1093. package/core-dist/src/utils/paths.test.d.ts +6 -0
  1094. package/core-dist/src/utils/paths.test.js +633 -0
  1095. package/core-dist/src/utils/paths.test.js.map +1 -0
  1096. package/core-dist/src/utils/projectSummary.d.ts +22 -0
  1097. package/core-dist/src/utils/projectSummary.js +86 -0
  1098. package/core-dist/src/utils/projectSummary.js.map +1 -0
  1099. package/core-dist/src/utils/promptIdContext.d.ts +7 -0
  1100. package/core-dist/src/utils/promptIdContext.js +8 -0
  1101. package/core-dist/src/utils/promptIdContext.js.map +1 -0
  1102. package/core-dist/src/utils/quotaErrorDetection.d.ts +19 -0
  1103. package/core-dist/src/utils/quotaErrorDetection.js +84 -0
  1104. package/core-dist/src/utils/quotaErrorDetection.js.map +1 -0
  1105. package/core-dist/src/utils/quotaErrorDetection.test.d.ts +6 -0
  1106. package/core-dist/src/utils/quotaErrorDetection.test.js +104 -0
  1107. package/core-dist/src/utils/quotaErrorDetection.test.js.map +1 -0
  1108. package/core-dist/src/utils/qwenIgnoreParser.d.ts +18 -0
  1109. package/core-dist/src/utils/qwenIgnoreParser.js +61 -0
  1110. package/core-dist/src/utils/qwenIgnoreParser.js.map +1 -0
  1111. package/core-dist/src/utils/qwenIgnoreParser.test.d.ts +6 -0
  1112. package/core-dist/src/utils/qwenIgnoreParser.test.js +50 -0
  1113. package/core-dist/src/utils/qwenIgnoreParser.test.js.map +1 -0
  1114. package/core-dist/src/utils/rateLimit.d.ts +23 -0
  1115. package/core-dist/src/utils/rateLimit.js +69 -0
  1116. package/core-dist/src/utils/rateLimit.js.map +1 -0
  1117. package/core-dist/src/utils/rateLimit.test.d.ts +6 -0
  1118. package/core-dist/src/utils/rateLimit.test.js +72 -0
  1119. package/core-dist/src/utils/rateLimit.test.js.map +1 -0
  1120. package/core-dist/src/utils/readManyFiles.d.ts +67 -0
  1121. package/core-dist/src/utils/readManyFiles.js +133 -0
  1122. package/core-dist/src/utils/readManyFiles.js.map +1 -0
  1123. package/core-dist/src/utils/readManyFiles.test.d.ts +6 -0
  1124. package/core-dist/src/utils/readManyFiles.test.js +230 -0
  1125. package/core-dist/src/utils/readManyFiles.test.js.map +1 -0
  1126. package/core-dist/src/utils/request-tokenizer/imageTokenizer.d.ts +112 -0
  1127. package/core-dist/src/utils/request-tokenizer/imageTokenizer.js +403 -0
  1128. package/core-dist/src/utils/request-tokenizer/imageTokenizer.js.map +1 -0
  1129. package/core-dist/src/utils/request-tokenizer/imageTokenizer.test.d.ts +6 -0
  1130. package/core-dist/src/utils/request-tokenizer/imageTokenizer.test.js +114 -0
  1131. package/core-dist/src/utils/request-tokenizer/imageTokenizer.test.js.map +1 -0
  1132. package/core-dist/src/utils/request-tokenizer/index.d.ts +9 -0
  1133. package/core-dist/src/utils/request-tokenizer/index.js +9 -0
  1134. package/core-dist/src/utils/request-tokenizer/index.js.map +1 -0
  1135. package/core-dist/src/utils/request-tokenizer/requestTokenizer.d.ts +52 -0
  1136. package/core-dist/src/utils/request-tokenizer/requestTokenizer.js +252 -0
  1137. package/core-dist/src/utils/request-tokenizer/requestTokenizer.js.map +1 -0
  1138. package/core-dist/src/utils/request-tokenizer/requestTokenizer.test.d.ts +6 -0
  1139. package/core-dist/src/utils/request-tokenizer/requestTokenizer.test.js +227 -0
  1140. package/core-dist/src/utils/request-tokenizer/requestTokenizer.test.js.map +1 -0
  1141. package/core-dist/src/utils/request-tokenizer/supportedImageFormats.d.ts +30 -0
  1142. package/core-dist/src/utils/request-tokenizer/supportedImageFormats.js +41 -0
  1143. package/core-dist/src/utils/request-tokenizer/supportedImageFormats.js.map +1 -0
  1144. package/core-dist/src/utils/request-tokenizer/textTokenizer.d.ts +32 -0
  1145. package/core-dist/src/utils/request-tokenizer/textTokenizer.js +54 -0
  1146. package/core-dist/src/utils/request-tokenizer/textTokenizer.js.map +1 -0
  1147. package/core-dist/src/utils/request-tokenizer/textTokenizer.test.d.ts +6 -0
  1148. package/core-dist/src/utils/request-tokenizer/textTokenizer.test.js +237 -0
  1149. package/core-dist/src/utils/request-tokenizer/textTokenizer.test.js.map +1 -0
  1150. package/core-dist/src/utils/request-tokenizer/types.d.ts +34 -0
  1151. package/core-dist/src/utils/request-tokenizer/types.js +7 -0
  1152. package/core-dist/src/utils/request-tokenizer/types.js.map +1 -0
  1153. package/core-dist/src/utils/retry.d.ts +38 -0
  1154. package/core-dist/src/utils/retry.js +180 -0
  1155. package/core-dist/src/utils/retry.js.map +1 -0
  1156. package/core-dist/src/utils/retry.test.d.ts +6 -0
  1157. package/core-dist/src/utils/retry.test.js +402 -0
  1158. package/core-dist/src/utils/retry.test.js.map +1 -0
  1159. package/core-dist/src/utils/ripgrepUtils.d.ts +61 -0
  1160. package/core-dist/src/utils/ripgrepUtils.js +227 -0
  1161. package/core-dist/src/utils/ripgrepUtils.js.map +1 -0
  1162. package/core-dist/src/utils/ripgrepUtils.test.d.ts +6 -0
  1163. package/core-dist/src/utils/ripgrepUtils.test.js +101 -0
  1164. package/core-dist/src/utils/ripgrepUtils.test.js.map +1 -0
  1165. package/core-dist/src/utils/runtimeFetchOptions.d.ts +44 -0
  1166. package/core-dist/src/utils/runtimeFetchOptions.js +92 -0
  1167. package/core-dist/src/utils/runtimeFetchOptions.js.map +1 -0
  1168. package/core-dist/src/utils/runtimeFetchOptions.test.d.ts +6 -0
  1169. package/core-dist/src/utils/runtimeFetchOptions.test.js +70 -0
  1170. package/core-dist/src/utils/runtimeFetchOptions.test.js.map +1 -0
  1171. package/core-dist/src/utils/safeJsonParse.d.ts +15 -0
  1172. package/core-dist/src/utils/safeJsonParse.js +43 -0
  1173. package/core-dist/src/utils/safeJsonParse.js.map +1 -0
  1174. package/core-dist/src/utils/safeJsonParse.test.d.ts +6 -0
  1175. package/core-dist/src/utils/safeJsonParse.test.js +112 -0
  1176. package/core-dist/src/utils/safeJsonParse.test.js.map +1 -0
  1177. package/core-dist/src/utils/safeJsonStringify.d.ts +13 -0
  1178. package/core-dist/src/utils/safeJsonStringify.js +25 -0
  1179. package/core-dist/src/utils/safeJsonStringify.js.map +1 -0
  1180. package/core-dist/src/utils/safeJsonStringify.test.d.ts +6 -0
  1181. package/core-dist/src/utils/safeJsonStringify.test.js +61 -0
  1182. package/core-dist/src/utils/safeJsonStringify.test.js.map +1 -0
  1183. package/core-dist/src/utils/schemaConverter.d.ts +15 -0
  1184. package/core-dist/src/utils/schemaConverter.js +109 -0
  1185. package/core-dist/src/utils/schemaConverter.js.map +1 -0
  1186. package/core-dist/src/utils/schemaConverter.test.d.ts +6 -0
  1187. package/core-dist/src/utils/schemaConverter.test.js +106 -0
  1188. package/core-dist/src/utils/schemaConverter.test.js.map +1 -0
  1189. package/core-dist/src/utils/schemaValidator.d.ts +16 -0
  1190. package/core-dist/src/utils/schemaValidator.js +123 -0
  1191. package/core-dist/src/utils/schemaValidator.js.map +1 -0
  1192. package/core-dist/src/utils/schemaValidator.test.d.ts +6 -0
  1193. package/core-dist/src/utils/schemaValidator.test.js +266 -0
  1194. package/core-dist/src/utils/schemaValidator.test.js.map +1 -0
  1195. package/core-dist/src/utils/secure-browser-launcher.d.ts +23 -0
  1196. package/core-dist/src/utils/secure-browser-launcher.js +165 -0
  1197. package/core-dist/src/utils/secure-browser-launcher.js.map +1 -0
  1198. package/core-dist/src/utils/secure-browser-launcher.test.d.ts +6 -0
  1199. package/core-dist/src/utils/secure-browser-launcher.test.js +149 -0
  1200. package/core-dist/src/utils/secure-browser-launcher.test.js.map +1 -0
  1201. package/core-dist/src/utils/shell-utils.d.ts +158 -0
  1202. package/core-dist/src/utils/shell-utils.js +739 -0
  1203. package/core-dist/src/utils/shell-utils.js.map +1 -0
  1204. package/core-dist/src/utils/shell-utils.test.d.ts +6 -0
  1205. package/core-dist/src/utils/shell-utils.test.js +466 -0
  1206. package/core-dist/src/utils/shell-utils.test.js.map +1 -0
  1207. package/core-dist/src/utils/shellReadOnlyChecker.d.ts +6 -0
  1208. package/core-dist/src/utils/shellReadOnlyChecker.js +290 -0
  1209. package/core-dist/src/utils/shellReadOnlyChecker.js.map +1 -0
  1210. package/core-dist/src/utils/shellReadOnlyChecker.test.d.ts +6 -0
  1211. package/core-dist/src/utils/shellReadOnlyChecker.test.js +157 -0
  1212. package/core-dist/src/utils/shellReadOnlyChecker.test.js.map +1 -0
  1213. package/core-dist/src/utils/subagentGenerator.d.ts +20 -0
  1214. package/core-dist/src/utils/subagentGenerator.js +120 -0
  1215. package/core-dist/src/utils/subagentGenerator.js.map +1 -0
  1216. package/core-dist/src/utils/subagentGenerator.test.d.ts +6 -0
  1217. package/core-dist/src/utils/subagentGenerator.test.js +135 -0
  1218. package/core-dist/src/utils/subagentGenerator.test.js.map +1 -0
  1219. package/core-dist/src/utils/summarizer.d.ts +25 -0
  1220. package/core-dist/src/utils/summarizer.js +53 -0
  1221. package/core-dist/src/utils/summarizer.js.map +1 -0
  1222. package/core-dist/src/utils/summarizer.test.d.ts +6 -0
  1223. package/core-dist/src/utils/summarizer.test.js +128 -0
  1224. package/core-dist/src/utils/summarizer.test.js.map +1 -0
  1225. package/core-dist/src/utils/symlink.d.ts +26 -0
  1226. package/core-dist/src/utils/symlink.js +43 -0
  1227. package/core-dist/src/utils/symlink.js.map +1 -0
  1228. package/core-dist/src/utils/systemEncoding.d.ts +40 -0
  1229. package/core-dist/src/utils/systemEncoding.js +160 -0
  1230. package/core-dist/src/utils/systemEncoding.js.map +1 -0
  1231. package/core-dist/src/utils/systemEncoding.test.d.ts +6 -0
  1232. package/core-dist/src/utils/systemEncoding.test.js +367 -0
  1233. package/core-dist/src/utils/systemEncoding.test.js.map +1 -0
  1234. package/core-dist/src/utils/terminalSerializer.d.ts +25 -0
  1235. package/core-dist/src/utils/terminalSerializer.js +432 -0
  1236. package/core-dist/src/utils/terminalSerializer.js.map +1 -0
  1237. package/core-dist/src/utils/terminalSerializer.test.d.ts +6 -0
  1238. package/core-dist/src/utils/terminalSerializer.test.js +176 -0
  1239. package/core-dist/src/utils/terminalSerializer.test.js.map +1 -0
  1240. package/core-dist/src/utils/testUtils.d.ts +29 -0
  1241. package/core-dist/src/utils/testUtils.js +70 -0
  1242. package/core-dist/src/utils/testUtils.js.map +1 -0
  1243. package/core-dist/src/utils/textUtils.d.ts +29 -0
  1244. package/core-dist/src/utils/textUtils.js +59 -0
  1245. package/core-dist/src/utils/textUtils.js.map +1 -0
  1246. package/core-dist/src/utils/textUtils.test.d.ts +6 -0
  1247. package/core-dist/src/utils/textUtils.test.js +91 -0
  1248. package/core-dist/src/utils/textUtils.test.js.map +1 -0
  1249. package/core-dist/src/utils/thoughtUtils.d.ts +23 -0
  1250. package/core-dist/src/utils/thoughtUtils.js +53 -0
  1251. package/core-dist/src/utils/thoughtUtils.js.map +1 -0
  1252. package/core-dist/src/utils/thoughtUtils.test.d.ts +6 -0
  1253. package/core-dist/src/utils/thoughtUtils.test.js +78 -0
  1254. package/core-dist/src/utils/thoughtUtils.test.js.map +1 -0
  1255. package/core-dist/src/utils/toml-to-markdown-converter.d.ts +22 -0
  1256. package/core-dist/src/utils/toml-to-markdown-converter.js +61 -0
  1257. package/core-dist/src/utils/toml-to-markdown-converter.js.map +1 -0
  1258. package/core-dist/src/utils/toml-to-markdown-converter.test.d.ts +6 -0
  1259. package/core-dist/src/utils/toml-to-markdown-converter.test.js +73 -0
  1260. package/core-dist/src/utils/toml-to-markdown-converter.test.js.map +1 -0
  1261. package/core-dist/src/utils/tool-utils.d.ts +22 -0
  1262. package/core-dist/src/utils/tool-utils.js +121 -0
  1263. package/core-dist/src/utils/tool-utils.js.map +1 -0
  1264. package/core-dist/src/utils/tool-utils.test.d.ts +6 -0
  1265. package/core-dist/src/utils/tool-utils.test.js +100 -0
  1266. package/core-dist/src/utils/tool-utils.test.js.map +1 -0
  1267. package/core-dist/src/utils/workspaceContext.d.ts +66 -0
  1268. package/core-dist/src/utils/workspaceContext.js +173 -0
  1269. package/core-dist/src/utils/workspaceContext.js.map +1 -0
  1270. package/core-dist/src/utils/workspaceContext.test.d.ts +6 -0
  1271. package/core-dist/src/utils/workspaceContext.test.js +313 -0
  1272. package/core-dist/src/utils/workspaceContext.test.js.map +1 -0
  1273. package/core-dist/src/utils/yaml-parser.d.ts +29 -0
  1274. package/core-dist/src/utils/yaml-parser.js +172 -0
  1275. package/core-dist/src/utils/yaml-parser.js.map +1 -0
  1276. package/core-dist/src/utils/yaml-parser.test.d.ts +6 -0
  1277. package/core-dist/src/utils/yaml-parser.test.js +170 -0
  1278. package/core-dist/src/utils/yaml-parser.test.js.map +1 -0
  1279. package/core-dist/tsconfig.tsbuildinfo +1 -0
  1280. package/package.json +3 -1
  1281. package/scripts/postinstall.cjs +102 -203
@@ -0,0 +1,1885 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
7
+ import { GeminiClient } from './client.js';
8
+ import { findCompressSplitPoint } from '../services/chatCompressionService.js';
9
+ import { AuthType, } from './contentGenerator.js';
10
+ import {} from './geminiChat.js';
11
+ import { ApprovalMode } from '../config/config.js';
12
+ import { CompressionStatus, GeminiEventType, Turn, } from './turn.js';
13
+ import { getCoreSystemPrompt } from './prompts.js';
14
+ import { DEFAULT_QWEN_FLASH_MODEL } from '../config/models.js';
15
+ import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
16
+ import { setSimulate429 } from '../utils/testUtils.js';
17
+ import { ideContextStore } from '../ide/ideContext.js';
18
+ import { uiTelemetryService } from '../telemetry/uiTelemetry.js';
19
+ // Mock fs module to prevent actual file system operations during tests
20
+ const mockFileSystem = new Map();
21
+ vi.mock('node:fs', () => {
22
+ const fsModule = {
23
+ mkdirSync: vi.fn(),
24
+ writeFileSync: vi.fn((path, data) => {
25
+ mockFileSystem.set(path, data);
26
+ }),
27
+ readFileSync: vi.fn((path) => {
28
+ if (mockFileSystem.has(path)) {
29
+ return mockFileSystem.get(path);
30
+ }
31
+ throw Object.assign(new Error('ENOENT: no such file or directory'), {
32
+ code: 'ENOENT',
33
+ });
34
+ }),
35
+ existsSync: vi.fn((path) => mockFileSystem.has(path)),
36
+ appendFileSync: vi.fn(),
37
+ };
38
+ return {
39
+ default: fsModule,
40
+ ...fsModule,
41
+ };
42
+ });
43
+ // --- Mocks ---
44
+ const mockTurnRunFn = vi.fn();
45
+ vi.mock('./turn', async (importOriginal) => {
46
+ const actual = await importOriginal();
47
+ // Define a mock class that has the same shape as the real Turn
48
+ class MockTurn {
49
+ pendingToolCalls = [];
50
+ // The run method is a property that holds our mock function
51
+ run = mockTurnRunFn;
52
+ constructor() {
53
+ // The constructor can be empty or do some mock setup
54
+ }
55
+ }
56
+ // Export the mock class as 'Turn'
57
+ return {
58
+ ...actual,
59
+ Turn: MockTurn,
60
+ };
61
+ });
62
+ vi.mock('../config/config.js');
63
+ vi.mock('./prompts');
64
+ vi.mock('../utils/getFolderStructure', () => ({
65
+ getFolderStructure: vi.fn().mockResolvedValue('Mock Folder Structure'),
66
+ }));
67
+ vi.mock('../utils/errorReporting', () => ({ reportError: vi.fn() }));
68
+ vi.mock('../utils/nextSpeakerChecker', () => ({
69
+ checkNextSpeaker: vi.fn().mockResolvedValue(null),
70
+ }));
71
+ vi.mock('../utils/environmentContext', () => ({
72
+ getEnvironmentContext: vi
73
+ .fn()
74
+ .mockResolvedValue([{ text: 'Mocked env context' }]),
75
+ getInitialChatHistory: vi.fn(async (_config, extraHistory) => [
76
+ {
77
+ role: 'user',
78
+ parts: [{ text: 'Mocked env context' }],
79
+ },
80
+ {
81
+ role: 'model',
82
+ parts: [{ text: 'Got it. Thanks for the context!' }],
83
+ },
84
+ ...(extraHistory ?? []),
85
+ ]),
86
+ }));
87
+ vi.mock('../utils/generateContentResponseUtilities', () => ({
88
+ getResponseText: (result) => result.candidates?.[0]?.content?.parts?.map((part) => part.text).join('') ||
89
+ undefined,
90
+ getFunctionCalls: (result) => {
91
+ // Extract function calls from the response
92
+ const parts = result.candidates?.[0]?.content?.parts;
93
+ if (!parts) {
94
+ return undefined;
95
+ }
96
+ const functionCallParts = parts
97
+ .filter((part) => !!part.functionCall)
98
+ .map((part) => part.functionCall);
99
+ return functionCallParts.length > 0 ? functionCallParts : undefined;
100
+ },
101
+ }));
102
+ // Create shared mock for uiTelemetryService that's used by both telemetry mocks
103
+ const mockUiTelemetryService = vi.hoisted(() => ({
104
+ setLastPromptTokenCount: vi.fn(),
105
+ getLastPromptTokenCount: vi.fn(),
106
+ }));
107
+ vi.mock('../telemetry/index.js', async (importOriginal) => {
108
+ const actual = await importOriginal();
109
+ return {
110
+ ...actual,
111
+ uiTelemetryService: mockUiTelemetryService,
112
+ // We keep the real implementations of logChatCompression, etc.
113
+ // but we can spy on QwenLogger if needed
114
+ };
115
+ });
116
+ vi.mock('../ide/ideContext.js');
117
+ vi.mock('../telemetry/uiTelemetry.js', () => ({
118
+ uiTelemetryService: mockUiTelemetryService,
119
+ }));
120
+ vi.mock('../telemetry/loggers.js', () => ({
121
+ logChatCompression: vi.fn(),
122
+ logNextSpeakerCheck: vi.fn(),
123
+ }));
124
+ // Mock RequestTokenizer to use simple character-based estimation
125
+ vi.mock('../utils/request-tokenizer/requestTokenizer.js', () => ({
126
+ RequestTokenizer: class {
127
+ async calculateTokens(request) {
128
+ // Simple estimation: count characters in JSON and divide by 4
129
+ const totalChars = JSON.stringify(request.contents).length;
130
+ return {
131
+ totalTokens: Math.floor(totalChars / 4),
132
+ breakdown: {
133
+ textTokens: Math.floor(totalChars / 4),
134
+ imageTokens: 0,
135
+ audioTokens: 0,
136
+ otherTokens: 0,
137
+ },
138
+ processingTime: 0,
139
+ };
140
+ }
141
+ },
142
+ }));
143
+ /**
144
+ * Array.fromAsync ponyfill, which will be available in es 2024.
145
+ *
146
+ * Buffers an async generator into an array and returns the result.
147
+ */
148
+ async function fromAsync(promise) {
149
+ const results = [];
150
+ for await (const result of promise) {
151
+ results.push(result);
152
+ }
153
+ return results;
154
+ }
155
+ describe('findCompressSplitPoint', () => {
156
+ it('should throw an error for non-positive numbers', () => {
157
+ expect(() => findCompressSplitPoint([], 0)).toThrow('Fraction must be between 0 and 1');
158
+ });
159
+ it('should throw an error for a fraction greater than or equal to 1', () => {
160
+ expect(() => findCompressSplitPoint([], 1)).toThrow('Fraction must be between 0 and 1');
161
+ });
162
+ it('should handle an empty history', () => {
163
+ expect(findCompressSplitPoint([], 0.5)).toBe(0);
164
+ });
165
+ it('should handle a fraction in the middle', () => {
166
+ const history = [
167
+ { role: 'user', parts: [{ text: 'This is the first message.' }] }, // JSON length: 66 (19%)
168
+ { role: 'model', parts: [{ text: 'This is the second message.' }] }, // JSON length: 68 (40%)
169
+ { role: 'user', parts: [{ text: 'This is the third message.' }] }, // JSON length: 66 (60%)
170
+ { role: 'model', parts: [{ text: 'This is the fourth message.' }] }, // JSON length: 68 (80%)
171
+ { role: 'user', parts: [{ text: 'This is the fifth message.' }] }, // JSON length: 65 (100%)
172
+ ];
173
+ expect(findCompressSplitPoint(history, 0.5)).toBe(4);
174
+ });
175
+ it('should handle a fraction of last index', () => {
176
+ const history = [
177
+ { role: 'user', parts: [{ text: 'This is the first message.' }] }, // JSON length: 66 (19%)
178
+ { role: 'model', parts: [{ text: 'This is the second message.' }] }, // JSON length: 68 (40%)
179
+ { role: 'user', parts: [{ text: 'This is the third message.' }] }, // JSON length: 66 (60%)
180
+ { role: 'model', parts: [{ text: 'This is the fourth message.' }] }, // JSON length: 68 (80%)
181
+ { role: 'user', parts: [{ text: 'This is the fifth message.' }] }, // JSON length: 65 (100%)
182
+ ];
183
+ expect(findCompressSplitPoint(history, 0.9)).toBe(4);
184
+ });
185
+ it('should handle a fraction of after last index', () => {
186
+ const history = [
187
+ { role: 'user', parts: [{ text: 'This is the first message.' }] }, // JSON length: 66 (24%%)
188
+ { role: 'model', parts: [{ text: 'This is the second message.' }] }, // JSON length: 68 (50%)
189
+ { role: 'user', parts: [{ text: 'This is the third message.' }] }, // JSON length: 66 (74%)
190
+ { role: 'model', parts: [{ text: 'This is the fourth message.' }] }, // JSON length: 68 (100%)
191
+ ];
192
+ expect(findCompressSplitPoint(history, 0.8)).toBe(4);
193
+ });
194
+ it('should return earlier splitpoint if no valid ones are after threshhold', () => {
195
+ const history = [
196
+ { role: 'user', parts: [{ text: 'This is the first message.' }] },
197
+ { role: 'model', parts: [{ text: 'This is the second message.' }] },
198
+ { role: 'user', parts: [{ text: 'This is the third message.' }] },
199
+ { role: 'model', parts: [{ functionCall: {} }] },
200
+ ];
201
+ // Can't return 4 because the previous item has a function call.
202
+ expect(findCompressSplitPoint(history, 0.99)).toBe(2);
203
+ });
204
+ it('should handle a history with only one item', () => {
205
+ const historyWithEmptyParts = [
206
+ { role: 'user', parts: [{ text: 'Message 1' }] },
207
+ ];
208
+ expect(findCompressSplitPoint(historyWithEmptyParts, 0.5)).toBe(0);
209
+ });
210
+ it('should handle history with weird parts', () => {
211
+ const historyWithEmptyParts = [
212
+ { role: 'user', parts: [{ text: 'Message 1' }] },
213
+ { role: 'model', parts: [{ fileData: { fileUri: 'derp' } }] },
214
+ { role: 'user', parts: [{ text: 'Message 2' }] },
215
+ ];
216
+ expect(findCompressSplitPoint(historyWithEmptyParts, 0.5)).toBe(2);
217
+ });
218
+ });
219
+ describe('Gemini Client (client.ts)', () => {
220
+ let mockContentGenerator;
221
+ let mockConfig;
222
+ let client;
223
+ let mockGenerateContentFn;
224
+ beforeEach(async () => {
225
+ vi.resetAllMocks();
226
+ vi.mocked(uiTelemetryService.setLastPromptTokenCount).mockClear();
227
+ mockGenerateContentFn = vi.fn().mockResolvedValue({
228
+ candidates: [{ content: { parts: [{ text: '{"key": "value"}' }] } }],
229
+ });
230
+ // Disable 429 simulation for tests
231
+ setSimulate429(false);
232
+ mockContentGenerator = {
233
+ generateContent: mockGenerateContentFn,
234
+ generateContentStream: vi.fn(),
235
+ batchEmbedContents: vi.fn(),
236
+ countTokens: vi.fn().mockResolvedValue({ totalTokens: 100 }),
237
+ };
238
+ // Because the GeminiClient constructor kicks off an async process (startChat)
239
+ // that depends on a fully-formed Config object, we need to mock the
240
+ // entire implementation of Config for these tests.
241
+ const mockToolRegistry = {
242
+ getFunctionDeclarations: vi.fn().mockReturnValue([]),
243
+ getTool: vi.fn().mockReturnValue(null),
244
+ };
245
+ const fileService = new FileDiscoveryService('/test/dir');
246
+ const contentGeneratorConfig = {
247
+ model: 'test-model',
248
+ apiKey: 'test-key',
249
+ vertexai: false,
250
+ authType: AuthType.USE_GEMINI,
251
+ };
252
+ const mockSubagentManager = {
253
+ listSubagents: vi.fn().mockResolvedValue([]),
254
+ addChangeListener: vi.fn().mockReturnValue(() => { }),
255
+ };
256
+ mockConfig = {
257
+ getContentGeneratorConfig: vi
258
+ .fn()
259
+ .mockReturnValue(contentGeneratorConfig),
260
+ getToolRegistry: vi.fn().mockReturnValue(mockToolRegistry),
261
+ getModel: vi.fn().mockReturnValue('test-model'),
262
+ getEmbeddingModel: vi.fn().mockReturnValue('test-embedding-model'),
263
+ getApiKey: vi.fn().mockReturnValue('test-key'),
264
+ getVertexAI: vi.fn().mockReturnValue(false),
265
+ getUserAgent: vi.fn().mockReturnValue('test-agent'),
266
+ getUserMemory: vi.fn().mockReturnValue(''),
267
+ getFullContext: vi.fn().mockReturnValue(false),
268
+ getSessionId: vi.fn().mockReturnValue('test-session-id'),
269
+ getProxy: vi.fn().mockReturnValue(undefined),
270
+ getWorkingDir: vi.fn().mockReturnValue('/test/dir'),
271
+ getFileService: vi.fn().mockReturnValue(fileService),
272
+ getMaxSessionTurns: vi.fn().mockReturnValue(0),
273
+ getSessionTokenLimit: vi.fn().mockReturnValue(32000),
274
+ getNoBrowser: vi.fn().mockReturnValue(false),
275
+ getUsageStatisticsEnabled: vi.fn().mockReturnValue(true),
276
+ getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
277
+ getIdeModeFeature: vi.fn().mockReturnValue(false),
278
+ getIdeMode: vi.fn().mockReturnValue(true),
279
+ getDebugMode: vi.fn().mockReturnValue(false),
280
+ getWorkspaceContext: vi.fn().mockReturnValue({
281
+ getDirectories: vi.fn().mockReturnValue(['/test/dir']),
282
+ }),
283
+ getGeminiClient: vi.fn(),
284
+ getModelRouterService: vi.fn().mockReturnValue({
285
+ route: vi.fn().mockResolvedValue({ model: 'default-routed-model' }),
286
+ }),
287
+ getCliVersion: vi.fn().mockReturnValue('1.0.0'),
288
+ getChatCompression: vi.fn().mockReturnValue(undefined),
289
+ getSkipNextSpeakerCheck: vi.fn().mockReturnValue(false),
290
+ getUseModelRouter: vi.fn().mockReturnValue(false),
291
+ getProjectRoot: vi.fn().mockReturnValue('/test/project/root'),
292
+ storage: {
293
+ getProjectTempDir: vi.fn().mockReturnValue('/test/temp'),
294
+ getProjectDir: vi
295
+ .fn()
296
+ .mockReturnValue('/test/project/root/.gemini/projects/test-project'),
297
+ },
298
+ getContentGenerator: vi.fn().mockReturnValue(mockContentGenerator),
299
+ getBaseLlmClient: vi.fn().mockReturnValue({
300
+ generateJson: vi.fn().mockResolvedValue({
301
+ next_speaker: 'user',
302
+ reasoning: 'test',
303
+ }),
304
+ }),
305
+ getSubagentManager: vi.fn().mockReturnValue(mockSubagentManager),
306
+ getSkipLoopDetection: vi.fn().mockReturnValue(false),
307
+ getChatRecordingService: vi.fn().mockReturnValue(undefined),
308
+ getResumedSessionData: vi.fn().mockReturnValue(undefined),
309
+ getEnableHooks: vi.fn().mockReturnValue(false),
310
+ getMessageBus: vi.fn().mockReturnValue(undefined),
311
+ };
312
+ client = new GeminiClient(mockConfig);
313
+ await client.initialize();
314
+ vi.mocked(mockConfig.getGeminiClient).mockReturnValue(client);
315
+ });
316
+ afterEach(() => {
317
+ vi.restoreAllMocks();
318
+ });
319
+ describe('addHistory', () => {
320
+ it('should call chat.addHistory with the provided content', async () => {
321
+ const mockChat = {
322
+ addHistory: vi.fn(),
323
+ };
324
+ client['chat'] = mockChat;
325
+ const newContent = {
326
+ role: 'user',
327
+ parts: [{ text: 'New history item' }],
328
+ };
329
+ await client.addHistory(newContent);
330
+ expect(mockChat.addHistory).toHaveBeenCalledWith(newContent);
331
+ });
332
+ });
333
+ describe('resetChat', () => {
334
+ it('should create a new chat session, clearing the old history', async () => {
335
+ // 1. Get the initial chat instance and add some history.
336
+ const initialChat = client.getChat();
337
+ const initialHistory = await client.getHistory();
338
+ await client.addHistory({
339
+ role: 'user',
340
+ parts: [{ text: 'some old message' }],
341
+ });
342
+ const historyWithOldMessage = await client.getHistory();
343
+ expect(historyWithOldMessage.length).toBeGreaterThan(initialHistory.length);
344
+ // 2. Call resetChat.
345
+ await client.resetChat();
346
+ // 3. Get the new chat instance and its history.
347
+ const newChat = client.getChat();
348
+ const newHistory = await client.getHistory();
349
+ // 4. Assert that the chat instance is new and the history is reset.
350
+ expect(newChat).not.toBe(initialChat);
351
+ expect(newHistory.length).toBe(initialHistory.length);
352
+ expect(JSON.stringify(newHistory)).not.toContain('some old message');
353
+ });
354
+ });
355
+ describe('tryCompressChat', () => {
356
+ const mockGetHistory = vi.fn();
357
+ beforeEach(() => {
358
+ client['chat'] = {
359
+ getHistory: mockGetHistory,
360
+ addHistory: vi.fn(),
361
+ setHistory: vi.fn(),
362
+ stripThoughtsFromHistory: vi.fn(),
363
+ };
364
+ });
365
+ function setup({ chatHistory = [
366
+ { role: 'user', parts: [{ text: 'Long conversation' }] },
367
+ { role: 'model', parts: [{ text: 'Long response' }] },
368
+ ], originalTokenCount = 1000, summaryText = 'This is a summary.',
369
+ // Token counts returned in usageMetadata to simulate what the API would return
370
+ // Default values ensure successful compression:
371
+ // newTokenCount = originalTokenCount - (compressionInputTokenCount - 1000) + compressionOutputTokenCount
372
+ // = 1000 - (1600 - 1000) + 50 = 1000 - 600 + 50 = 450 (< 1000, success)
373
+ compressionInputTokenCount = 1600, compressionOutputTokenCount = 50, } = {}) {
374
+ const mockOriginalChat = {
375
+ getHistory: vi.fn((_curated) => chatHistory),
376
+ setHistory: vi.fn(),
377
+ stripThoughtsFromHistory: vi.fn(),
378
+ };
379
+ client['chat'] = mockOriginalChat;
380
+ vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
381
+ mockGenerateContentFn.mockResolvedValue({
382
+ candidates: [
383
+ {
384
+ content: {
385
+ role: 'model',
386
+ parts: [{ text: summaryText }],
387
+ },
388
+ },
389
+ ],
390
+ usageMetadata: {
391
+ promptTokenCount: compressionInputTokenCount,
392
+ candidatesTokenCount: compressionOutputTokenCount,
393
+ totalTokenCount: compressionInputTokenCount + compressionOutputTokenCount,
394
+ },
395
+ });
396
+ // Calculate what the new history will be
397
+ const splitPoint = findCompressSplitPoint(chatHistory, 0.7); // 1 - 0.3
398
+ const historyToKeep = chatHistory.slice(splitPoint);
399
+ // This is the history that the new chat will have.
400
+ // It includes the default startChat history + the extra history from tryCompressChat
401
+ const newCompressedHistory = [
402
+ // Mocked envParts + canned response from startChat
403
+ {
404
+ role: 'user',
405
+ parts: [{ text: 'Mocked env context' }],
406
+ },
407
+ {
408
+ role: 'model',
409
+ parts: [{ text: 'Got it. Thanks for the context!' }],
410
+ },
411
+ // extraHistory from tryCompressChat
412
+ {
413
+ role: 'user',
414
+ parts: [{ text: summaryText }],
415
+ },
416
+ {
417
+ role: 'model',
418
+ parts: [{ text: 'Got it. Thanks for the additional context!' }],
419
+ },
420
+ ...historyToKeep,
421
+ ];
422
+ const mockNewChat = {
423
+ getHistory: vi.fn().mockReturnValue(newCompressedHistory),
424
+ setHistory: vi.fn(),
425
+ };
426
+ client['startChat'] = vi
427
+ .fn()
428
+ .mockResolvedValue(mockNewChat);
429
+ // New token count formula: originalTokenCount - (compressionInputTokenCount - 1000) + compressionOutputTokenCount
430
+ const estimatedNewTokenCount = Math.max(0, originalTokenCount -
431
+ (compressionInputTokenCount - 1000) +
432
+ compressionOutputTokenCount);
433
+ return {
434
+ client,
435
+ mockOriginalChat,
436
+ mockNewChat,
437
+ estimatedNewTokenCount,
438
+ };
439
+ }
440
+ describe('when compression inflates the token count', () => {
441
+ it('allows compression to be forced/manual after a failure', async () => {
442
+ // Call 1 (Fails): Setup with token counts that will inflate
443
+ // newTokenCount = originalTokenCount - (compressionInputTokenCount - 1000) + compressionOutputTokenCount
444
+ // = 100 - (1010 - 1000) + 200 = 100 - 10 + 200 = 290 > 100 (inflation)
445
+ const longSummary = 'long summary '.repeat(100);
446
+ const { client, estimatedNewTokenCount: inflatedTokenCount } = setup({
447
+ originalTokenCount: 100,
448
+ summaryText: longSummary,
449
+ compressionInputTokenCount: 1010,
450
+ compressionOutputTokenCount: 200,
451
+ });
452
+ expect(inflatedTokenCount).toBeGreaterThan(100); // Ensure setup is correct
453
+ await client.tryCompressChat('prompt-id-4', false); // Fails
454
+ // Call 2 (Forced): Re-setup with token counts that will compress
455
+ // newTokenCount = 100 - (1100 - 1000) + 50 = 100 - 100 + 50 = 50 <= 100 (compression)
456
+ const shortSummary = 'short';
457
+ const { estimatedNewTokenCount: compressedTokenCount } = setup({
458
+ originalTokenCount: 100,
459
+ summaryText: shortSummary,
460
+ compressionInputTokenCount: 1100,
461
+ compressionOutputTokenCount: 50,
462
+ });
463
+ expect(compressedTokenCount).toBeLessThanOrEqual(100); // Ensure setup is correct
464
+ const result = await client.tryCompressChat('prompt-id-4', true); // Forced
465
+ expect(result.compressionStatus).toBe(CompressionStatus.COMPRESSED);
466
+ expect(result.originalTokenCount).toBe(100);
467
+ // newTokenCount might be clamped to originalTokenCount due to tolerance logic
468
+ expect(result.newTokenCount).toBeLessThanOrEqual(100);
469
+ });
470
+ it('yields the result even if the compression inflated the tokens', async () => {
471
+ // newTokenCount = 100 - (1010 - 1000) + 200 = 100 - 10 + 200 = 290 > 100 (inflation)
472
+ const longSummary = 'long summary '.repeat(100);
473
+ const { client, estimatedNewTokenCount } = setup({
474
+ originalTokenCount: 100,
475
+ summaryText: longSummary,
476
+ compressionInputTokenCount: 1010,
477
+ compressionOutputTokenCount: 200,
478
+ });
479
+ expect(estimatedNewTokenCount).toBeGreaterThan(100); // Ensure setup is correct
480
+ // Mock contextWindowSize to ensure compression is triggered
481
+ vi.spyOn(client['config'], 'getContentGeneratorConfig').mockReturnValue({
482
+ model: 'test-model',
483
+ apiKey: 'test-key',
484
+ vertexai: false,
485
+ authType: AuthType.USE_GEMINI,
486
+ contextWindowSize: 100, // Set to same as originalTokenCount to ensure threshold is exceeded
487
+ });
488
+ const result = await client.tryCompressChat('prompt-id-4', false);
489
+ expect(result.compressionStatus).toBe(CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT);
490
+ expect(result.originalTokenCount).toBe(100);
491
+ // The newTokenCount should be higher than original since compression failed due to inflation
492
+ expect(result.newTokenCount).toBeGreaterThan(100);
493
+ // IMPORTANT: The change in client.ts means setLastPromptTokenCount is NOT called on failure
494
+ expect(uiTelemetryService.setLastPromptTokenCount).not.toHaveBeenCalled();
495
+ });
496
+ it('does not manipulate the source chat', async () => {
497
+ // newTokenCount = 100 - (1010 - 1000) + 200 = 100 - 10 + 200 = 290 > 100 (inflation)
498
+ const longSummary = 'long summary '.repeat(100);
499
+ const { client, mockOriginalChat, estimatedNewTokenCount } = setup({
500
+ originalTokenCount: 100,
501
+ summaryText: longSummary,
502
+ compressionInputTokenCount: 1010,
503
+ compressionOutputTokenCount: 200,
504
+ });
505
+ expect(estimatedNewTokenCount).toBeGreaterThan(100); // Ensure setup is correct
506
+ await client.tryCompressChat('prompt-id-4', false);
507
+ // On failure, the chat should NOT be replaced
508
+ expect(client['chat']).toBe(mockOriginalChat);
509
+ });
510
+ it('will not attempt to compress context after a failure', async () => {
511
+ // newTokenCount = 100 - (1010 - 1000) + 200 = 100 - 10 + 200 = 290 > 100 (inflation)
512
+ const longSummary = 'long summary '.repeat(100);
513
+ const { client, estimatedNewTokenCount } = setup({
514
+ originalTokenCount: 100,
515
+ summaryText: longSummary,
516
+ compressionInputTokenCount: 1010,
517
+ compressionOutputTokenCount: 200,
518
+ });
519
+ expect(estimatedNewTokenCount).toBeGreaterThan(100); // Ensure setup is correct
520
+ // Mock contextWindowSize to ensure compression is triggered
521
+ vi.spyOn(client['config'], 'getContentGeneratorConfig').mockReturnValue({
522
+ model: 'test-model',
523
+ apiKey: 'test-key',
524
+ vertexai: false,
525
+ authType: AuthType.USE_GEMINI,
526
+ contextWindowSize: 100, // Set to same as originalTokenCount to ensure threshold is exceeded
527
+ });
528
+ await client.tryCompressChat('prompt-id-4', false); // This fails and sets hasFailedCompressionAttempt = true
529
+ // This call should now be a NOOP
530
+ const result = await client.tryCompressChat('prompt-id-5', false);
531
+ // generateContent (for summary) should only have been called once
532
+ expect(mockGenerateContentFn).toHaveBeenCalledTimes(1);
533
+ expect(result).toEqual({
534
+ compressionStatus: CompressionStatus.NOOP,
535
+ newTokenCount: 0,
536
+ originalTokenCount: 0,
537
+ });
538
+ });
539
+ });
540
+ it('should not trigger summarization if token count is below threshold', async () => {
541
+ const MOCKED_TOKEN_LIMIT = 1000;
542
+ vi.spyOn(client['config'], 'getContentGeneratorConfig').mockReturnValue({
543
+ model: 'test-model',
544
+ apiKey: 'test-key',
545
+ vertexai: false,
546
+ authType: AuthType.USE_GEMINI,
547
+ contextWindowSize: MOCKED_TOKEN_LIMIT,
548
+ });
549
+ mockGetHistory.mockReturnValue([
550
+ { role: 'user', parts: [{ text: '...history...' }] },
551
+ ]);
552
+ const originalTokenCount = MOCKED_TOKEN_LIMIT * 0.699;
553
+ vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
554
+ const initialChat = client.getChat();
555
+ const result = await client.tryCompressChat('prompt-id-2', false);
556
+ const newChat = client.getChat();
557
+ expect(result).toEqual({
558
+ compressionStatus: CompressionStatus.NOOP,
559
+ newTokenCount: originalTokenCount,
560
+ originalTokenCount,
561
+ });
562
+ expect(newChat).toBe(initialChat);
563
+ });
564
+ it('logs a telemetry event when compressing', async () => {
565
+ const { logChatCompression } = await import('../telemetry/loggers.js');
566
+ vi.mocked(logChatCompression).mockClear();
567
+ const MOCKED_TOKEN_LIMIT = 1000;
568
+ const MOCKED_CONTEXT_PERCENTAGE_THRESHOLD = 0.5;
569
+ vi.spyOn(client['config'], 'getContentGeneratorConfig').mockReturnValue({
570
+ model: 'test-model',
571
+ apiKey: 'test-key',
572
+ vertexai: false,
573
+ authType: AuthType.USE_GEMINI,
574
+ contextWindowSize: MOCKED_TOKEN_LIMIT,
575
+ });
576
+ vi.spyOn(client['config'], 'getChatCompression').mockReturnValue({
577
+ contextPercentageThreshold: MOCKED_CONTEXT_PERCENTAGE_THRESHOLD,
578
+ });
579
+ // Need multiple history items so there's something to compress
580
+ const history = [
581
+ { role: 'user', parts: [{ text: '...history 1...' }] },
582
+ { role: 'model', parts: [{ text: '...history 2...' }] },
583
+ { role: 'user', parts: [{ text: '...history 3...' }] },
584
+ { role: 'model', parts: [{ text: '...history 4...' }] },
585
+ ];
586
+ mockGetHistory.mockReturnValue(history);
587
+ // Token count needs to be ABOVE the threshold to trigger compression
588
+ const originalTokenCount = MOCKED_TOKEN_LIMIT * MOCKED_CONTEXT_PERCENTAGE_THRESHOLD + 1;
589
+ vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
590
+ // Mock the summary response from the chat
591
+ // newTokenCount = 501 - (1400 - 1000) + 50 = 501 - 400 + 50 = 151 <= 501 (success)
592
+ const summaryText = 'This is a summary.';
593
+ mockGenerateContentFn.mockResolvedValue({
594
+ candidates: [
595
+ {
596
+ content: {
597
+ role: 'model',
598
+ parts: [{ text: summaryText }],
599
+ },
600
+ },
601
+ ],
602
+ usageMetadata: {
603
+ promptTokenCount: 1400,
604
+ candidatesTokenCount: 50,
605
+ totalTokenCount: 1450,
606
+ },
607
+ });
608
+ // Mock startChat to complete the compression flow
609
+ const splitPoint = findCompressSplitPoint(history, 0.7);
610
+ const historyToKeep = history.slice(splitPoint);
611
+ const newCompressedHistory = [
612
+ { role: 'user', parts: [{ text: 'Mocked env context' }] },
613
+ { role: 'model', parts: [{ text: 'Got it. Thanks for the context!' }] },
614
+ { role: 'user', parts: [{ text: summaryText }] },
615
+ {
616
+ role: 'model',
617
+ parts: [{ text: 'Got it. Thanks for the additional context!' }],
618
+ },
619
+ ...historyToKeep,
620
+ ];
621
+ const mockNewChat = {
622
+ getHistory: vi.fn().mockReturnValue(newCompressedHistory),
623
+ };
624
+ client['startChat'] = vi
625
+ .fn()
626
+ .mockResolvedValue(mockNewChat);
627
+ await client.tryCompressChat('prompt-id-3', false);
628
+ expect(logChatCompression).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({
629
+ tokens_before: originalTokenCount,
630
+ }));
631
+ expect(uiTelemetryService.setLastPromptTokenCount).toHaveBeenCalled();
632
+ });
633
+ it('should trigger summarization if token count is above threshold with contextPercentageThreshold setting', async () => {
634
+ const MOCKED_TOKEN_LIMIT = 1000;
635
+ const MOCKED_CONTEXT_PERCENTAGE_THRESHOLD = 0.5;
636
+ vi.spyOn(client['config'], 'getContentGeneratorConfig').mockReturnValue({
637
+ model: 'test-model',
638
+ apiKey: 'test-key',
639
+ vertexai: false,
640
+ authType: AuthType.USE_GEMINI,
641
+ contextWindowSize: MOCKED_TOKEN_LIMIT,
642
+ });
643
+ vi.spyOn(client['config'], 'getChatCompression').mockReturnValue({
644
+ contextPercentageThreshold: MOCKED_CONTEXT_PERCENTAGE_THRESHOLD,
645
+ });
646
+ // Need multiple history items so there's something to compress
647
+ const history = [
648
+ { role: 'user', parts: [{ text: '...history 1...' }] },
649
+ { role: 'model', parts: [{ text: '...history 2...' }] },
650
+ { role: 'user', parts: [{ text: '...history 3...' }] },
651
+ { role: 'model', parts: [{ text: '...history 4...' }] },
652
+ ];
653
+ mockGetHistory.mockReturnValue(history);
654
+ // Token count needs to be ABOVE the threshold to trigger compression
655
+ const originalTokenCount = MOCKED_TOKEN_LIMIT * MOCKED_CONTEXT_PERCENTAGE_THRESHOLD + 1;
656
+ vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
657
+ // Mock summary and new chat
658
+ const summaryText = 'This is a summary.';
659
+ const splitPoint = findCompressSplitPoint(history, 0.7);
660
+ const historyToKeep = history.slice(splitPoint);
661
+ const newCompressedHistory = [
662
+ { role: 'user', parts: [{ text: 'Mocked env context' }] },
663
+ { role: 'model', parts: [{ text: 'Got it. Thanks for the context!' }] },
664
+ { role: 'user', parts: [{ text: summaryText }] },
665
+ {
666
+ role: 'model',
667
+ parts: [{ text: 'Got it. Thanks for the additional context!' }],
668
+ },
669
+ ...historyToKeep,
670
+ ];
671
+ const mockNewChat = {
672
+ getHistory: vi.fn().mockReturnValue(newCompressedHistory),
673
+ };
674
+ client['startChat'] = vi
675
+ .fn()
676
+ .mockResolvedValue(mockNewChat);
677
+ // Mock the summary response from the chat
678
+ // newTokenCount = 501 - (1400 - 1000) + 50 = 501 - 400 + 50 = 151 <= 501 (success)
679
+ mockGenerateContentFn.mockResolvedValue({
680
+ candidates: [
681
+ {
682
+ content: {
683
+ role: 'model',
684
+ parts: [{ text: summaryText }],
685
+ },
686
+ },
687
+ ],
688
+ usageMetadata: {
689
+ promptTokenCount: 1400,
690
+ candidatesTokenCount: 50,
691
+ totalTokenCount: 1450,
692
+ },
693
+ });
694
+ const initialChat = client.getChat();
695
+ const result = await client.tryCompressChat('prompt-id-3', false);
696
+ const newChat = client.getChat();
697
+ expect(mockGenerateContentFn).toHaveBeenCalled();
698
+ // Assert that summarization happened
699
+ expect(result.compressionStatus).toBe(CompressionStatus.COMPRESSED);
700
+ expect(result.originalTokenCount).toBe(originalTokenCount);
701
+ // newTokenCount might be clamped to originalTokenCount due to tolerance logic
702
+ expect(result.newTokenCount).toBeLessThanOrEqual(originalTokenCount);
703
+ // Assert that the chat was reset
704
+ expect(newChat).not.toBe(initialChat);
705
+ });
706
+ it('should not compress across a function call response', async () => {
707
+ const MOCKED_TOKEN_LIMIT = 1000;
708
+ vi.spyOn(client['config'], 'getContentGeneratorConfig').mockReturnValue({
709
+ model: 'test-model',
710
+ apiKey: 'test-key',
711
+ vertexai: false,
712
+ authType: AuthType.USE_GEMINI,
713
+ contextWindowSize: MOCKED_TOKEN_LIMIT,
714
+ });
715
+ const history = [
716
+ { role: 'user', parts: [{ text: '...history 1...' }] },
717
+ { role: 'model', parts: [{ text: '...history 2...' }] },
718
+ { role: 'user', parts: [{ text: '...history 3...' }] },
719
+ { role: 'model', parts: [{ text: '...history 4...' }] },
720
+ { role: 'user', parts: [{ text: '...history 5...' }] },
721
+ { role: 'model', parts: [{ text: '...history 6...' }] },
722
+ { role: 'user', parts: [{ text: '...history 7...' }] },
723
+ { role: 'model', parts: [{ text: '...history 8...' }] },
724
+ // Normally we would break here, but we have a function response.
725
+ {
726
+ role: 'user',
727
+ parts: [{ functionResponse: { name: '...history 8...' } }],
728
+ },
729
+ { role: 'model', parts: [{ text: '...history 10...' }] },
730
+ // Instead we will break here.
731
+ { role: 'user', parts: [{ text: '...history 10...' }] },
732
+ ];
733
+ mockGetHistory.mockReturnValue(history);
734
+ const originalTokenCount = 1000 * 0.7;
735
+ vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
736
+ // Mock summary and new chat
737
+ const summaryText = 'This is a summary.';
738
+ const splitPoint = findCompressSplitPoint(history, 0.7); // This should be 10
739
+ expect(splitPoint).toBe(10); // Verify split point logic
740
+ const historyToKeep = history.slice(splitPoint); // Should keep last user message
741
+ expect(historyToKeep).toEqual([
742
+ { role: 'user', parts: [{ text: '...history 10...' }] },
743
+ ]);
744
+ const newCompressedHistory = [
745
+ { role: 'user', parts: [{ text: 'Mocked env context' }] },
746
+ { role: 'model', parts: [{ text: 'Got it. Thanks for the context!' }] },
747
+ { role: 'user', parts: [{ text: summaryText }] },
748
+ {
749
+ role: 'model',
750
+ parts: [{ text: 'Got it. Thanks for the additional context!' }],
751
+ },
752
+ ...historyToKeep,
753
+ ];
754
+ const mockNewChat = {
755
+ getHistory: vi.fn().mockReturnValue(newCompressedHistory),
756
+ };
757
+ client['startChat'] = vi
758
+ .fn()
759
+ .mockResolvedValue(mockNewChat);
760
+ // Mock the summary response from the chat
761
+ // newTokenCount = 700 - (1500 - 1000) + 50 = 700 - 500 + 50 = 250 <= 700 (success)
762
+ mockGenerateContentFn.mockResolvedValue({
763
+ candidates: [
764
+ {
765
+ content: {
766
+ role: 'model',
767
+ parts: [{ text: summaryText }],
768
+ },
769
+ },
770
+ ],
771
+ usageMetadata: {
772
+ promptTokenCount: 1500,
773
+ candidatesTokenCount: 50,
774
+ totalTokenCount: 1550,
775
+ },
776
+ });
777
+ const initialChat = client.getChat();
778
+ const result = await client.tryCompressChat('prompt-id-3', false);
779
+ const newChat = client.getChat();
780
+ expect(mockGenerateContentFn).toHaveBeenCalled();
781
+ // Assert that summarization happened
782
+ expect(result.compressionStatus).toBe(CompressionStatus.COMPRESSED);
783
+ expect(result.originalTokenCount).toBe(originalTokenCount);
784
+ // newTokenCount might be clamped to originalTokenCount due to tolerance logic
785
+ expect(result.newTokenCount).toBeLessThanOrEqual(originalTokenCount);
786
+ // Assert that the chat was reset
787
+ expect(newChat).not.toBe(initialChat);
788
+ // 1. standard start context message (env)
789
+ // 2. standard canned model response
790
+ // 3. compressed summary message (user)
791
+ // 4. standard canned model response
792
+ // 5. The last user message (historyToKeep)
793
+ expect(newChat.getHistory().length).toEqual(5);
794
+ });
795
+ it('should always trigger summarization when force is true, regardless of token count', async () => {
796
+ // Need multiple history items so there's something to compress
797
+ const history = [
798
+ { role: 'user', parts: [{ text: '...history 1...' }] },
799
+ { role: 'model', parts: [{ text: '...history 2...' }] },
800
+ { role: 'user', parts: [{ text: '...history 3...' }] },
801
+ { role: 'model', parts: [{ text: '...history 4...' }] },
802
+ ];
803
+ mockGetHistory.mockReturnValue(history);
804
+ const originalTokenCount = 100; // Well below threshold, but > estimated new count
805
+ vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
806
+ // Mock summary and new chat
807
+ const summaryText = 'This is a summary.';
808
+ const splitPoint = findCompressSplitPoint(history, 0.7);
809
+ const historyToKeep = history.slice(splitPoint);
810
+ const newCompressedHistory = [
811
+ { role: 'user', parts: [{ text: 'Mocked env context' }] },
812
+ { role: 'model', parts: [{ text: 'Got it. Thanks for the context!' }] },
813
+ { role: 'user', parts: [{ text: summaryText }] },
814
+ {
815
+ role: 'model',
816
+ parts: [{ text: 'Got it. Thanks for the additional context!' }],
817
+ },
818
+ ...historyToKeep,
819
+ ];
820
+ const mockNewChat = {
821
+ getHistory: vi.fn().mockReturnValue(newCompressedHistory),
822
+ };
823
+ client['startChat'] = vi
824
+ .fn()
825
+ .mockResolvedValue(mockNewChat);
826
+ // Mock the summary response from the chat
827
+ // newTokenCount = 100 - (1060 - 1000) + 20 = 100 - 60 + 20 = 60 <= 100 (success)
828
+ mockGenerateContentFn.mockResolvedValue({
829
+ candidates: [
830
+ {
831
+ content: {
832
+ role: 'model',
833
+ parts: [{ text: summaryText }],
834
+ },
835
+ },
836
+ ],
837
+ usageMetadata: {
838
+ promptTokenCount: 1060,
839
+ candidatesTokenCount: 20,
840
+ totalTokenCount: 1080,
841
+ },
842
+ });
843
+ const initialChat = client.getChat();
844
+ const result = await client.tryCompressChat('prompt-id-1', true); // force = true
845
+ const newChat = client.getChat();
846
+ expect(mockGenerateContentFn).toHaveBeenCalled();
847
+ expect(result.compressionStatus).toBe(CompressionStatus.COMPRESSED);
848
+ expect(result.originalTokenCount).toBe(originalTokenCount);
849
+ // newTokenCount might be clamped to originalTokenCount due to tolerance logic
850
+ expect(result.newTokenCount).toBeLessThanOrEqual(originalTokenCount);
851
+ // Assert that the chat was reset
852
+ expect(newChat).not.toBe(initialChat);
853
+ });
854
+ });
855
+ describe('sendMessageStream', () => {
856
+ it('emits a compression event when the context was automatically compressed', async () => {
857
+ // Arrange
858
+ mockTurnRunFn.mockReturnValue((async function* () {
859
+ yield { type: 'content', value: 'Hello' };
860
+ })());
861
+ const compressionInfo = {
862
+ compressionStatus: CompressionStatus.COMPRESSED,
863
+ originalTokenCount: 1000,
864
+ newTokenCount: 500,
865
+ };
866
+ vi.spyOn(client, 'tryCompressChat').mockResolvedValueOnce(compressionInfo);
867
+ // Act
868
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-1');
869
+ const events = await fromAsync(stream);
870
+ // Assert
871
+ expect(events).toContainEqual({
872
+ type: GeminiEventType.ChatCompressed,
873
+ value: compressionInfo,
874
+ });
875
+ });
876
+ it.each([
877
+ {
878
+ compressionStatus: CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
879
+ },
880
+ { compressionStatus: CompressionStatus.NOOP },
881
+ ])('does not emit a compression event when the status is $compressionStatus', async ({ compressionStatus }) => {
882
+ // Arrange
883
+ const mockStream = (async function* () {
884
+ yield { type: 'content', value: 'Hello' };
885
+ })();
886
+ mockTurnRunFn.mockReturnValue(mockStream);
887
+ const compressionInfo = {
888
+ compressionStatus,
889
+ originalTokenCount: 1000,
890
+ newTokenCount: 500,
891
+ };
892
+ vi.spyOn(client, 'tryCompressChat').mockResolvedValueOnce(compressionInfo);
893
+ // Act
894
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-1');
895
+ const events = await fromAsync(stream);
896
+ // Assert
897
+ expect(events).not.toContainEqual({
898
+ type: GeminiEventType.ChatCompressed,
899
+ value: expect.anything(),
900
+ });
901
+ });
902
+ it('should include editor context when ideMode is enabled', async () => {
903
+ // Arrange
904
+ vi.mocked(ideContextStore.get).mockReturnValue({
905
+ workspaceState: {
906
+ openFiles: [
907
+ {
908
+ path: '/path/to/active/file.ts',
909
+ timestamp: Date.now(),
910
+ isActive: true,
911
+ selectedText: 'hello',
912
+ cursor: { line: 5, character: 10 },
913
+ },
914
+ {
915
+ path: '/path/to/recent/file1.ts',
916
+ timestamp: Date.now(),
917
+ },
918
+ {
919
+ path: '/path/to/recent/file2.ts',
920
+ timestamp: Date.now(),
921
+ },
922
+ ],
923
+ },
924
+ });
925
+ vi.mocked(mockConfig.getIdeMode).mockReturnValue(true);
926
+ vi.spyOn(client, 'tryCompressChat').mockResolvedValue({
927
+ originalTokenCount: 0,
928
+ newTokenCount: 0,
929
+ compressionStatus: CompressionStatus.COMPRESSED,
930
+ });
931
+ mockTurnRunFn.mockReturnValue((async function* () {
932
+ yield { type: 'content', value: 'Hello' };
933
+ })());
934
+ const mockChat = {
935
+ addHistory: vi.fn(),
936
+ getHistory: vi.fn().mockReturnValue([]),
937
+ stripThoughtsFromHistory: vi.fn(),
938
+ };
939
+ client['chat'] = mockChat;
940
+ const initialRequest = [{ text: 'Hi' }];
941
+ // Act
942
+ const stream = client.sendMessageStream(initialRequest, new AbortController().signal, 'prompt-id-ide');
943
+ for await (const _ of stream) {
944
+ // consume stream
945
+ }
946
+ // Assert
947
+ expect(ideContextStore.get).toHaveBeenCalled();
948
+ const expectedContext = `Here is the user's editor context. This is for your information only.
949
+ Active file:
950
+ Path: /path/to/active/file.ts
951
+ Cursor: line 5, character 10
952
+ Selected text:
953
+ \`\`\`
954
+ hello
955
+ \`\`\`
956
+
957
+ Other open files:
958
+ - /path/to/recent/file1.ts
959
+ - /path/to/recent/file2.ts`;
960
+ const expectedRequest = [{ text: expectedContext }];
961
+ expect(mockChat.addHistory).toHaveBeenCalledWith({
962
+ role: 'user',
963
+ parts: expectedRequest,
964
+ });
965
+ });
966
+ it('should not add context if ideMode is enabled but no open files', async () => {
967
+ // Arrange
968
+ vi.mocked(ideContextStore.get).mockReturnValue({
969
+ workspaceState: {
970
+ openFiles: [],
971
+ },
972
+ });
973
+ vi.spyOn(client['config'], 'getIdeMode').mockReturnValue(true);
974
+ const mockStream = (async function* () {
975
+ yield { type: 'content', value: 'Hello' };
976
+ })();
977
+ mockTurnRunFn.mockReturnValue(mockStream);
978
+ const mockChat = {
979
+ addHistory: vi.fn(),
980
+ getHistory: vi.fn().mockReturnValue([]),
981
+ stripThoughtsFromHistory: vi.fn(),
982
+ };
983
+ client['chat'] = mockChat;
984
+ const initialRequest = [{ text: 'Hi' }];
985
+ // Act
986
+ const stream = client.sendMessageStream(initialRequest, new AbortController().signal, 'prompt-id-ide');
987
+ for await (const _ of stream) {
988
+ // consume stream
989
+ }
990
+ // Assert
991
+ expect(ideContextStore.get).toHaveBeenCalled();
992
+ // The `turn.run` method is now called with the model name as the first
993
+ // argument and the request parts are passed in a simplified format.
994
+ // We verify that turn.run was called (indicating no IDE context was added).
995
+ expect(mockTurnRunFn).toHaveBeenCalled();
996
+ });
997
+ it('should add context if ideMode is enabled and there is one active file', async () => {
998
+ // Arrange
999
+ vi.mocked(ideContextStore.get).mockReturnValue({
1000
+ workspaceState: {
1001
+ openFiles: [
1002
+ {
1003
+ path: '/path/to/active/file.ts',
1004
+ timestamp: Date.now(),
1005
+ isActive: true,
1006
+ selectedText: 'hello',
1007
+ cursor: { line: 5, character: 10 },
1008
+ },
1009
+ ],
1010
+ },
1011
+ });
1012
+ vi.spyOn(client['config'], 'getIdeMode').mockReturnValue(true);
1013
+ vi.spyOn(client, 'tryCompressChat').mockResolvedValue({
1014
+ originalTokenCount: 0,
1015
+ newTokenCount: 0,
1016
+ compressionStatus: CompressionStatus.COMPRESSED,
1017
+ });
1018
+ const mockStream = (async function* () {
1019
+ yield { type: 'content', value: 'Hello' };
1020
+ })();
1021
+ mockTurnRunFn.mockReturnValue(mockStream);
1022
+ const mockChat = {
1023
+ addHistory: vi.fn(),
1024
+ getHistory: vi.fn().mockReturnValue([]),
1025
+ stripThoughtsFromHistory: vi.fn(),
1026
+ };
1027
+ client['chat'] = mockChat;
1028
+ const initialRequest = [{ text: 'Hi' }];
1029
+ // Act
1030
+ const stream = client.sendMessageStream(initialRequest, new AbortController().signal, 'prompt-id-ide');
1031
+ for await (const _ of stream) {
1032
+ // consume stream
1033
+ }
1034
+ // Assert
1035
+ expect(ideContextStore.get).toHaveBeenCalled();
1036
+ const expectedContext = `Here is the user's editor context. This is for your information only.
1037
+ Active file:
1038
+ Path: /path/to/active/file.ts
1039
+ Cursor: line 5, character 10
1040
+ Selected text:
1041
+ \`\`\`
1042
+ hello
1043
+ \`\`\``;
1044
+ const expectedRequest = [{ text: expectedContext }];
1045
+ expect(mockChat.addHistory).toHaveBeenCalledWith({
1046
+ role: 'user',
1047
+ parts: expectedRequest,
1048
+ });
1049
+ });
1050
+ it('should add context if ideMode is enabled and there are open files but no active file', async () => {
1051
+ // Arrange
1052
+ vi.mocked(ideContextStore.get).mockReturnValue({
1053
+ workspaceState: {
1054
+ openFiles: [
1055
+ {
1056
+ path: '/path/to/recent/file1.ts',
1057
+ timestamp: Date.now(),
1058
+ },
1059
+ {
1060
+ path: '/path/to/recent/file2.ts',
1061
+ timestamp: Date.now(),
1062
+ },
1063
+ ],
1064
+ },
1065
+ });
1066
+ vi.spyOn(client['config'], 'getIdeMode').mockReturnValue(true);
1067
+ vi.spyOn(client, 'tryCompressChat').mockResolvedValue({
1068
+ originalTokenCount: 0,
1069
+ newTokenCount: 0,
1070
+ compressionStatus: CompressionStatus.COMPRESSED,
1071
+ });
1072
+ const mockStream = (async function* () {
1073
+ yield { type: 'content', value: 'Hello' };
1074
+ })();
1075
+ mockTurnRunFn.mockReturnValue(mockStream);
1076
+ const mockChat = {
1077
+ addHistory: vi.fn(),
1078
+ getHistory: vi.fn().mockReturnValue([]),
1079
+ stripThoughtsFromHistory: vi.fn(),
1080
+ };
1081
+ client['chat'] = mockChat;
1082
+ const initialRequest = [{ text: 'Hi' }];
1083
+ // Act
1084
+ const stream = client.sendMessageStream(initialRequest, new AbortController().signal, 'prompt-id-ide');
1085
+ for await (const _ of stream) {
1086
+ // consume stream
1087
+ }
1088
+ // Assert
1089
+ expect(ideContextStore.get).toHaveBeenCalled();
1090
+ const expectedContext = `Here is the user's editor context. This is for your information only.
1091
+ Other open files:
1092
+ - /path/to/recent/file1.ts
1093
+ - /path/to/recent/file2.ts`;
1094
+ const expectedRequest = [{ text: expectedContext }];
1095
+ expect(mockChat.addHistory).toHaveBeenCalledWith({
1096
+ role: 'user',
1097
+ parts: expectedRequest,
1098
+ });
1099
+ });
1100
+ it('should return the turn instance after the stream is complete', async () => {
1101
+ // Arrange
1102
+ const mockStream = (async function* () {
1103
+ yield { type: 'content', value: 'Hello' };
1104
+ })();
1105
+ mockTurnRunFn.mockReturnValue(mockStream);
1106
+ const mockChat = {
1107
+ addHistory: vi.fn(),
1108
+ getHistory: vi.fn().mockReturnValue([]),
1109
+ stripThoughtsFromHistory: vi.fn(),
1110
+ };
1111
+ client['chat'] = mockChat;
1112
+ // Act
1113
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-1');
1114
+ // Consume the stream manually to get the final return value.
1115
+ let finalResult;
1116
+ while (true) {
1117
+ const result = await stream.next();
1118
+ if (result.done) {
1119
+ finalResult = result.value;
1120
+ break;
1121
+ }
1122
+ }
1123
+ // Assert
1124
+ expect(finalResult).toBeInstanceOf(Turn);
1125
+ });
1126
+ it('should stop infinite loop after MAX_TURNS when nextSpeaker always returns model', async () => {
1127
+ // Get the mocked checkNextSpeaker function and configure it to trigger infinite loop
1128
+ const { checkNextSpeaker } = await import('../utils/nextSpeakerChecker.js');
1129
+ const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
1130
+ mockCheckNextSpeaker.mockResolvedValue({
1131
+ next_speaker: 'model',
1132
+ reasoning: 'Test case - always continue',
1133
+ });
1134
+ // Mock Turn to have no pending tool calls (which would allow nextSpeaker check)
1135
+ const mockStream = (async function* () {
1136
+ yield { type: 'content', value: 'Continue...' };
1137
+ })();
1138
+ mockTurnRunFn.mockReturnValue(mockStream);
1139
+ const mockChat = {
1140
+ addHistory: vi.fn(),
1141
+ getHistory: vi.fn().mockReturnValue([]),
1142
+ stripThoughtsFromHistory: vi.fn(),
1143
+ };
1144
+ client['chat'] = mockChat;
1145
+ // Use a signal that never gets aborted
1146
+ const abortController = new AbortController();
1147
+ const signal = abortController.signal;
1148
+ // Act - Start the stream that should loop
1149
+ const stream = client.sendMessageStream([{ text: 'Start conversation' }], signal, 'prompt-id-2');
1150
+ // Count how many stream events we get
1151
+ let eventCount = 0;
1152
+ let finalResult;
1153
+ // Consume the stream and count iterations
1154
+ while (true) {
1155
+ const result = await stream.next();
1156
+ if (result.done) {
1157
+ finalResult = result.value;
1158
+ break;
1159
+ }
1160
+ eventCount++;
1161
+ // Safety check to prevent actual infinite loop in test
1162
+ if (eventCount > 200) {
1163
+ abortController.abort();
1164
+ throw new Error('Test exceeded expected event limit - possible actual infinite loop');
1165
+ }
1166
+ }
1167
+ // Assert
1168
+ expect(finalResult).toBeInstanceOf(Turn);
1169
+ // Debug: Check how many times checkNextSpeaker was called
1170
+ const callCount = mockCheckNextSpeaker.mock.calls.length;
1171
+ // If infinite loop protection is working, checkNextSpeaker should be called many times
1172
+ // but stop at MAX_TURNS (100). Since each recursive call should trigger checkNextSpeaker,
1173
+ // we expect it to be called multiple times before hitting the limit
1174
+ expect(mockCheckNextSpeaker).toHaveBeenCalled();
1175
+ // The test should demonstrate that the infinite loop protection works:
1176
+ // - If checkNextSpeaker is called many times (close to MAX_TURNS), it shows the loop was happening
1177
+ // - If it's only called once, the recursive behavior might not be triggered
1178
+ if (callCount === 0) {
1179
+ throw new Error('checkNextSpeaker was never called - the recursive condition was not met');
1180
+ }
1181
+ else if (callCount === 1) {
1182
+ // This might be expected behavior if the turn has pending tool calls or other conditions prevent recursion
1183
+ console.log('checkNextSpeaker called only once - no infinite loop occurred');
1184
+ }
1185
+ else {
1186
+ console.log(`checkNextSpeaker called ${callCount} times - infinite loop protection worked`);
1187
+ // If called multiple times, we expect it to be stopped before MAX_TURNS
1188
+ expect(callCount).toBeLessThanOrEqual(100); // Should not exceed MAX_TURNS
1189
+ }
1190
+ // The stream should produce events and eventually terminate
1191
+ expect(eventCount).toBeGreaterThanOrEqual(1);
1192
+ expect(eventCount).toBeLessThan(200); // Should not exceed our safety limit
1193
+ });
1194
+ it('should yield MaxSessionTurns and stop when session turn limit is reached', async () => {
1195
+ // Arrange
1196
+ const MAX_SESSION_TURNS = 5;
1197
+ vi.spyOn(client['config'], 'getMaxSessionTurns').mockReturnValue(MAX_SESSION_TURNS);
1198
+ const mockStream = (async function* () {
1199
+ yield { type: 'content', value: 'Hello' };
1200
+ })();
1201
+ mockTurnRunFn.mockReturnValue(mockStream);
1202
+ const mockChat = {
1203
+ addHistory: vi.fn(),
1204
+ getHistory: vi.fn().mockReturnValue([]),
1205
+ stripThoughtsFromHistory: vi.fn(),
1206
+ };
1207
+ client['chat'] = mockChat;
1208
+ // Act & Assert
1209
+ // Run up to the limit
1210
+ for (let i = 0; i < MAX_SESSION_TURNS; i++) {
1211
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-4');
1212
+ // consume stream
1213
+ for await (const _event of stream) {
1214
+ // do nothing
1215
+ }
1216
+ }
1217
+ // This call should exceed the limit
1218
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-5');
1219
+ const events = [];
1220
+ for await (const event of stream) {
1221
+ events.push(event);
1222
+ }
1223
+ expect(events).toEqual([{ type: GeminiEventType.MaxSessionTurns }]);
1224
+ expect(mockTurnRunFn).toHaveBeenCalledTimes(MAX_SESSION_TURNS);
1225
+ });
1226
+ it('should respect MAX_TURNS limit even when turns parameter is set to a large value', async () => {
1227
+ // This test verifies that the infinite loop protection works even when
1228
+ // someone tries to bypass it by calling with a very large turns value
1229
+ // Get the mocked checkNextSpeaker function and configure it to trigger infinite loop
1230
+ const { checkNextSpeaker } = await import('../utils/nextSpeakerChecker.js');
1231
+ const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
1232
+ mockCheckNextSpeaker.mockResolvedValue({
1233
+ next_speaker: 'model',
1234
+ reasoning: 'Test case - always continue',
1235
+ });
1236
+ // Mock Turn to have no pending tool calls (which would allow nextSpeaker check)
1237
+ const mockStream = (async function* () {
1238
+ yield { type: 'content', value: 'Continue...' };
1239
+ })();
1240
+ mockTurnRunFn.mockReturnValue(mockStream);
1241
+ const mockChat = {
1242
+ addHistory: vi.fn(),
1243
+ getHistory: vi.fn().mockReturnValue([]),
1244
+ stripThoughtsFromHistory: vi.fn(),
1245
+ };
1246
+ client['chat'] = mockChat;
1247
+ // Use a signal that never gets aborted
1248
+ const abortController = new AbortController();
1249
+ const signal = abortController.signal;
1250
+ // Act - Start the stream with an extremely high turns value
1251
+ // This simulates a case where the turns protection is bypassed
1252
+ const stream = client.sendMessageStream([{ text: 'Start conversation' }], signal, 'prompt-id-3', { isContinuation: false }, Number.MAX_SAFE_INTEGER);
1253
+ // Count how many stream events we get
1254
+ let eventCount = 0;
1255
+ const maxTestIterations = 1000; // Higher limit to show the loop continues
1256
+ // Consume the stream and count iterations
1257
+ try {
1258
+ while (true) {
1259
+ const result = await stream.next();
1260
+ if (result.done) {
1261
+ break;
1262
+ }
1263
+ eventCount++;
1264
+ // This test should hit this limit, demonstrating the infinite loop
1265
+ if (eventCount > maxTestIterations) {
1266
+ abortController.abort();
1267
+ // This is the expected behavior - we hit the infinite loop
1268
+ break;
1269
+ }
1270
+ }
1271
+ }
1272
+ catch (error) {
1273
+ // If the test framework times out, that also demonstrates the infinite loop
1274
+ console.error('Test timed out or errored:', error);
1275
+ }
1276
+ // Assert that the fix works - the loop should stop at MAX_TURNS
1277
+ const callCount = mockCheckNextSpeaker.mock.calls.length;
1278
+ // With the fix: even when turns is set to a very high value,
1279
+ // the loop should stop at MAX_TURNS (100)
1280
+ expect(callCount).toBeLessThanOrEqual(100); // Should not exceed MAX_TURNS
1281
+ expect(eventCount).toBeLessThanOrEqual(200); // Should have reasonable number of events
1282
+ console.log(`Infinite loop protection working: checkNextSpeaker called ${callCount} times, ` +
1283
+ `${eventCount} events generated (properly bounded by MAX_TURNS)`);
1284
+ });
1285
+ describe('Editor context delta', () => {
1286
+ const mockStream = (async function* () {
1287
+ yield { type: 'content', value: 'Hello' };
1288
+ })();
1289
+ beforeEach(() => {
1290
+ client['forceFullIdeContext'] = false; // Reset before each delta test
1291
+ vi.spyOn(client, 'tryCompressChat').mockResolvedValue({
1292
+ originalTokenCount: 0,
1293
+ newTokenCount: 0,
1294
+ compressionStatus: CompressionStatus.COMPRESSED,
1295
+ });
1296
+ vi.spyOn(client['config'], 'getIdeMode').mockReturnValue(true);
1297
+ mockTurnRunFn.mockReturnValue(mockStream);
1298
+ const mockChat = {
1299
+ addHistory: vi.fn(),
1300
+ setHistory: vi.fn(),
1301
+ // Assume history is not empty for delta checks
1302
+ getHistory: vi
1303
+ .fn()
1304
+ .mockReturnValue([
1305
+ { role: 'user', parts: [{ text: 'previous message' }] },
1306
+ ]),
1307
+ stripThoughtsFromHistory: vi.fn(),
1308
+ };
1309
+ client['chat'] = mockChat;
1310
+ });
1311
+ const testCases = [
1312
+ {
1313
+ description: 'sends delta when active file changes',
1314
+ previousActiveFile: {
1315
+ path: '/path/to/old/file.ts',
1316
+ cursor: { line: 5, character: 10 },
1317
+ selectedText: 'hello',
1318
+ },
1319
+ currentActiveFile: {
1320
+ path: '/path/to/active/file.ts',
1321
+ cursor: { line: 5, character: 10 },
1322
+ selectedText: 'hello',
1323
+ },
1324
+ shouldSendContext: true,
1325
+ },
1326
+ {
1327
+ description: 'sends delta when cursor line changes',
1328
+ previousActiveFile: {
1329
+ path: '/path/to/active/file.ts',
1330
+ cursor: { line: 1, character: 10 },
1331
+ selectedText: 'hello',
1332
+ },
1333
+ currentActiveFile: {
1334
+ path: '/path/to/active/file.ts',
1335
+ cursor: { line: 5, character: 10 },
1336
+ selectedText: 'hello',
1337
+ },
1338
+ shouldSendContext: true,
1339
+ },
1340
+ {
1341
+ description: 'sends delta when cursor character changes',
1342
+ previousActiveFile: {
1343
+ path: '/path/to/active/file.ts',
1344
+ cursor: { line: 5, character: 1 },
1345
+ selectedText: 'hello',
1346
+ },
1347
+ currentActiveFile: {
1348
+ path: '/path/to/active/file.ts',
1349
+ cursor: { line: 5, character: 10 },
1350
+ selectedText: 'hello',
1351
+ },
1352
+ shouldSendContext: true,
1353
+ },
1354
+ {
1355
+ description: 'sends delta when selected text changes',
1356
+ previousActiveFile: {
1357
+ path: '/path/to/active/file.ts',
1358
+ cursor: { line: 5, character: 10 },
1359
+ selectedText: 'world',
1360
+ },
1361
+ currentActiveFile: {
1362
+ path: '/path/to/active/file.ts',
1363
+ cursor: { line: 5, character: 10 },
1364
+ selectedText: 'hello',
1365
+ },
1366
+ shouldSendContext: true,
1367
+ },
1368
+ {
1369
+ description: 'sends delta when selected text is added',
1370
+ previousActiveFile: {
1371
+ path: '/path/to/active/file.ts',
1372
+ cursor: { line: 5, character: 10 },
1373
+ },
1374
+ currentActiveFile: {
1375
+ path: '/path/to/active/file.ts',
1376
+ cursor: { line: 5, character: 10 },
1377
+ selectedText: 'hello',
1378
+ },
1379
+ shouldSendContext: true,
1380
+ },
1381
+ {
1382
+ description: 'sends delta when selected text is removed',
1383
+ previousActiveFile: {
1384
+ path: '/path/to/active/file.ts',
1385
+ cursor: { line: 5, character: 10 },
1386
+ selectedText: 'hello',
1387
+ },
1388
+ currentActiveFile: {
1389
+ path: '/path/to/active/file.ts',
1390
+ cursor: { line: 5, character: 10 },
1391
+ },
1392
+ shouldSendContext: true,
1393
+ },
1394
+ {
1395
+ description: 'does not send context when nothing changes',
1396
+ previousActiveFile: {
1397
+ path: '/path/to/active/file.ts',
1398
+ cursor: { line: 5, character: 10 },
1399
+ selectedText: 'hello',
1400
+ },
1401
+ currentActiveFile: {
1402
+ path: '/path/to/active/file.ts',
1403
+ cursor: { line: 5, character: 10 },
1404
+ selectedText: 'hello',
1405
+ },
1406
+ shouldSendContext: false,
1407
+ },
1408
+ ];
1409
+ it.each(testCases)('$description', async ({ previousActiveFile, currentActiveFile, shouldSendContext, }) => {
1410
+ // Setup previous context
1411
+ client['lastSentIdeContext'] = {
1412
+ workspaceState: {
1413
+ openFiles: [
1414
+ {
1415
+ path: previousActiveFile.path,
1416
+ cursor: previousActiveFile.cursor,
1417
+ selectedText: previousActiveFile.selectedText,
1418
+ isActive: true,
1419
+ timestamp: Date.now() - 1000,
1420
+ },
1421
+ ],
1422
+ },
1423
+ };
1424
+ // Setup current context
1425
+ vi.mocked(ideContextStore.get).mockReturnValue({
1426
+ workspaceState: {
1427
+ openFiles: [
1428
+ { ...currentActiveFile, isActive: true, timestamp: Date.now() },
1429
+ ],
1430
+ },
1431
+ });
1432
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-delta');
1433
+ for await (const _ of stream) {
1434
+ // consume stream
1435
+ }
1436
+ const mockChat = client['chat'];
1437
+ if (shouldSendContext) {
1438
+ expect(mockChat.addHistory).toHaveBeenCalledWith(expect.objectContaining({
1439
+ parts: expect.arrayContaining([
1440
+ expect.objectContaining({
1441
+ text: expect.stringContaining("Here is a summary of changes in the user's editor context"),
1442
+ }),
1443
+ ]),
1444
+ }));
1445
+ }
1446
+ else {
1447
+ expect(mockChat.addHistory).not.toHaveBeenCalled();
1448
+ }
1449
+ });
1450
+ it('sends full context when history is cleared, even if editor state is unchanged', async () => {
1451
+ const activeFile = {
1452
+ path: '/path/to/active/file.ts',
1453
+ cursor: { line: 5, character: 10 },
1454
+ selectedText: 'hello',
1455
+ };
1456
+ // Setup previous context
1457
+ client['lastSentIdeContext'] = {
1458
+ workspaceState: {
1459
+ openFiles: [
1460
+ {
1461
+ path: activeFile.path,
1462
+ cursor: activeFile.cursor,
1463
+ selectedText: activeFile.selectedText,
1464
+ isActive: true,
1465
+ timestamp: Date.now() - 1000,
1466
+ },
1467
+ ],
1468
+ },
1469
+ };
1470
+ // Setup current context (same as previous)
1471
+ vi.mocked(ideContextStore.get).mockReturnValue({
1472
+ workspaceState: {
1473
+ openFiles: [
1474
+ { ...activeFile, isActive: true, timestamp: Date.now() },
1475
+ ],
1476
+ },
1477
+ });
1478
+ // Make history empty
1479
+ const mockChat = client['chat'];
1480
+ mockChat.getHistory.mockReturnValue([]);
1481
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-history-cleared');
1482
+ for await (const _ of stream) {
1483
+ // consume stream
1484
+ }
1485
+ expect(mockChat.addHistory).toHaveBeenCalledWith(expect.objectContaining({
1486
+ parts: expect.arrayContaining([
1487
+ expect.objectContaining({
1488
+ text: expect.stringContaining("Here is the user's editor context"),
1489
+ }),
1490
+ ]),
1491
+ }));
1492
+ // Also verify it's the full context, not a delta.
1493
+ const call = mockChat.addHistory.mock.calls[0][0];
1494
+ const contextText = call.parts[0].text;
1495
+ // Verify it contains the active file information in plain text format
1496
+ expect(contextText).toContain('Active file:');
1497
+ expect(contextText).toContain('Path: /path/to/active/file.ts');
1498
+ });
1499
+ });
1500
+ describe('IDE context with pending tool calls', () => {
1501
+ let mockChat;
1502
+ beforeEach(() => {
1503
+ vi.spyOn(client, 'tryCompressChat').mockResolvedValue({
1504
+ originalTokenCount: 0,
1505
+ newTokenCount: 0,
1506
+ compressionStatus: CompressionStatus.COMPRESSED,
1507
+ });
1508
+ const mockStream = (async function* () {
1509
+ yield { type: 'content', value: 'response' };
1510
+ })();
1511
+ mockTurnRunFn.mockReturnValue(mockStream);
1512
+ mockChat = {
1513
+ addHistory: vi.fn(),
1514
+ getHistory: vi.fn().mockReturnValue([]), // Default empty history
1515
+ setHistory: vi.fn(),
1516
+ stripThoughtsFromHistory: vi.fn(),
1517
+ };
1518
+ client['chat'] = mockChat;
1519
+ vi.spyOn(client['config'], 'getIdeMode').mockReturnValue(true);
1520
+ vi.mocked(ideContextStore.get).mockReturnValue({
1521
+ workspaceState: {
1522
+ openFiles: [{ path: '/path/to/file.ts', timestamp: Date.now() }],
1523
+ },
1524
+ });
1525
+ });
1526
+ it('should NOT add IDE context when a tool call is pending', async () => {
1527
+ // Arrange: History ends with a functionCall from the model
1528
+ const historyWithPendingCall = [
1529
+ { role: 'user', parts: [{ text: 'Please use a tool.' }] },
1530
+ {
1531
+ role: 'model',
1532
+ parts: [{ functionCall: { name: 'some_tool', args: {} } }],
1533
+ },
1534
+ ];
1535
+ vi.mocked(mockChat.getHistory).mockReturnValue(historyWithPendingCall);
1536
+ // Act: Simulate sending the tool's response back
1537
+ const stream = client.sendMessageStream([
1538
+ {
1539
+ functionResponse: {
1540
+ name: 'some_tool',
1541
+ response: { success: true },
1542
+ },
1543
+ },
1544
+ ], new AbortController().signal, 'prompt-id-tool-response');
1545
+ for await (const _ of stream) {
1546
+ // consume stream to complete the call
1547
+ }
1548
+ // Assert: The IDE context message should NOT have been added to the history.
1549
+ expect(mockChat.addHistory).not.toHaveBeenCalledWith(expect.objectContaining({
1550
+ parts: expect.arrayContaining([
1551
+ expect.objectContaining({
1552
+ text: expect.stringContaining("user's editor context"),
1553
+ }),
1554
+ ]),
1555
+ }));
1556
+ });
1557
+ it('should add IDE context when no tool call is pending', async () => {
1558
+ // Arrange: History is normal, no pending calls
1559
+ const normalHistory = [
1560
+ { role: 'user', parts: [{ text: 'A normal message.' }] },
1561
+ { role: 'model', parts: [{ text: 'A normal response.' }] },
1562
+ ];
1563
+ vi.mocked(mockChat.getHistory).mockReturnValue(normalHistory);
1564
+ // Act
1565
+ const stream = client.sendMessageStream([{ text: 'Another normal message' }], new AbortController().signal, 'prompt-id-normal');
1566
+ for await (const _ of stream) {
1567
+ // consume stream
1568
+ }
1569
+ // Assert: The IDE context message SHOULD have been added.
1570
+ expect(mockChat.addHistory).toHaveBeenCalledWith(expect.objectContaining({
1571
+ role: 'user',
1572
+ parts: expect.arrayContaining([
1573
+ expect.objectContaining({
1574
+ text: expect.stringContaining("user's editor context"),
1575
+ }),
1576
+ ]),
1577
+ }));
1578
+ });
1579
+ it('should send the latest IDE context on the next message after a skipped context', async () => {
1580
+ // --- Step 1: A tool call is pending, context should be skipped ---
1581
+ // Arrange: History ends with a functionCall
1582
+ const historyWithPendingCall = [
1583
+ { role: 'user', parts: [{ text: 'Please use a tool.' }] },
1584
+ {
1585
+ role: 'model',
1586
+ parts: [{ functionCall: { name: 'some_tool', args: {} } }],
1587
+ },
1588
+ ];
1589
+ vi.mocked(mockChat.getHistory).mockReturnValue(historyWithPendingCall);
1590
+ // Arrange: Set the initial IDE context
1591
+ const initialIdeContext = {
1592
+ workspaceState: {
1593
+ openFiles: [{ path: '/path/to/fileA.ts', timestamp: Date.now() }],
1594
+ },
1595
+ };
1596
+ vi.mocked(ideContextStore.get).mockReturnValue(initialIdeContext);
1597
+ // Act: Send the tool response
1598
+ let stream = client.sendMessageStream([
1599
+ {
1600
+ functionResponse: {
1601
+ name: 'some_tool',
1602
+ response: { success: true },
1603
+ },
1604
+ },
1605
+ ], new AbortController().signal, 'prompt-id-tool-response');
1606
+ for await (const _ of stream) {
1607
+ /* consume */
1608
+ }
1609
+ // Assert: The initial context was NOT sent
1610
+ expect(mockChat.addHistory).not.toHaveBeenCalledWith(expect.objectContaining({
1611
+ parts: expect.arrayContaining([
1612
+ expect.objectContaining({
1613
+ text: expect.stringContaining("user's editor context"),
1614
+ }),
1615
+ ]),
1616
+ }));
1617
+ // --- Step 2: A new message is sent, latest context should be included ---
1618
+ // Arrange: The model has responded to the tool, and the user is sending a new message.
1619
+ const historyAfterToolResponse = [
1620
+ ...historyWithPendingCall,
1621
+ {
1622
+ role: 'user',
1623
+ parts: [
1624
+ {
1625
+ functionResponse: {
1626
+ name: 'some_tool',
1627
+ response: { success: true },
1628
+ },
1629
+ },
1630
+ ],
1631
+ },
1632
+ { role: 'model', parts: [{ text: 'The tool ran successfully.' }] },
1633
+ ];
1634
+ vi.mocked(mockChat.getHistory).mockReturnValue(historyAfterToolResponse);
1635
+ vi.mocked(mockChat.addHistory).mockClear(); // Clear previous calls for the next assertion
1636
+ // Arrange: The IDE context has now changed
1637
+ const newIdeContext = {
1638
+ workspaceState: {
1639
+ openFiles: [{ path: '/path/to/fileB.ts', timestamp: Date.now() }],
1640
+ },
1641
+ };
1642
+ vi.mocked(ideContextStore.get).mockReturnValue(newIdeContext);
1643
+ // Act: Send a new, regular user message
1644
+ stream = client.sendMessageStream([{ text: 'Thanks!' }], new AbortController().signal, 'prompt-id-final');
1645
+ for await (const _ of stream) {
1646
+ /* consume */
1647
+ }
1648
+ // Assert: The NEW context was sent as a FULL context because there was no previously sent context.
1649
+ const addHistoryCalls = vi.mocked(mockChat.addHistory).mock.calls;
1650
+ const contextCall = addHistoryCalls.find((call) => JSON.stringify(call[0]).includes("user's editor context"));
1651
+ expect(contextCall).toBeDefined();
1652
+ expect(JSON.stringify(contextCall[0])).toContain("Here is the user's editor context.");
1653
+ // Check that the sent context is the new one (fileB.ts)
1654
+ expect(JSON.stringify(contextCall[0])).toContain('fileB.ts');
1655
+ // Check that the sent context is NOT the old one (fileA.ts)
1656
+ expect(JSON.stringify(contextCall[0])).not.toContain('fileA.ts');
1657
+ });
1658
+ it('should send a context DELTA on the next message after a skipped context', async () => {
1659
+ // --- Step 0: Establish an initial context ---
1660
+ vi.mocked(mockChat.getHistory).mockReturnValue([]); // Start with empty history
1661
+ const contextA = {
1662
+ workspaceState: {
1663
+ openFiles: [
1664
+ {
1665
+ path: '/path/to/fileA.ts',
1666
+ isActive: true,
1667
+ timestamp: Date.now(),
1668
+ },
1669
+ ],
1670
+ },
1671
+ };
1672
+ vi.mocked(ideContextStore.get).mockReturnValue(contextA);
1673
+ // Act: Send a regular message to establish the initial context
1674
+ let stream = client.sendMessageStream([{ text: 'Initial message' }], new AbortController().signal, 'prompt-id-initial');
1675
+ for await (const _ of stream) {
1676
+ /* consume */
1677
+ }
1678
+ // Assert: Full context for fileA.ts was sent and stored.
1679
+ const initialCall = vi.mocked(mockChat.addHistory).mock.calls[0][0];
1680
+ expect(JSON.stringify(initialCall)).toContain("user's editor context.");
1681
+ expect(JSON.stringify(initialCall)).toContain('fileA.ts');
1682
+ // This implicitly tests that `lastSentIdeContext` is now set internally by the client.
1683
+ vi.mocked(mockChat.addHistory).mockClear();
1684
+ // --- Step 1: A tool call is pending, context should be skipped ---
1685
+ const historyWithPendingCall = [
1686
+ { role: 'user', parts: [{ text: 'Please use a tool.' }] },
1687
+ {
1688
+ role: 'model',
1689
+ parts: [{ functionCall: { name: 'some_tool', args: {} } }],
1690
+ },
1691
+ ];
1692
+ vi.mocked(mockChat.getHistory).mockReturnValue(historyWithPendingCall);
1693
+ // Arrange: IDE context changes, but this should be skipped
1694
+ const contextB = {
1695
+ workspaceState: {
1696
+ openFiles: [
1697
+ {
1698
+ path: '/path/to/fileB.ts',
1699
+ isActive: true,
1700
+ timestamp: Date.now(),
1701
+ },
1702
+ ],
1703
+ },
1704
+ };
1705
+ vi.mocked(ideContextStore.get).mockReturnValue(contextB);
1706
+ // Act: Send the tool response
1707
+ stream = client.sendMessageStream([
1708
+ {
1709
+ functionResponse: {
1710
+ name: 'some_tool',
1711
+ response: { success: true },
1712
+ },
1713
+ },
1714
+ ], new AbortController().signal, 'prompt-id-tool-response');
1715
+ for await (const _ of stream) {
1716
+ /* consume */
1717
+ }
1718
+ // Assert: No context was sent
1719
+ expect(mockChat.addHistory).not.toHaveBeenCalled();
1720
+ // --- Step 2: A new message is sent, latest context DELTA should be included ---
1721
+ const historyAfterToolResponse = [
1722
+ ...historyWithPendingCall,
1723
+ {
1724
+ role: 'user',
1725
+ parts: [
1726
+ {
1727
+ functionResponse: {
1728
+ name: 'some_tool',
1729
+ response: { success: true },
1730
+ },
1731
+ },
1732
+ ],
1733
+ },
1734
+ { role: 'model', parts: [{ text: 'The tool ran successfully.' }] },
1735
+ ];
1736
+ vi.mocked(mockChat.getHistory).mockReturnValue(historyAfterToolResponse);
1737
+ // Arrange: The IDE context has changed again
1738
+ const contextC = {
1739
+ workspaceState: {
1740
+ openFiles: [
1741
+ // fileA is now closed, fileC is open
1742
+ {
1743
+ path: '/path/to/fileC.ts',
1744
+ isActive: true,
1745
+ timestamp: Date.now(),
1746
+ },
1747
+ ],
1748
+ },
1749
+ };
1750
+ vi.mocked(ideContextStore.get).mockReturnValue(contextC);
1751
+ // Act: Send a new, regular user message
1752
+ stream = client.sendMessageStream([{ text: 'Thanks!' }], new AbortController().signal, 'prompt-id-final');
1753
+ for await (const _ of stream) {
1754
+ /* consume */
1755
+ }
1756
+ // Assert: The DELTA context was sent
1757
+ const finalCall = vi.mocked(mockChat.addHistory).mock.calls[0][0];
1758
+ expect(JSON.stringify(finalCall)).toContain('summary of changes');
1759
+ // The delta should reflect fileA being closed and fileC being opened.
1760
+ expect(JSON.stringify(finalCall)).toContain('Files closed');
1761
+ expect(JSON.stringify(finalCall)).toContain('fileA.ts');
1762
+ expect(JSON.stringify(finalCall)).toContain('Active file changed');
1763
+ expect(JSON.stringify(finalCall)).toContain('fileC.ts');
1764
+ });
1765
+ });
1766
+ it('should not call checkNextSpeaker when turn.run() yields an error', async () => {
1767
+ // Arrange
1768
+ const { checkNextSpeaker } = await import('../utils/nextSpeakerChecker.js');
1769
+ const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
1770
+ const mockStream = (async function* () {
1771
+ yield {
1772
+ type: GeminiEventType.Error,
1773
+ value: { error: { message: 'test error' } },
1774
+ };
1775
+ })();
1776
+ mockTurnRunFn.mockReturnValue(mockStream);
1777
+ const mockChat = {
1778
+ addHistory: vi.fn(),
1779
+ getHistory: vi.fn().mockReturnValue([]),
1780
+ stripThoughtsFromHistory: vi.fn(),
1781
+ };
1782
+ client['chat'] = mockChat;
1783
+ // Act
1784
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-error');
1785
+ for await (const _ of stream) {
1786
+ // consume stream
1787
+ }
1788
+ // Assert
1789
+ expect(mockCheckNextSpeaker).not.toHaveBeenCalled();
1790
+ });
1791
+ it('should not call checkNextSpeaker when turn.run() yields a value then an error', async () => {
1792
+ // Arrange
1793
+ const { checkNextSpeaker } = await import('../utils/nextSpeakerChecker.js');
1794
+ const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
1795
+ const mockStream = (async function* () {
1796
+ yield { type: GeminiEventType.Content, value: 'some content' };
1797
+ yield {
1798
+ type: GeminiEventType.Error,
1799
+ value: { error: { message: 'test error' } },
1800
+ };
1801
+ })();
1802
+ mockTurnRunFn.mockReturnValue(mockStream);
1803
+ const mockChat = {
1804
+ addHistory: vi.fn(),
1805
+ getHistory: vi.fn().mockReturnValue([]),
1806
+ stripThoughtsFromHistory: vi.fn(),
1807
+ };
1808
+ client['chat'] = mockChat;
1809
+ // Act
1810
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-error');
1811
+ for await (const _ of stream) {
1812
+ // consume stream
1813
+ }
1814
+ // Assert
1815
+ expect(mockCheckNextSpeaker).not.toHaveBeenCalled();
1816
+ });
1817
+ it('does not run loop checks when skipLoopDetection is true', async () => {
1818
+ // Arrange
1819
+ // Ensure config returns true for skipLoopDetection
1820
+ vi.spyOn(client['config'], 'getSkipLoopDetection').mockReturnValue(true);
1821
+ // Replace loop detector with spies
1822
+ const ldMock = {
1823
+ addAndCheck: vi.fn().mockReturnValue(false),
1824
+ reset: vi.fn(),
1825
+ };
1826
+ // @ts-expect-error override private for testing
1827
+ client['loopDetector'] = ldMock;
1828
+ const mockStream = (async function* () {
1829
+ yield { type: 'content', value: 'Hello' };
1830
+ yield { type: 'content', value: 'World' };
1831
+ })();
1832
+ mockTurnRunFn.mockReturnValue(mockStream);
1833
+ const mockChat = {
1834
+ addHistory: vi.fn(),
1835
+ getHistory: vi.fn().mockReturnValue([]),
1836
+ stripThoughtsFromHistory: vi.fn(),
1837
+ };
1838
+ client['chat'] = mockChat;
1839
+ // Act
1840
+ const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-skip-loop');
1841
+ for await (const _ of stream) {
1842
+ // consume stream
1843
+ }
1844
+ // Assert - loop detection methods should not be called when skipLoopDetection is true
1845
+ expect(ldMock.addAndCheck).not.toHaveBeenCalled();
1846
+ });
1847
+ });
1848
+ describe('generateContent', () => {
1849
+ it('should call generateContent with the correct parameters', async () => {
1850
+ const contents = [{ role: 'user', parts: [{ text: 'hello' }] }];
1851
+ const generationConfig = { temperature: 0.5 };
1852
+ const abortSignal = new AbortController().signal;
1853
+ await client.generateContent(contents, generationConfig, abortSignal, DEFAULT_QWEN_FLASH_MODEL);
1854
+ expect(mockContentGenerator.generateContent).toHaveBeenCalledWith(expect.objectContaining({
1855
+ model: DEFAULT_QWEN_FLASH_MODEL,
1856
+ config: expect.objectContaining({
1857
+ abortSignal,
1858
+ systemInstruction: getCoreSystemPrompt(''),
1859
+ temperature: 0.5,
1860
+ }),
1861
+ contents,
1862
+ }), 'test-session-id');
1863
+ });
1864
+ it('should use current model from config for content generation', async () => {
1865
+ const initialModel = client['config'].getModel();
1866
+ const contents = [{ role: 'user', parts: [{ text: 'test' }] }];
1867
+ const currentModel = initialModel + '-changed';
1868
+ vi.spyOn(client['config'], 'getModel').mockReturnValueOnce(currentModel);
1869
+ await client.generateContent(contents, {}, new AbortController().signal, DEFAULT_QWEN_FLASH_MODEL);
1870
+ expect(mockContentGenerator.generateContent).not.toHaveBeenCalledWith({
1871
+ model: initialModel,
1872
+ config: expect.any(Object),
1873
+ contents,
1874
+ });
1875
+ expect(mockContentGenerator.generateContent).toHaveBeenCalledWith({
1876
+ model: DEFAULT_QWEN_FLASH_MODEL,
1877
+ config: expect.any(Object),
1878
+ contents,
1879
+ }, 'test-session-id');
1880
+ });
1881
+ // Note: there is currently no "fallback mode" model routing; the model used
1882
+ // is always the one explicitly requested by the caller.
1883
+ });
1884
+ });
1885
+ //# sourceMappingURL=client.test.js.map