@office-ai/aioncli-core 0.1.21 → 0.2.2

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 (349) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +3 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/code_assist/converter.d.ts +3 -2
  5. package/dist/src/code_assist/converter.js +1 -0
  6. package/dist/src/code_assist/converter.js.map +1 -1
  7. package/dist/src/code_assist/oauth2.d.ts +2 -0
  8. package/dist/src/code_assist/oauth2.js +47 -25
  9. package/dist/src/code_assist/oauth2.js.map +1 -1
  10. package/dist/src/code_assist/oauth2.test.js +99 -8
  11. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  12. package/dist/src/code_assist/server.js +1 -1
  13. package/dist/src/code_assist/server.js.map +1 -1
  14. package/dist/src/code_assist/setup.js +48 -17
  15. package/dist/src/code_assist/setup.js.map +1 -1
  16. package/dist/src/code_assist/setup.test.js +114 -8
  17. package/dist/src/code_assist/setup.test.js.map +1 -1
  18. package/dist/src/config/config.d.ts +27 -8
  19. package/dist/src/config/config.js +54 -25
  20. package/dist/src/config/config.js.map +1 -1
  21. package/dist/src/config/config.test.js +109 -1
  22. package/dist/src/config/config.test.js.map +1 -1
  23. package/dist/src/core/client.d.ts +13 -15
  24. package/dist/src/core/client.js +215 -54
  25. package/dist/src/core/client.js.map +1 -1
  26. package/dist/src/core/client.test.js +631 -36
  27. package/dist/src/core/client.test.js.map +1 -1
  28. package/dist/src/core/contentGenerator.js +20 -12
  29. package/dist/src/core/contentGenerator.js.map +1 -1
  30. package/dist/src/core/contentGenerator.test.js +39 -15
  31. package/dist/src/core/contentGenerator.test.js.map +1 -1
  32. package/dist/src/core/coreToolScheduler.d.ts +2 -1
  33. package/dist/src/core/coreToolScheduler.js +26 -4
  34. package/dist/src/core/coreToolScheduler.js.map +1 -1
  35. package/dist/src/core/coreToolScheduler.test.js +230 -71
  36. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  37. package/dist/src/core/geminiChat.js +1 -1
  38. package/dist/src/core/geminiChat.js.map +1 -1
  39. package/dist/src/core/logger.d.ts +22 -1
  40. package/dist/src/core/logger.js +103 -17
  41. package/dist/src/core/logger.js.map +1 -1
  42. package/dist/src/core/logger.test.js +86 -20
  43. package/dist/src/core/logger.test.js.map +1 -1
  44. package/dist/src/core/loggingContentGenerator.d.ts +1 -0
  45. package/dist/src/core/loggingContentGenerator.js +7 -1
  46. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  47. package/dist/src/core/nonInteractiveToolExecutor.d.ts +2 -2
  48. package/dist/src/core/nonInteractiveToolExecutor.js +11 -3
  49. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  50. package/dist/src/core/nonInteractiveToolExecutor.test.js +95 -46
  51. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  52. package/dist/src/core/openaiContentGenerator.js +71 -25
  53. package/dist/src/core/openaiContentGenerator.js.map +1 -1
  54. package/dist/src/core/openaiContentGenerator.test.js +1 -1
  55. package/dist/src/core/openaiContentGenerator.test.js.map +1 -1
  56. package/dist/src/core/prompts.js +4 -4
  57. package/dist/src/core/prompts.js.map +1 -1
  58. package/dist/src/core/subagent.js +5 -5
  59. package/dist/src/core/subagent.js.map +1 -1
  60. package/dist/src/core/subagent.test.js +3 -3
  61. package/dist/src/core/subagent.test.js.map +1 -1
  62. package/dist/src/generated/git-commit.d.ts +7 -0
  63. package/dist/src/generated/git-commit.js +10 -0
  64. package/dist/src/generated/git-commit.js.map +1 -0
  65. package/dist/src/ide/constants.d.ts +6 -0
  66. package/dist/src/ide/constants.js +7 -0
  67. package/dist/src/ide/constants.js.map +1 -0
  68. package/dist/src/ide/detect-ide.d.ts +12 -2
  69. package/dist/src/ide/detect-ide.js +64 -5
  70. package/dist/src/ide/detect-ide.js.map +1 -1
  71. package/dist/src/ide/detect-ide.test.d.ts +6 -0
  72. package/dist/src/ide/detect-ide.test.js +65 -0
  73. package/dist/src/ide/detect-ide.test.js.map +1 -0
  74. package/dist/src/ide/ide-client.d.ts +9 -1
  75. package/dist/src/ide/ide-client.js +113 -30
  76. package/dist/src/ide/ide-client.js.map +1 -1
  77. package/dist/src/ide/ide-client.test.d.ts +6 -0
  78. package/dist/src/ide/ide-client.test.js +43 -0
  79. package/dist/src/ide/ide-client.test.js.map +1 -0
  80. package/dist/src/ide/ide-installer.js +23 -34
  81. package/dist/src/ide/ide-installer.js.map +1 -1
  82. package/dist/src/ide/ide-installer.test.js +6 -8
  83. package/dist/src/ide/ide-installer.test.js.map +1 -1
  84. package/dist/src/ide/ideContext.d.ts +6 -6
  85. package/dist/src/ide/process-utils.d.ts +19 -0
  86. package/dist/src/ide/process-utils.js +140 -0
  87. package/dist/src/ide/process-utils.js.map +1 -0
  88. package/dist/src/index.d.ts +6 -1
  89. package/dist/src/index.js +6 -1
  90. package/dist/src/index.js.map +1 -1
  91. package/dist/src/mcp/google-auth-provider.js +9 -0
  92. package/dist/src/mcp/google-auth-provider.js.map +1 -1
  93. package/dist/src/mcp/google-auth-provider.test.js +45 -10
  94. package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
  95. package/dist/src/mcp/oauth-provider.d.ts +0 -1
  96. package/dist/src/mcp/oauth-provider.js +176 -59
  97. package/dist/src/mcp/oauth-provider.js.map +1 -1
  98. package/dist/src/mcp/oauth-provider.test.js +132 -62
  99. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  100. package/dist/src/mcp/oauth-utils.d.ts +3 -1
  101. package/dist/src/mcp/oauth-utils.js +50 -12
  102. package/dist/src/mcp/oauth-utils.js.map +1 -1
  103. package/dist/src/mcp/oauth-utils.test.js +17 -2
  104. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  105. package/dist/src/mocks/msw.d.ts +6 -0
  106. package/dist/src/mocks/msw.js +8 -0
  107. package/dist/src/mocks/msw.js.map +1 -0
  108. package/dist/src/services/chatRecordingService.d.ts +150 -0
  109. package/dist/src/services/chatRecordingService.js +318 -0
  110. package/dist/src/services/chatRecordingService.js.map +1 -0
  111. package/dist/src/services/chatRecordingService.test.d.ts +6 -0
  112. package/dist/src/services/chatRecordingService.test.js +288 -0
  113. package/dist/src/services/chatRecordingService.test.js.map +1 -0
  114. package/dist/src/services/fileSystemService.d.ts +31 -0
  115. package/dist/src/services/fileSystemService.js +18 -0
  116. package/dist/src/services/fileSystemService.js.map +1 -0
  117. package/dist/src/services/fileSystemService.test.d.ts +6 -0
  118. package/dist/src/services/fileSystemService.test.js +41 -0
  119. package/dist/src/services/fileSystemService.test.js.map +1 -0
  120. package/dist/src/services/loopDetectionService.js +9 -10
  121. package/dist/src/services/loopDetectionService.js.map +1 -1
  122. package/dist/src/services/loopDetectionService.test.js +52 -0
  123. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  124. package/dist/src/services/shellExecutionService.d.ts +8 -10
  125. package/dist/src/services/shellExecutionService.js +289 -133
  126. package/dist/src/services/shellExecutionService.js.map +1 -1
  127. package/dist/src/services/shellExecutionService.test.js +274 -30
  128. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  129. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +61 -17
  130. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +211 -233
  131. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  132. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +11 -0
  133. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +250 -94
  134. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  135. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +9 -2
  136. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +19 -9
  137. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  138. package/dist/src/telemetry/constants.d.ts +1 -0
  139. package/dist/src/telemetry/constants.js +1 -0
  140. package/dist/src/telemetry/constants.js.map +1 -1
  141. package/dist/src/telemetry/index.d.ts +2 -2
  142. package/dist/src/telemetry/index.js +2 -2
  143. package/dist/src/telemetry/index.js.map +1 -1
  144. package/dist/src/telemetry/integration.test.circular.js +1 -0
  145. package/dist/src/telemetry/integration.test.circular.js.map +1 -1
  146. package/dist/src/telemetry/loggers.d.ts +3 -1
  147. package/dist/src/telemetry/loggers.js +39 -6
  148. package/dist/src/telemetry/loggers.js.map +1 -1
  149. package/dist/src/telemetry/loggers.test.js +37 -7
  150. package/dist/src/telemetry/loggers.test.js.map +1 -1
  151. package/dist/src/telemetry/metrics.d.ts +5 -1
  152. package/dist/src/telemetry/metrics.js +23 -9
  153. package/dist/src/telemetry/metrics.js.map +1 -1
  154. package/dist/src/telemetry/metrics.test.js +31 -1
  155. package/dist/src/telemetry/metrics.test.js.map +1 -1
  156. package/dist/src/telemetry/sdk.d.ts +1 -1
  157. package/dist/src/telemetry/sdk.js +80 -44
  158. package/dist/src/telemetry/sdk.js.map +1 -1
  159. package/dist/src/telemetry/sdk.test.d.ts +6 -0
  160. package/dist/src/telemetry/sdk.test.js +82 -0
  161. package/dist/src/telemetry/sdk.test.js.map +1 -0
  162. package/dist/src/telemetry/telemetry.test.js +2 -2
  163. package/dist/src/telemetry/telemetry.test.js.map +1 -1
  164. package/dist/src/telemetry/types.d.ts +41 -14
  165. package/dist/src/telemetry/types.js +52 -23
  166. package/dist/src/telemetry/types.js.map +1 -1
  167. package/dist/src/telemetry/uiTelemetry.d.ts +4 -0
  168. package/dist/src/telemetry/uiTelemetry.js +14 -1
  169. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  170. package/dist/src/telemetry/uiTelemetry.test.js +45 -9
  171. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  172. package/dist/src/test-utils/config.d.ts +16 -0
  173. package/dist/src/test-utils/config.js +32 -0
  174. package/dist/src/test-utils/config.js.map +1 -0
  175. package/dist/src/test-utils/tools.d.ts +29 -8
  176. package/dist/src/test-utils/tools.js +80 -16
  177. package/dist/src/test-utils/tools.js.map +1 -1
  178. package/dist/src/tools/edit.d.ts +1 -1
  179. package/dist/src/tools/edit.js +23 -19
  180. package/dist/src/tools/edit.js.map +1 -1
  181. package/dist/src/tools/edit.test.js +11 -3
  182. package/dist/src/tools/edit.test.js.map +1 -1
  183. package/dist/src/tools/glob.d.ts +1 -1
  184. package/dist/src/tools/glob.js +15 -16
  185. package/dist/src/tools/glob.js.map +1 -1
  186. package/dist/src/tools/glob.test.js +20 -0
  187. package/dist/src/tools/glob.test.js.map +1 -1
  188. package/dist/src/tools/grep.d.ts +1 -1
  189. package/dist/src/tools/grep.js +7 -13
  190. package/dist/src/tools/grep.js.map +1 -1
  191. package/dist/src/tools/ls.d.ts +4 -23
  192. package/dist/src/tools/ls.js +77 -79
  193. package/dist/src/tools/ls.js.map +1 -1
  194. package/dist/src/tools/ls.test.js +62 -34
  195. package/dist/src/tools/ls.test.js.map +1 -1
  196. package/dist/src/tools/mcp-client-manager.d.ts +38 -0
  197. package/dist/src/tools/mcp-client-manager.js +74 -0
  198. package/dist/src/tools/mcp-client-manager.js.map +1 -0
  199. package/dist/src/tools/mcp-client-manager.test.d.ts +6 -0
  200. package/dist/src/tools/mcp-client-manager.test.js +39 -0
  201. package/dist/src/tools/mcp-client-manager.test.js.map +1 -0
  202. package/dist/src/tools/mcp-client.d.ts +43 -0
  203. package/dist/src/tools/mcp-client.js +157 -11
  204. package/dist/src/tools/mcp-client.js.map +1 -1
  205. package/dist/src/tools/mcp-client.test.js +62 -276
  206. package/dist/src/tools/mcp-client.test.js.map +1 -1
  207. package/dist/src/tools/mcp-tool.d.ts +6 -13
  208. package/dist/src/tools/mcp-tool.js +62 -34
  209. package/dist/src/tools/mcp-tool.js.map +1 -1
  210. package/dist/src/tools/mcp-tool.test.js +118 -59
  211. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  212. package/dist/src/tools/memoryTool.d.ts +9 -13
  213. package/dist/src/tools/memoryTool.js +122 -121
  214. package/dist/src/tools/memoryTool.js.map +1 -1
  215. package/dist/src/tools/memoryTool.test.js +38 -18
  216. package/dist/src/tools/memoryTool.test.js.map +1 -1
  217. package/dist/src/tools/read-file.d.ts +1 -1
  218. package/dist/src/tools/read-file.js +11 -14
  219. package/dist/src/tools/read-file.js.map +1 -1
  220. package/dist/src/tools/read-file.test.js +8 -0
  221. package/dist/src/tools/read-file.test.js.map +1 -1
  222. package/dist/src/tools/read-many-files.d.ts +3 -5
  223. package/dist/src/tools/read-many-files.js +121 -105
  224. package/dist/src/tools/read-many-files.js.map +1 -1
  225. package/dist/src/tools/read-many-files.test.js +94 -37
  226. package/dist/src/tools/read-many-files.test.js.map +1 -1
  227. package/dist/src/tools/shell.d.ts +4 -6
  228. package/dist/src/tools/shell.js +120 -124
  229. package/dist/src/tools/shell.js.map +1 -1
  230. package/dist/src/tools/shell.test.js +63 -65
  231. package/dist/src/tools/shell.test.js.map +1 -1
  232. package/dist/src/tools/tool-error.d.ts +1 -0
  233. package/dist/src/tools/tool-error.js +1 -0
  234. package/dist/src/tools/tool-error.js.map +1 -1
  235. package/dist/src/tools/tool-registry.d.ts +14 -18
  236. package/dist/src/tools/tool-registry.js +73 -106
  237. package/dist/src/tools/tool-registry.js.map +1 -1
  238. package/dist/src/tools/tool-registry.test.js +24 -192
  239. package/dist/src/tools/tool-registry.test.js.map +1 -1
  240. package/dist/src/tools/tools.d.ts +33 -89
  241. package/dist/src/tools/tools.js +76 -119
  242. package/dist/src/tools/tools.js.map +1 -1
  243. package/dist/src/tools/tools.test.js +91 -2
  244. package/dist/src/tools/tools.test.js.map +1 -1
  245. package/dist/src/tools/web-fetch.d.ts +4 -7
  246. package/dist/src/tools/web-fetch.js +58 -64
  247. package/dist/src/tools/web-fetch.js.map +1 -1
  248. package/dist/src/tools/web-fetch.test.js +8 -4
  249. package/dist/src/tools/web-fetch.test.js.map +1 -1
  250. package/dist/src/tools/web-search.d.ts +4 -5
  251. package/dist/src/tools/web-search.js +47 -51
  252. package/dist/src/tools/web-search.js.map +1 -1
  253. package/dist/src/tools/web-search.test.d.ts +6 -0
  254. package/dist/src/tools/web-search.test.js +139 -0
  255. package/dist/src/tools/web-search.test.js.map +1 -0
  256. package/dist/src/tools/write-file.d.ts +15 -10
  257. package/dist/src/tools/write-file.js +134 -145
  258. package/dist/src/tools/write-file.js.map +1 -1
  259. package/dist/src/tools/write-file.test.js +82 -127
  260. package/dist/src/tools/write-file.test.js.map +1 -1
  261. package/dist/src/utils/browser.js +4 -3
  262. package/dist/src/utils/browser.js.map +1 -1
  263. package/dist/src/utils/editCorrector.js +21 -22
  264. package/dist/src/utils/editCorrector.js.map +1 -1
  265. package/dist/src/utils/editor.js +1 -1
  266. package/dist/src/utils/editor.js.map +1 -1
  267. package/dist/src/utils/editor.test.js +10 -10
  268. package/dist/src/utils/editor.test.js.map +1 -1
  269. package/dist/src/utils/environmentContext.js +2 -2
  270. package/dist/src/utils/environmentContext.js.map +1 -1
  271. package/dist/src/utils/environmentContext.test.js +3 -2
  272. package/dist/src/utils/environmentContext.test.js.map +1 -1
  273. package/dist/src/utils/errorParsing.d.ts +8 -0
  274. package/dist/src/utils/errorParsing.js +93 -0
  275. package/dist/src/utils/errorParsing.js.map +1 -0
  276. package/dist/src/utils/errorParsing.test.d.ts +6 -0
  277. package/dist/src/utils/errorParsing.test.js +172 -0
  278. package/dist/src/utils/errorParsing.test.js.map +1 -0
  279. package/dist/src/utils/fileUtils.d.ts +2 -1
  280. package/dist/src/utils/fileUtils.js +3 -3
  281. package/dist/src/utils/fileUtils.js.map +1 -1
  282. package/dist/src/utils/fileUtils.test.js +18 -17
  283. package/dist/src/utils/fileUtils.test.js.map +1 -1
  284. package/dist/src/utils/filesearch/crawler.d.ts +15 -0
  285. package/dist/src/utils/filesearch/crawler.js +50 -0
  286. package/dist/src/utils/filesearch/crawler.js.map +1 -0
  287. package/dist/src/utils/filesearch/crawler.test.d.ts +6 -0
  288. package/dist/src/utils/filesearch/crawler.test.js +468 -0
  289. package/dist/src/utils/filesearch/crawler.test.js.map +1 -0
  290. package/dist/src/utils/filesearch/fileSearch.d.ts +9 -53
  291. package/dist/src/utils/filesearch/fileSearch.js +63 -118
  292. package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
  293. package/dist/src/utils/filesearch/fileSearch.test.js +95 -197
  294. package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -1
  295. package/dist/src/utils/filesearch/ignore.d.ts +7 -0
  296. package/dist/src/utils/filesearch/ignore.js +25 -0
  297. package/dist/src/utils/filesearch/ignore.js.map +1 -1
  298. package/dist/src/utils/filesearch/ignore.test.js +89 -2
  299. package/dist/src/utils/filesearch/ignore.test.js.map +1 -1
  300. package/dist/src/utils/filesearch/result-cache.d.ts +1 -2
  301. package/dist/src/utils/filesearch/result-cache.js +1 -3
  302. package/dist/src/utils/filesearch/result-cache.js.map +1 -1
  303. package/dist/src/utils/filesearch/result-cache.test.js +3 -4
  304. package/dist/src/utils/filesearch/result-cache.test.js.map +1 -1
  305. package/dist/src/utils/getPty.d.ts +19 -0
  306. package/dist/src/utils/getPty.js +23 -0
  307. package/dist/src/utils/getPty.js.map +1 -0
  308. package/dist/src/utils/memoryDiscovery.js +3 -3
  309. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  310. package/dist/src/utils/memoryDiscovery.test.js +3 -2
  311. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  312. package/dist/src/utils/memoryImportProcessor.js +3 -7
  313. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  314. package/dist/src/utils/memoryImportProcessor.test.js +17 -20
  315. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  316. package/dist/src/utils/nextSpeakerChecker.js +3 -4
  317. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  318. package/dist/src/utils/paths.d.ts +7 -0
  319. package/dist/src/utils/paths.js +15 -0
  320. package/dist/src/utils/paths.js.map +1 -1
  321. package/dist/src/utils/paths.test.js +74 -2
  322. package/dist/src/utils/paths.test.js.map +1 -1
  323. package/dist/src/utils/quotaErrorDetection.d.ts +1 -5
  324. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  325. package/dist/src/utils/schemaValidator.d.ts +1 -8
  326. package/dist/src/utils/schemaValidator.js +1 -32
  327. package/dist/src/utils/schemaValidator.js.map +1 -1
  328. package/dist/src/utils/secure-browser-launcher.js +4 -3
  329. package/dist/src/utils/secure-browser-launcher.js.map +1 -1
  330. package/dist/src/utils/shell-utils.d.ts +39 -0
  331. package/dist/src/utils/shell-utils.js +72 -2
  332. package/dist/src/utils/shell-utils.js.map +1 -1
  333. package/dist/src/utils/shell-utils.test.js +132 -4
  334. package/dist/src/utils/shell-utils.test.js.map +1 -1
  335. package/dist/src/utils/systemEncoding.js +1 -1
  336. package/dist/src/utils/systemEncoding.js.map +1 -1
  337. package/dist/src/utils/systemEncoding.test.js +23 -23
  338. package/dist/src/utils/systemEncoding.test.js.map +1 -1
  339. package/dist/src/utils/user_account.js +58 -48
  340. package/dist/src/utils/user_account.js.map +1 -1
  341. package/dist/src/utils/user_account.test.js +76 -9
  342. package/dist/src/utils/user_account.test.js.map +1 -1
  343. package/dist/src/utils/workspaceContext.d.ts +22 -7
  344. package/dist/src/utils/workspaceContext.js +81 -55
  345. package/dist/src/utils/workspaceContext.js.map +1 -1
  346. package/dist/src/utils/workspaceContext.test.js +221 -137
  347. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  348. package/dist/tsconfig.tsbuildinfo +1 -1
  349. package/package.json +21 -8
@@ -3,28 +3,32 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { Buffer } from 'buffer';
7
- import * as https from 'https';
8
6
  import { HttpsProxyAgent } from 'https-proxy-agent';
9
- import { EndSessionEvent, } from '../types.js';
10
7
  import { EventMetadataKey } from './event-metadata-key.js';
11
8
  import { safeJsonStringify } from '../../utils/safeJsonStringify.js';
12
9
  import { getCachedGoogleAccount, getLifetimeGoogleAccounts, } from '../../utils/user_account.js';
13
10
  import { getInstallationId } from '../../utils/user_id.js';
14
11
  import { FixedDeque } from 'mnemonist';
15
- const start_session_event_name = 'start_session';
16
- const new_prompt_event_name = 'new_prompt';
17
- const tool_call_event_name = 'tool_call';
18
- const api_request_event_name = 'api_request';
19
- const api_response_event_name = 'api_response';
20
- const api_error_event_name = 'api_error';
21
- const end_session_event_name = 'end_session';
22
- const flash_fallback_event_name = 'flash_fallback';
23
- const loop_detected_event_name = 'loop_detected';
24
- const next_speaker_check_event_name = 'next_speaker_check';
25
- const slash_command_event_name = 'slash_command';
26
- const malformed_json_response_event_name = 'malformed_json_response';
27
- const ide_connection_event_name = 'ide_connection';
12
+ import { GIT_COMMIT_INFO, CLI_VERSION } from '../../generated/git-commit.js';
13
+ import { DetectedIde, detectIde } from '../../ide/detect-ide.js';
14
+ export var EventNames;
15
+ (function (EventNames) {
16
+ EventNames["START_SESSION"] = "start_session";
17
+ EventNames["NEW_PROMPT"] = "new_prompt";
18
+ EventNames["TOOL_CALL"] = "tool_call";
19
+ EventNames["API_REQUEST"] = "api_request";
20
+ EventNames["API_RESPONSE"] = "api_response";
21
+ EventNames["API_ERROR"] = "api_error";
22
+ EventNames["END_SESSION"] = "end_session";
23
+ EventNames["FLASH_FALLBACK"] = "flash_fallback";
24
+ EventNames["LOOP_DETECTED"] = "loop_detected";
25
+ EventNames["NEXT_SPEAKER_CHECK"] = "next_speaker_check";
26
+ EventNames["SLASH_COMMAND"] = "slash_command";
27
+ EventNames["MALFORMED_JSON_RESPONSE"] = "malformed_json_response";
28
+ EventNames["IDE_CONNECTION"] = "ide_connection";
29
+ EventNames["KITTY_SEQUENCE_OVERFLOW"] = "kitty_sequence_overflow";
30
+ EventNames["CHAT_COMPRESSION"] = "chat_compression";
31
+ })(EventNames || (EventNames = {}));
28
32
  /**
29
33
  * Determine the surface that the user is currently using. Surface is effectively the
30
34
  * distribution channel in which the user is using Gemini CLI. Gemini CLI comes bundled
@@ -35,31 +39,66 @@ const ide_connection_event_name = 'ide_connection';
35
39
  * methods might have in their runtimes.
36
40
  */
37
41
  function determineSurface() {
38
- if (process.env.CLOUD_SHELL === 'true') {
39
- return 'CLOUD_SHELL';
42
+ if (process.env['SURFACE']) {
43
+ return process.env['SURFACE'];
40
44
  }
41
- else if (process.env.MONOSPACE_ENV === 'true') {
42
- return 'FIREBASE_STUDIO';
45
+ else if (process.env['GITHUB_SHA']) {
46
+ return 'GitHub';
47
+ }
48
+ else if (process.env['TERM_PROGRAM'] === 'vscode') {
49
+ return detectIde() || DetectedIde.VSCode;
43
50
  }
44
51
  else {
45
- return process.env.SURFACE || 'SURFACE_NOT_SET';
52
+ return 'SURFACE_NOT_SET';
46
53
  }
47
54
  }
55
+ /**
56
+ * Clearcut URL to send logging events to.
57
+ */
58
+ const CLEARCUT_URL = 'https://play.googleapis.com/log?format=json&hasfast=true';
59
+ /**
60
+ * Interval in which buffered events are sent to clearcut.
61
+ */
62
+ const FLUSH_INTERVAL_MS = 1000 * 60;
63
+ /**
64
+ * Maximum amount of events to keep in memory. Events added after this amount
65
+ * are dropped until the next flush to clearcut, which happens periodically as
66
+ * defined by {@link FLUSH_INTERVAL_MS}.
67
+ */
68
+ const MAX_EVENTS = 1000;
69
+ /**
70
+ * Maximum events to retry after a failed clearcut flush
71
+ */
72
+ const MAX_RETRY_EVENTS = 100;
48
73
  // Singleton class for batch posting log events to Clearcut. When a new event comes in, the elapsed time
49
74
  // is checked and events are flushed to Clearcut if at least a minute has passed since the last flush.
50
75
  export class ClearcutLogger {
51
76
  static instance;
52
77
  config;
78
+ sessionData = [];
79
+ promptId = '';
80
+ /**
81
+ * Queue of pending events that need to be flushed to the server. New events
82
+ * are added to this queue and then flushed on demand (via `flushToClearcut`)
83
+ */
53
84
  events;
54
- last_flush_time = Date.now();
55
- flush_interval_ms = 1000 * 60; // Wait at least a minute before flushing events.
56
- max_events = 1000; // Maximum events to keep in memory
57
- max_retry_events = 100; // Maximum failed events to retry
58
- flushing = false; // Prevent concurrent flush operations
59
- pendingFlush = false; // Track if a flush was requested during an ongoing flush
85
+ /**
86
+ * The last time that the events were successfully flushed to the server.
87
+ */
88
+ lastFlushTime = Date.now();
89
+ /**
90
+ * the value is true when there is a pending flush happening. This prevents
91
+ * concurrent flush operations.
92
+ */
93
+ flushing = false;
94
+ /**
95
+ * This value is true when a flush was requested during an ongoing flush.
96
+ */
97
+ pendingFlush = false;
60
98
  constructor(config) {
61
99
  this.config = config;
62
- this.events = new FixedDeque(Array, this.max_events);
100
+ this.events = new FixedDeque(Array, MAX_EVENTS);
101
+ this.promptId = config?.getSessionId() ?? '';
63
102
  }
64
103
  static getInstance(config) {
65
104
  if (config === undefined || !config?.getUsageStatisticsEnabled())
@@ -77,7 +116,7 @@ export class ClearcutLogger {
77
116
  enqueueLogEvent(event) {
78
117
  try {
79
118
  // Manually handle overflow for FixedDeque, which throws when full.
80
- const wasAtCapacity = this.events.size >= this.max_events;
119
+ const wasAtCapacity = this.events.size >= MAX_EVENTS;
81
120
  if (wasAtCapacity) {
82
121
  this.events.shift(); // Evict oldest element to make space.
83
122
  }
@@ -97,17 +136,16 @@ export class ClearcutLogger {
97
136
  }
98
137
  }
99
138
  }
100
- createLogEvent(name, data) {
139
+ createLogEvent(eventName, data = []) {
101
140
  const email = getCachedGoogleAccount();
102
- const totalAccounts = getLifetimeGoogleAccounts();
103
- data.push({
104
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_GOOGLE_ACCOUNTS_COUNT,
105
- value: totalAccounts.toString(),
106
- });
141
+ if (eventName !== EventNames.START_SESSION) {
142
+ data.push(...this.sessionData);
143
+ }
144
+ data = this.addDefaultFields(data);
107
145
  const logEvent = {
108
146
  console_type: 'GEMINI_CLI',
109
- application: 102,
110
- event_name: name,
147
+ application: 102, // GEMINI_CLI
148
+ event_name: eventName,
111
149
  event_metadata: [data],
112
150
  };
113
151
  // Should log either email or install ID, not both. See go/cloudmill-1p-oss-instrumentation#define-sessionable-id
@@ -120,7 +158,7 @@ export class ClearcutLogger {
120
158
  return logEvent;
121
159
  }
122
160
  flushIfNeeded() {
123
- if (Date.now() - this.last_flush_time < this.flush_interval_ms) {
161
+ if (Date.now() - this.lastFlushTime < FLUSH_INTERVAL_MS) {
124
162
  return;
125
163
  }
126
164
  this.flushToClearcut().catch((error) => {
@@ -141,137 +179,65 @@ export class ClearcutLogger {
141
179
  }
142
180
  const eventsToSend = this.events.toArray();
143
181
  this.events.clear();
144
- return new Promise((resolve, reject) => {
145
- const request = [
146
- {
147
- log_source_name: 'CONCORD',
148
- request_time_ms: Date.now(),
149
- log_event: eventsToSend,
150
- },
151
- ];
152
- const body = safeJsonStringify(request);
153
- const options = {
154
- hostname: 'play.googleapis.com',
155
- path: '/log',
182
+ const request = [
183
+ {
184
+ log_source_name: 'CONCORD',
185
+ request_time_ms: Date.now(),
186
+ log_event: eventsToSend,
187
+ },
188
+ ];
189
+ let result = {};
190
+ try {
191
+ const response = await fetch(CLEARCUT_URL, {
156
192
  method: 'POST',
157
- headers: { 'Content-Length': Buffer.byteLength(body) },
158
- timeout: 30000, // 30-second timeout
159
- };
160
- const bufs = [];
161
- const req = https.request({
162
- ...options,
163
- agent: this.getProxyAgent(),
164
- }, (res) => {
165
- res.on('error', reject); // Handle stream errors
166
- res.on('data', (buf) => bufs.push(buf));
167
- res.on('end', () => {
168
- try {
169
- const buffer = Buffer.concat(bufs);
170
- // Check if we got a successful response
171
- if (res.statusCode &&
172
- res.statusCode >= 200 &&
173
- res.statusCode < 300) {
174
- resolve({ buffer, statusCode: res.statusCode });
175
- }
176
- else {
177
- // HTTP error - reject with status code for retry handling
178
- reject(new Error(`HTTP ${res.statusCode}: ${res.statusMessage}`));
179
- }
180
- }
181
- catch (e) {
182
- reject(e);
183
- }
184
- });
185
- });
186
- req.on('error', (e) => {
187
- // Network-level error
188
- reject(e);
189
- });
190
- req.on('timeout', () => {
191
- if (!req.destroyed) {
192
- req.destroy(new Error('Request timeout after 30 seconds'));
193
- }
193
+ body: safeJsonStringify(request),
194
+ headers: {
195
+ 'Content-Type': 'application/json',
196
+ },
194
197
  });
195
- req.end(body);
196
- })
197
- .then(({ buffer }) => {
198
- try {
199
- this.last_flush_time = Date.now();
200
- return this.decodeLogResponse(buffer) || {};
198
+ const responseBody = await response.text();
199
+ if (response.status >= 200 && response.status < 300) {
200
+ this.lastFlushTime = Date.now();
201
+ const nextRequestWaitMs = Number(JSON.parse(responseBody)[0]);
202
+ result = {
203
+ ...result,
204
+ nextRequestWaitMs,
205
+ };
201
206
  }
202
- catch (error) {
203
- console.error('Error decoding log response:', error);
204
- return {};
207
+ else {
208
+ if (this.config?.getDebugMode()) {
209
+ console.error(`Error flushing log events: HTTP ${response.status}: ${response.statusText}`);
210
+ }
211
+ // Re-queue failed events for retry
212
+ this.requeueFailedEvents(eventsToSend);
205
213
  }
206
- })
207
- .catch((error) => {
208
- // Handle both network-level and HTTP-level errors
214
+ }
215
+ catch (e) {
209
216
  if (this.config?.getDebugMode()) {
210
- console.error('Error flushing log events:', error);
217
+ console.error('Error flushing log events:', e);
211
218
  }
212
219
  // Re-queue failed events for retry
213
220
  this.requeueFailedEvents(eventsToSend);
214
- // Return empty response to maintain the Promise<LogResponse> contract
215
- return {};
216
- })
217
- .finally(() => {
218
- this.flushing = false;
219
- // If a flush was requested while we were flushing, flush again
220
- if (this.pendingFlush) {
221
- this.pendingFlush = false;
222
- // Fire and forget the pending flush
223
- this.flushToClearcut().catch((error) => {
224
- if (this.config?.getDebugMode()) {
225
- console.debug('Error in pending flush to Clearcut:', error);
226
- }
227
- });
228
- }
229
- });
230
- }
231
- // Visible for testing. Decodes protobuf-encoded response from Clearcut server.
232
- decodeLogResponse(buf) {
233
- // TODO(obrienowen): return specific errors to facilitate debugging.
234
- if (buf.length < 1) {
235
- return undefined;
236
- }
237
- // The first byte of the buffer is `field<<3 | type`. We're looking for field
238
- // 1, with type varint, represented by type=0. If the first byte isn't 8, that
239
- // means field 1 is missing or the message is corrupted. Either way, we return
240
- // undefined.
241
- if (buf.readUInt8(0) !== 8) {
242
- return undefined;
243
221
  }
244
- let ms = BigInt(0);
245
- let cont = true;
246
- // In each byte, the most significant bit is the continuation bit. If it's
247
- // set, we keep going. The lowest 7 bits, are data bits. They are concatenated
248
- // in reverse order to form the final number.
249
- for (let i = 1; cont && i < buf.length; i++) {
250
- const byte = buf.readUInt8(i);
251
- ms |= BigInt(byte & 0x7f) << BigInt(7 * (i - 1));
252
- cont = (byte & 0x80) !== 0;
253
- }
254
- if (cont) {
255
- // We have fallen off the buffer without seeing a terminating byte. The
256
- // message is corrupted.
257
- return undefined;
222
+ this.flushing = false;
223
+ // If a flush was requested while we were flushing, flush again
224
+ if (this.pendingFlush) {
225
+ this.pendingFlush = false;
226
+ // Fire and forget the pending flush
227
+ this.flushToClearcut().catch((error) => {
228
+ if (this.config?.getDebugMode()) {
229
+ console.debug('Error in pending flush to Clearcut:', error);
230
+ }
231
+ });
258
232
  }
259
- const returnVal = {
260
- nextRequestWaitMs: Number(ms),
261
- };
262
- return returnVal;
233
+ return result;
263
234
  }
264
235
  logStartSessionEvent(event) {
265
- const surface = determineSurface();
266
236
  const data = [
267
237
  {
268
238
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_START_SESSION_MODEL,
269
239
  value: event.model,
270
240
  },
271
- {
272
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
273
- value: this.config?.getSessionId() ?? '',
274
- },
275
241
  {
276
242
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_START_SESSION_EMBEDDING_MODEL,
277
243
  value: event.embedding_model,
@@ -320,37 +286,23 @@ export class ClearcutLogger {
320
286
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_START_SESSION_TELEMETRY_LOG_USER_PROMPTS_ENABLED,
321
287
  value: event.telemetry_log_user_prompts_enabled.toString(),
322
288
  },
323
- {
324
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SURFACE,
325
- value: surface,
326
- },
327
289
  ];
290
+ this.sessionData = data;
328
291
  // Flush start event immediately
329
- this.enqueueLogEvent(this.createLogEvent(start_session_event_name, data));
292
+ this.enqueueLogEvent(this.createLogEvent(EventNames.START_SESSION, data));
330
293
  this.flushToClearcut().catch((error) => {
331
294
  console.debug('Error flushing to Clearcut:', error);
332
295
  });
333
296
  }
334
297
  logNewPromptEvent(event) {
298
+ this.promptId = event.prompt_id;
335
299
  const data = [
336
300
  {
337
301
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_USER_PROMPT_LENGTH,
338
302
  value: JSON.stringify(event.prompt_length),
339
303
  },
340
- {
341
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
342
- value: this.config?.getSessionId() ?? '',
343
- },
344
- {
345
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
346
- value: JSON.stringify(event.prompt_id),
347
- },
348
- {
349
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
350
- value: JSON.stringify(event.auth_type),
351
- },
352
304
  ];
353
- this.enqueueLogEvent(this.createLogEvent(new_prompt_event_name, data));
305
+ this.enqueueLogEvent(this.createLogEvent(EventNames.NEW_PROMPT, data));
354
306
  this.flushIfNeeded();
355
307
  }
356
308
  logToolCallEvent(event) {
@@ -359,10 +311,6 @@ export class ClearcutLogger {
359
311
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_NAME,
360
312
  value: JSON.stringify(event.function_name),
361
313
  },
362
- {
363
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
364
- value: JSON.stringify(event.prompt_id),
365
- },
366
314
  {
367
315
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_DECISION,
368
316
  value: JSON.stringify(event.decision),
@@ -383,6 +331,10 @@ export class ClearcutLogger {
383
331
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_ERROR_TYPE,
384
332
  value: JSON.stringify(event.error_type),
385
333
  },
334
+ {
335
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_TYPE,
336
+ value: JSON.stringify(event.tool_type),
337
+ },
386
338
  ];
387
339
  if (event.metadata) {
388
340
  const metadataMapping = {
@@ -400,7 +352,7 @@ export class ClearcutLogger {
400
352
  }
401
353
  }
402
354
  }
403
- const logEvent = this.createLogEvent(tool_call_event_name, data);
355
+ const logEvent = this.createLogEvent(EventNames.TOOL_CALL, data);
404
356
  this.enqueueLogEvent(logEvent);
405
357
  this.flushIfNeeded();
406
358
  }
@@ -410,12 +362,8 @@ export class ClearcutLogger {
410
362
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_REQUEST_MODEL,
411
363
  value: JSON.stringify(event.model),
412
364
  },
413
- {
414
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
415
- value: JSON.stringify(event.prompt_id),
416
- },
417
365
  ];
418
- this.enqueueLogEvent(this.createLogEvent(api_request_event_name, data));
366
+ this.enqueueLogEvent(this.createLogEvent(EventNames.API_REQUEST, data));
419
367
  this.flushIfNeeded();
420
368
  }
421
369
  logApiResponseEvent(event) {
@@ -424,10 +372,6 @@ export class ClearcutLogger {
424
372
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_RESPONSE_MODEL,
425
373
  value: JSON.stringify(event.model),
426
374
  },
427
- {
428
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
429
- value: JSON.stringify(event.prompt_id),
430
- },
431
375
  {
432
376
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_RESPONSE_STATUS_CODE,
433
377
  value: JSON.stringify(event.status_code),
@@ -460,12 +404,8 @@ export class ClearcutLogger {
460
404
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_RESPONSE_TOOL_TOKEN_COUNT,
461
405
  value: JSON.stringify(event.tool_token_count),
462
406
  },
463
- {
464
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
465
- value: JSON.stringify(event.auth_type),
466
- },
467
407
  ];
468
- this.enqueueLogEvent(this.createLogEvent(api_response_event_name, data));
408
+ this.enqueueLogEvent(this.createLogEvent(EventNames.API_RESPONSE, data));
469
409
  this.flushIfNeeded();
470
410
  }
471
411
  logApiErrorEvent(event) {
@@ -474,10 +414,6 @@ export class ClearcutLogger {
474
414
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_ERROR_MODEL,
475
415
  value: JSON.stringify(event.model),
476
416
  },
477
- {
478
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
479
- value: JSON.stringify(event.prompt_id),
480
- },
481
417
  {
482
418
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_ERROR_TYPE,
483
419
  value: JSON.stringify(event.error_type),
@@ -490,50 +426,41 @@ export class ClearcutLogger {
490
426
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_ERROR_DURATION_MS,
491
427
  value: JSON.stringify(event.duration_ms),
492
428
  },
493
- {
494
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
495
- value: JSON.stringify(event.auth_type),
496
- },
497
429
  ];
498
- this.enqueueLogEvent(this.createLogEvent(api_error_event_name, data));
430
+ this.enqueueLogEvent(this.createLogEvent(EventNames.API_ERROR, data));
499
431
  this.flushIfNeeded();
500
432
  }
501
- logFlashFallbackEvent(event) {
433
+ logChatCompressionEvent(event) {
502
434
  const data = [
503
435
  {
504
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
505
- value: JSON.stringify(event.auth_type),
436
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_COMPRESSION_TOKENS_BEFORE,
437
+ value: `${event.tokens_before}`,
506
438
  },
507
439
  {
508
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
509
- value: this.config?.getSessionId() ?? '',
440
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_COMPRESSION_TOKENS_AFTER,
441
+ value: `${event.tokens_after}`,
510
442
  },
511
443
  ];
512
- this.enqueueLogEvent(this.createLogEvent(flash_fallback_event_name, data));
444
+ this.enqueueLogEvent(this.createLogEvent(EventNames.CHAT_COMPRESSION, data));
445
+ }
446
+ logFlashFallbackEvent() {
447
+ this.enqueueLogEvent(this.createLogEvent(EventNames.FLASH_FALLBACK, []));
513
448
  this.flushToClearcut().catch((error) => {
514
449
  console.debug('Error flushing to Clearcut:', error);
515
450
  });
516
451
  }
517
452
  logLoopDetectedEvent(event) {
518
453
  const data = [
519
- {
520
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
521
- value: JSON.stringify(event.prompt_id),
522
- },
523
454
  {
524
455
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_LOOP_DETECTED_TYPE,
525
456
  value: JSON.stringify(event.loop_type),
526
457
  },
527
458
  ];
528
- this.enqueueLogEvent(this.createLogEvent(loop_detected_event_name, data));
459
+ this.enqueueLogEvent(this.createLogEvent(EventNames.LOOP_DETECTED, data));
529
460
  this.flushIfNeeded();
530
461
  }
531
462
  logNextSpeakerCheck(event) {
532
463
  const data = [
533
- {
534
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
535
- value: JSON.stringify(event.prompt_id),
536
- },
537
464
  {
538
465
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_RESPONSE_FINISH_REASON,
539
466
  value: JSON.stringify(event.finish_reason),
@@ -542,12 +469,8 @@ export class ClearcutLogger {
542
469
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_NEXT_SPEAKER_CHECK_RESULT,
543
470
  value: JSON.stringify(event.result),
544
471
  },
545
- {
546
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
547
- value: this.config?.getSessionId() ?? '',
548
- },
549
472
  ];
550
- this.enqueueLogEvent(this.createLogEvent(next_speaker_check_event_name, data));
473
+ this.enqueueLogEvent(this.createLogEvent(EventNames.NEXT_SPEAKER_CHECK, data));
551
474
  this.flushIfNeeded();
552
475
  }
553
476
  logSlashCommandEvent(event) {
@@ -563,7 +486,13 @@ export class ClearcutLogger {
563
486
  value: JSON.stringify(event.subcommand),
564
487
  });
565
488
  }
566
- this.enqueueLogEvent(this.createLogEvent(slash_command_event_name, data));
489
+ if (event.status) {
490
+ data.push({
491
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_SLASH_COMMAND_STATUS,
492
+ value: JSON.stringify(event.status),
493
+ });
494
+ }
495
+ this.enqueueLogEvent(this.createLogEvent(EventNames.SLASH_COMMAND, data));
567
496
  this.flushIfNeeded();
568
497
  }
569
498
  logMalformedJsonResponseEvent(event) {
@@ -573,7 +502,7 @@ export class ClearcutLogger {
573
502
  value: JSON.stringify(event.model),
574
503
  },
575
504
  ];
576
- this.enqueueLogEvent(this.createLogEvent(malformed_json_response_event_name, data));
505
+ this.enqueueLogEvent(this.createLogEvent(EventNames.MALFORMED_JSON_RESPONSE, data));
577
506
  this.flushIfNeeded();
578
507
  }
579
508
  logIdeConnectionEvent(event) {
@@ -583,22 +512,69 @@ export class ClearcutLogger {
583
512
  value: JSON.stringify(event.connection_type),
584
513
  },
585
514
  ];
586
- this.enqueueLogEvent(this.createLogEvent(ide_connection_event_name, data));
515
+ this.enqueueLogEvent(this.createLogEvent(EventNames.IDE_CONNECTION, data));
587
516
  this.flushIfNeeded();
588
517
  }
589
- logEndSessionEvent(event) {
518
+ logKittySequenceOverflowEvent(event) {
590
519
  const data = [
591
520
  {
592
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
593
- value: event?.session_id?.toString() ?? '',
521
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_KITTY_SEQUENCE_LENGTH,
522
+ value: event.sequence_length.toString(),
523
+ },
524
+ {
525
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_KITTY_TRUNCATED_SEQUENCE,
526
+ value: event.truncated_sequence,
594
527
  },
595
528
  ];
529
+ this.enqueueLogEvent(this.createLogEvent(EventNames.KITTY_SEQUENCE_OVERFLOW, data));
530
+ this.flushIfNeeded();
531
+ }
532
+ logEndSessionEvent() {
596
533
  // Flush immediately on session end.
597
- this.enqueueLogEvent(this.createLogEvent(end_session_event_name, data));
534
+ this.enqueueLogEvent(this.createLogEvent(EventNames.END_SESSION, []));
598
535
  this.flushToClearcut().catch((error) => {
599
536
  console.debug('Error flushing to Clearcut:', error);
600
537
  });
601
538
  }
539
+ /**
540
+ * Adds default fields to data, and returns a new data array. This fields
541
+ * should exist on all log events.
542
+ */
543
+ addDefaultFields(data) {
544
+ const totalAccounts = getLifetimeGoogleAccounts();
545
+ const surface = determineSurface();
546
+ const defaultLogMetadata = [
547
+ {
548
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
549
+ value: this.config?.getSessionId() ?? '',
550
+ },
551
+ {
552
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
553
+ value: JSON.stringify(this.config?.getContentGeneratorConfig()?.authType),
554
+ },
555
+ {
556
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_GOOGLE_ACCOUNTS_COUNT,
557
+ value: `${totalAccounts}`,
558
+ },
559
+ {
560
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_SURFACE,
561
+ value: surface,
562
+ },
563
+ {
564
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_VERSION,
565
+ value: CLI_VERSION,
566
+ },
567
+ {
568
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_GIT_COMMIT_HASH,
569
+ value: GIT_COMMIT_INFO,
570
+ },
571
+ {
572
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
573
+ value: this.promptId,
574
+ },
575
+ ];
576
+ return [...data, ...defaultLogMetadata];
577
+ }
602
578
  getProxyAgent() {
603
579
  const proxyUrl = this.config?.getProxy();
604
580
  if (!proxyUrl)
@@ -613,19 +589,17 @@ export class ClearcutLogger {
613
589
  }
614
590
  }
615
591
  shutdown() {
616
- const event = new EndSessionEvent(this.config);
617
- this.logEndSessionEvent(event);
592
+ this.logEndSessionEvent();
618
593
  }
619
594
  requeueFailedEvents(eventsToSend) {
620
595
  // Add the events back to the front of the queue to be retried, but limit retry queue size
621
- const eventsToRetry = eventsToSend.slice(-this.max_retry_events); // Keep only the most recent events
596
+ const eventsToRetry = eventsToSend.slice(-MAX_RETRY_EVENTS); // Keep only the most recent events
622
597
  // Log a warning if we're dropping events
623
- if (eventsToSend.length > this.max_retry_events &&
624
- this.config?.getDebugMode()) {
625
- console.warn(`ClearcutLogger: Dropping ${eventsToSend.length - this.max_retry_events} events due to retry queue limit. Total events: ${eventsToSend.length}, keeping: ${this.max_retry_events}`);
598
+ if (eventsToSend.length > MAX_RETRY_EVENTS && this.config?.getDebugMode()) {
599
+ console.warn(`ClearcutLogger: Dropping ${eventsToSend.length - MAX_RETRY_EVENTS} events due to retry queue limit. Total events: ${eventsToSend.length}, keeping: ${MAX_RETRY_EVENTS}`);
626
600
  }
627
601
  // Determine how many events can be re-queued
628
- const availableSpace = this.max_events - this.events.size;
602
+ const availableSpace = MAX_EVENTS - this.events.size;
629
603
  const numEventsToRequeue = Math.min(eventsToRetry.length, availableSpace);
630
604
  if (numEventsToRequeue === 0) {
631
605
  if (this.config?.getDebugMode()) {
@@ -641,7 +615,7 @@ export class ClearcutLogger {
641
615
  this.events.unshift(eventsToRequeue[i]);
642
616
  }
643
617
  // Clear any potential overflow
644
- while (this.events.size > this.max_events) {
618
+ while (this.events.size > MAX_EVENTS) {
645
619
  this.events.pop();
646
620
  }
647
621
  if (this.config?.getDebugMode()) {
@@ -649,4 +623,8 @@ export class ClearcutLogger {
649
623
  }
650
624
  }
651
625
  }
626
+ export const TEST_ONLY = {
627
+ MAX_RETRY_EVENTS,
628
+ MAX_EVENTS,
629
+ };
652
630
  //# sourceMappingURL=clearcut-logger.js.map