@google/gemini-cli-core 0.34.0-preview.3 → 0.35.0-nightly.20260314.3038fdce2

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 (355) hide show
  1. package/dist/docs/changelogs/index.md +19 -0
  2. package/dist/docs/changelogs/latest.md +217 -191
  3. package/dist/docs/changelogs/preview.md +447 -184
  4. package/dist/docs/cli/model-routing.md +18 -1
  5. package/dist/docs/cli/model-steering.md +79 -0
  6. package/dist/docs/cli/plan-mode.md +99 -14
  7. package/dist/docs/cli/settings.md +14 -12
  8. package/dist/docs/cli/telemetry.md +45 -0
  9. package/dist/docs/cli/tutorials/plan-mode-steering.md +89 -0
  10. package/dist/docs/core/index.md +2 -0
  11. package/dist/docs/core/local-model-routing.md +193 -0
  12. package/dist/docs/reference/configuration.md +27 -3
  13. package/dist/docs/reference/keyboard-shortcuts.md +168 -90
  14. package/dist/docs/reference/policy-engine.md +30 -6
  15. package/dist/docs/resources/troubleshooting.md +15 -0
  16. package/dist/docs/sidebar.json +10 -0
  17. package/dist/docs/tools/shell.md +8 -0
  18. package/dist/google-gemini-cli-core-0.35.0-nightly.20260311.657f19c1f.tgz +0 -0
  19. package/dist/src/agents/a2a-client-manager.d.ts +11 -4
  20. package/dist/src/agents/a2a-client-manager.js +61 -34
  21. package/dist/src/agents/a2a-client-manager.js.map +1 -1
  22. package/dist/src/agents/a2a-client-manager.test.js +178 -115
  23. package/dist/src/agents/a2a-client-manager.test.js.map +1 -1
  24. package/dist/src/agents/a2aUtils.d.ts +4 -28
  25. package/dist/src/agents/a2aUtils.js +20 -181
  26. package/dist/src/agents/a2aUtils.js.map +1 -1
  27. package/dist/src/agents/a2aUtils.test.js +19 -106
  28. package/dist/src/agents/a2aUtils.test.js.map +1 -1
  29. package/dist/src/agents/agent-scheduler.d.ts +2 -0
  30. package/dist/src/agents/agent-scheduler.js +3 -2
  31. package/dist/src/agents/agent-scheduler.js.map +1 -1
  32. package/dist/src/agents/agent-scheduler.test.js +12 -3
  33. package/dist/src/agents/agent-scheduler.test.js.map +1 -1
  34. package/dist/src/agents/agentLoader.d.ts +2 -2
  35. package/dist/src/agents/agentLoader.js +15 -0
  36. package/dist/src/agents/agentLoader.js.map +1 -1
  37. package/dist/src/agents/auth-provider/factory.d.ts +2 -0
  38. package/dist/src/agents/auth-provider/factory.js +6 -3
  39. package/dist/src/agents/auth-provider/factory.js.map +1 -1
  40. package/dist/src/agents/auth-provider/google-credentials-provider.d.ts +26 -0
  41. package/dist/src/agents/auth-provider/google-credentials-provider.js +117 -0
  42. package/dist/src/agents/auth-provider/google-credentials-provider.js.map +1 -0
  43. package/dist/src/agents/auth-provider/google-credentials-provider.test.d.ts +6 -0
  44. package/dist/src/agents/auth-provider/google-credentials-provider.test.js +126 -0
  45. package/dist/src/agents/auth-provider/google-credentials-provider.test.js.map +1 -0
  46. package/dist/src/agents/browser/browserAgentFactory.js +11 -2
  47. package/dist/src/agents/browser/browserAgentFactory.js.map +1 -1
  48. package/dist/src/agents/browser/browserAgentInvocation.d.ts +4 -3
  49. package/dist/src/agents/browser/browserAgentInvocation.js +10 -4
  50. package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -1
  51. package/dist/src/agents/browser/browserAgentInvocation.test.js +1 -0
  52. package/dist/src/agents/browser/browserAgentInvocation.test.js.map +1 -1
  53. package/dist/src/agents/browser/browserManager.d.ts +10 -0
  54. package/dist/src/agents/browser/browserManager.js +53 -8
  55. package/dist/src/agents/browser/browserManager.js.map +1 -1
  56. package/dist/src/agents/browser/inputBlocker.d.ts +51 -0
  57. package/dist/src/agents/browser/inputBlocker.js +234 -0
  58. package/dist/src/agents/browser/inputBlocker.js.map +1 -0
  59. package/dist/src/agents/browser/inputBlocker.test.d.ts +6 -0
  60. package/dist/src/agents/browser/inputBlocker.test.js +82 -0
  61. package/dist/src/agents/browser/inputBlocker.test.js.map +1 -0
  62. package/dist/src/agents/browser/mcpToolWrapper.d.ts +3 -2
  63. package/dist/src/agents/browser/mcpToolWrapper.js +49 -8
  64. package/dist/src/agents/browser/mcpToolWrapper.js.map +1 -1
  65. package/dist/src/agents/browser/mcpToolWrapper.test.js +51 -0
  66. package/dist/src/agents/browser/mcpToolWrapper.test.js.map +1 -1
  67. package/dist/src/agents/local-executor.d.ts +5 -4
  68. package/dist/src/agents/local-executor.js +30 -25
  69. package/dist/src/agents/local-executor.js.map +1 -1
  70. package/dist/src/agents/local-executor.test.js +269 -3
  71. package/dist/src/agents/local-executor.test.js.map +1 -1
  72. package/dist/src/agents/local-invocation.d.ts +4 -4
  73. package/dist/src/agents/local-invocation.js +12 -9
  74. package/dist/src/agents/local-invocation.js.map +1 -1
  75. package/dist/src/agents/local-invocation.test.js +19 -3
  76. package/dist/src/agents/local-invocation.test.js.map +1 -1
  77. package/dist/src/agents/registry.js +3 -2
  78. package/dist/src/agents/registry.js.map +1 -1
  79. package/dist/src/agents/registry.test.js +1 -0
  80. package/dist/src/agents/registry.test.js.map +1 -1
  81. package/dist/src/agents/remote-invocation.d.ts +0 -9
  82. package/dist/src/agents/remote-invocation.js +1 -28
  83. package/dist/src/agents/remote-invocation.js.map +1 -1
  84. package/dist/src/agents/remote-invocation.test.js +1 -0
  85. package/dist/src/agents/remote-invocation.test.js.map +1 -1
  86. package/dist/src/agents/subagent-tool-wrapper.d.ts +5 -4
  87. package/dist/src/agents/subagent-tool-wrapper.js +9 -5
  88. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -1
  89. package/dist/src/agents/subagent-tool-wrapper.test.js +15 -1
  90. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
  91. package/dist/src/agents/subagent-tool.d.ts +3 -3
  92. package/dist/src/agents/subagent-tool.js +16 -12
  93. package/dist/src/agents/subagent-tool.js.map +1 -1
  94. package/dist/src/agents/subagent-tool.test.js +13 -3
  95. package/dist/src/agents/subagent-tool.test.js.map +1 -1
  96. package/dist/src/code_assist/oauth2.js +0 -1
  97. package/dist/src/code_assist/oauth2.js.map +1 -1
  98. package/dist/src/code_assist/server.js +2 -2
  99. package/dist/src/code_assist/server.js.map +1 -1
  100. package/dist/src/code_assist/server.test.js +5 -1
  101. package/dist/src/code_assist/server.test.js.map +1 -1
  102. package/dist/src/code_assist/telemetry.d.ts +2 -2
  103. package/dist/src/code_assist/telemetry.js +5 -3
  104. package/dist/src/code_assist/telemetry.js.map +1 -1
  105. package/dist/src/code_assist/telemetry.test.js +14 -12
  106. package/dist/src/code_assist/telemetry.test.js.map +1 -1
  107. package/dist/src/code_assist/types.d.ts +14 -12
  108. package/dist/src/code_assist/types.js.map +1 -1
  109. package/dist/src/config/agent-loop-context.d.ts +3 -0
  110. package/dist/src/config/config.d.ts +75 -2
  111. package/dist/src/config/config.js +78 -11
  112. package/dist/src/config/config.js.map +1 -1
  113. package/dist/src/config/config.test.js +170 -10
  114. package/dist/src/config/config.test.js.map +1 -1
  115. package/dist/src/config/models.d.ts +14 -0
  116. package/dist/src/config/models.js +37 -0
  117. package/dist/src/config/models.js.map +1 -1
  118. package/dist/src/config/models.test.js +51 -1
  119. package/dist/src/config/models.test.js.map +1 -1
  120. package/dist/src/config/storage.d.ts +1 -0
  121. package/dist/src/config/storage.js +3 -0
  122. package/dist/src/config/storage.js.map +1 -1
  123. package/dist/src/core/baseLlmClient.js +19 -3
  124. package/dist/src/core/baseLlmClient.js.map +1 -1
  125. package/dist/src/core/baseLlmClient.test.js +2 -0
  126. package/dist/src/core/baseLlmClient.test.js.map +1 -1
  127. package/dist/src/core/client.d.ts +4 -3
  128. package/dist/src/core/client.js +42 -17
  129. package/dist/src/core/client.js.map +1 -1
  130. package/dist/src/core/client.test.js +8 -0
  131. package/dist/src/core/client.test.js.map +1 -1
  132. package/dist/src/core/contentGenerator.d.ts +1 -0
  133. package/dist/src/core/contentGenerator.js +35 -3
  134. package/dist/src/core/contentGenerator.js.map +1 -1
  135. package/dist/src/core/contentGenerator.test.js +137 -2
  136. package/dist/src/core/contentGenerator.test.js.map +1 -1
  137. package/dist/src/core/coreToolHookTriggers.d.ts +2 -3
  138. package/dist/src/core/coreToolHookTriggers.js +5 -11
  139. package/dist/src/core/coreToolHookTriggers.js.map +1 -1
  140. package/dist/src/core/coreToolHookTriggers.test.js +24 -0
  141. package/dist/src/core/coreToolHookTriggers.test.js.map +1 -1
  142. package/dist/src/core/coreToolScheduler.js +1 -1
  143. package/dist/src/core/coreToolScheduler.js.map +1 -1
  144. package/dist/src/core/geminiChat.js +31 -21
  145. package/dist/src/core/geminiChat.js.map +1 -1
  146. package/dist/src/core/geminiChat.test.js +6 -4
  147. package/dist/src/core/geminiChat.test.js.map +1 -1
  148. package/dist/src/core/geminiChat_network_retry.test.js +21 -11
  149. package/dist/src/core/geminiChat_network_retry.test.js.map +1 -1
  150. package/dist/src/fallback/handler.js +0 -4
  151. package/dist/src/fallback/handler.js.map +1 -1
  152. package/dist/src/fallback/handler.test.js +0 -6
  153. package/dist/src/fallback/handler.test.js.map +1 -1
  154. package/dist/src/generated/git-commit.d.ts +2 -2
  155. package/dist/src/generated/git-commit.js +2 -2
  156. package/dist/src/generated/git-commit.js.map +1 -1
  157. package/dist/src/ide/detect-ide.d.ts +8 -0
  158. package/dist/src/ide/detect-ide.js +12 -1
  159. package/dist/src/ide/detect-ide.js.map +1 -1
  160. package/dist/src/ide/detect-ide.test.js +12 -0
  161. package/dist/src/ide/detect-ide.test.js.map +1 -1
  162. package/dist/src/ide/ide-installer.js +20 -8
  163. package/dist/src/ide/ide-installer.js.map +1 -1
  164. package/dist/src/ide/ide-installer.test.js +60 -4
  165. package/dist/src/ide/ide-installer.test.js.map +1 -1
  166. package/dist/src/mcp/oauth-provider.js +0 -2
  167. package/dist/src/mcp/oauth-provider.js.map +1 -1
  168. package/dist/src/mcp/oauth-token-storage.test.js +6 -10
  169. package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
  170. package/dist/src/mcp/oauth-utils.js +0 -2
  171. package/dist/src/mcp/oauth-utils.js.map +1 -1
  172. package/dist/src/mcp/token-storage/file-token-storage.d.ts +24 -0
  173. package/dist/src/mcp/token-storage/file-token-storage.js +152 -0
  174. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -0
  175. package/dist/src/mcp/token-storage/file-token-storage.test.d.ts +6 -0
  176. package/dist/src/mcp/token-storage/file-token-storage.test.js +276 -0
  177. package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -0
  178. package/dist/src/mcp/token-storage/hybrid-token-storage.js +21 -9
  179. package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -1
  180. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js +59 -10
  181. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -1
  182. package/dist/src/mcp/token-storage/index.d.ts +1 -1
  183. package/dist/src/mcp/token-storage/index.js +1 -1
  184. package/dist/src/mcp/token-storage/index.js.map +1 -1
  185. package/dist/src/mcp/token-storage/keychain-token-storage.d.ts +0 -1
  186. package/dist/src/mcp/token-storage/keychain-token-storage.js +0 -3
  187. package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -1
  188. package/dist/src/policy/config.d.ts +14 -2
  189. package/dist/src/policy/config.js +94 -49
  190. package/dist/src/policy/config.js.map +1 -1
  191. package/dist/src/policy/config.test.js +208 -488
  192. package/dist/src/policy/config.test.js.map +1 -1
  193. package/dist/src/policy/policies/plan.toml +1 -1
  194. package/dist/src/policy/stable-stringify.js +15 -5
  195. package/dist/src/policy/stable-stringify.js.map +1 -1
  196. package/dist/src/policy/types.d.ts +1 -0
  197. package/dist/src/policy/types.js.map +1 -1
  198. package/dist/src/policy/utils.d.ts +17 -0
  199. package/dist/src/policy/utils.js +27 -7
  200. package/dist/src/policy/utils.js.map +1 -1
  201. package/dist/src/prompts/snippets.js +2 -1
  202. package/dist/src/prompts/snippets.js.map +1 -1
  203. package/dist/src/prompts/utils.test.d.ts +6 -0
  204. package/dist/src/prompts/utils.test.js +225 -0
  205. package/dist/src/prompts/utils.test.js.map +1 -0
  206. package/dist/src/routing/modelRouterService.js +2 -2
  207. package/dist/src/routing/modelRouterService.js.map +1 -1
  208. package/dist/src/routing/modelRouterService.test.js +4 -3
  209. package/dist/src/routing/modelRouterService.test.js.map +1 -1
  210. package/dist/src/routing/strategies/numericalClassifierStrategy.js +6 -40
  211. package/dist/src/routing/strategies/numericalClassifierStrategy.js.map +1 -1
  212. package/dist/src/routing/strategies/numericalClassifierStrategy.test.js +29 -64
  213. package/dist/src/routing/strategies/numericalClassifierStrategy.test.js.map +1 -1
  214. package/dist/src/scheduler/policy.d.ts +3 -7
  215. package/dist/src/scheduler/policy.js +4 -3
  216. package/dist/src/scheduler/policy.js.map +1 -1
  217. package/dist/src/scheduler/policy.test.js +51 -31
  218. package/dist/src/scheduler/policy.test.js.map +1 -1
  219. package/dist/src/scheduler/scheduler.d.ts +4 -2
  220. package/dist/src/scheduler/scheduler.js +19 -16
  221. package/dist/src/scheduler/scheduler.js.map +1 -1
  222. package/dist/src/scheduler/scheduler.test.js +33 -10
  223. package/dist/src/scheduler/scheduler.test.js.map +1 -1
  224. package/dist/src/scheduler/scheduler_parallel.test.js +40 -2
  225. package/dist/src/scheduler/scheduler_parallel.test.js.map +1 -1
  226. package/dist/src/scheduler/scheduler_waiting_callback.test.js +1 -1
  227. package/dist/src/scheduler/scheduler_waiting_callback.test.js.map +1 -1
  228. package/dist/src/scheduler/tool-executor.d.ts +3 -3
  229. package/dist/src/scheduler/tool-executor.js +15 -21
  230. package/dist/src/scheduler/tool-executor.js.map +1 -1
  231. package/dist/src/scheduler/tool-executor.test.js +43 -8
  232. package/dist/src/scheduler/tool-executor.test.js.map +1 -1
  233. package/dist/src/services/chatRecordingService.js +2 -1
  234. package/dist/src/services/chatRecordingService.js.map +1 -1
  235. package/dist/src/services/chatRecordingService.test.js +21 -0
  236. package/dist/src/services/chatRecordingService.test.js.map +1 -1
  237. package/dist/src/services/executionLifecycleService.d.ts +83 -0
  238. package/dist/src/services/executionLifecycleService.js +271 -0
  239. package/dist/src/services/executionLifecycleService.js.map +1 -0
  240. package/dist/src/services/executionLifecycleService.test.d.ts +6 -0
  241. package/dist/src/services/executionLifecycleService.test.js +227 -0
  242. package/dist/src/services/executionLifecycleService.test.js.map +1 -0
  243. package/dist/src/services/keychainService.d.ts +0 -5
  244. package/dist/src/services/keychainService.js +13 -30
  245. package/dist/src/services/keychainService.js.map +1 -1
  246. package/dist/src/services/keychainService.test.js +22 -52
  247. package/dist/src/services/keychainService.test.js.map +1 -1
  248. package/dist/src/services/sandboxManager.d.ts +54 -0
  249. package/dist/src/services/sandboxManager.js +30 -0
  250. package/dist/src/services/sandboxManager.js.map +1 -0
  251. package/dist/src/services/sandboxManager.test.d.ts +6 -0
  252. package/dist/src/services/sandboxManager.test.js +95 -0
  253. package/dist/src/services/sandboxManager.test.js.map +1 -0
  254. package/dist/src/services/shellExecutionService.d.ts +4 -52
  255. package/dist/src/services/shellExecutionService.js +437 -498
  256. package/dist/src/services/shellExecutionService.js.map +1 -1
  257. package/dist/src/services/shellExecutionService.test.js +10 -21
  258. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  259. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +13 -2
  260. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +91 -1
  261. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  262. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +77 -0
  263. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  264. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +10 -1
  265. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +25 -1
  266. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  267. package/dist/src/telemetry/index.d.ts +3 -3
  268. package/dist/src/telemetry/index.js +3 -3
  269. package/dist/src/telemetry/index.js.map +1 -1
  270. package/dist/src/telemetry/loggers.d.ts +2 -1
  271. package/dist/src/telemetry/loggers.js +32 -1
  272. package/dist/src/telemetry/loggers.js.map +1 -1
  273. package/dist/src/telemetry/loggers.test.js +37 -2
  274. package/dist/src/telemetry/loggers.test.js.map +1 -1
  275. package/dist/src/telemetry/metrics.d.ts +13 -0
  276. package/dist/src/telemetry/metrics.js +17 -0
  277. package/dist/src/telemetry/metrics.js.map +1 -1
  278. package/dist/src/telemetry/startupProfiler.js +4 -4
  279. package/dist/src/telemetry/startupProfiler.js.map +1 -1
  280. package/dist/src/telemetry/startupProfiler.test.js +19 -0
  281. package/dist/src/telemetry/startupProfiler.test.js.map +1 -1
  282. package/dist/src/telemetry/telemetry-utils.test.js +3 -3
  283. package/dist/src/telemetry/types.d.ts +16 -2
  284. package/dist/src/telemetry/types.js +34 -0
  285. package/dist/src/telemetry/types.js.map +1 -1
  286. package/dist/src/telemetry/uiTelemetry.d.ts +7 -0
  287. package/dist/src/telemetry/uiTelemetry.js +78 -0
  288. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  289. package/dist/src/telemetry/uiTelemetry.test.js +101 -0
  290. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  291. package/dist/src/tools/exit-plan-mode.js +10 -2
  292. package/dist/src/tools/exit-plan-mode.js.map +1 -1
  293. package/dist/src/tools/exit-plan-mode.test.js +15 -0
  294. package/dist/src/tools/exit-plan-mode.test.js.map +1 -1
  295. package/dist/src/tools/ls.js +2 -2
  296. package/dist/src/tools/ls.js.map +1 -1
  297. package/dist/src/tools/mcp-client.js +0 -1
  298. package/dist/src/tools/mcp-client.js.map +1 -1
  299. package/dist/src/tools/mcp-client.test.js +4 -0
  300. package/dist/src/tools/mcp-client.test.js.map +1 -1
  301. package/dist/src/tools/mcp-tool.test.js +10 -1
  302. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  303. package/dist/src/tools/read-many-files.js +2 -4
  304. package/dist/src/tools/read-many-files.js.map +1 -1
  305. package/dist/src/tools/shell.d.ts +1 -1
  306. package/dist/src/tools/shell.js +3 -3
  307. package/dist/src/tools/shell.js.map +1 -1
  308. package/dist/src/tools/tool-registry.test.js +4 -0
  309. package/dist/src/tools/tool-registry.test.js.map +1 -1
  310. package/dist/src/tools/tools.d.ts +34 -1
  311. package/dist/src/tools/tools.js +47 -1
  312. package/dist/src/tools/tools.js.map +1 -1
  313. package/dist/src/tools/web-fetch.d.ts +5 -0
  314. package/dist/src/tools/web-fetch.js +177 -100
  315. package/dist/src/tools/web-fetch.js.map +1 -1
  316. package/dist/src/tools/web-fetch.test.js +130 -26
  317. package/dist/src/tools/web-fetch.test.js.map +1 -1
  318. package/dist/src/tools/web-search.test.js +2 -0
  319. package/dist/src/tools/web-search.test.js.map +1 -1
  320. package/dist/src/utils/fetch.d.ts +0 -29
  321. package/dist/src/utils/fetch.js +10 -123
  322. package/dist/src/utils/fetch.js.map +1 -1
  323. package/dist/src/utils/fetch.test.js +1 -103
  324. package/dist/src/utils/fetch.test.js.map +1 -1
  325. package/dist/src/utils/language-detection.js +96 -89
  326. package/dist/src/utils/language-detection.js.map +1 -1
  327. package/dist/src/utils/language-detection.test.d.ts +6 -0
  328. package/dist/src/utils/language-detection.test.js +39 -0
  329. package/dist/src/utils/language-detection.test.js.map +1 -0
  330. package/dist/src/utils/oauth-flow.js +0 -2
  331. package/dist/src/utils/oauth-flow.js.map +1 -1
  332. package/dist/src/utils/paths.js +5 -2
  333. package/dist/src/utils/paths.js.map +1 -1
  334. package/dist/src/utils/paths.test.js +11 -0
  335. package/dist/src/utils/paths.test.js.map +1 -1
  336. package/dist/src/utils/process-utils.js +18 -4
  337. package/dist/src/utils/process-utils.js.map +1 -1
  338. package/dist/src/utils/process-utils.test.js +32 -10
  339. package/dist/src/utils/process-utils.test.js.map +1 -1
  340. package/dist/src/utils/retry.d.ts +7 -0
  341. package/dist/src/utils/retry.js +40 -3
  342. package/dist/src/utils/retry.js.map +1 -1
  343. package/dist/src/utils/retry.test.js +13 -0
  344. package/dist/src/utils/retry.test.js.map +1 -1
  345. package/dist/src/utils/summarizer.test.js +5 -0
  346. package/dist/src/utils/summarizer.test.js.map +1 -1
  347. package/dist/src/utils/surface.d.ts +18 -0
  348. package/dist/src/utils/surface.js +46 -0
  349. package/dist/src/utils/surface.js.map +1 -0
  350. package/dist/tsconfig.tsbuildinfo +1 -1
  351. package/package.json +1 -1
  352. package/dist/google-gemini-cli-core-0.34.0-preview.2.tgz +0 -0
  353. package/dist/src/services/fileKeychain.d.ts +0 -24
  354. package/dist/src/services/fileKeychain.js +0 -123
  355. package/dist/src/services/fileKeychain.js.map +0 -1
@@ -3,41 +3,51 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { ClientFactory, ClientFactoryOptions, DefaultAgentCardResolver, RestTransportFactory, JsonRpcTransportFactory, createAuthenticatingFetchWithRetry, } from '@a2a-js/sdk/client';
6
+ import { ClientFactory, ClientFactoryOptions, DefaultAgentCardResolver, JsonRpcTransportFactory, RestTransportFactory, createAuthenticatingFetchWithRetry, } from '@a2a-js/sdk/client';
7
+ import { GrpcTransportFactory } from '@a2a-js/sdk/client/grpc';
8
+ import * as grpc from '@grpc/grpc-js';
7
9
  import { v4 as uuidv4 } from 'uuid';
8
- import { Agent as UndiciAgent } from 'undici';
10
+ import { Agent as UndiciAgent, ProxyAgent } from 'undici';
11
+ import { normalizeAgentCard } from './a2aUtils.js';
9
12
  import { debugLogger } from '../utils/debugLogger.js';
10
- import { safeLookup } from '../utils/fetch.js';
11
13
  import { classifyAgentError } from './a2a-errors.js';
12
14
  // Remote agents can take 10+ minutes (e.g. Deep Research).
13
15
  // Use a dedicated dispatcher so the global 5-min timeout isn't affected.
14
16
  const A2A_TIMEOUT = 1800000; // 30 minutes
15
- const a2aDispatcher = new UndiciAgent({
16
- headersTimeout: A2A_TIMEOUT,
17
- bodyTimeout: A2A_TIMEOUT,
18
- connect: {
19
- lookup: safeLookup, // SSRF protection at connection level
20
- },
21
- });
22
- const a2aFetch = (input, init) =>
23
- // eslint-disable-next-line no-restricted-syntax -- TODO: Migrate to safeFetch for SSRF protection
24
- fetch(input, { ...init, dispatcher: a2aDispatcher });
25
17
  /**
26
- * Manages A2A clients and caches loaded agent information.
27
- * Follows a singleton pattern to ensure a single client instance.
18
+ * Orchestrates communication with remote A2A agents.
19
+ * Manages protocol negotiation, authentication, and transport selection.
28
20
  */
29
21
  export class A2AClientManager {
30
22
  static instance;
31
23
  // Each agent should manage their own context/taskIds/card/etc
32
24
  clients = new Map();
33
25
  agentCards = new Map();
34
- constructor() { }
26
+ a2aDispatcher;
27
+ a2aFetch;
28
+ constructor(config) {
29
+ const proxyUrl = config?.getProxy();
30
+ const agentOptions = {
31
+ headersTimeout: A2A_TIMEOUT,
32
+ bodyTimeout: A2A_TIMEOUT,
33
+ };
34
+ if (proxyUrl) {
35
+ this.a2aDispatcher = new ProxyAgent({
36
+ uri: proxyUrl,
37
+ ...agentOptions,
38
+ });
39
+ }
40
+ else {
41
+ this.a2aDispatcher = new UndiciAgent(agentOptions);
42
+ }
43
+ this.a2aFetch = (input, init) => fetch(input, { ...init, dispatcher: this.a2aDispatcher });
44
+ }
35
45
  /**
36
46
  * Gets the singleton instance of the A2AClientManager.
37
47
  */
38
- static getInstance() {
48
+ static getInstance(config) {
39
49
  if (!A2AClientManager.instance) {
40
- A2AClientManager.instance = new A2AClientManager();
50
+ A2AClientManager.instance = new A2AClientManager(config);
41
51
  }
42
52
  return A2AClientManager.instance;
43
53
  }
@@ -61,15 +71,15 @@ export class A2AClientManager {
61
71
  throw new Error(`Agent with name '${name}' is already loaded.`);
62
72
  }
63
73
  // Authenticated fetch for API calls (transports).
64
- let authFetch = a2aFetch;
74
+ let authFetch = this.a2aFetch;
65
75
  if (authHandler) {
66
- authFetch = createAuthenticatingFetchWithRetry(a2aFetch, authHandler);
76
+ authFetch = createAuthenticatingFetchWithRetry(this.a2aFetch, authHandler);
67
77
  }
68
78
  // Use unauthenticated fetch for the agent card unless explicitly required.
69
79
  // Some servers reject unexpected auth headers on the card endpoint (e.g. 400).
70
80
  const cardFetch = async (input, init) => {
71
81
  // Try without auth first
72
- const response = await a2aFetch(input, init);
82
+ const response = await this.a2aFetch(input, init);
73
83
  // Retry with auth if we hit a 401/403
74
84
  if ((response.status === 401 || response.status === 403) && authFetch) {
75
85
  return authFetch(input, init);
@@ -77,17 +87,28 @@ export class A2AClientManager {
77
87
  return response;
78
88
  };
79
89
  const resolver = new DefaultAgentCardResolver({ fetchImpl: cardFetch });
80
- const options = ClientFactoryOptions.createFrom(ClientFactoryOptions.default, {
90
+ const rawCard = await resolver.resolve(agentCardUrl, '');
91
+ // TODO: Remove normalizeAgentCard once @a2a-js/sdk handles
92
+ // proto field name aliases (supportedInterfaces → additionalInterfaces,
93
+ // protocolBinding → transport).
94
+ const agentCard = normalizeAgentCard(rawCard);
95
+ const grpcUrl = agentCard.additionalInterfaces?.find((i) => i.transport === 'GRPC')
96
+ ?.url ?? agentCard.url;
97
+ const clientOptions = ClientFactoryOptions.createFrom(ClientFactoryOptions.default, {
81
98
  transports: [
82
99
  new RestTransportFactory({ fetchImpl: authFetch }),
83
100
  new JsonRpcTransportFactory({ fetchImpl: authFetch }),
101
+ new GrpcTransportFactory({
102
+ grpcChannelCredentials: grpcUrl.startsWith('https://')
103
+ ? grpc.credentials.createSsl()
104
+ : grpc.credentials.createInsecure(),
105
+ }),
84
106
  ],
85
107
  cardResolver: resolver,
86
108
  });
87
109
  try {
88
- const factory = new ClientFactory(options);
89
- const client = await factory.createFromUrl(agentCardUrl, '');
90
- const agentCard = await client.getAgentCard();
110
+ const factory = new ClientFactory(clientOptions);
111
+ const client = await factory.createFromAgentCard(agentCard);
91
112
  this.clients.set(name, client);
92
113
  this.agentCards.set(name, agentCard);
93
114
  debugLogger.debug(`[A2AClientManager] Loaded agent '${name}' from ${agentCardUrl}`);
@@ -115,9 +136,8 @@ export class A2AClientManager {
115
136
  */
116
137
  async *sendMessageStream(agentName, message, options) {
117
138
  const client = this.clients.get(agentName);
118
- if (!client) {
139
+ if (!client)
119
140
  throw new Error(`Agent '${agentName}' not found.`);
120
- }
121
141
  const messageParams = {
122
142
  message: {
123
143
  kind: 'message',
@@ -128,9 +148,18 @@ export class A2AClientManager {
128
148
  taskId: options?.taskId,
129
149
  },
130
150
  };
131
- yield* client.sendMessageStream(messageParams, {
132
- signal: options?.signal,
133
- });
151
+ try {
152
+ yield* client.sendMessageStream(messageParams, {
153
+ signal: options?.signal,
154
+ });
155
+ }
156
+ catch (error) {
157
+ const prefix = `[A2AClientManager] sendMessageStream Error [${agentName}]`;
158
+ if (error instanceof Error) {
159
+ throw new Error(`${prefix}: ${error.message}`, { cause: error });
160
+ }
161
+ throw new Error(`${prefix}: Unexpected error during sendMessageStream: ${String(error)}`);
162
+ }
134
163
  }
135
164
  /**
136
165
  * Retrieves a loaded agent card.
@@ -156,9 +185,8 @@ export class A2AClientManager {
156
185
  */
157
186
  async getTask(agentName, taskId) {
158
187
  const client = this.clients.get(agentName);
159
- if (!client) {
188
+ if (!client)
160
189
  throw new Error(`Agent '${agentName}' not found.`);
161
- }
162
190
  try {
163
191
  return await client.getTask({ id: taskId });
164
192
  }
@@ -178,9 +206,8 @@ export class A2AClientManager {
178
206
  */
179
207
  async cancelTask(agentName, taskId) {
180
208
  const client = this.clients.get(agentName);
181
- if (!client) {
209
+ if (!client)
182
210
  throw new Error(`Agent '${agentName}' not found.`);
183
- }
184
211
  try {
185
212
  return await client.cancelTask({ id: taskId });
186
213
  }
@@ -1 +1 @@
1
- {"version":3,"file":"a2a-client-manager.js","sourceRoot":"","sources":["../../../src/agents/a2a-client-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"a2a-client-manager.js","sourceRoot":"","sources":["../../../src/agents/a2a-client-manager.ts"],"names":[],"mappings":"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"}
@@ -4,66 +4,72 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
7
- import { A2AClientManager, } from './a2a-client-manager.js';
7
+ import { A2AClientManager } from './a2a-client-manager.js';
8
8
  import { ClientFactory, DefaultAgentCardResolver, createAuthenticatingFetchWithRetry, ClientFactoryOptions, } from '@a2a-js/sdk/client';
9
+ import { Agent as UndiciAgent, ProxyAgent } from 'undici';
9
10
  import { debugLogger } from '../utils/debugLogger.js';
11
+ vi.mock('@a2a-js/sdk/client', async (importOriginal) => {
12
+ const actual = await importOriginal();
13
+ return {
14
+ ...actual,
15
+ createAuthenticatingFetchWithRetry: vi.fn(),
16
+ ClientFactory: vi.fn(),
17
+ DefaultAgentCardResolver: vi.fn(),
18
+ ClientFactoryOptions: {
19
+ createFrom: vi.fn(),
20
+ default: {},
21
+ },
22
+ };
23
+ });
10
24
  vi.mock('../utils/debugLogger.js', () => ({
11
25
  debugLogger: {
12
26
  debug: vi.fn(),
13
27
  },
14
28
  }));
15
- vi.mock('@a2a-js/sdk/client', () => {
16
- const ClientFactory = vi.fn();
17
- const DefaultAgentCardResolver = vi.fn();
18
- const RestTransportFactory = vi.fn();
19
- const JsonRpcTransportFactory = vi.fn();
20
- const ClientFactoryOptions = {
21
- default: {},
22
- createFrom: vi.fn(),
23
- };
24
- const createAuthenticatingFetchWithRetry = vi.fn();
25
- DefaultAgentCardResolver.prototype.resolve = vi.fn();
26
- ClientFactory.prototype.createFromUrl = vi.fn();
27
- return {
28
- ClientFactory,
29
- ClientFactoryOptions,
30
- DefaultAgentCardResolver,
31
- RestTransportFactory,
32
- JsonRpcTransportFactory,
33
- createAuthenticatingFetchWithRetry,
34
- };
35
- });
36
29
  describe('A2AClientManager', () => {
37
30
  let manager;
38
- // Stable mocks initialized once
39
- const sendMessageStreamMock = vi.fn();
40
- const getTaskMock = vi.fn();
41
- const cancelTaskMock = vi.fn();
42
- const getAgentCardMock = vi.fn();
43
- const authFetchMock = vi.fn();
31
+ const mockAgentCard = {
32
+ name: 'test-agent',
33
+ description: 'A test agent',
34
+ url: 'http://test.agent',
35
+ version: '1.0.0',
36
+ protocolVersion: '0.1.0',
37
+ capabilities: {},
38
+ skills: [],
39
+ defaultInputModes: [],
40
+ defaultOutputModes: [],
41
+ };
44
42
  const mockClient = {
45
- sendMessageStream: sendMessageStreamMock,
46
- getTask: getTaskMock,
47
- cancelTask: cancelTaskMock,
48
- getAgentCard: getAgentCardMock,
43
+ sendMessageStream: vi.fn(),
44
+ getTask: vi.fn(),
45
+ cancelTask: vi.fn(),
49
46
  };
50
- const mockAgentCard = { name: 'TestAgent' };
47
+ const authFetchMock = vi.fn();
51
48
  beforeEach(() => {
52
49
  vi.clearAllMocks();
53
50
  A2AClientManager.resetInstanceForTesting();
54
51
  manager = A2AClientManager.getInstance();
55
- // Default mock implementations
56
- getAgentCardMock.mockResolvedValue({
52
+ // Re-create the instances as plain objects that can be spied on
53
+ const factoryInstance = {
54
+ createFromUrl: vi.fn(),
55
+ createFromAgentCard: vi.fn(),
56
+ };
57
+ const resolverInstance = {
58
+ resolve: vi.fn(),
59
+ };
60
+ vi.mocked(ClientFactory).mockReturnValue(factoryInstance);
61
+ vi.mocked(DefaultAgentCardResolver).mockReturnValue(resolverInstance);
62
+ vi.spyOn(factoryInstance, 'createFromUrl').mockResolvedValue(mockClient);
63
+ vi.spyOn(factoryInstance, 'createFromAgentCard').mockResolvedValue(mockClient);
64
+ vi.spyOn(resolverInstance, 'resolve').mockResolvedValue({
57
65
  ...mockAgentCard,
58
66
  url: 'http://test.agent/real/endpoint',
59
67
  });
60
- vi.mocked(ClientFactory.prototype.createFromUrl).mockResolvedValue(mockClient);
61
- vi.mocked(DefaultAgentCardResolver.prototype.resolve).mockResolvedValue({
62
- ...mockAgentCard,
63
- url: 'http://test.agent/real/endpoint',
64
- });
65
- vi.mocked(ClientFactoryOptions.createFrom).mockImplementation((_defaults, overrides) => overrides);
66
- vi.mocked(createAuthenticatingFetchWithRetry).mockReturnValue(authFetchMock);
68
+ vi.spyOn(ClientFactoryOptions, 'createFrom').mockImplementation((_defaults, overrides) => overrides);
69
+ vi.mocked(createAuthenticatingFetchWithRetry).mockImplementation(() => authFetchMock.mockResolvedValue({
70
+ ok: true,
71
+ json: async () => ({}),
72
+ }));
67
73
  vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
68
74
  ok: true,
69
75
  json: async () => ({}),
@@ -78,16 +84,51 @@ describe('A2AClientManager', () => {
78
84
  const instance2 = A2AClientManager.getInstance();
79
85
  expect(instance1).toBe(instance2);
80
86
  });
87
+ describe('getInstance / dispatcher initialization', () => {
88
+ it('should use UndiciAgent when no proxy is configured', async () => {
89
+ await manager.loadAgent('TestAgent', 'http://test.agent/card');
90
+ const resolverOptions = vi.mocked(DefaultAgentCardResolver).mock
91
+ .calls[0][0];
92
+ const cardFetch = resolverOptions?.fetchImpl;
93
+ await cardFetch('http://test.agent/card');
94
+ const fetchCall = vi
95
+ .mocked(fetch)
96
+ .mock.calls.find((call) => call[0] === 'http://test.agent/card');
97
+ expect(fetchCall).toBeDefined();
98
+ expect(fetchCall[1]?.dispatcher).toBeInstanceOf(UndiciAgent);
99
+ expect(fetchCall[1]?.dispatcher).not.toBeInstanceOf(ProxyAgent);
100
+ });
101
+ it('should use ProxyAgent when a proxy is configured via Config', async () => {
102
+ A2AClientManager.resetInstanceForTesting();
103
+ const mockConfig = {
104
+ getProxy: () => 'http://my-proxy:8080',
105
+ };
106
+ manager = A2AClientManager.getInstance(mockConfig);
107
+ await manager.loadAgent('TestProxyAgent', 'http://test.proxy.agent/card');
108
+ const resolverOptions = vi.mocked(DefaultAgentCardResolver).mock
109
+ .calls[0][0];
110
+ const cardFetch = resolverOptions?.fetchImpl;
111
+ await cardFetch('http://test.proxy.agent/card');
112
+ const fetchCall = vi
113
+ .mocked(fetch)
114
+ .mock.calls.find((call) => call[0] === 'http://test.proxy.agent/card');
115
+ expect(fetchCall).toBeDefined();
116
+ expect(fetchCall[1]?.dispatcher).toBeInstanceOf(ProxyAgent);
117
+ });
118
+ });
81
119
  describe('loadAgent', () => {
82
120
  it('should create and cache an A2AClient', async () => {
83
121
  const agentCard = await manager.loadAgent('TestAgent', 'http://test.agent/card');
84
- expect(agentCard).toMatchObject(mockAgentCard);
85
122
  expect(manager.getAgentCard('TestAgent')).toBe(agentCard);
86
123
  expect(manager.getClient('TestAgent')).toBeDefined();
87
124
  });
125
+ it('should configure ClientFactory with REST, JSON-RPC, and gRPC transports', async () => {
126
+ await manager.loadAgent('TestAgent', 'http://test.agent/card');
127
+ expect(ClientFactoryOptions.createFrom).toHaveBeenCalled();
128
+ });
88
129
  it('should throw an error if an agent with the same name is already loaded', async () => {
89
130
  await manager.loadAgent('TestAgent', 'http://test.agent/card');
90
- await expect(manager.loadAgent('TestAgent', 'http://another.agent/card')).rejects.toThrow("Agent with name 'TestAgent' is already loaded.");
131
+ await expect(manager.loadAgent('TestAgent', 'http://test.agent/card')).rejects.toThrow("Agent with name 'TestAgent' is already loaded.");
91
132
  });
92
133
  it('should use native fetch by default', async () => {
93
134
  await manager.loadAgent('TestAgent', 'http://test.agent/card');
@@ -98,12 +139,8 @@ describe('A2AClientManager', () => {
98
139
  headers: vi.fn(),
99
140
  shouldRetryWithHeaders: vi.fn(),
100
141
  };
101
- await manager.loadAgent('CustomAuthAgent', 'http://custom.agent/card', customAuthHandler);
102
- expect(createAuthenticatingFetchWithRetry).toHaveBeenCalledWith(expect.anything(), customAuthHandler);
142
+ await manager.loadAgent('TestAgent', 'http://test.agent/card', customAuthHandler);
103
143
  // Card resolver should NOT use the authenticated fetch by default.
104
- const resolverInstance = vi.mocked(DefaultAgentCardResolver).mock
105
- .instances[0];
106
- expect(resolverInstance).toBeDefined();
107
144
  const resolverOptions = vi.mocked(DefaultAgentCardResolver).mock
108
145
  .calls[0][0];
109
146
  expect(resolverOptions?.fetchImpl).not.toBe(authFetchMock);
@@ -143,103 +180,134 @@ describe('A2AClientManager', () => {
143
180
  });
144
181
  it('should log a debug message upon loading an agent', async () => {
145
182
  await manager.loadAgent('TestAgent', 'http://test.agent/card');
146
- expect(debugLogger.debug).toHaveBeenCalledWith("[A2AClientManager] Loaded agent 'TestAgent' from http://test.agent/card");
183
+ expect(debugLogger.debug).toHaveBeenCalledWith(expect.stringContaining("Loaded agent 'TestAgent'"));
147
184
  });
148
185
  it('should clear the cache', async () => {
149
186
  await manager.loadAgent('TestAgent', 'http://test.agent/card');
150
- expect(manager.getAgentCard('TestAgent')).toBeDefined();
151
- expect(manager.getClient('TestAgent')).toBeDefined();
152
187
  manager.clearCache();
153
188
  expect(manager.getAgentCard('TestAgent')).toBeUndefined();
154
189
  expect(manager.getClient('TestAgent')).toBeUndefined();
155
- expect(debugLogger.debug).toHaveBeenCalledWith('[A2AClientManager] Cache cleared.');
190
+ });
191
+ it('should throw if resolveAgentCard fails', async () => {
192
+ const resolverInstance = {
193
+ resolve: vi.fn().mockRejectedValue(new Error('Resolution failed')),
194
+ };
195
+ vi.mocked(DefaultAgentCardResolver).mockReturnValue(resolverInstance);
196
+ await expect(manager.loadAgent('FailAgent', 'http://fail.agent')).rejects.toThrow('Resolution failed');
197
+ });
198
+ it('should throw if factory.createFromAgentCard fails', async () => {
199
+ const factoryInstance = {
200
+ createFromAgentCard: vi
201
+ .fn()
202
+ .mockRejectedValue(new Error('Factory failed')),
203
+ };
204
+ vi.mocked(ClientFactory).mockReturnValue(factoryInstance);
205
+ await expect(manager.loadAgent('FailAgent', 'http://fail.agent')).rejects.toThrow('Factory failed');
206
+ });
207
+ });
208
+ describe('getAgentCard and getClient', () => {
209
+ it('should return undefined if agent is not found', () => {
210
+ expect(manager.getAgentCard('Unknown')).toBeUndefined();
211
+ expect(manager.getClient('Unknown')).toBeUndefined();
156
212
  });
157
213
  });
158
214
  describe('sendMessageStream', () => {
159
215
  beforeEach(async () => {
160
- await manager.loadAgent('TestAgent', 'http://test.agent');
216
+ await manager.loadAgent('TestAgent', 'http://test.agent/card');
161
217
  });
162
218
  it('should send a message and return a stream', async () => {
163
- const mockResult = {
164
- kind: 'message',
165
- messageId: 'a',
166
- parts: [],
167
- role: 'agent',
168
- };
169
- sendMessageStreamMock.mockReturnValue((async function* () {
170
- yield mockResult;
219
+ mockClient.sendMessageStream.mockReturnValue((async function* () {
220
+ yield { kind: 'message' };
171
221
  })());
172
222
  const stream = manager.sendMessageStream('TestAgent', 'Hello');
173
223
  const results = [];
174
- for await (const res of stream) {
175
- results.push(res);
224
+ for await (const result of stream) {
225
+ results.push(result);
176
226
  }
177
- expect(results).toEqual([mockResult]);
178
- expect(sendMessageStreamMock).toHaveBeenCalledWith(expect.objectContaining({
179
- message: expect.anything(),
180
- }), expect.any(Object));
227
+ expect(results).toHaveLength(1);
228
+ expect(mockClient.sendMessageStream).toHaveBeenCalled();
181
229
  });
182
230
  it('should use contextId and taskId when provided', async () => {
183
- sendMessageStreamMock.mockReturnValue((async function* () {
184
- yield {
185
- kind: 'message',
186
- messageId: 'a',
187
- parts: [],
188
- role: 'agent',
189
- };
231
+ mockClient.sendMessageStream.mockReturnValue((async function* () {
232
+ yield { kind: 'message' };
190
233
  })());
191
- const expectedContextId = 'user-context-id';
192
- const expectedTaskId = 'user-task-id';
193
234
  const stream = manager.sendMessageStream('TestAgent', 'Hello', {
194
- contextId: expectedContextId,
195
- taskId: expectedTaskId,
235
+ contextId: 'ctx123',
236
+ taskId: 'task456',
196
237
  });
238
+ // trigger execution
197
239
  for await (const _ of stream) {
198
- // consume stream
240
+ break;
199
241
  }
200
- const call = sendMessageStreamMock.mock.calls[0][0];
201
- expect(call.message.contextId).toBe(expectedContextId);
202
- expect(call.message.taskId).toBe(expectedTaskId);
242
+ expect(mockClient.sendMessageStream).toHaveBeenCalledWith(expect.objectContaining({
243
+ message: expect.objectContaining({
244
+ contextId: 'ctx123',
245
+ taskId: 'task456',
246
+ }),
247
+ }), expect.any(Object));
203
248
  });
204
- it('should propagate the original error on failure', async () => {
205
- sendMessageStreamMock.mockImplementationOnce(() => {
206
- throw new Error('Network error');
249
+ it('should correctly propagate AbortSignal to the stream', async () => {
250
+ mockClient.sendMessageStream.mockReturnValue((async function* () {
251
+ yield { kind: 'message' };
252
+ })());
253
+ const controller = new AbortController();
254
+ const stream = manager.sendMessageStream('TestAgent', 'Hello', {
255
+ signal: controller.signal,
256
+ });
257
+ // trigger execution
258
+ for await (const _ of stream) {
259
+ break;
260
+ }
261
+ expect(mockClient.sendMessageStream).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ signal: controller.signal }));
262
+ });
263
+ it('should handle a multi-chunk stream with different event types', async () => {
264
+ mockClient.sendMessageStream.mockReturnValue((async function* () {
265
+ yield { kind: 'message', messageId: 'm1' };
266
+ yield { kind: 'status-update', taskId: 't1' };
267
+ })());
268
+ const stream = manager.sendMessageStream('TestAgent', 'Hello');
269
+ const results = [];
270
+ for await (const result of stream) {
271
+ results.push(result);
272
+ }
273
+ expect(results).toHaveLength(2);
274
+ expect(results[0].kind).toBe('message');
275
+ expect(results[1].kind).toBe('status-update');
276
+ });
277
+ it('should throw prefixed error on failure', async () => {
278
+ mockClient.sendMessageStream.mockImplementation(() => {
279
+ throw new Error('Network failure');
207
280
  });
208
281
  const stream = manager.sendMessageStream('TestAgent', 'Hello');
209
282
  await expect(async () => {
210
283
  for await (const _ of stream) {
211
- // consume
284
+ // empty
212
285
  }
213
- }).rejects.toThrow('Network error');
286
+ }).rejects.toThrow('[A2AClientManager] sendMessageStream Error [TestAgent]: Network failure');
214
287
  });
215
288
  it('should throw an error if the agent is not found', async () => {
216
289
  const stream = manager.sendMessageStream('NonExistentAgent', 'Hello');
217
290
  await expect(async () => {
218
291
  for await (const _ of stream) {
219
- // consume
292
+ // empty
220
293
  }
221
294
  }).rejects.toThrow("Agent 'NonExistentAgent' not found.");
222
295
  });
223
296
  });
224
297
  describe('getTask', () => {
225
298
  beforeEach(async () => {
226
- await manager.loadAgent('TestAgent', 'http://test.agent');
299
+ await manager.loadAgent('TestAgent', 'http://test.agent/card');
227
300
  });
228
301
  it('should get a task from the correct agent', async () => {
229
- getTaskMock.mockResolvedValue({
230
- id: 'task123',
231
- contextId: 'a',
232
- kind: 'task',
233
- status: { state: 'completed' },
234
- });
235
- await manager.getTask('TestAgent', 'task123');
236
- expect(getTaskMock).toHaveBeenCalledWith({
237
- id: 'task123',
238
- });
302
+ const mockTask = { id: 'task123', kind: 'task' };
303
+ mockClient.getTask.mockResolvedValue(mockTask);
304
+ const result = await manager.getTask('TestAgent', 'task123');
305
+ expect(result).toBe(mockTask);
306
+ expect(mockClient.getTask).toHaveBeenCalledWith({ id: 'task123' });
239
307
  });
240
308
  it('should throw prefixed error on failure', async () => {
241
- getTaskMock.mockRejectedValueOnce(new Error('Network error'));
242
- await expect(manager.getTask('TestAgent', 'task123')).rejects.toThrow('A2AClient getTask Error [TestAgent]: Network error');
309
+ mockClient.getTask.mockRejectedValue(new Error('Not found'));
310
+ await expect(manager.getTask('TestAgent', 'task123')).rejects.toThrow('A2AClient getTask Error [TestAgent]: Not found');
243
311
  });
244
312
  it('should throw an error if the agent is not found', async () => {
245
313
  await expect(manager.getTask('NonExistentAgent', 'task123')).rejects.toThrow("Agent 'NonExistentAgent' not found.");
@@ -247,23 +315,18 @@ describe('A2AClientManager', () => {
247
315
  });
248
316
  describe('cancelTask', () => {
249
317
  beforeEach(async () => {
250
- await manager.loadAgent('TestAgent', 'http://test.agent');
318
+ await manager.loadAgent('TestAgent', 'http://test.agent/card');
251
319
  });
252
320
  it('should cancel a task on the correct agent', async () => {
253
- cancelTaskMock.mockResolvedValue({
254
- id: 'task123',
255
- contextId: 'a',
256
- kind: 'task',
257
- status: { state: 'canceled' },
258
- });
259
- await manager.cancelTask('TestAgent', 'task123');
260
- expect(cancelTaskMock).toHaveBeenCalledWith({
261
- id: 'task123',
262
- });
321
+ const mockTask = { id: 'task123', kind: 'task' };
322
+ mockClient.cancelTask.mockResolvedValue(mockTask);
323
+ const result = await manager.cancelTask('TestAgent', 'task123');
324
+ expect(result).toBe(mockTask);
325
+ expect(mockClient.cancelTask).toHaveBeenCalledWith({ id: 'task123' });
263
326
  });
264
327
  it('should throw prefixed error on failure', async () => {
265
- cancelTaskMock.mockRejectedValueOnce(new Error('Network error'));
266
- await expect(manager.cancelTask('TestAgent', 'task123')).rejects.toThrow('A2AClient cancelTask Error [TestAgent]: Network error');
328
+ mockClient.cancelTask.mockRejectedValue(new Error('Cannot cancel'));
329
+ await expect(manager.cancelTask('TestAgent', 'task123')).rejects.toThrow('A2AClient cancelTask Error [TestAgent]: Cannot cancel');
267
330
  });
268
331
  it('should throw an error if the agent is not found', async () => {
269
332
  await expect(manager.cancelTask('NonExistentAgent', 'task123')).rejects.toThrow("Agent 'NonExistentAgent' not found.");