@google/gemini-cli-core 0.0.8999999 → 0.0.77777773

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 (362) hide show
  1. package/README.md +105 -62
  2. package/dist/index.d.ts +5 -2
  3. package/dist/index.js +4 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/src/agents/codebase-investigator.d.ts +46 -0
  6. package/dist/src/agents/codebase-investigator.js +136 -0
  7. package/dist/src/agents/codebase-investigator.js.map +1 -0
  8. package/dist/src/agents/executor.d.ts +92 -0
  9. package/dist/src/agents/executor.js +579 -0
  10. package/dist/src/agents/executor.js.map +1 -0
  11. package/dist/src/agents/executor.test.d.ts +6 -0
  12. package/dist/src/agents/executor.test.js +595 -0
  13. package/dist/src/agents/executor.test.js.map +1 -0
  14. package/dist/src/agents/invocation.d.ts +46 -0
  15. package/dist/src/agents/invocation.js +102 -0
  16. package/dist/src/agents/invocation.js.map +1 -0
  17. package/dist/src/agents/invocation.test.d.ts +6 -0
  18. package/dist/src/agents/invocation.test.js +215 -0
  19. package/dist/src/agents/invocation.test.js.map +1 -0
  20. package/dist/src/agents/registry.d.ts +36 -0
  21. package/dist/src/agents/registry.js +60 -0
  22. package/dist/src/agents/registry.js.map +1 -0
  23. package/dist/src/agents/registry.test.d.ts +6 -0
  24. package/dist/src/agents/registry.test.js +146 -0
  25. package/dist/src/agents/registry.test.js.map +1 -0
  26. package/dist/src/agents/schema-utils.d.ts +39 -0
  27. package/dist/src/agents/schema-utils.js +57 -0
  28. package/dist/src/agents/schema-utils.js.map +1 -0
  29. package/dist/src/agents/schema-utils.test.d.ts +6 -0
  30. package/dist/src/agents/schema-utils.test.js +144 -0
  31. package/dist/src/agents/schema-utils.test.js.map +1 -0
  32. package/dist/src/agents/subagent-tool-wrapper.d.ts +38 -0
  33. package/dist/src/agents/subagent-tool-wrapper.js +48 -0
  34. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -0
  35. package/dist/src/agents/subagent-tool-wrapper.test.d.ts +6 -0
  36. package/dist/src/agents/subagent-tool-wrapper.test.js +112 -0
  37. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -0
  38. package/dist/src/agents/types.d.ts +145 -0
  39. package/dist/src/agents/types.js +18 -0
  40. package/dist/src/agents/types.js.map +1 -0
  41. package/dist/src/agents/utils.d.ts +15 -0
  42. package/dist/src/agents/utils.js +29 -0
  43. package/dist/src/agents/utils.js.map +1 -0
  44. package/dist/src/agents/utils.test.d.ts +6 -0
  45. package/dist/src/agents/utils.test.js +87 -0
  46. package/dist/src/agents/utils.test.js.map +1 -0
  47. package/dist/src/code_assist/oauth-credential-storage.js +1 -1
  48. package/dist/src/code_assist/oauth-credential-storage.js.map +1 -1
  49. package/dist/src/code_assist/oauth2.test.js +14 -13
  50. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  51. package/dist/src/code_assist/setup.js +4 -2
  52. package/dist/src/code_assist/setup.js.map +1 -1
  53. package/dist/src/config/config.d.ts +46 -15
  54. package/dist/src/config/config.js +106 -27
  55. package/dist/src/config/config.js.map +1 -1
  56. package/dist/src/config/config.test.js +88 -3
  57. package/dist/src/config/config.test.js.map +1 -1
  58. package/dist/src/config/constants.d.ts +11 -0
  59. package/dist/src/config/constants.js +16 -0
  60. package/dist/src/config/constants.js.map +1 -0
  61. package/dist/src/config/storage.d.ts +0 -1
  62. package/dist/src/config/storage.js +2 -2
  63. package/dist/src/config/storage.js.map +1 -1
  64. package/dist/src/config/storage.test.js +7 -6
  65. package/dist/src/config/storage.test.js.map +1 -1
  66. package/dist/src/core/baseLlmClient.d.ts +4 -0
  67. package/dist/src/core/baseLlmClient.js +24 -23
  68. package/dist/src/core/baseLlmClient.js.map +1 -1
  69. package/dist/src/core/baseLlmClient.test.js +76 -13
  70. package/dist/src/core/baseLlmClient.test.js.map +1 -1
  71. package/dist/src/core/client.d.ts +3 -1
  72. package/dist/src/core/client.js +68 -47
  73. package/dist/src/core/client.js.map +1 -1
  74. package/dist/src/core/client.test.js +385 -134
  75. package/dist/src/core/client.test.js.map +1 -1
  76. package/dist/src/core/contentGenerator.js +3 -1
  77. package/dist/src/core/contentGenerator.js.map +1 -1
  78. package/dist/src/core/coreToolScheduler.js +24 -15
  79. package/dist/src/core/coreToolScheduler.js.map +1 -1
  80. package/dist/src/core/coreToolScheduler.test.js +359 -23
  81. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  82. package/dist/src/core/geminiChat.d.ts +11 -14
  83. package/dist/src/core/geminiChat.js +75 -124
  84. package/dist/src/core/geminiChat.js.map +1 -1
  85. package/dist/src/core/geminiChat.test.js +260 -239
  86. package/dist/src/core/geminiChat.test.js.map +1 -1
  87. package/dist/src/core/logger.test.js +2 -2
  88. package/dist/src/core/logger.test.js.map +1 -1
  89. package/dist/src/core/nonInteractiveToolExecutor.test.js +11 -11
  90. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  91. package/dist/src/core/prompts.d.ts +2 -1
  92. package/dist/src/core/prompts.js +93 -18
  93. package/dist/src/core/prompts.js.map +1 -1
  94. package/dist/src/core/prompts.test.js +78 -29
  95. package/dist/src/core/prompts.test.js.map +1 -1
  96. package/dist/src/core/turn.d.ts +15 -6
  97. package/dist/src/core/turn.js +14 -13
  98. package/dist/src/core/turn.js.map +1 -1
  99. package/dist/src/core/turn.test.js +14 -2
  100. package/dist/src/core/turn.test.js.map +1 -1
  101. package/dist/src/generated/git-commit.d.ts +2 -2
  102. package/dist/src/generated/git-commit.js +2 -2
  103. package/dist/src/generated/git-commit.js.map +1 -1
  104. package/dist/src/ide/detect-ide.d.ts +5 -2
  105. package/dist/src/ide/detect-ide.js +11 -2
  106. package/dist/src/ide/detect-ide.js.map +1 -1
  107. package/dist/src/ide/detect-ide.test.js +34 -0
  108. package/dist/src/ide/detect-ide.test.js.map +1 -1
  109. package/dist/src/ide/ide-client.d.ts +2 -1
  110. package/dist/src/ide/ide-client.js +25 -20
  111. package/dist/src/ide/ide-client.js.map +1 -1
  112. package/dist/src/ide/ide-client.test.js +6 -6
  113. package/dist/src/ide/ide-client.test.js.map +1 -1
  114. package/dist/src/ide/ide-installer.js +1 -1
  115. package/dist/src/ide/ide-installer.js.map +1 -1
  116. package/dist/src/ide/ide-installer.test.js +13 -1
  117. package/dist/src/ide/ide-installer.test.js.map +1 -1
  118. package/dist/src/index.d.ts +3 -0
  119. package/dist/src/index.js +3 -0
  120. package/dist/src/index.js.map +1 -1
  121. package/dist/src/mcp/oauth-provider.d.ts +1 -0
  122. package/dist/src/mcp/oauth-provider.js +19 -14
  123. package/dist/src/mcp/oauth-provider.js.map +1 -1
  124. package/dist/src/mcp/oauth-provider.test.js +137 -1
  125. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  126. package/dist/src/mcp/oauth-utils.js +1 -0
  127. package/dist/src/mcp/oauth-utils.js.map +1 -1
  128. package/dist/src/mcp/sa-impersonation-provider.d.ts +33 -0
  129. package/dist/src/mcp/sa-impersonation-provider.js +130 -0
  130. package/dist/src/mcp/sa-impersonation-provider.js.map +1 -0
  131. package/dist/src/mcp/sa-impersonation-provider.test.d.ts +6 -0
  132. package/dist/src/mcp/sa-impersonation-provider.test.js +117 -0
  133. package/dist/src/mcp/sa-impersonation-provider.test.js.map +1 -0
  134. package/dist/src/mcp/token-storage/file-token-storage.js +2 -1
  135. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
  136. package/dist/src/mcp/token-storage/file-token-storage.test.js +4 -3
  137. package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -1
  138. package/dist/src/routing/strategies/compositeStrategy.js +4 -3
  139. package/dist/src/routing/strategies/compositeStrategy.js.map +1 -1
  140. package/dist/src/services/chatRecordingService.d.ts +3 -2
  141. package/dist/src/services/chatRecordingService.js +3 -2
  142. package/dist/src/services/chatRecordingService.js.map +1 -1
  143. package/dist/src/services/fileSystemService.d.ts +9 -0
  144. package/dist/src/services/fileSystemService.js +11 -0
  145. package/dist/src/services/fileSystemService.js.map +1 -1
  146. package/dist/src/services/shellExecutionService.d.ts +3 -0
  147. package/dist/src/services/shellExecutionService.js +165 -49
  148. package/dist/src/services/shellExecutionService.js.map +1 -1
  149. package/dist/src/services/shellExecutionService.test.js +74 -5
  150. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  151. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +18 -2
  152. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +156 -11
  153. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  154. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +1 -0
  155. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +226 -1
  156. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  157. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +19 -3
  158. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +44 -5
  159. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  160. package/dist/src/telemetry/config.d.ts +31 -0
  161. package/dist/src/telemetry/config.js +76 -0
  162. package/dist/src/telemetry/config.js.map +1 -0
  163. package/dist/src/telemetry/config.test.d.ts +6 -0
  164. package/dist/src/telemetry/config.test.js +124 -0
  165. package/dist/src/telemetry/config.test.js.map +1 -0
  166. package/dist/src/telemetry/constants.d.ts +0 -34
  167. package/dist/src/telemetry/constants.js +0 -34
  168. package/dist/src/telemetry/constants.js.map +1 -1
  169. package/dist/src/telemetry/index.d.ts +6 -2
  170. package/dist/src/telemetry/index.js +17 -2
  171. package/dist/src/telemetry/index.js.map +1 -1
  172. package/dist/src/telemetry/loggers.d.ts +10 -2
  173. package/dist/src/telemetry/loggers.js +206 -273
  174. package/dist/src/telemetry/loggers.js.map +1 -1
  175. package/dist/src/telemetry/loggers.test.circular.js +3 -3
  176. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  177. package/dist/src/telemetry/loggers.test.js +260 -13
  178. package/dist/src/telemetry/loggers.test.js.map +1 -1
  179. package/dist/src/telemetry/memory-monitor.d.ts +149 -0
  180. package/dist/src/telemetry/memory-monitor.js +335 -0
  181. package/dist/src/telemetry/memory-monitor.js.map +1 -0
  182. package/dist/src/telemetry/memory-monitor.test.d.ts +6 -0
  183. package/dist/src/telemetry/memory-monitor.test.js +472 -0
  184. package/dist/src/telemetry/memory-monitor.test.js.map +1 -0
  185. package/dist/src/telemetry/metrics.d.ts +436 -11
  186. package/dist/src/telemetry/metrics.js +600 -110
  187. package/dist/src/telemetry/metrics.js.map +1 -1
  188. package/dist/src/telemetry/metrics.test.js +898 -16
  189. package/dist/src/telemetry/metrics.test.js.map +1 -1
  190. package/dist/src/telemetry/sdk.js +4 -1
  191. package/dist/src/telemetry/sdk.js.map +1 -1
  192. package/dist/src/telemetry/sdk.test.js +13 -0
  193. package/dist/src/telemetry/sdk.test.js.map +1 -1
  194. package/dist/src/telemetry/telemetryAttributes.d.ts +8 -0
  195. package/dist/src/telemetry/telemetryAttributes.js +18 -0
  196. package/dist/src/telemetry/telemetryAttributes.js.map +1 -0
  197. package/dist/src/telemetry/types.d.ts +167 -5
  198. package/dist/src/telemetry/types.js +692 -35
  199. package/dist/src/telemetry/types.js.map +1 -1
  200. package/dist/src/telemetry/uiTelemetry.d.ts +1 -1
  201. package/dist/src/telemetry/uiTelemetry.js +1 -1
  202. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  203. package/dist/src/telemetry/uiTelemetry.test.js +3 -3
  204. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  205. package/dist/src/test-utils/mock-tool.d.ts +28 -3
  206. package/dist/src/test-utils/mock-tool.js +71 -1
  207. package/dist/src/test-utils/mock-tool.js.map +1 -1
  208. package/dist/src/tools/edit.js +6 -0
  209. package/dist/src/tools/edit.js.map +1 -1
  210. package/dist/src/tools/edit.test.js +41 -0
  211. package/dist/src/tools/edit.test.js.map +1 -1
  212. package/dist/src/tools/glob.js +4 -2
  213. package/dist/src/tools/glob.js.map +1 -1
  214. package/dist/src/tools/ls.js +1 -1
  215. package/dist/src/tools/ls.js.map +1 -1
  216. package/dist/src/tools/mcp-client.d.ts +5 -14
  217. package/dist/src/tools/mcp-client.js +50 -97
  218. package/dist/src/tools/mcp-client.js.map +1 -1
  219. package/dist/src/tools/mcp-client.test.js +175 -157
  220. package/dist/src/tools/mcp-client.test.js.map +1 -1
  221. package/dist/src/tools/mcp-tool.js +30 -2
  222. package/dist/src/tools/mcp-tool.js.map +1 -1
  223. package/dist/src/tools/mcp-tool.test.js +117 -0
  224. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  225. package/dist/src/tools/memoryTool.d.ts +1 -1
  226. package/dist/src/tools/memoryTool.js +1 -2
  227. package/dist/src/tools/memoryTool.js.map +1 -1
  228. package/dist/src/tools/memoryTool.test.js +9 -8
  229. package/dist/src/tools/memoryTool.test.js.map +1 -1
  230. package/dist/src/tools/message-bus-integration.test.d.ts +6 -0
  231. package/dist/src/tools/message-bus-integration.test.js +183 -0
  232. package/dist/src/tools/message-bus-integration.test.js.map +1 -0
  233. package/dist/src/tools/shell.js +60 -4
  234. package/dist/src/tools/shell.js.map +1 -1
  235. package/dist/src/tools/shell.test.js +2 -1
  236. package/dist/src/tools/shell.test.js.map +1 -1
  237. package/dist/src/tools/smart-edit.d.ts +1 -1
  238. package/dist/src/tools/smart-edit.js +122 -12
  239. package/dist/src/tools/smart-edit.js.map +1 -1
  240. package/dist/src/tools/smart-edit.test.js +136 -29
  241. package/dist/src/tools/smart-edit.test.js.map +1 -1
  242. package/dist/src/tools/tool-error.d.ts +22 -0
  243. package/dist/src/tools/tool-error.js +28 -0
  244. package/dist/src/tools/tool-error.js.map +1 -1
  245. package/dist/src/tools/tool-names.d.ts +9 -0
  246. package/dist/src/tools/tool-names.js +18 -0
  247. package/dist/src/tools/tool-names.js.map +1 -0
  248. package/dist/src/tools/tool-registry.test.js +10 -10
  249. package/dist/src/tools/tool-registry.test.js.map +1 -1
  250. package/dist/src/tools/tools.d.ts +11 -3
  251. package/dist/src/tools/tools.js +94 -3
  252. package/dist/src/tools/tools.js.map +1 -1
  253. package/dist/src/tools/web-fetch.js +3 -0
  254. package/dist/src/tools/web-fetch.js.map +1 -1
  255. package/dist/src/tools/web-fetch.test.js +44 -0
  256. package/dist/src/tools/web-fetch.test.js.map +1 -1
  257. package/dist/src/tools/web-search.js +2 -1
  258. package/dist/src/tools/web-search.js.map +1 -1
  259. package/dist/src/tools/write-file.js +2 -1
  260. package/dist/src/tools/write-file.js.map +1 -1
  261. package/dist/src/tools/write-todos.d.ts +25 -0
  262. package/dist/src/tools/write-todos.js +151 -0
  263. package/dist/src/tools/write-todos.js.map +1 -0
  264. package/dist/src/tools/write-todos.test.d.ts +6 -0
  265. package/dist/src/tools/write-todos.test.js +89 -0
  266. package/dist/src/tools/write-todos.test.js.map +1 -0
  267. package/dist/src/utils/bfsFileSearch.d.ts +1 -1
  268. package/dist/src/utils/editCorrector.js +2 -2
  269. package/dist/src/utils/editCorrector.js.map +1 -1
  270. package/dist/src/utils/editor.js +1 -0
  271. package/dist/src/utils/editor.js.map +1 -1
  272. package/dist/src/utils/editor.test.js +1 -0
  273. package/dist/src/utils/editor.test.js.map +1 -1
  274. package/dist/src/utils/errorParsing.d.ts +1 -1
  275. package/dist/src/utils/errorParsing.js +5 -33
  276. package/dist/src/utils/errorParsing.js.map +1 -1
  277. package/dist/src/utils/errorParsing.test.js +0 -88
  278. package/dist/src/utils/errorParsing.test.js.map +1 -1
  279. package/dist/src/utils/flashFallback.test.js +26 -45
  280. package/dist/src/utils/flashFallback.test.js.map +1 -1
  281. package/dist/src/utils/formatters.d.ts +1 -0
  282. package/dist/src/utils/formatters.js +2 -1
  283. package/dist/src/utils/formatters.js.map +1 -1
  284. package/dist/src/utils/formatters.test.d.ts +6 -0
  285. package/dist/src/utils/formatters.test.js +26 -0
  286. package/dist/src/utils/formatters.test.js.map +1 -0
  287. package/dist/src/utils/getFolderStructure.d.ts +1 -1
  288. package/dist/src/utils/getFolderStructure.js +1 -1
  289. package/dist/src/utils/getFolderStructure.js.map +1 -1
  290. package/dist/src/utils/getFolderStructure.test.js +7 -6
  291. package/dist/src/utils/getFolderStructure.test.js.map +1 -1
  292. package/dist/src/utils/googleErrors.d.ts +104 -0
  293. package/dist/src/utils/googleErrors.js +108 -0
  294. package/dist/src/utils/googleErrors.js.map +1 -0
  295. package/dist/src/utils/googleErrors.test.d.ts +6 -0
  296. package/dist/src/utils/googleErrors.test.js +212 -0
  297. package/dist/src/utils/googleErrors.test.js.map +1 -0
  298. package/dist/src/utils/googleQuotaErrors.d.ts +35 -0
  299. package/dist/src/utils/googleQuotaErrors.js +108 -0
  300. package/dist/src/utils/googleQuotaErrors.js.map +1 -0
  301. package/dist/src/utils/googleQuotaErrors.test.d.ts +6 -0
  302. package/dist/src/utils/googleQuotaErrors.test.js +189 -0
  303. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -0
  304. package/dist/src/utils/installationManager.test.js +2 -1
  305. package/dist/src/utils/installationManager.test.js.map +1 -1
  306. package/dist/src/utils/llm-edit-fixer.js +14 -4
  307. package/dist/src/utils/llm-edit-fixer.js.map +1 -1
  308. package/dist/src/utils/llm-edit-fixer.test.js +81 -0
  309. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -1
  310. package/dist/src/utils/memoryDiscovery.d.ts +2 -1
  311. package/dist/src/utils/memoryDiscovery.js +3 -2
  312. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  313. package/dist/src/utils/memoryDiscovery.test.js +99 -21
  314. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  315. package/dist/src/utils/memoryImportProcessor.js +13 -20
  316. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  317. package/dist/src/utils/memoryImportProcessor.test.js +14 -0
  318. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  319. package/dist/src/utils/pathCorrector.d.ts +25 -0
  320. package/dist/src/utils/pathCorrector.js +33 -0
  321. package/dist/src/utils/pathCorrector.js.map +1 -0
  322. package/dist/src/utils/pathCorrector.test.d.ts +6 -0
  323. package/dist/src/utils/pathCorrector.test.js +83 -0
  324. package/dist/src/utils/pathCorrector.test.js.map +1 -0
  325. package/dist/src/utils/quotaErrorDetection.d.ts +0 -2
  326. package/dist/src/utils/quotaErrorDetection.js +0 -46
  327. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  328. package/dist/src/utils/retry.d.ts +3 -1
  329. package/dist/src/utils/retry.js +60 -162
  330. package/dist/src/utils/retry.js.map +1 -1
  331. package/dist/src/utils/retry.test.js +105 -135
  332. package/dist/src/utils/retry.test.js.map +1 -1
  333. package/dist/src/utils/schemaValidator.js +11 -1
  334. package/dist/src/utils/schemaValidator.js.map +1 -1
  335. package/dist/src/utils/schemaValidator.test.d.ts +6 -0
  336. package/dist/src/utils/schemaValidator.test.js +113 -0
  337. package/dist/src/utils/schemaValidator.test.js.map +1 -0
  338. package/dist/src/utils/shell-utils.d.ts +1 -0
  339. package/dist/src/utils/shell-utils.js +6 -2
  340. package/dist/src/utils/shell-utils.js.map +1 -1
  341. package/dist/src/utils/shell-utils.test.js +5 -0
  342. package/dist/src/utils/shell-utils.test.js.map +1 -1
  343. package/dist/src/utils/terminalSerializer.d.ts +1 -4
  344. package/dist/src/utils/terminalSerializer.js +3 -3
  345. package/dist/src/utils/terminalSerializer.js.map +1 -1
  346. package/dist/src/utils/thoughtUtils.d.ts +21 -0
  347. package/dist/src/utils/thoughtUtils.js +39 -0
  348. package/dist/src/utils/thoughtUtils.js.map +1 -0
  349. package/dist/src/utils/thoughtUtils.test.d.ts +6 -0
  350. package/dist/src/utils/thoughtUtils.test.js +78 -0
  351. package/dist/src/utils/thoughtUtils.test.js.map +1 -0
  352. package/dist/src/utils/tool-utils.js +2 -2
  353. package/dist/src/utils/tool-utils.js.map +1 -1
  354. package/dist/src/utils/tool-utils.test.js +8 -0
  355. package/dist/src/utils/tool-utils.test.js.map +1 -1
  356. package/dist/src/utils/userAccountManager.test.js +2 -1
  357. package/dist/src/utils/userAccountManager.test.js.map +1 -1
  358. package/dist/tsconfig.tsbuildinfo +1 -1
  359. package/package.json +2 -2
  360. package/dist/src/test-utils/tools.d.ts +0 -45
  361. package/dist/src/test-utils/tools.js +0 -105
  362. package/dist/src/test-utils/tools.js.map +0 -1
@@ -4,12 +4,12 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
7
- import { GeminiChat, EmptyStreamError, StreamEventType, } from './geminiChat.js';
7
+ import { ApiError } from '@google/genai';
8
+ import { GeminiChat, InvalidStreamError, StreamEventType, } from './geminiChat.js';
8
9
  import { setSimulate429 } from '../utils/testUtils.js';
9
10
  import { DEFAULT_GEMINI_FLASH_MODEL } from '../config/models.js';
10
11
  import { AuthType } from './contentGenerator.js';
11
12
  import {} from '../utils/retry.js';
12
- import { Kind } from '../tools/tools.js';
13
13
  import { uiTelemetryService } from '../telemetry/uiTelemetry.js';
14
14
  // Mock fs module to prevent actual file system operations during tests
15
15
  const mockFileSystem = new Map();
@@ -47,13 +47,11 @@ vi.mock('../utils/retry.js', () => ({
47
47
  vi.mock('../fallback/handler.js', () => ({
48
48
  handleFallback: mockHandleFallback,
49
49
  }));
50
- const { mockLogInvalidChunk, mockLogContentRetry, mockLogContentRetryFailure } = vi.hoisted(() => ({
51
- mockLogInvalidChunk: vi.fn(),
50
+ const { mockLogContentRetry, mockLogContentRetryFailure } = vi.hoisted(() => ({
52
51
  mockLogContentRetry: vi.fn(),
53
52
  mockLogContentRetryFailure: vi.fn(),
54
53
  }));
55
54
  vi.mock('../telemetry/loggers.js', () => ({
56
- logInvalidChunk: mockLogInvalidChunk,
57
55
  logContentRetry: mockLogContentRetry,
58
56
  logContentRetryFailure: mockLogContentRetryFailure,
59
57
  }));
@@ -187,7 +185,7 @@ describe('GeminiChat', () => {
187
185
  for await (const _ of stream) {
188
186
  /* consume stream */
189
187
  }
190
- })()).rejects.toThrow(EmptyStreamError);
188
+ })()).rejects.toThrow(InvalidStreamError);
191
189
  });
192
190
  it('should succeed if the stream ends with an invalid part but has a finishReason and contained a valid part', async () => {
193
191
  // 1. Mock a stream that sends a valid chunk, then an invalid one, but has a finish reason.
@@ -352,7 +350,7 @@ describe('GeminiChat', () => {
352
350
  expect(modelTurn?.parts?.length).toBe(1);
353
351
  expect(modelTurn?.parts[0].text).toBe('This is the visible text that should not be lost.');
354
352
  });
355
- it('should add a placeholder model turn when a tool call is followed by an empty stream response', async () => {
353
+ it('should throw an error when a tool call is followed by an empty stream response', async () => {
356
354
  // 1. Setup: A history where the model has just made a function call.
357
355
  const initialHistory = [
358
356
  {
@@ -393,20 +391,113 @@ describe('GeminiChat', () => {
393
391
  },
394
392
  },
395
393
  }, 'prompt-id-stream-1');
396
- for await (const _ of stream) {
397
- // This loop consumes the stream to trigger the internal logic.
398
- }
399
- // 4. Assert: The history should now have four valid, alternating turns.
400
- const history = chat.getHistory();
401
- expect(history.length).toBe(4);
402
- // The final turn must be the empty model placeholder.
403
- const lastTurn = history[3];
404
- expect(lastTurn.role).toBe('model');
405
- expect(lastTurn?.parts?.length).toBe(0);
406
- // The second-to-last turn must be the function response we sent.
407
- const secondToLastTurn = history[2];
408
- expect(secondToLastTurn.role).toBe('user');
409
- expect(secondToLastTurn?.parts[0].functionResponse).toBeDefined();
394
+ // 4. Assert: The stream processing should throw an InvalidStreamError.
395
+ await expect((async () => {
396
+ for await (const _ of stream) {
397
+ // This loop consumes the stream to trigger the internal logic.
398
+ }
399
+ })()).rejects.toThrow(InvalidStreamError);
400
+ });
401
+ it('should succeed when there is a tool call without finish reason', async () => {
402
+ // Setup: Stream with tool call but no finish reason
403
+ const streamWithToolCall = (async function* () {
404
+ yield {
405
+ candidates: [
406
+ {
407
+ content: {
408
+ role: 'model',
409
+ parts: [
410
+ {
411
+ functionCall: {
412
+ name: 'test_function',
413
+ args: { param: 'value' },
414
+ },
415
+ },
416
+ ],
417
+ },
418
+ // No finishReason
419
+ },
420
+ ],
421
+ };
422
+ })();
423
+ vi.mocked(mockContentGenerator.generateContentStream).mockResolvedValue(streamWithToolCall);
424
+ const stream = await chat.sendMessageStream('test-model', { message: 'test' }, 'prompt-id-1');
425
+ // Should not throw an error
426
+ await expect((async () => {
427
+ for await (const _ of stream) {
428
+ // consume stream
429
+ }
430
+ })()).resolves.not.toThrow();
431
+ });
432
+ it('should throw InvalidStreamError when no tool call and no finish reason', async () => {
433
+ // Setup: Stream with text but no finish reason and no tool call
434
+ const streamWithoutFinishReason = (async function* () {
435
+ yield {
436
+ candidates: [
437
+ {
438
+ content: {
439
+ role: 'model',
440
+ parts: [{ text: 'some response' }],
441
+ },
442
+ // No finishReason
443
+ },
444
+ ],
445
+ };
446
+ })();
447
+ vi.mocked(mockContentGenerator.generateContentStream).mockResolvedValue(streamWithoutFinishReason);
448
+ const stream = await chat.sendMessageStream('test-model', { message: 'test' }, 'prompt-id-1');
449
+ await expect((async () => {
450
+ for await (const _ of stream) {
451
+ // consume stream
452
+ }
453
+ })()).rejects.toThrow(InvalidStreamError);
454
+ });
455
+ it('should throw InvalidStreamError when no tool call and empty response text', async () => {
456
+ // Setup: Stream with finish reason but empty response (only thoughts)
457
+ const streamWithEmptyResponse = (async function* () {
458
+ yield {
459
+ candidates: [
460
+ {
461
+ content: {
462
+ role: 'model',
463
+ parts: [{ thought: 'thinking...' }],
464
+ },
465
+ finishReason: 'STOP',
466
+ },
467
+ ],
468
+ };
469
+ })();
470
+ vi.mocked(mockContentGenerator.generateContentStream).mockResolvedValue(streamWithEmptyResponse);
471
+ const stream = await chat.sendMessageStream('test-model', { message: 'test' }, 'prompt-id-1');
472
+ await expect((async () => {
473
+ for await (const _ of stream) {
474
+ // consume stream
475
+ }
476
+ })()).rejects.toThrow(InvalidStreamError);
477
+ });
478
+ it('should succeed when there is finish reason and response text', async () => {
479
+ // Setup: Stream with both finish reason and text content
480
+ const validStream = (async function* () {
481
+ yield {
482
+ candidates: [
483
+ {
484
+ content: {
485
+ role: 'model',
486
+ parts: [{ text: 'valid response' }],
487
+ },
488
+ finishReason: 'STOP',
489
+ },
490
+ ],
491
+ };
492
+ })();
493
+ vi.mocked(mockContentGenerator.generateContentStream).mockResolvedValue(validStream);
494
+ const stream = await chat.sendMessageStream('test-model', { message: 'test' }, 'prompt-id-1');
495
+ // Should not throw an error
496
+ await expect((async () => {
497
+ for await (const _ of stream) {
498
+ // consume stream
499
+ }
500
+ })()).resolves.not.toThrow();
410
501
  });
411
502
  it('should call generateContentStream with the correct parameters', async () => {
412
503
  const response = (async function* () {
@@ -540,7 +631,6 @@ describe('GeminiChat', () => {
540
631
  chunks.push(chunk);
541
632
  }
542
633
  // Assertions
543
- expect(mockLogInvalidChunk).toHaveBeenCalledTimes(1);
544
634
  expect(mockLogContentRetry).toHaveBeenCalledTimes(1);
545
635
  expect(mockLogContentRetryFailure).not.toHaveBeenCalled();
546
636
  expect(mockContentGenerator.generateContentStream).toHaveBeenCalledTimes(2);
@@ -564,6 +654,46 @@ describe('GeminiChat', () => {
564
654
  // Verify that token counting is not called when usageMetadata is missing
565
655
  expect(uiTelemetryService.setLastPromptTokenCount).not.toHaveBeenCalled();
566
656
  });
657
+ it('should set temperature to 1 on retry', async () => {
658
+ // Use mockImplementationOnce to provide a fresh, promise-wrapped generator for each attempt.
659
+ vi.mocked(mockContentGenerator.generateContentStream)
660
+ .mockImplementationOnce(async () =>
661
+ // First call returns an invalid stream
662
+ (async function* () {
663
+ yield {
664
+ candidates: [{ content: { parts: [{ text: '' }] } }], // Invalid empty text part
665
+ };
666
+ })())
667
+ .mockImplementationOnce(async () =>
668
+ // Second call returns a valid stream
669
+ (async function* () {
670
+ yield {
671
+ candidates: [
672
+ {
673
+ content: { parts: [{ text: 'Successful response' }] },
674
+ finishReason: 'STOP',
675
+ },
676
+ ],
677
+ };
678
+ })());
679
+ const stream = await chat.sendMessageStream('test-model', { message: 'test', config: { temperature: 0.5 } }, 'prompt-id-retry-temperature');
680
+ for await (const _ of stream) {
681
+ // consume stream
682
+ }
683
+ expect(mockContentGenerator.generateContentStream).toHaveBeenCalledTimes(2);
684
+ // First call should have original temperature
685
+ expect(mockContentGenerator.generateContentStream).toHaveBeenNthCalledWith(1, expect.objectContaining({
686
+ config: expect.objectContaining({
687
+ temperature: 0.5,
688
+ }),
689
+ }), 'prompt-id-retry-temperature');
690
+ // Second call (retry) should have temperature 1
691
+ expect(mockContentGenerator.generateContentStream).toHaveBeenNthCalledWith(2, expect.objectContaining({
692
+ config: expect.objectContaining({
693
+ temperature: 1,
694
+ }),
695
+ }), 'prompt-id-retry-temperature');
696
+ });
567
697
  it('should fail after all retries on persistent invalid content and report metrics', async () => {
568
698
  vi.mocked(mockContentGenerator.generateContentStream).mockImplementation(async () => (async function* () {
569
699
  yield {
@@ -582,15 +712,114 @@ describe('GeminiChat', () => {
582
712
  for await (const _ of stream) {
583
713
  // Must loop to trigger the internal logic that throws.
584
714
  }
585
- }).rejects.toThrow(EmptyStreamError);
586
- // Should be called 3 times (initial + 2 retries)
587
- expect(mockContentGenerator.generateContentStream).toHaveBeenCalledTimes(3);
588
- expect(mockLogInvalidChunk).toHaveBeenCalledTimes(3);
589
- expect(mockLogContentRetry).toHaveBeenCalledTimes(2);
715
+ }).rejects.toThrow(InvalidStreamError);
716
+ // Should be called 2 times (initial + 1 retry)
717
+ expect(mockContentGenerator.generateContentStream).toHaveBeenCalledTimes(2);
718
+ expect(mockLogContentRetry).toHaveBeenCalledTimes(1);
590
719
  expect(mockLogContentRetryFailure).toHaveBeenCalledTimes(1);
591
- // History should be clean, as if the failed turn never happened.
720
+ // History should still contain the user message.
592
721
  const history = chat.getHistory();
593
- expect(history.length).toBe(0);
722
+ expect(history.length).toBe(1);
723
+ expect(history[0]).toEqual({
724
+ role: 'user',
725
+ parts: [{ text: 'test' }],
726
+ });
727
+ });
728
+ describe('API error retry behavior', () => {
729
+ beforeEach(() => {
730
+ // Use a more direct mock for retry testing
731
+ mockRetryWithBackoff.mockImplementation(async (apiCall) => {
732
+ try {
733
+ return await apiCall();
734
+ }
735
+ catch (error) {
736
+ // Simulate the logic of defaultShouldRetry for ApiError
737
+ let shouldRetry = false;
738
+ if (error instanceof ApiError && error.message) {
739
+ if (error.status === 429 ||
740
+ (error.status >= 500 && error.status < 600)) {
741
+ shouldRetry = true;
742
+ }
743
+ // Explicitly don't retry on these
744
+ if (error.status === 400) {
745
+ shouldRetry = false;
746
+ }
747
+ }
748
+ if (shouldRetry) {
749
+ // Try again
750
+ return await apiCall();
751
+ }
752
+ throw error;
753
+ }
754
+ });
755
+ });
756
+ it('should not retry on 400 Bad Request errors', async () => {
757
+ const error400 = new ApiError({ message: 'Bad Request', status: 400 });
758
+ vi.mocked(mockContentGenerator.generateContentStream).mockRejectedValue(error400);
759
+ const stream = await chat.sendMessageStream('test-model', { message: 'test' }, 'prompt-id-400');
760
+ await expect((async () => {
761
+ for await (const _ of stream) {
762
+ /* consume stream */
763
+ }
764
+ })()).rejects.toThrow(error400);
765
+ // Should only be called once (no retry)
766
+ expect(mockContentGenerator.generateContentStream).toHaveBeenCalledTimes(1);
767
+ });
768
+ it('should retry on 429 Rate Limit errors', async () => {
769
+ const error429 = new ApiError({ message: 'Rate Limited', status: 429 });
770
+ vi.mocked(mockContentGenerator.generateContentStream)
771
+ .mockRejectedValueOnce(error429)
772
+ .mockResolvedValueOnce((async function* () {
773
+ yield {
774
+ candidates: [
775
+ {
776
+ content: { parts: [{ text: 'Success after retry' }] },
777
+ finishReason: 'STOP',
778
+ },
779
+ ],
780
+ };
781
+ })());
782
+ const stream = await chat.sendMessageStream('test-model', { message: 'test' }, 'prompt-id-429-retry');
783
+ const events = [];
784
+ for await (const event of stream) {
785
+ events.push(event);
786
+ }
787
+ // Should be called twice (initial + retry)
788
+ expect(mockContentGenerator.generateContentStream).toHaveBeenCalledTimes(2);
789
+ // Should have successful content
790
+ expect(events.some((e) => e.type === StreamEventType.CHUNK &&
791
+ e.value.candidates?.[0]?.content?.parts?.[0]?.text ===
792
+ 'Success after retry')).toBe(true);
793
+ });
794
+ it('should retry on 5xx server errors', async () => {
795
+ const error500 = new ApiError({
796
+ message: 'Internal Server Error 500',
797
+ status: 500,
798
+ });
799
+ vi.mocked(mockContentGenerator.generateContentStream)
800
+ .mockRejectedValueOnce(error500)
801
+ .mockResolvedValueOnce((async function* () {
802
+ yield {
803
+ candidates: [
804
+ {
805
+ content: { parts: [{ text: 'Recovered from 500' }] },
806
+ finishReason: 'STOP',
807
+ },
808
+ ],
809
+ };
810
+ })());
811
+ const stream = await chat.sendMessageStream('test-model', { message: 'test' }, 'prompt-id-500-retry');
812
+ const events = [];
813
+ for await (const event of stream) {
814
+ events.push(event);
815
+ }
816
+ // Should be called twice (initial + retry)
817
+ expect(mockContentGenerator.generateContentStream).toHaveBeenCalledTimes(2);
818
+ });
819
+ afterEach(() => {
820
+ // Reset to default behavior
821
+ mockRetryWithBackoff.mockImplementation(async (apiCall) => apiCall());
822
+ });
594
823
  });
595
824
  });
596
825
  it('should correctly retry and append to an existing history mid-conversation', async () => {
@@ -762,215 +991,6 @@ describe('GeminiChat', () => {
762
991
  }
763
992
  expect(turn4.parts[0].text).toBe('second response');
764
993
  });
765
- describe('stopBeforeSecondMutator', () => {
766
- beforeEach(() => {
767
- // Common setup for these tests: mock the tool registry.
768
- const mockToolRegistry = {
769
- getTool: vi.fn((toolName) => {
770
- if (toolName === 'edit') {
771
- return { kind: Kind.Edit };
772
- }
773
- return { kind: Kind.Other };
774
- }),
775
- };
776
- vi.mocked(mockConfig.getToolRegistry).mockReturnValue(mockToolRegistry);
777
- });
778
- it('should stop streaming before a second mutator tool call', async () => {
779
- const responses = [
780
- {
781
- candidates: [
782
- { content: { role: 'model', parts: [{ text: 'First part. ' }] } },
783
- ],
784
- },
785
- {
786
- candidates: [
787
- {
788
- content: {
789
- role: 'model',
790
- parts: [{ functionCall: { name: 'edit', args: {} } }],
791
- },
792
- },
793
- ],
794
- },
795
- {
796
- candidates: [
797
- {
798
- content: {
799
- role: 'model',
800
- parts: [{ functionCall: { name: 'fetch', args: {} } }],
801
- },
802
- },
803
- ],
804
- },
805
- // This chunk contains the second mutator and should be clipped.
806
- {
807
- candidates: [
808
- {
809
- content: {
810
- role: 'model',
811
- parts: [
812
- { functionCall: { name: 'edit', args: {} } },
813
- { text: 'some trailing text' },
814
- ],
815
- },
816
- },
817
- ],
818
- },
819
- // This chunk should never be reached.
820
- {
821
- candidates: [
822
- {
823
- content: {
824
- role: 'model',
825
- parts: [{ text: 'This should not appear.' }],
826
- },
827
- },
828
- ],
829
- },
830
- ];
831
- vi.mocked(mockContentGenerator.generateContentStream).mockResolvedValue((async function* () {
832
- for (const response of responses) {
833
- yield response;
834
- }
835
- })());
836
- const stream = await chat.sendMessageStream('test-model', { message: 'test message' }, 'prompt-id-mutator-test');
837
- for await (const _ of stream) {
838
- // Consume the stream to trigger history recording.
839
- }
840
- const history = chat.getHistory();
841
- expect(history.length).toBe(2);
842
- const modelTurn = history[1];
843
- expect(modelTurn.role).toBe('model');
844
- expect(modelTurn?.parts?.length).toBe(3);
845
- expect(modelTurn?.parts[0].text).toBe('First part. ');
846
- expect(modelTurn.parts[1].functionCall?.name).toBe('edit');
847
- expect(modelTurn.parts[2].functionCall?.name).toBe('fetch');
848
- });
849
- it('should not stop streaming if only one mutator is present', async () => {
850
- const responses = [
851
- {
852
- candidates: [
853
- { content: { role: 'model', parts: [{ text: 'Part 1. ' }] } },
854
- ],
855
- },
856
- {
857
- candidates: [
858
- {
859
- content: {
860
- role: 'model',
861
- parts: [{ functionCall: { name: 'edit', args: {} } }],
862
- },
863
- },
864
- ],
865
- },
866
- {
867
- candidates: [
868
- {
869
- content: {
870
- role: 'model',
871
- parts: [{ text: 'Part 2.' }],
872
- },
873
- finishReason: 'STOP',
874
- },
875
- ],
876
- },
877
- ];
878
- vi.mocked(mockContentGenerator.generateContentStream).mockResolvedValue((async function* () {
879
- for (const response of responses) {
880
- yield response;
881
- }
882
- })());
883
- const stream = await chat.sendMessageStream('test-model', { message: 'test message' }, 'prompt-id-one-mutator');
884
- for await (const _ of stream) {
885
- /* consume */
886
- }
887
- const history = chat.getHistory();
888
- const modelTurn = history[1];
889
- expect(modelTurn?.parts?.length).toBe(3);
890
- expect(modelTurn.parts[1].functionCall?.name).toBe('edit');
891
- expect(modelTurn.parts[2].text).toBe('Part 2.');
892
- });
893
- it('should clip the chunk containing the second mutator, preserving prior parts', async () => {
894
- const responses = [
895
- {
896
- candidates: [
897
- {
898
- content: {
899
- role: 'model',
900
- parts: [{ functionCall: { name: 'edit', args: {} } }],
901
- },
902
- },
903
- ],
904
- },
905
- // This chunk has a valid part before the second mutator.
906
- // The valid part should be kept, the rest of the chunk discarded.
907
- {
908
- candidates: [
909
- {
910
- content: {
911
- role: 'model',
912
- parts: [
913
- { text: 'Keep this text. ' },
914
- { functionCall: { name: 'edit', args: {} } },
915
- { text: 'Discard this text.' },
916
- ],
917
- },
918
- finishReason: 'STOP',
919
- },
920
- ],
921
- },
922
- ];
923
- const stream = (async function* () {
924
- for (const response of responses) {
925
- yield response;
926
- }
927
- })();
928
- vi.mocked(mockContentGenerator.generateContentStream).mockResolvedValue(stream);
929
- const resultStream = await chat.sendMessageStream('test-model', { message: 'test' }, 'prompt-id-clip-chunk');
930
- for await (const _ of resultStream) {
931
- /* consume */
932
- }
933
- const history = chat.getHistory();
934
- const modelTurn = history[1];
935
- expect(modelTurn?.parts?.length).toBe(2);
936
- expect(modelTurn.parts[0].functionCall?.name).toBe('edit');
937
- expect(modelTurn.parts[1].text).toBe('Keep this text. ');
938
- });
939
- it('should handle two mutators in the same chunk (parallel call scenario)', async () => {
940
- const responses = [
941
- {
942
- candidates: [
943
- {
944
- content: {
945
- role: 'model',
946
- parts: [
947
- { text: 'Some text. ' },
948
- { functionCall: { name: 'edit', args: {} } },
949
- { functionCall: { name: 'edit', args: {} } },
950
- ],
951
- },
952
- finishReason: 'STOP',
953
- },
954
- ],
955
- },
956
- ];
957
- const stream = (async function* () {
958
- for (const response of responses) {
959
- yield response;
960
- }
961
- })();
962
- vi.mocked(mockContentGenerator.generateContentStream).mockResolvedValue(stream);
963
- const resultStream = await chat.sendMessageStream('test-model', { message: 'test' }, 'prompt-id-parallel-mutators');
964
- for await (const _ of resultStream) {
965
- /* consume */
966
- }
967
- const history = chat.getHistory();
968
- const modelTurn = history[1];
969
- expect(modelTurn?.parts?.length).toBe(2);
970
- expect(modelTurn.parts[0].text).toBe('Some text. ');
971
- expect(modelTurn.parts[1].functionCall?.name).toBe('edit');
972
- });
973
- });
974
994
  describe('Model Resolution', () => {
975
995
  const mockResponse = {
976
996
  candidates: [
@@ -996,7 +1016,8 @@ describe('GeminiChat', () => {
996
1016
  });
997
1017
  });
998
1018
  describe('Fallback Integration (Retries)', () => {
999
- const error429 = Object.assign(new Error('API Error 429: Quota exceeded'), {
1019
+ const error429 = new ApiError({
1020
+ message: 'API Error 429: Quota exceeded',
1000
1021
  status: 429,
1001
1022
  });
1002
1023
  // Define the simulated behavior for retryWithBackoff for these tests.