@google/gemini-cli-core 0.0.3-preview.4 → 0.0.4

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 (490) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +12 -2
  3. package/dist/index.d.ts +6 -2
  4. package/dist/index.js +6 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/src/code_assist/codeAssist.d.ts +2 -0
  7. package/dist/src/code_assist/codeAssist.js +12 -0
  8. package/dist/src/code_assist/codeAssist.js.map +1 -1
  9. package/dist/src/code_assist/converter.d.ts +3 -1
  10. package/dist/src/code_assist/converter.js +2 -1
  11. package/dist/src/code_assist/converter.js.map +1 -1
  12. package/dist/src/code_assist/converter.test.js +10 -0
  13. package/dist/src/code_assist/converter.test.js.map +1 -1
  14. package/dist/src/code_assist/oauth-credential-storage.d.ts +25 -0
  15. package/dist/src/code_assist/oauth-credential-storage.js +109 -0
  16. package/dist/src/code_assist/oauth-credential-storage.js.map +1 -0
  17. package/dist/src/code_assist/oauth-credential-storage.test.js +136 -0
  18. package/dist/src/code_assist/oauth-credential-storage.test.js.map +1 -0
  19. package/dist/src/code_assist/oauth2.js +92 -29
  20. package/dist/src/code_assist/oauth2.js.map +1 -1
  21. package/dist/src/code_assist/oauth2.test.js +729 -339
  22. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  23. package/dist/src/code_assist/server.d.ts +1 -1
  24. package/dist/src/code_assist/server.js +24 -1
  25. package/dist/src/code_assist/server.js.map +1 -1
  26. package/dist/src/code_assist/server.test.js +25 -0
  27. package/dist/src/code_assist/server.test.js.map +1 -1
  28. package/dist/src/code_assist/types.d.ts +17 -2
  29. package/dist/src/config/config.d.ts +72 -12
  30. package/dist/src/config/config.js +196 -64
  31. package/dist/src/config/config.js.map +1 -1
  32. package/dist/src/config/config.test.js +305 -178
  33. package/dist/src/config/config.test.js.map +1 -1
  34. package/dist/src/config/models.d.ts +16 -0
  35. package/dist/src/config/models.js +29 -0
  36. package/dist/src/config/models.js.map +1 -1
  37. package/dist/src/config/models.test.d.ts +6 -0
  38. package/dist/src/config/models.test.js +55 -0
  39. package/dist/src/config/models.test.js.map +1 -0
  40. package/dist/src/config/storage.d.ts +2 -0
  41. package/dist/src/config/storage.js +6 -1
  42. package/dist/src/config/storage.js.map +1 -1
  43. package/dist/src/config/storage.test.js +4 -0
  44. package/dist/src/config/storage.test.js.map +1 -1
  45. package/dist/src/confirmation-bus/index.d.ts +7 -0
  46. package/dist/src/confirmation-bus/index.js +8 -0
  47. package/dist/src/confirmation-bus/index.js.map +1 -0
  48. package/dist/src/confirmation-bus/message-bus.d.ts +17 -0
  49. package/dist/src/confirmation-bus/message-bus.js +81 -0
  50. package/dist/src/confirmation-bus/message-bus.js.map +1 -0
  51. package/dist/src/confirmation-bus/message-bus.test.d.ts +6 -0
  52. package/dist/src/confirmation-bus/message-bus.test.js +164 -0
  53. package/dist/src/confirmation-bus/message-bus.test.js.map +1 -0
  54. package/dist/src/confirmation-bus/types.d.ts +38 -0
  55. package/dist/src/confirmation-bus/types.js +15 -0
  56. package/dist/src/confirmation-bus/types.js.map +1 -0
  57. package/dist/src/core/baseLlmClient.d.ts +46 -0
  58. package/dist/src/core/baseLlmClient.js +112 -0
  59. package/dist/src/core/baseLlmClient.js.map +1 -0
  60. package/dist/src/core/baseLlmClient.test.d.ts +6 -0
  61. package/dist/src/core/baseLlmClient.test.js +253 -0
  62. package/dist/src/core/baseLlmClient.test.js.map +1 -0
  63. package/dist/src/core/client.d.ts +16 -21
  64. package/dist/src/core/client.js +145 -232
  65. package/dist/src/core/client.js.map +1 -1
  66. package/dist/src/core/client.test.js +393 -492
  67. package/dist/src/core/client.test.js.map +1 -1
  68. package/dist/src/core/contentGenerator.d.ts +2 -3
  69. package/dist/src/core/contentGenerator.js +0 -4
  70. package/dist/src/core/contentGenerator.js.map +1 -1
  71. package/dist/src/core/contentGenerator.test.js +1 -3
  72. package/dist/src/core/contentGenerator.test.js.map +1 -1
  73. package/dist/src/core/coreToolScheduler.d.ts +8 -3
  74. package/dist/src/core/coreToolScheduler.js +106 -5
  75. package/dist/src/core/coreToolScheduler.js.map +1 -1
  76. package/dist/src/core/coreToolScheduler.test.js +233 -5
  77. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  78. package/dist/src/core/geminiChat.d.ts +38 -32
  79. package/dist/src/core/geminiChat.js +209 -219
  80. package/dist/src/core/geminiChat.js.map +1 -1
  81. package/dist/src/core/geminiChat.test.js +674 -386
  82. package/dist/src/core/geminiChat.test.js.map +1 -1
  83. package/dist/src/core/loggingContentGenerator.js +13 -16
  84. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  85. package/dist/src/core/nonInteractiveToolExecutor.test.js +59 -1
  86. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  87. package/dist/src/core/prompts.d.ts +5 -0
  88. package/dist/src/core/prompts.js +63 -42
  89. package/dist/src/core/prompts.js.map +1 -1
  90. package/dist/src/core/prompts.test.js +130 -1
  91. package/dist/src/core/prompts.test.js.map +1 -1
  92. package/dist/src/core/subagent.js +7 -10
  93. package/dist/src/core/subagent.js.map +1 -1
  94. package/dist/src/core/subagent.test.js +32 -22
  95. package/dist/src/core/subagent.test.js.map +1 -1
  96. package/dist/src/core/turn.d.ts +21 -5
  97. package/dist/src/core/turn.js +45 -11
  98. package/dist/src/core/turn.js.map +1 -1
  99. package/dist/src/core/turn.test.js +340 -100
  100. package/dist/src/core/turn.test.js.map +1 -1
  101. package/dist/src/fallback/handler.d.ts +7 -0
  102. package/dist/src/fallback/handler.js +51 -0
  103. package/dist/src/fallback/handler.js.map +1 -0
  104. package/dist/src/fallback/handler.test.d.ts +6 -0
  105. package/dist/src/fallback/handler.test.js +130 -0
  106. package/dist/src/fallback/handler.test.js.map +1 -0
  107. package/dist/src/fallback/types.d.ts +14 -0
  108. package/dist/src/fallback/types.js +7 -0
  109. package/dist/src/fallback/types.js.map +1 -0
  110. package/dist/src/generated/git-commit.d.ts +2 -2
  111. package/dist/src/generated/git-commit.js +2 -2
  112. package/dist/src/generated/git-commit.js.map +1 -1
  113. package/dist/src/ide/constants.d.ts +3 -0
  114. package/dist/src/ide/constants.js +3 -0
  115. package/dist/src/ide/constants.js.map +1 -1
  116. package/dist/src/ide/detect-ide.d.ts +42 -14
  117. package/dist/src/ide/detect-ide.js +22 -68
  118. package/dist/src/ide/detect-ide.js.map +1 -1
  119. package/dist/src/ide/detect-ide.test.js +11 -51
  120. package/dist/src/ide/detect-ide.test.js.map +1 -1
  121. package/dist/src/ide/ide-client.d.ts +60 -18
  122. package/dist/src/ide/ide-client.js +275 -53
  123. package/dist/src/ide/ide-client.js.map +1 -1
  124. package/dist/src/ide/ide-client.test.js +239 -6
  125. package/dist/src/ide/ide-client.test.js.map +1 -1
  126. package/dist/src/ide/ide-installer.d.ts +2 -2
  127. package/dist/src/ide/ide-installer.js +15 -11
  128. package/dist/src/ide/ide-installer.js.map +1 -1
  129. package/dist/src/ide/ide-installer.test.js +30 -12
  130. package/dist/src/ide/ide-installer.test.js.map +1 -1
  131. package/dist/src/ide/ideContext.d.ts +35 -365
  132. package/dist/src/ide/ideContext.js +60 -106
  133. package/dist/src/ide/ideContext.js.map +1 -1
  134. package/dist/src/ide/ideContext.test.js +152 -24
  135. package/dist/src/ide/ideContext.test.js.map +1 -1
  136. package/dist/src/ide/process-utils.d.ts +0 -1
  137. package/dist/src/ide/process-utils.js +43 -25
  138. package/dist/src/ide/process-utils.js.map +1 -1
  139. package/dist/src/ide/process-utils.test.js +90 -4
  140. package/dist/src/ide/process-utils.test.js.map +1 -1
  141. package/dist/src/ide/types.d.ts +486 -0
  142. package/dist/src/ide/types.js +138 -0
  143. package/dist/src/ide/types.js.map +1 -0
  144. package/dist/src/index.d.ts +10 -2
  145. package/dist/src/index.js +11 -2
  146. package/dist/src/index.js.map +1 -1
  147. package/dist/src/mcp/oauth-provider.d.ts +15 -12
  148. package/dist/src/mcp/oauth-provider.js +63 -56
  149. package/dist/src/mcp/oauth-provider.js.map +1 -1
  150. package/dist/src/mcp/oauth-provider.test.js +74 -35
  151. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  152. package/dist/src/mcp/oauth-token-storage.d.ts +14 -10
  153. package/dist/src/mcp/oauth-token-storage.js +52 -20
  154. package/dist/src/mcp/oauth-token-storage.js.map +1 -1
  155. package/dist/src/mcp/oauth-token-storage.test.js +255 -162
  156. package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
  157. package/dist/src/mcp/token-storage/base-token-storage.d.ts +1 -1
  158. package/dist/src/mcp/token-storage/base-token-storage.js +1 -1
  159. package/dist/src/mcp/token-storage/base-token-storage.js.map +1 -1
  160. package/dist/src/mcp/token-storage/base-token-storage.test.js +1 -1
  161. package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -1
  162. package/dist/src/mcp/token-storage/file-token-storage.d.ts +24 -0
  163. package/dist/src/mcp/token-storage/file-token-storage.js +144 -0
  164. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -0
  165. package/dist/src/mcp/token-storage/file-token-storage.test.d.ts +6 -0
  166. package/dist/src/mcp/token-storage/file-token-storage.test.js +235 -0
  167. package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -0
  168. package/dist/src/mcp/token-storage/hybrid-token-storage.d.ts +23 -0
  169. package/dist/src/mcp/token-storage/hybrid-token-storage.js +78 -0
  170. package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -0
  171. package/dist/src/mcp/token-storage/hybrid-token-storage.test.d.ts +6 -0
  172. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js +193 -0
  173. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -0
  174. package/dist/src/mcp/token-storage/index.d.ts +11 -0
  175. package/dist/src/mcp/token-storage/index.js +12 -0
  176. package/dist/src/mcp/token-storage/index.js.map +1 -0
  177. package/dist/src/mcp/token-storage/keychain-token-storage.d.ts +31 -0
  178. package/dist/src/mcp/token-storage/keychain-token-storage.js +190 -0
  179. package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -0
  180. package/dist/src/mcp/token-storage/keychain-token-storage.test.d.ts +6 -0
  181. package/dist/src/mcp/token-storage/keychain-token-storage.test.js +254 -0
  182. package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -0
  183. package/dist/src/mcp/token-storage/types.d.ts +4 -0
  184. package/dist/src/mcp/token-storage/types.js +5 -1
  185. package/dist/src/mcp/token-storage/types.js.map +1 -1
  186. package/dist/src/output/json-formatter.d.ts +11 -0
  187. package/dist/src/output/json-formatter.js +30 -0
  188. package/dist/src/output/json-formatter.js.map +1 -0
  189. package/dist/src/output/json-formatter.test.d.ts +6 -0
  190. package/dist/src/output/json-formatter.test.js +266 -0
  191. package/dist/src/output/json-formatter.test.js.map +1 -0
  192. package/dist/src/output/types.d.ts +20 -0
  193. package/dist/src/output/types.js +11 -0
  194. package/dist/src/output/types.js.map +1 -0
  195. package/dist/src/policy/index.d.ts +7 -0
  196. package/dist/src/policy/index.js +8 -0
  197. package/dist/src/policy/index.js.map +1 -0
  198. package/dist/src/policy/policy-engine.d.ts +30 -0
  199. package/dist/src/policy/policy-engine.js +92 -0
  200. package/dist/src/policy/policy-engine.js.map +1 -0
  201. package/dist/src/policy/policy-engine.test.d.ts +6 -0
  202. package/dist/src/policy/policy-engine.test.js +515 -0
  203. package/dist/src/policy/policy-engine.test.js.map +1 -0
  204. package/dist/src/policy/stable-stringify.d.ts +58 -0
  205. package/dist/src/policy/stable-stringify.js +122 -0
  206. package/dist/src/policy/stable-stringify.js.map +1 -0
  207. package/dist/src/policy/types.d.ts +47 -0
  208. package/dist/src/policy/types.js +12 -0
  209. package/dist/src/policy/types.js.map +1 -0
  210. package/dist/src/routing/modelRouterService.d.ts +23 -0
  211. package/dist/src/routing/modelRouterService.js +70 -0
  212. package/dist/src/routing/modelRouterService.js.map +1 -0
  213. package/dist/src/routing/modelRouterService.test.d.ts +6 -0
  214. package/dist/src/routing/modelRouterService.test.js +98 -0
  215. package/dist/src/routing/modelRouterService.test.js.map +1 -0
  216. package/dist/src/routing/routingStrategy.d.ts +62 -0
  217. package/dist/src/routing/routingStrategy.js +7 -0
  218. package/dist/src/routing/routingStrategy.js.map +1 -0
  219. package/dist/src/routing/strategies/classifierStrategy.d.ts +12 -0
  220. package/dist/src/routing/strategies/classifierStrategy.js +173 -0
  221. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -0
  222. package/dist/src/routing/strategies/classifierStrategy.test.d.ts +6 -0
  223. package/dist/src/routing/strategies/classifierStrategy.test.js +192 -0
  224. package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -0
  225. package/dist/src/routing/strategies/compositeStrategy.d.ts +26 -0
  226. package/dist/src/routing/strategies/compositeStrategy.js +67 -0
  227. package/dist/src/routing/strategies/compositeStrategy.js.map +1 -0
  228. package/dist/src/routing/strategies/compositeStrategy.test.d.ts +6 -0
  229. package/dist/src/routing/strategies/compositeStrategy.test.js +123 -0
  230. package/dist/src/routing/strategies/compositeStrategy.test.js.map +1 -0
  231. package/dist/src/routing/strategies/defaultStrategy.d.ts +12 -0
  232. package/dist/src/routing/strategies/defaultStrategy.js +20 -0
  233. package/dist/src/routing/strategies/defaultStrategy.js.map +1 -0
  234. package/dist/src/routing/strategies/defaultStrategy.test.d.ts +6 -0
  235. package/dist/src/routing/strategies/defaultStrategy.test.js +26 -0
  236. package/dist/src/routing/strategies/defaultStrategy.test.js.map +1 -0
  237. package/dist/src/routing/strategies/fallbackStrategy.d.ts +12 -0
  238. package/dist/src/routing/strategies/fallbackStrategy.js +25 -0
  239. package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -0
  240. package/dist/src/routing/strategies/fallbackStrategy.test.d.ts +6 -0
  241. package/dist/src/routing/strategies/fallbackStrategy.test.js +55 -0
  242. package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -0
  243. package/dist/src/routing/strategies/overrideStrategy.d.ts +15 -0
  244. package/dist/src/routing/strategies/overrideStrategy.js +28 -0
  245. package/dist/src/routing/strategies/overrideStrategy.js.map +1 -0
  246. package/dist/src/routing/strategies/overrideStrategy.test.d.ts +6 -0
  247. package/dist/src/routing/strategies/overrideStrategy.test.js +42 -0
  248. package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -0
  249. package/dist/src/services/chatRecordingService.d.ts +7 -13
  250. package/dist/src/services/chatRecordingService.js +28 -19
  251. package/dist/src/services/chatRecordingService.js.map +1 -1
  252. package/dist/src/services/chatRecordingService.test.js +62 -20
  253. package/dist/src/services/chatRecordingService.test.js.map +1 -1
  254. package/dist/src/services/fileDiscoveryService.d.ts +10 -0
  255. package/dist/src/services/fileDiscoveryService.js +31 -17
  256. package/dist/src/services/fileDiscoveryService.js.map +1 -1
  257. package/dist/src/services/gitService.js +9 -12
  258. package/dist/src/services/gitService.js.map +1 -1
  259. package/dist/src/services/gitService.test.js +10 -20
  260. package/dist/src/services/gitService.test.js.map +1 -1
  261. package/dist/src/services/loopDetectionService.d.ts +5 -0
  262. package/dist/src/services/loopDetectionService.js +36 -20
  263. package/dist/src/services/loopDetectionService.js.map +1 -1
  264. package/dist/src/services/loopDetectionService.test.js +41 -12
  265. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  266. package/dist/src/services/shellExecutionService.d.ts +34 -2
  267. package/dist/src/services/shellExecutionService.js +192 -43
  268. package/dist/src/services/shellExecutionService.js.map +1 -1
  269. package/dist/src/services/shellExecutionService.test.js +184 -55
  270. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  271. package/dist/src/telemetry/activity-detector.d.ts +41 -0
  272. package/dist/src/telemetry/activity-detector.js +61 -0
  273. package/dist/src/telemetry/activity-detector.js.map +1 -0
  274. package/dist/src/telemetry/activity-detector.test.d.ts +6 -0
  275. package/dist/src/telemetry/activity-detector.test.js +136 -0
  276. package/dist/src/telemetry/activity-detector.test.js.map +1 -0
  277. package/dist/src/telemetry/activity-types.d.ts +19 -0
  278. package/dist/src/telemetry/activity-types.js +21 -0
  279. package/dist/src/telemetry/activity-types.js.map +1 -0
  280. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +16 -2
  281. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +143 -24
  282. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  283. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +101 -1
  284. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  285. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +19 -2
  286. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +48 -2
  287. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  288. package/dist/src/telemetry/constants.d.ts +8 -0
  289. package/dist/src/telemetry/constants.js +8 -0
  290. package/dist/src/telemetry/constants.js.map +1 -1
  291. package/dist/src/telemetry/gcp-exporters.d.ts +34 -0
  292. package/dist/src/telemetry/gcp-exporters.js +117 -0
  293. package/dist/src/telemetry/gcp-exporters.js.map +1 -0
  294. package/dist/src/telemetry/gcp-exporters.test.d.ts +6 -0
  295. package/dist/src/telemetry/gcp-exporters.test.js +318 -0
  296. package/dist/src/telemetry/gcp-exporters.test.js.map +1 -0
  297. package/dist/src/telemetry/high-water-mark-tracker.d.ts +43 -0
  298. package/dist/src/telemetry/high-water-mark-tracker.js +88 -0
  299. package/dist/src/telemetry/high-water-mark-tracker.js.map +1 -0
  300. package/dist/src/telemetry/high-water-mark-tracker.test.d.ts +6 -0
  301. package/dist/src/telemetry/high-water-mark-tracker.test.js +152 -0
  302. package/dist/src/telemetry/high-water-mark-tracker.test.js.map +1 -0
  303. package/dist/src/telemetry/index.d.ts +7 -2
  304. package/dist/src/telemetry/index.js +7 -2
  305. package/dist/src/telemetry/index.js.map +1 -1
  306. package/dist/src/telemetry/loggers.d.ts +8 -1
  307. package/dist/src/telemetry/loggers.js +140 -8
  308. package/dist/src/telemetry/loggers.js.map +1 -1
  309. package/dist/src/telemetry/loggers.test.js +268 -39
  310. package/dist/src/telemetry/loggers.test.js.map +1 -1
  311. package/dist/src/telemetry/metrics.d.ts +4 -3
  312. package/dist/src/telemetry/metrics.js +33 -10
  313. package/dist/src/telemetry/metrics.js.map +1 -1
  314. package/dist/src/telemetry/metrics.test.js +47 -25
  315. package/dist/src/telemetry/metrics.test.js.map +1 -1
  316. package/dist/src/telemetry/rate-limiter.d.ts +48 -0
  317. package/dist/src/telemetry/rate-limiter.js +100 -0
  318. package/dist/src/telemetry/rate-limiter.js.map +1 -0
  319. package/dist/src/telemetry/rate-limiter.test.d.ts +6 -0
  320. package/dist/src/telemetry/rate-limiter.test.js +207 -0
  321. package/dist/src/telemetry/rate-limiter.test.js.map +1 -0
  322. package/dist/src/telemetry/sdk.js +16 -1
  323. package/dist/src/telemetry/sdk.js.map +1 -1
  324. package/dist/src/telemetry/sdk.test.js +95 -0
  325. package/dist/src/telemetry/sdk.test.js.map +1 -1
  326. package/dist/src/telemetry/types.d.ts +70 -6
  327. package/dist/src/telemetry/types.js +112 -8
  328. package/dist/src/telemetry/types.js.map +1 -1
  329. package/dist/src/telemetry/uiTelemetry.d.ts +1 -1
  330. package/dist/src/telemetry/uiTelemetry.js +6 -7
  331. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  332. package/dist/src/telemetry/uiTelemetry.test.js +15 -15
  333. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  334. package/dist/src/test-utils/index.d.ts +6 -0
  335. package/dist/src/test-utils/index.js +7 -0
  336. package/dist/src/test-utils/index.js.map +1 -0
  337. package/dist/src/test-utils/mock-tool.d.ts +41 -0
  338. package/dist/src/test-utils/mock-tool.js +51 -0
  339. package/dist/src/test-utils/mock-tool.js.map +1 -0
  340. package/dist/src/tools/diffOptions.js +21 -13
  341. package/dist/src/tools/diffOptions.js.map +1 -1
  342. package/dist/src/tools/diffOptions.test.js +58 -22
  343. package/dist/src/tools/diffOptions.test.js.map +1 -1
  344. package/dist/src/tools/edit.d.ts +2 -2
  345. package/dist/src/tools/edit.js +35 -44
  346. package/dist/src/tools/edit.js.map +1 -1
  347. package/dist/src/tools/edit.test.js +124 -13
  348. package/dist/src/tools/edit.test.js.map +1 -1
  349. package/dist/src/tools/glob.d.ts +5 -1
  350. package/dist/src/tools/glob.js +24 -17
  351. package/dist/src/tools/glob.js.map +1 -1
  352. package/dist/src/tools/glob.test.js +51 -0
  353. package/dist/src/tools/glob.test.js.map +1 -1
  354. package/dist/src/tools/ls.js +19 -32
  355. package/dist/src/tools/ls.js.map +1 -1
  356. package/dist/src/tools/ls.test.js +140 -280
  357. package/dist/src/tools/ls.test.js.map +1 -1
  358. package/dist/src/tools/mcp-client-manager.d.ts +5 -3
  359. package/dist/src/tools/mcp-client-manager.js +13 -4
  360. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  361. package/dist/src/tools/mcp-client-manager.test.js +20 -1
  362. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  363. package/dist/src/tools/mcp-client.d.ts +5 -5
  364. package/dist/src/tools/mcp-client.js +40 -35
  365. package/dist/src/tools/mcp-client.js.map +1 -1
  366. package/dist/src/tools/mcp-client.test.js +3 -3
  367. package/dist/src/tools/mcp-client.test.js.map +1 -1
  368. package/dist/src/tools/mcp-tool.d.ts +3 -2
  369. package/dist/src/tools/mcp-tool.js +9 -9
  370. package/dist/src/tools/mcp-tool.js.map +1 -1
  371. package/dist/src/tools/mcp-tool.test.js +28 -7
  372. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  373. package/dist/src/tools/memoryTool.js +5 -33
  374. package/dist/src/tools/memoryTool.js.map +1 -1
  375. package/dist/src/tools/read-file.js +8 -3
  376. package/dist/src/tools/read-file.js.map +1 -1
  377. package/dist/src/tools/read-file.test.js +29 -0
  378. package/dist/src/tools/read-file.test.js.map +1 -1
  379. package/dist/src/tools/read-many-files.d.ts +1 -1
  380. package/dist/src/tools/read-many-files.js +18 -50
  381. package/dist/src/tools/read-many-files.js.map +1 -1
  382. package/dist/src/tools/read-many-files.test.js +4 -4
  383. package/dist/src/tools/read-many-files.test.js.map +1 -1
  384. package/dist/src/tools/ripGrep.d.ts +8 -0
  385. package/dist/src/tools/ripGrep.js +26 -1
  386. package/dist/src/tools/ripGrep.js.map +1 -1
  387. package/dist/src/tools/ripGrep.test.js +107 -5
  388. package/dist/src/tools/ripGrep.test.js.map +1 -1
  389. package/dist/src/tools/shell.d.ts +12 -2
  390. package/dist/src/tools/shell.js +20 -24
  391. package/dist/src/tools/shell.js.map +1 -1
  392. package/dist/src/tools/shell.test.js +35 -70
  393. package/dist/src/tools/shell.test.js.map +1 -1
  394. package/dist/src/tools/smart-edit.d.ts +72 -0
  395. package/dist/src/tools/smart-edit.js +594 -0
  396. package/dist/src/tools/smart-edit.js.map +1 -0
  397. package/dist/src/tools/smart-edit.test.d.ts +6 -0
  398. package/dist/src/tools/smart-edit.test.js +419 -0
  399. package/dist/src/tools/smart-edit.test.js.map +1 -0
  400. package/dist/src/tools/tool-registry.d.ts +2 -1
  401. package/dist/src/tools/tool-registry.js +6 -5
  402. package/dist/src/tools/tool-registry.js.map +1 -1
  403. package/dist/src/tools/tools.d.ts +14 -7
  404. package/dist/src/tools/tools.js +9 -2
  405. package/dist/src/tools/tools.js.map +1 -1
  406. package/dist/src/tools/web-fetch.js +4 -3
  407. package/dist/src/tools/web-fetch.js.map +1 -1
  408. package/dist/src/tools/web-search.d.ts +1 -1
  409. package/dist/src/tools/web-search.js +3 -1
  410. package/dist/src/tools/web-search.js.map +1 -1
  411. package/dist/src/tools/write-file.js +14 -19
  412. package/dist/src/tools/write-file.js.map +1 -1
  413. package/dist/src/tools/write-file.test.js +99 -19
  414. package/dist/src/tools/write-file.test.js.map +1 -1
  415. package/dist/src/utils/bfsFileSearch.js +11 -5
  416. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  417. package/dist/src/utils/editCorrector.d.ts +7 -6
  418. package/dist/src/utils/editCorrector.js +61 -18
  419. package/dist/src/utils/editCorrector.js.map +1 -1
  420. package/dist/src/utils/editCorrector.test.js +30 -79
  421. package/dist/src/utils/editCorrector.test.js.map +1 -1
  422. package/dist/src/utils/editor.js +31 -44
  423. package/dist/src/utils/editor.js.map +1 -1
  424. package/dist/src/utils/editor.test.js +61 -75
  425. package/dist/src/utils/editor.test.js.map +1 -1
  426. package/dist/src/utils/errorParsing.js +2 -2
  427. package/dist/src/utils/errorParsing.js.map +1 -1
  428. package/dist/src/utils/errorParsing.test.js +7 -7
  429. package/dist/src/utils/errorParsing.test.js.map +1 -1
  430. package/dist/src/utils/errors.d.ts +6 -0
  431. package/dist/src/utils/errors.js +10 -0
  432. package/dist/src/utils/errors.js.map +1 -1
  433. package/dist/src/utils/fileUtils.d.ts +20 -3
  434. package/dist/src/utils/fileUtils.js +154 -32
  435. package/dist/src/utils/fileUtils.js.map +1 -1
  436. package/dist/src/utils/fileUtils.test.js +347 -29
  437. package/dist/src/utils/fileUtils.test.js.map +1 -1
  438. package/dist/src/utils/flashFallback.test.d.ts +6 -0
  439. package/dist/src/utils/{flashFallback.integration.test.js → flashFallback.test.js} +31 -27
  440. package/dist/src/utils/flashFallback.test.js.map +1 -0
  441. package/dist/src/utils/geminiIgnoreParser.d.ts +18 -0
  442. package/dist/src/utils/geminiIgnoreParser.js +61 -0
  443. package/dist/src/utils/geminiIgnoreParser.js.map +1 -0
  444. package/dist/src/utils/geminiIgnoreParser.test.d.ts +6 -0
  445. package/dist/src/utils/geminiIgnoreParser.test.js +50 -0
  446. package/dist/src/utils/geminiIgnoreParser.test.js.map +1 -0
  447. package/dist/src/utils/gitIgnoreParser.d.ts +3 -7
  448. package/dist/src/utils/gitIgnoreParser.js +125 -34
  449. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  450. package/dist/src/utils/gitIgnoreParser.test.js +66 -35
  451. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
  452. package/dist/src/utils/llm-edit-fixer.d.ts +26 -0
  453. package/dist/src/utils/llm-edit-fixer.js +121 -0
  454. package/dist/src/utils/llm-edit-fixer.js.map +1 -0
  455. package/dist/src/utils/llm-edit-fixer.test.d.ts +6 -0
  456. package/dist/src/utils/llm-edit-fixer.test.js +105 -0
  457. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -0
  458. package/dist/src/utils/memoryDiscovery.d.ts +5 -4
  459. package/dist/src/utils/memoryDiscovery.js +10 -9
  460. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  461. package/dist/src/utils/memoryDiscovery.test.js +50 -25
  462. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  463. package/dist/src/utils/nextSpeakerChecker.d.ts +2 -2
  464. package/dist/src/utils/nextSpeakerChecker.js +8 -2
  465. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  466. package/dist/src/utils/nextSpeakerChecker.test.js +75 -64
  467. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  468. package/dist/src/utils/promptIdContext.d.ts +7 -0
  469. package/dist/src/utils/promptIdContext.js +8 -0
  470. package/dist/src/utils/promptIdContext.js.map +1 -0
  471. package/dist/src/utils/shell-utils.d.ts +5 -0
  472. package/dist/src/utils/shell-utils.js +23 -0
  473. package/dist/src/utils/shell-utils.js.map +1 -1
  474. package/dist/src/utils/terminalSerializer.d.ts +28 -0
  475. package/dist/src/utils/terminalSerializer.js +432 -0
  476. package/dist/src/utils/terminalSerializer.js.map +1 -0
  477. package/dist/src/utils/terminalSerializer.test.d.ts +6 -0
  478. package/dist/src/utils/terminalSerializer.test.js +176 -0
  479. package/dist/src/utils/terminalSerializer.test.js.map +1 -0
  480. package/dist/src/utils/textUtils.d.ts +5 -0
  481. package/dist/src/utils/textUtils.js +14 -0
  482. package/dist/src/utils/textUtils.js.map +1 -1
  483. package/dist/src/utils/textUtils.test.d.ts +6 -0
  484. package/dist/src/utils/textUtils.test.js +59 -0
  485. package/dist/src/utils/textUtils.test.js.map +1 -0
  486. package/dist/tsconfig.tsbuildinfo +1 -1
  487. package/package.json +9 -3
  488. package/dist/google-gemini-cli-core-0.3.0-preview.3.tgz +0 -0
  489. package/dist/src/utils/flashFallback.integration.test.js.map +0 -1
  490. /package/dist/src/{utils/flashFallback.integration.test.d.ts → code_assist/oauth-credential-storage.test.d.ts} +0 -0
@@ -0,0 +1,164 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
7
+ import { MessageBus } from './message-bus.js';
8
+ import { PolicyEngine } from '../policy/policy-engine.js';
9
+ import { PolicyDecision } from '../policy/types.js';
10
+ import { MessageBusType, } from './types.js';
11
+ describe('MessageBus', () => {
12
+ let messageBus;
13
+ let policyEngine;
14
+ beforeEach(() => {
15
+ policyEngine = new PolicyEngine();
16
+ messageBus = new MessageBus(policyEngine);
17
+ });
18
+ describe('publish', () => {
19
+ it('should emit error for invalid message', () => {
20
+ const errorHandler = vi.fn();
21
+ messageBus.on('error', errorHandler);
22
+ // @ts-expect-error - Testing invalid message
23
+ messageBus.publish({ invalid: 'message' });
24
+ expect(errorHandler).toHaveBeenCalledWith(expect.objectContaining({
25
+ message: expect.stringContaining('Invalid message structure'),
26
+ }));
27
+ });
28
+ it('should validate tool confirmation requests have correlationId', () => {
29
+ const errorHandler = vi.fn();
30
+ messageBus.on('error', errorHandler);
31
+ // @ts-expect-error - Testing missing correlationId
32
+ messageBus.publish({
33
+ type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
34
+ toolCall: { name: 'test' },
35
+ });
36
+ expect(errorHandler).toHaveBeenCalled();
37
+ });
38
+ it('should emit confirmation response when policy allows', () => {
39
+ vi.spyOn(policyEngine, 'check').mockReturnValue(PolicyDecision.ALLOW);
40
+ const responseHandler = vi.fn();
41
+ messageBus.subscribe(MessageBusType.TOOL_CONFIRMATION_RESPONSE, responseHandler);
42
+ const request = {
43
+ type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
44
+ toolCall: { name: 'test-tool', args: {} },
45
+ correlationId: '123',
46
+ };
47
+ messageBus.publish(request);
48
+ const expectedResponse = {
49
+ type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
50
+ correlationId: '123',
51
+ confirmed: true,
52
+ };
53
+ expect(responseHandler).toHaveBeenCalledWith(expectedResponse);
54
+ });
55
+ it('should emit rejection and response when policy denies', () => {
56
+ vi.spyOn(policyEngine, 'check').mockReturnValue(PolicyDecision.DENY);
57
+ const responseHandler = vi.fn();
58
+ const rejectionHandler = vi.fn();
59
+ messageBus.subscribe(MessageBusType.TOOL_CONFIRMATION_RESPONSE, responseHandler);
60
+ messageBus.subscribe(MessageBusType.TOOL_POLICY_REJECTION, rejectionHandler);
61
+ const request = {
62
+ type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
63
+ toolCall: { name: 'test-tool', args: {} },
64
+ correlationId: '123',
65
+ };
66
+ messageBus.publish(request);
67
+ const expectedRejection = {
68
+ type: MessageBusType.TOOL_POLICY_REJECTION,
69
+ toolCall: { name: 'test-tool', args: {} },
70
+ };
71
+ expect(rejectionHandler).toHaveBeenCalledWith(expectedRejection);
72
+ const expectedResponse = {
73
+ type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
74
+ correlationId: '123',
75
+ confirmed: false,
76
+ };
77
+ expect(responseHandler).toHaveBeenCalledWith(expectedResponse);
78
+ });
79
+ it('should pass through to UI when policy says ASK_USER', () => {
80
+ vi.spyOn(policyEngine, 'check').mockReturnValue(PolicyDecision.ASK_USER);
81
+ const requestHandler = vi.fn();
82
+ messageBus.subscribe(MessageBusType.TOOL_CONFIRMATION_REQUEST, requestHandler);
83
+ const request = {
84
+ type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
85
+ toolCall: { name: 'test-tool', args: {} },
86
+ correlationId: '123',
87
+ };
88
+ messageBus.publish(request);
89
+ expect(requestHandler).toHaveBeenCalledWith(request);
90
+ });
91
+ it('should emit other message types directly', () => {
92
+ const successHandler = vi.fn();
93
+ messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, successHandler);
94
+ const message = {
95
+ type: MessageBusType.TOOL_EXECUTION_SUCCESS,
96
+ toolCall: { name: 'test-tool' },
97
+ result: 'success',
98
+ };
99
+ messageBus.publish(message);
100
+ expect(successHandler).toHaveBeenCalledWith(message);
101
+ });
102
+ });
103
+ describe('subscribe/unsubscribe', () => {
104
+ it('should allow subscribing to specific message types', () => {
105
+ const handler = vi.fn();
106
+ messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler);
107
+ const message = {
108
+ type: MessageBusType.TOOL_EXECUTION_SUCCESS,
109
+ toolCall: { name: 'test' },
110
+ result: 'test',
111
+ };
112
+ messageBus.publish(message);
113
+ expect(handler).toHaveBeenCalledWith(message);
114
+ });
115
+ it('should allow unsubscribing from message types', () => {
116
+ const handler = vi.fn();
117
+ messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler);
118
+ messageBus.unsubscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler);
119
+ const message = {
120
+ type: MessageBusType.TOOL_EXECUTION_SUCCESS,
121
+ toolCall: { name: 'test' },
122
+ result: 'test',
123
+ };
124
+ messageBus.publish(message);
125
+ expect(handler).not.toHaveBeenCalled();
126
+ });
127
+ it('should support multiple subscribers for the same message type', () => {
128
+ const handler1 = vi.fn();
129
+ const handler2 = vi.fn();
130
+ messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler1);
131
+ messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler2);
132
+ const message = {
133
+ type: MessageBusType.TOOL_EXECUTION_SUCCESS,
134
+ toolCall: { name: 'test' },
135
+ result: 'test',
136
+ };
137
+ messageBus.publish(message);
138
+ expect(handler1).toHaveBeenCalledWith(message);
139
+ expect(handler2).toHaveBeenCalledWith(message);
140
+ });
141
+ });
142
+ describe('error handling', () => {
143
+ it('should not crash on errors during message processing', () => {
144
+ const errorHandler = vi.fn();
145
+ messageBus.on('error', errorHandler);
146
+ // Mock policyEngine to throw an error
147
+ vi.spyOn(policyEngine, 'check').mockImplementation(() => {
148
+ throw new Error('Policy check failed');
149
+ });
150
+ const request = {
151
+ type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
152
+ toolCall: { name: 'test-tool' },
153
+ correlationId: '123',
154
+ };
155
+ // Should not throw
156
+ expect(() => messageBus.publish(request)).not.toThrow();
157
+ // Should emit error
158
+ expect(errorHandler).toHaveBeenCalledWith(expect.objectContaining({
159
+ message: 'Policy check failed',
160
+ }));
161
+ });
162
+ });
163
+ });
164
+ //# sourceMappingURL=message-bus.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-bus.test.js","sourceRoot":"","sources":["../../../src/confirmation-bus/message-bus.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { type FunctionCall } from '@google/genai';
7
+ export declare enum MessageBusType {
8
+ TOOL_CONFIRMATION_REQUEST = "tool-confirmation-request",
9
+ TOOL_CONFIRMATION_RESPONSE = "tool-confirmation-response",
10
+ TOOL_POLICY_REJECTION = "tool-policy-rejection",
11
+ TOOL_EXECUTION_SUCCESS = "tool-execution-success",
12
+ TOOL_EXECUTION_FAILURE = "tool-execution-failure"
13
+ }
14
+ export interface ToolConfirmationRequest {
15
+ type: MessageBusType.TOOL_CONFIRMATION_REQUEST;
16
+ toolCall: FunctionCall;
17
+ correlationId: string;
18
+ }
19
+ export interface ToolConfirmationResponse {
20
+ type: MessageBusType.TOOL_CONFIRMATION_RESPONSE;
21
+ correlationId: string;
22
+ confirmed: boolean;
23
+ }
24
+ export interface ToolPolicyRejection {
25
+ type: MessageBusType.TOOL_POLICY_REJECTION;
26
+ toolCall: FunctionCall;
27
+ }
28
+ export interface ToolExecutionSuccess<T = unknown> {
29
+ type: MessageBusType.TOOL_EXECUTION_SUCCESS;
30
+ toolCall: FunctionCall;
31
+ result: T;
32
+ }
33
+ export interface ToolExecutionFailure<E = Error> {
34
+ type: MessageBusType.TOOL_EXECUTION_FAILURE;
35
+ toolCall: FunctionCall;
36
+ error: E;
37
+ }
38
+ export type Message = ToolConfirmationRequest | ToolConfirmationResponse | ToolPolicyRejection | ToolExecutionSuccess | ToolExecutionFailure;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import {} from '@google/genai';
7
+ export var MessageBusType;
8
+ (function (MessageBusType) {
9
+ MessageBusType["TOOL_CONFIRMATION_REQUEST"] = "tool-confirmation-request";
10
+ MessageBusType["TOOL_CONFIRMATION_RESPONSE"] = "tool-confirmation-response";
11
+ MessageBusType["TOOL_POLICY_REJECTION"] = "tool-policy-rejection";
12
+ MessageBusType["TOOL_EXECUTION_SUCCESS"] = "tool-execution-success";
13
+ MessageBusType["TOOL_EXECUTION_FAILURE"] = "tool-execution-failure";
14
+ })(MessageBusType || (MessageBusType = {}));
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/confirmation-bus/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAqB,MAAM,eAAe,CAAC;AAElD,MAAM,CAAN,IAAY,cAMX;AAND,WAAY,cAAc;IACxB,yEAAuD,CAAA;IACvD,2EAAyD,CAAA;IACzD,iEAA+C,CAAA;IAC/C,mEAAiD,CAAA;IACjD,mEAAiD,CAAA;AACnD,CAAC,EANW,cAAc,KAAd,cAAc,QAMzB"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { Content, GenerateContentConfig, Part } from '@google/genai';
7
+ import type { Config } from '../config/config.js';
8
+ import type { ContentGenerator } from './contentGenerator.js';
9
+ /**
10
+ * Options for the generateJson utility function.
11
+ */
12
+ export interface GenerateJsonOptions {
13
+ /** The input prompt or history. */
14
+ contents: Content[];
15
+ /** The required JSON schema for the output. */
16
+ schema: Record<string, unknown>;
17
+ /** The specific model to use for this task. */
18
+ model: string;
19
+ /**
20
+ * Task-specific system instructions.
21
+ * If omitted, no system instruction is sent.
22
+ */
23
+ systemInstruction?: string | Part | Part[] | Content;
24
+ /**
25
+ * Overrides for generation configuration (e.g., temperature).
26
+ */
27
+ config?: Omit<GenerateContentConfig, 'systemInstruction' | 'responseJsonSchema' | 'responseMimeType' | 'tools' | 'abortSignal'>;
28
+ /** Signal for cancellation. */
29
+ abortSignal: AbortSignal;
30
+ /**
31
+ * A unique ID for the prompt, used for logging/telemetry correlation.
32
+ */
33
+ promptId: string;
34
+ }
35
+ /**
36
+ * A client dedicated to stateless, utility-focused LLM calls.
37
+ */
38
+ export declare class BaseLlmClient {
39
+ private readonly contentGenerator;
40
+ private readonly config;
41
+ private readonly defaultUtilityConfig;
42
+ constructor(contentGenerator: ContentGenerator, config: Config);
43
+ generateJson(options: GenerateJsonOptions): Promise<Record<string, unknown>>;
44
+ generateEmbedding(texts: string[]): Promise<number[][]>;
45
+ private cleanJsonResponse;
46
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { getResponseText } from '../utils/partUtils.js';
7
+ import { reportError } from '../utils/errorReporting.js';
8
+ import { getErrorMessage } from '../utils/errors.js';
9
+ import { logMalformedJsonResponse } from '../telemetry/loggers.js';
10
+ import { MalformedJsonResponseEvent } from '../telemetry/types.js';
11
+ import { retryWithBackoff } from '../utils/retry.js';
12
+ /**
13
+ * A client dedicated to stateless, utility-focused LLM calls.
14
+ */
15
+ export class BaseLlmClient {
16
+ contentGenerator;
17
+ config;
18
+ // Default configuration for utility tasks
19
+ defaultUtilityConfig = {
20
+ temperature: 0,
21
+ topP: 1,
22
+ };
23
+ constructor(contentGenerator, config) {
24
+ this.contentGenerator = contentGenerator;
25
+ this.config = config;
26
+ }
27
+ async generateJson(options) {
28
+ const { contents, schema, model, abortSignal, systemInstruction, promptId, } = options;
29
+ const requestConfig = {
30
+ abortSignal,
31
+ ...this.defaultUtilityConfig,
32
+ ...options.config,
33
+ ...(systemInstruction && { systemInstruction }),
34
+ responseJsonSchema: schema,
35
+ responseMimeType: 'application/json',
36
+ };
37
+ try {
38
+ const apiCall = () => this.contentGenerator.generateContent({
39
+ model,
40
+ config: requestConfig,
41
+ contents,
42
+ }, promptId);
43
+ const result = await retryWithBackoff(apiCall);
44
+ let text = getResponseText(result)?.trim();
45
+ if (!text) {
46
+ const error = new Error('API returned an empty response for generateJson.');
47
+ await reportError(error, 'Error in generateJson: API returned an empty response.', contents, 'generateJson-empty-response');
48
+ throw error;
49
+ }
50
+ text = this.cleanJsonResponse(text, model);
51
+ try {
52
+ return JSON.parse(text);
53
+ }
54
+ catch (parseError) {
55
+ const error = new Error(`Failed to parse API response as JSON: ${getErrorMessage(parseError)}`);
56
+ await reportError(parseError, 'Failed to parse JSON response from generateJson.', {
57
+ responseTextFailedToParse: text,
58
+ originalRequestContents: contents,
59
+ }, 'generateJson-parse');
60
+ throw error;
61
+ }
62
+ }
63
+ catch (error) {
64
+ if (abortSignal.aborted) {
65
+ throw error;
66
+ }
67
+ if (error instanceof Error &&
68
+ (error.message === 'API returned an empty response for generateJson.' ||
69
+ error.message.startsWith('Failed to parse API response as JSON:'))) {
70
+ // We perform this check so that we don't report these again.
71
+ }
72
+ else {
73
+ await reportError(error, 'Error generating JSON content via API.', contents, 'generateJson-api');
74
+ }
75
+ throw new Error(`Failed to generate JSON content: ${getErrorMessage(error)}`);
76
+ }
77
+ }
78
+ async generateEmbedding(texts) {
79
+ if (!texts || texts.length === 0) {
80
+ return [];
81
+ }
82
+ const embedModelParams = {
83
+ model: this.config.getEmbeddingModel(),
84
+ contents: texts,
85
+ };
86
+ const embedContentResponse = await this.contentGenerator.embedContent(embedModelParams);
87
+ if (!embedContentResponse.embeddings ||
88
+ embedContentResponse.embeddings.length === 0) {
89
+ throw new Error('No embeddings found in API response.');
90
+ }
91
+ if (embedContentResponse.embeddings.length !== texts.length) {
92
+ throw new Error(`API returned a mismatched number of embeddings. Expected ${texts.length}, got ${embedContentResponse.embeddings.length}.`);
93
+ }
94
+ return embedContentResponse.embeddings.map((embedding, index) => {
95
+ const values = embedding.values;
96
+ if (!values || values.length === 0) {
97
+ throw new Error(`API returned an empty embedding for input text at index ${index}: "${texts[index]}"`);
98
+ }
99
+ return values;
100
+ });
101
+ }
102
+ cleanJsonResponse(text, model) {
103
+ const prefix = '```json';
104
+ const suffix = '```';
105
+ if (text.startsWith(prefix) && text.endsWith(suffix)) {
106
+ logMalformedJsonResponse(this.config, new MalformedJsonResponseEvent(model));
107
+ return text.substring(prefix.length, text.length - suffix.length).trim();
108
+ }
109
+ return text;
110
+ }
111
+ }
112
+ //# sourceMappingURL=baseLlmClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseLlmClient.js","sourceRoot":"","sources":["../../../src/core/baseLlmClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
@@ -0,0 +1,253 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
7
+ import { BaseLlmClient } from './baseLlmClient.js';
8
+ import { AuthType } from './contentGenerator.js';
9
+ import { reportError } from '../utils/errorReporting.js';
10
+ import { logMalformedJsonResponse } from '../telemetry/loggers.js';
11
+ import { retryWithBackoff } from '../utils/retry.js';
12
+ import { MalformedJsonResponseEvent } from '../telemetry/types.js';
13
+ import { getErrorMessage } from '../utils/errors.js';
14
+ vi.mock('../utils/errorReporting.js');
15
+ vi.mock('../telemetry/loggers.js');
16
+ vi.mock('../utils/errors.js', async (importOriginal) => {
17
+ const actual = await importOriginal();
18
+ return {
19
+ ...actual,
20
+ getErrorMessage: vi.fn((e) => (e instanceof Error ? e.message : String(e))),
21
+ };
22
+ });
23
+ vi.mock('../utils/retry.js', () => ({
24
+ retryWithBackoff: vi.fn(async (fn) => await fn()),
25
+ }));
26
+ const mockGenerateContent = vi.fn();
27
+ const mockEmbedContent = vi.fn();
28
+ const mockContentGenerator = {
29
+ generateContent: mockGenerateContent,
30
+ embedContent: mockEmbedContent,
31
+ };
32
+ const mockConfig = {
33
+ getSessionId: vi.fn().mockReturnValue('test-session-id'),
34
+ getContentGeneratorConfig: vi
35
+ .fn()
36
+ .mockReturnValue({ authType: AuthType.USE_GEMINI }),
37
+ getEmbeddingModel: vi.fn().mockReturnValue('test-embedding-model'),
38
+ };
39
+ // Helper to create a mock GenerateContentResponse
40
+ const createMockResponse = (text) => ({
41
+ candidates: [{ content: { role: 'model', parts: [{ text }] }, index: 0 }],
42
+ });
43
+ describe('BaseLlmClient', () => {
44
+ let client;
45
+ let abortController;
46
+ let defaultOptions;
47
+ beforeEach(() => {
48
+ vi.clearAllMocks();
49
+ // Reset the mocked implementation for getErrorMessage for accurate error message assertions
50
+ vi.mocked(getErrorMessage).mockImplementation((e) => e instanceof Error ? e.message : String(e));
51
+ client = new BaseLlmClient(mockContentGenerator, mockConfig);
52
+ abortController = new AbortController();
53
+ defaultOptions = {
54
+ contents: [{ role: 'user', parts: [{ text: 'Give me a color.' }] }],
55
+ schema: { type: 'object', properties: { color: { type: 'string' } } },
56
+ model: 'test-model',
57
+ abortSignal: abortController.signal,
58
+ promptId: 'test-prompt-id',
59
+ };
60
+ });
61
+ afterEach(() => {
62
+ abortController.abort();
63
+ });
64
+ describe('generateJson - Success Scenarios', () => {
65
+ it('should call generateContent with correct parameters, defaults, and utilize retry mechanism', async () => {
66
+ const mockResponse = createMockResponse('{"color": "blue"}');
67
+ mockGenerateContent.mockResolvedValue(mockResponse);
68
+ const result = await client.generateJson(defaultOptions);
69
+ expect(result).toEqual({ color: 'blue' });
70
+ // Ensure the retry mechanism was engaged
71
+ expect(retryWithBackoff).toHaveBeenCalledTimes(1);
72
+ // Validate the parameters passed to the underlying generator
73
+ expect(mockGenerateContent).toHaveBeenCalledTimes(1);
74
+ expect(mockGenerateContent).toHaveBeenCalledWith({
75
+ model: 'test-model',
76
+ contents: defaultOptions.contents,
77
+ config: {
78
+ abortSignal: defaultOptions.abortSignal,
79
+ temperature: 0,
80
+ topP: 1,
81
+ responseJsonSchema: defaultOptions.schema,
82
+ responseMimeType: 'application/json',
83
+ // Crucial: systemInstruction should NOT be in the config object if not provided
84
+ },
85
+ }, 'test-prompt-id');
86
+ });
87
+ it('should respect configuration overrides', async () => {
88
+ const mockResponse = createMockResponse('{"color": "red"}');
89
+ mockGenerateContent.mockResolvedValue(mockResponse);
90
+ const options = {
91
+ ...defaultOptions,
92
+ config: { temperature: 0.8, topK: 10 },
93
+ };
94
+ await client.generateJson(options);
95
+ expect(mockGenerateContent).toHaveBeenCalledWith(expect.objectContaining({
96
+ config: expect.objectContaining({
97
+ temperature: 0.8,
98
+ topP: 1, // Default should remain if not overridden
99
+ topK: 10,
100
+ }),
101
+ }), expect.any(String));
102
+ });
103
+ it('should include system instructions when provided', async () => {
104
+ const mockResponse = createMockResponse('{"color": "green"}');
105
+ mockGenerateContent.mockResolvedValue(mockResponse);
106
+ const systemInstruction = 'You are a helpful assistant.';
107
+ const options = {
108
+ ...defaultOptions,
109
+ systemInstruction,
110
+ };
111
+ await client.generateJson(options);
112
+ expect(mockGenerateContent).toHaveBeenCalledWith(expect.objectContaining({
113
+ config: expect.objectContaining({
114
+ systemInstruction,
115
+ }),
116
+ }), expect.any(String));
117
+ });
118
+ it('should use the provided promptId', async () => {
119
+ const mockResponse = createMockResponse('{"color": "yellow"}');
120
+ mockGenerateContent.mockResolvedValue(mockResponse);
121
+ const customPromptId = 'custom-id-123';
122
+ const options = {
123
+ ...defaultOptions,
124
+ promptId: customPromptId,
125
+ };
126
+ await client.generateJson(options);
127
+ expect(mockGenerateContent).toHaveBeenCalledWith(expect.any(Object), customPromptId);
128
+ });
129
+ });
130
+ describe('generateJson - Response Cleaning', () => {
131
+ it('should clean JSON wrapped in markdown backticks and log telemetry', async () => {
132
+ const malformedResponse = '```json\n{"color": "purple"}\n```';
133
+ mockGenerateContent.mockResolvedValue(createMockResponse(malformedResponse));
134
+ const result = await client.generateJson(defaultOptions);
135
+ expect(result).toEqual({ color: 'purple' });
136
+ expect(logMalformedJsonResponse).toHaveBeenCalledTimes(1);
137
+ expect(logMalformedJsonResponse).toHaveBeenCalledWith(mockConfig, expect.any(MalformedJsonResponseEvent));
138
+ // Validate the telemetry event content
139
+ const event = vi.mocked(logMalformedJsonResponse).mock
140
+ .calls[0][1];
141
+ expect(event.model).toBe('test-model');
142
+ });
143
+ it('should handle extra whitespace correctly without logging malformed telemetry', async () => {
144
+ const responseWithWhitespace = ' \n {"color": "orange"} \n';
145
+ mockGenerateContent.mockResolvedValue(createMockResponse(responseWithWhitespace));
146
+ const result = await client.generateJson(defaultOptions);
147
+ expect(result).toEqual({ color: 'orange' });
148
+ expect(logMalformedJsonResponse).not.toHaveBeenCalled();
149
+ });
150
+ });
151
+ describe('generateJson - Error Handling', () => {
152
+ it('should throw and report error for empty response', async () => {
153
+ mockGenerateContent.mockResolvedValue(createMockResponse(''));
154
+ // The final error message includes the prefix added by the client's outer catch block.
155
+ await expect(client.generateJson(defaultOptions)).rejects.toThrow('Failed to generate JSON content: API returned an empty response for generateJson.');
156
+ // Verify error reporting details
157
+ expect(reportError).toHaveBeenCalledTimes(1);
158
+ expect(reportError).toHaveBeenCalledWith(expect.any(Error), 'Error in generateJson: API returned an empty response.', defaultOptions.contents, 'generateJson-empty-response');
159
+ });
160
+ it('should throw and report error for invalid JSON syntax', async () => {
161
+ const invalidJson = '{"color": "blue"'; // missing closing brace
162
+ mockGenerateContent.mockResolvedValue(createMockResponse(invalidJson));
163
+ await expect(client.generateJson(defaultOptions)).rejects.toThrow(/^Failed to generate JSON content: Failed to parse API response as JSON:/);
164
+ expect(reportError).toHaveBeenCalledTimes(1);
165
+ expect(reportError).toHaveBeenCalledWith(expect.any(Error), 'Failed to parse JSON response from generateJson.', expect.objectContaining({ responseTextFailedToParse: invalidJson }), 'generateJson-parse');
166
+ });
167
+ it('should throw and report generic API errors', async () => {
168
+ const apiError = new Error('Service Unavailable (503)');
169
+ // Simulate the generator failing
170
+ mockGenerateContent.mockRejectedValue(apiError);
171
+ await expect(client.generateJson(defaultOptions)).rejects.toThrow('Failed to generate JSON content: Service Unavailable (503)');
172
+ // Verify generic error reporting
173
+ expect(reportError).toHaveBeenCalledTimes(1);
174
+ expect(reportError).toHaveBeenCalledWith(apiError, 'Error generating JSON content via API.', defaultOptions.contents, 'generateJson-api');
175
+ });
176
+ it('should throw immediately without reporting if aborted', async () => {
177
+ const abortError = new DOMException('Aborted', 'AbortError');
178
+ // Simulate abortion happening during the API call
179
+ mockGenerateContent.mockImplementation(() => {
180
+ abortController.abort(); // Ensure the signal is aborted when the service checks
181
+ throw abortError;
182
+ });
183
+ const options = {
184
+ ...defaultOptions,
185
+ abortSignal: abortController.signal,
186
+ };
187
+ await expect(client.generateJson(options)).rejects.toThrow(abortError);
188
+ // Crucially, it should not report a cancellation as an application error
189
+ expect(reportError).not.toHaveBeenCalled();
190
+ });
191
+ });
192
+ describe('generateEmbedding', () => {
193
+ const texts = ['hello world', 'goodbye world'];
194
+ const testEmbeddingModel = 'test-embedding-model';
195
+ it('should call embedContent with correct parameters and return embeddings', async () => {
196
+ const mockEmbeddings = [
197
+ [0.1, 0.2, 0.3],
198
+ [0.4, 0.5, 0.6],
199
+ ];
200
+ mockEmbedContent.mockResolvedValue({
201
+ embeddings: [
202
+ { values: mockEmbeddings[0] },
203
+ { values: mockEmbeddings[1] },
204
+ ],
205
+ });
206
+ const result = await client.generateEmbedding(texts);
207
+ expect(mockEmbedContent).toHaveBeenCalledTimes(1);
208
+ expect(mockEmbedContent).toHaveBeenCalledWith({
209
+ model: testEmbeddingModel,
210
+ contents: texts,
211
+ });
212
+ expect(result).toEqual(mockEmbeddings);
213
+ });
214
+ it('should return an empty array if an empty array is passed', async () => {
215
+ const result = await client.generateEmbedding([]);
216
+ expect(result).toEqual([]);
217
+ expect(mockEmbedContent).not.toHaveBeenCalled();
218
+ });
219
+ it('should throw an error if API response has no embeddings array', async () => {
220
+ mockEmbedContent.mockResolvedValue({});
221
+ await expect(client.generateEmbedding(texts)).rejects.toThrow('No embeddings found in API response.');
222
+ });
223
+ it('should throw an error if API response has an empty embeddings array', async () => {
224
+ mockEmbedContent.mockResolvedValue({
225
+ embeddings: [],
226
+ });
227
+ await expect(client.generateEmbedding(texts)).rejects.toThrow('No embeddings found in API response.');
228
+ });
229
+ it('should throw an error if API returns a mismatched number of embeddings', async () => {
230
+ mockEmbedContent.mockResolvedValue({
231
+ embeddings: [{ values: [1, 2, 3] }], // Only one for two texts
232
+ });
233
+ await expect(client.generateEmbedding(texts)).rejects.toThrow('API returned a mismatched number of embeddings. Expected 2, got 1.');
234
+ });
235
+ it('should throw an error if any embedding has nullish values', async () => {
236
+ mockEmbedContent.mockResolvedValue({
237
+ embeddings: [{ values: [1, 2, 3] }, { values: undefined }], // Second one is bad
238
+ });
239
+ await expect(client.generateEmbedding(texts)).rejects.toThrow('API returned an empty embedding for input text at index 1: "goodbye world"');
240
+ });
241
+ it('should throw an error if any embedding has an empty values array', async () => {
242
+ mockEmbedContent.mockResolvedValue({
243
+ embeddings: [{ values: [] }, { values: [1, 2, 3] }], // First one is bad
244
+ });
245
+ await expect(client.generateEmbedding(texts)).rejects.toThrow('API returned an empty embedding for input text at index 0: "hello world"');
246
+ });
247
+ it('should propagate errors from the API call', async () => {
248
+ mockEmbedContent.mockRejectedValue(new Error('API Failure'));
249
+ await expect(client.generateEmbedding(texts)).rejects.toThrow('API Failure');
250
+ });
251
+ });
252
+ });
253
+ //# sourceMappingURL=baseLlmClient.test.js.map