@agent-native/core 0.108.0 → 0.109.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +18 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/a2a/client.ts +140 -17
  5. package/corpus/core/src/a2a/handlers.ts +60 -0
  6. package/corpus/core/src/a2a/index.ts +6 -1
  7. package/corpus/core/src/a2a/invoke.ts +68 -1
  8. package/corpus/core/src/a2a/server.ts +13 -1
  9. package/corpus/core/src/a2a/types.ts +16 -0
  10. package/corpus/core/src/action.ts +3 -2
  11. package/corpus/core/src/agent/production-agent.ts +10 -4
  12. package/corpus/core/src/client/AssistantChat.tsx +648 -603
  13. package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -4
  14. package/corpus/core/src/client/agent-chat-adapter.ts +23 -37
  15. package/corpus/core/src/client/agent-sidebar-state.ts +4 -0
  16. package/corpus/core/src/client/analytics.ts +84 -0
  17. package/corpus/core/src/client/chat/message-components.tsx +94 -22
  18. package/corpus/core/src/client/chat/tool-call-display.tsx +170 -47
  19. package/corpus/core/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
  20. package/corpus/core/src/client/chat-thread-url.ts +11 -0
  21. package/corpus/core/src/client/error-capture.ts +12 -0
  22. package/corpus/core/src/client/extensions/ExtensionSlot.tsx +37 -1
  23. package/corpus/core/src/client/index.ts +2 -0
  24. package/corpus/core/src/client/route-chunk-recovery.ts +20 -8
  25. package/corpus/core/src/client/session-replay.ts +31 -0
  26. package/corpus/core/src/extensions/actions.ts +2 -14
  27. package/corpus/core/src/extensions/store.ts +1 -1
  28. package/corpus/core/src/localization/default-messages.ts +3 -0
  29. package/corpus/core/src/mcp/build-server.ts +2 -2
  30. package/corpus/core/src/progress/actions.ts +4 -2
  31. package/corpus/core/src/provider-api/index.ts +205 -105
  32. package/corpus/core/src/scripts/call-agent.ts +137 -17
  33. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +40 -0
  34. package/corpus/core/src/server/agent-chat-plugin.ts +31 -0
  35. package/corpus/core/src/styles/agent-conversation.css +7 -0
  36. package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +20 -0
  37. package/corpus/core/src/templates/default/app/i18n/de-DE.ts +20 -0
  38. package/corpus/core/src/templates/default/app/i18n/en-US.ts +20 -0
  39. package/corpus/core/src/templates/default/app/i18n/es-ES.ts +20 -0
  40. package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
  41. package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +19 -0
  42. package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +20 -0
  43. package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +19 -0
  44. package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +20 -0
  45. package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +19 -0
  46. package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
  47. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
  48. package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
  49. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
  50. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -10
  51. package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +54 -23
  52. package/corpus/templates/analytics/.builder/skills/apollo/SKILL.md +19 -41
  53. package/corpus/templates/analytics/.builder/skills/commonroom/SKILL.md +20 -35
  54. package/corpus/templates/analytics/.builder/skills/github/SKILL.md +23 -67
  55. package/corpus/templates/analytics/.builder/skills/pylon/SKILL.md +25 -43
  56. package/corpus/templates/analytics/AGENTS.md +22 -13
  57. package/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
  58. package/corpus/templates/analytics/actions/configure-gong-native-insights.ts +29 -0
  59. package/corpus/templates/analytics/actions/content-calendar-schema.ts +8 -4
  60. package/corpus/templates/analytics/actions/content-calendar.ts +12 -4
  61. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -1
  62. package/corpus/templates/analytics/actions/gong-calls.ts +113 -22
  63. package/corpus/templates/analytics/actions/gong-native-insights.ts +166 -0
  64. package/corpus/templates/analytics/actions/hubspot-deals.ts +190 -46
  65. package/corpus/templates/analytics/actions/pylon-issues.ts +123 -0
  66. package/corpus/templates/analytics/actions/slack-messages.ts +179 -27
  67. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +48 -152
  68. package/corpus/templates/analytics/app/components/ui/chart.tsx +1 -1
  69. package/corpus/templates/analytics/app/hooks/use-chart-tooltip-flip.ts +21 -6
  70. package/corpus/templates/analytics/app/i18n/zh-TW.ts +13 -0
  71. package/corpus/templates/analytics/app/i18n-data.ts +134 -0
  72. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +181 -30
  73. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
  74. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +4 -3
  75. package/corpus/templates/analytics/changelog/2026-07-17-dashboard-editors-can-add-shared-extensions-or-opt-into-per-.md +6 -0
  76. package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extensions-show-a-loading-skeleton.md +6 -0
  77. package/corpus/templates/analytics/changelog/2026-07-17-errors-now-group-repeat-failures-consistently-and-keep-priva.md +6 -0
  78. package/corpus/templates/analytics/changelog/2026-07-17-gong-transcript-reviews-now-batch-bounded-call-windows-for-f.md +6 -0
  79. package/corpus/templates/analytics/changelog/2026-07-17-hubspot-deal-filters-now-run-in-hubspot-before-paging-result.md +6 -0
  80. package/corpus/templates/analytics/changelog/2026-07-17-notion-content-calendars-now-discover-the-matching-database-.md +6 -0
  81. package/corpus/templates/analytics/changelog/2026-07-17-pylon-dashboard-reads-now-use-the-paginated-issue-search-api.md +6 -0
  82. package/corpus/templates/analytics/changelog/2026-07-17-slack-reads-no-longer-join-channels-and-report-pagination-coverage.md +6 -0
  83. package/corpus/templates/analytics/server/handlers/notion.ts +14 -3
  84. package/corpus/templates/analytics/server/handlers/slack.ts +182 -29
  85. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -6
  86. package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +6 -2
  87. package/corpus/templates/analytics/server/lib/error-capture.ts +75 -8
  88. package/corpus/templates/analytics/server/lib/gong-native-policy.ts +72 -0
  89. package/corpus/templates/analytics/server/lib/gong.ts +54 -66
  90. package/corpus/templates/analytics/server/lib/hubspot.ts +40 -3
  91. package/corpus/templates/analytics/server/lib/notion.ts +83 -8
  92. package/corpus/templates/analytics/server/lib/real-data-actions.ts +4 -0
  93. package/corpus/templates/analytics/server/lib/slack.ts +242 -90
  94. package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -3
  95. package/corpus/templates/analytics/server/routes/api/pylon/accounts.get.ts +42 -1
  96. package/corpus/templates/analytics/server/routes/api/pylon/issues.get.ts +71 -1
  97. package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +44 -4
  98. package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +19 -1
  99. package/corpus/templates/clips/app/components/library/create-folder-dialog.tsx +123 -0
  100. package/corpus/templates/clips/app/components/library/library-grid.tsx +42 -4
  101. package/corpus/templates/clips/app/components/library/recording-card.tsx +30 -0
  102. package/corpus/templates/clips/app/entry.client.tsx +6 -1
  103. package/corpus/templates/clips/app/i18n/ar-SA.ts +12 -1
  104. package/corpus/templates/clips/app/i18n/de-DE.ts +12 -1
  105. package/corpus/templates/clips/app/i18n/en-US.ts +12 -1
  106. package/corpus/templates/clips/app/i18n/es-ES.ts +11 -1
  107. package/corpus/templates/clips/app/i18n/fr-FR.ts +11 -1
  108. package/corpus/templates/clips/app/i18n/hi-IN.ts +10 -1
  109. package/corpus/templates/clips/app/i18n/ja-JP.ts +12 -1
  110. package/corpus/templates/clips/app/i18n/ko-KR.ts +11 -1
  111. package/corpus/templates/clips/app/i18n/pt-BR.ts +11 -1
  112. package/corpus/templates/clips/app/i18n/zh-CN.ts +11 -1
  113. package/corpus/templates/clips/app/i18n/zh-TW.ts +11 -1
  114. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +72 -1
  115. package/corpus/templates/clips/changelog/2026-07-17-choose-which-workspace-receives-new-clips-recordings-and-des.md +6 -0
  116. package/corpus/templates/clips/changelog/2026-07-17-create-folders-directly-from-the-move-menu.md +6 -0
  117. package/corpus/templates/clips/changelog/2026-07-17-failed-desktop-uploads-now-offer-a-direct-way-to-reopen-clip.md +6 -0
  118. package/corpus/templates/clips/desktop/src/app.tsx +1 -1
  119. package/corpus/templates/content/app/entry.client.tsx +6 -1
  120. package/corpus/templates/dispatch/AGENTS.md +5 -0
  121. package/corpus/templates/dispatch/changelog/2026-07-17-apps-page-links-to-other-available-apps.md +6 -0
  122. package/corpus/templates/dispatch/changelog/2026-07-17-curated-template-remixes.md +6 -0
  123. package/corpus/templates/mail/app/entry.client.tsx +6 -1
  124. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +11 -7
  125. package/corpus/templates/slides/.env.example +0 -1
  126. package/corpus/templates/slides/AGENTS.md +4 -0
  127. package/corpus/templates/slides/DEVELOPING.md +2 -2
  128. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
  129. package/corpus/templates/slides/actions/logo-config.ts +6 -7
  130. package/corpus/templates/slides/actions/search-images.ts +11 -39
  131. package/corpus/templates/slides/actions/search-logos.ts +5 -52
  132. package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +1 -1
  133. package/corpus/templates/slides/app/components/editor/LogoSearchPanel.tsx +16 -26
  134. package/corpus/templates/slides/app/entry.client.tsx +6 -1
  135. package/corpus/templates/slides/server/lib/media-search-providers.ts +216 -0
  136. package/corpus/templates/slides/server/register-secrets.ts +30 -0
  137. package/dist/a2a/client.d.ts +38 -1
  138. package/dist/a2a/client.d.ts.map +1 -1
  139. package/dist/a2a/client.js +81 -12
  140. package/dist/a2a/client.js.map +1 -1
  141. package/dist/a2a/handlers.d.ts.map +1 -1
  142. package/dist/a2a/handlers.js +47 -0
  143. package/dist/a2a/handlers.js.map +1 -1
  144. package/dist/a2a/index.d.ts +4 -4
  145. package/dist/a2a/index.d.ts.map +1 -1
  146. package/dist/a2a/index.js +2 -2
  147. package/dist/a2a/index.js.map +1 -1
  148. package/dist/a2a/invoke.d.ts +26 -2
  149. package/dist/a2a/invoke.d.ts.map +1 -1
  150. package/dist/a2a/invoke.js +30 -1
  151. package/dist/a2a/invoke.js.map +1 -1
  152. package/dist/a2a/server.d.ts.map +1 -1
  153. package/dist/a2a/server.js +14 -1
  154. package/dist/a2a/server.js.map +1 -1
  155. package/dist/a2a/types.d.ts +12 -0
  156. package/dist/a2a/types.d.ts.map +1 -1
  157. package/dist/a2a/types.js.map +1 -1
  158. package/dist/action.d.ts +3 -2
  159. package/dist/action.d.ts.map +1 -1
  160. package/dist/action.js.map +1 -1
  161. package/dist/agent/production-agent.d.ts +5 -0
  162. package/dist/agent/production-agent.d.ts.map +1 -1
  163. package/dist/agent/production-agent.js +5 -3
  164. package/dist/agent/production-agent.js.map +1 -1
  165. package/dist/client/AssistantChat.d.ts +14 -1
  166. package/dist/client/AssistantChat.d.ts.map +1 -1
  167. package/dist/client/AssistantChat.js +158 -136
  168. package/dist/client/AssistantChat.js.map +1 -1
  169. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  170. package/dist/client/MultiTabAssistantChat.js +27 -4
  171. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  172. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  173. package/dist/client/agent-chat-adapter.js +21 -39
  174. package/dist/client/agent-chat-adapter.js.map +1 -1
  175. package/dist/client/agent-sidebar-state.d.ts +1 -0
  176. package/dist/client/agent-sidebar-state.d.ts.map +1 -1
  177. package/dist/client/agent-sidebar-state.js +4 -0
  178. package/dist/client/agent-sidebar-state.js.map +1 -1
  179. package/dist/client/analytics.d.ts +14 -0
  180. package/dist/client/analytics.d.ts.map +1 -1
  181. package/dist/client/analytics.js +67 -0
  182. package/dist/client/analytics.js.map +1 -1
  183. package/dist/client/chat/message-components.d.ts +8 -0
  184. package/dist/client/chat/message-components.d.ts.map +1 -1
  185. package/dist/client/chat/message-components.js +62 -19
  186. package/dist/client/chat/message-components.js.map +1 -1
  187. package/dist/client/chat/tool-call-display.d.ts +6 -0
  188. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  189. package/dist/client/chat/tool-call-display.js +83 -14
  190. package/dist/client/chat/tool-call-display.js.map +1 -1
  191. package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts +8 -0
  192. package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts.map +1 -0
  193. package/dist/client/chat/use-agent-chat-lifecycle-tracking.js +51 -0
  194. package/dist/client/chat/use-agent-chat-lifecycle-tracking.js.map +1 -0
  195. package/dist/client/chat-thread-url.d.ts +2 -0
  196. package/dist/client/chat-thread-url.d.ts.map +1 -0
  197. package/dist/client/chat-thread-url.js +12 -0
  198. package/dist/client/chat-thread-url.js.map +1 -0
  199. package/dist/client/error-capture.d.ts.map +1 -1
  200. package/dist/client/error-capture.js +7 -0
  201. package/dist/client/error-capture.js.map +1 -1
  202. package/dist/client/extensions/ExtensionSlot.d.ts +3 -1
  203. package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
  204. package/dist/client/extensions/ExtensionSlot.js +28 -3
  205. package/dist/client/extensions/ExtensionSlot.js.map +1 -1
  206. package/dist/client/index.d.ts +1 -1
  207. package/dist/client/index.d.ts.map +1 -1
  208. package/dist/client/index.js +1 -1
  209. package/dist/client/index.js.map +1 -1
  210. package/dist/client/route-chunk-recovery.d.ts.map +1 -1
  211. package/dist/client/route-chunk-recovery.js +14 -9
  212. package/dist/client/route-chunk-recovery.js.map +1 -1
  213. package/dist/client/session-replay.d.ts +15 -0
  214. package/dist/client/session-replay.d.ts.map +1 -1
  215. package/dist/client/session-replay.js +20 -0
  216. package/dist/client/session-replay.js.map +1 -1
  217. package/dist/collab/routes.d.ts +1 -1
  218. package/dist/collab/struct-routes.d.ts +1 -1
  219. package/dist/extensions/actions.d.ts.map +1 -1
  220. package/dist/extensions/actions.js +2 -10
  221. package/dist/extensions/actions.js.map +1 -1
  222. package/dist/extensions/store.js +1 -1
  223. package/dist/extensions/store.js.map +1 -1
  224. package/dist/localization/default-messages.d.ts +3 -0
  225. package/dist/localization/default-messages.d.ts.map +1 -1
  226. package/dist/localization/default-messages.js +3 -0
  227. package/dist/localization/default-messages.js.map +1 -1
  228. package/dist/mcp/build-server.d.ts +2 -0
  229. package/dist/mcp/build-server.d.ts.map +1 -1
  230. package/dist/mcp/build-server.js +2 -2
  231. package/dist/mcp/build-server.js.map +1 -1
  232. package/dist/notifications/routes.d.ts +2 -2
  233. package/dist/observability/routes.d.ts +1 -1
  234. package/dist/progress/actions.d.ts.map +1 -1
  235. package/dist/progress/actions.js +3 -2
  236. package/dist/progress/actions.js.map +1 -1
  237. package/dist/progress/routes.d.ts +1 -1
  238. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  239. package/dist/provider-api/index.d.ts.map +1 -1
  240. package/dist/provider-api/index.js +91 -8
  241. package/dist/provider-api/index.js.map +1 -1
  242. package/dist/resources/handlers.d.ts +2 -2
  243. package/dist/scripts/call-agent.d.ts.map +1 -1
  244. package/dist/scripts/call-agent.js +107 -16
  245. package/dist/scripts/call-agent.js.map +1 -1
  246. package/dist/server/agent-chat/action-filters-a2a.d.ts +6 -0
  247. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  248. package/dist/server/agent-chat/action-filters-a2a.js +27 -0
  249. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  250. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  251. package/dist/server/agent-chat-plugin.js +27 -1
  252. package/dist/server/agent-chat-plugin.js.map +1 -1
  253. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  254. package/dist/server/transcribe-voice.d.ts +1 -1
  255. package/dist/styles/agent-conversation.css +7 -0
  256. package/dist/templates/default/app/i18n/ar-SA.ts +20 -0
  257. package/dist/templates/default/app/i18n/de-DE.ts +20 -0
  258. package/dist/templates/default/app/i18n/en-US.ts +20 -0
  259. package/dist/templates/default/app/i18n/es-ES.ts +20 -0
  260. package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
  261. package/dist/templates/default/app/i18n/hi-IN.ts +19 -0
  262. package/dist/templates/default/app/i18n/ja-JP.ts +20 -0
  263. package/dist/templates/default/app/i18n/ko-KR.ts +19 -0
  264. package/dist/templates/default/app/i18n/pt-BR.ts +20 -0
  265. package/dist/templates/default/app/i18n/zh-CN.ts +19 -0
  266. package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
  267. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
  268. package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
  269. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
  270. package/package.json +1 -1
  271. package/src/templates/default/app/i18n/ar-SA.ts +20 -0
  272. package/src/templates/default/app/i18n/de-DE.ts +20 -0
  273. package/src/templates/default/app/i18n/en-US.ts +20 -0
  274. package/src/templates/default/app/i18n/es-ES.ts +20 -0
  275. package/src/templates/default/app/i18n/fr-FR.ts +21 -0
  276. package/src/templates/default/app/i18n/hi-IN.ts +19 -0
  277. package/src/templates/default/app/i18n/ja-JP.ts +20 -0
  278. package/src/templates/default/app/i18n/ko-KR.ts +19 -0
  279. package/src/templates/default/app/i18n/pt-BR.ts +20 -0
  280. package/src/templates/default/app/i18n/zh-CN.ts +19 -0
  281. package/src/templates/default/app/i18n/zh-TW.ts +19 -0
  282. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
  283. package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
  284. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
  285. package/corpus/templates/analytics/server/handlers/github.ts +0 -200
  286. package/corpus/templates/analytics/server/handlers/pylon.ts +0 -43
  287. package/corpus/templates/analytics/server/lib/apollo.ts +0 -167
  288. package/corpus/templates/analytics/server/lib/commonroom.ts +0 -149
  289. package/corpus/templates/analytics/server/lib/github.ts +0 -660
  290. package/corpus/templates/analytics/server/lib/mixpanel.ts +0 -156
  291. package/corpus/templates/analytics/server/lib/posthog.ts +0 -194
  292. package/corpus/templates/analytics/server/lib/pylon.ts +0 -109
  293. package/corpus/templates/analytics/server/routes/api/github/graphql.post.ts +0 -1
  294. package/corpus/templates/analytics/server/routes/api/github/issue.get.ts +0 -1
  295. package/corpus/templates/analytics/server/routes/api/github/org-prs.get.ts +0 -1
  296. package/corpus/templates/analytics/server/routes/api/github/pr.get.ts +0 -1
  297. package/corpus/templates/analytics/server/routes/api/github/prs.get.ts +0 -1
  298. package/corpus/templates/analytics/server/routes/api/github/search.get.ts +0 -1
  299. package/corpus/templates/slides/actions/fetch-logos.ts +0 -90
  300. package/corpus/templates/slides/actions/image-search.ts +0 -64
  301. package/corpus/templates/slides/actions/import-github.ts +0 -182
  302. package/corpus/templates/slides/actions/logo-lookup.ts +0 -113
@@ -0,0 +1,216 @@
1
+ import { resolveSecret } from "@agent-native/core/server";
2
+
3
+ const GOOGLE_IMAGE_SEARCH_URL = "https://www.googleapis.com/customsearch/v1";
4
+ const LOGO_DEV_SEARCH_URL = "https://api.logo.dev/search";
5
+ const PROVIDER_TIMEOUT_MS = 15_000;
6
+
7
+ export interface ImageSearchResult {
8
+ url: string;
9
+ thumbnail: string;
10
+ title: string;
11
+ width?: number;
12
+ height?: number;
13
+ }
14
+
15
+ export interface LogoSearchResult {
16
+ name: string;
17
+ domain: string;
18
+ logoUrl: string;
19
+ source: "logo.dev" | "domain-guess";
20
+ }
21
+
22
+ export interface MediaSearchRuntime {
23
+ resolveSecret: (key: string) => Promise<string | null | undefined>;
24
+ fetch: typeof fetch;
25
+ }
26
+
27
+ const defaultRuntime: MediaSearchRuntime = {
28
+ resolveSecret,
29
+ fetch: (...args) => fetch(...args),
30
+ };
31
+
32
+ function fetchOptions(init: RequestInit = {}): RequestInit {
33
+ return {
34
+ ...init,
35
+ signal: init.signal ?? AbortSignal.timeout(PROVIDER_TIMEOUT_MS),
36
+ };
37
+ }
38
+
39
+ function normalizedDomain(value: string): string {
40
+ return value
41
+ .trim()
42
+ .toLowerCase()
43
+ .replace(/^https?:\/\//, "")
44
+ .replace(/^www\./, "")
45
+ .split("/", 1)[0]!
46
+ .replace(/[^a-z0-9.-]/g, "");
47
+ }
48
+
49
+ function logoResult(
50
+ name: string,
51
+ domain: string,
52
+ source: LogoSearchResult["source"],
53
+ ): LogoSearchResult | null {
54
+ const normalized = normalizedDomain(domain);
55
+ if (!normalized || !normalized.includes(".")) return null;
56
+ return {
57
+ name: name.trim() || normalized.split(".")[0] || normalized,
58
+ domain: normalized,
59
+ logoUrl: `https://cdn.brandfetch.io/${normalized}/logo.png`,
60
+ source,
61
+ };
62
+ }
63
+
64
+ function guessedLogoDomains(query: string): LogoSearchResult[] {
65
+ const normalized = normalizedDomain(query);
66
+ if (normalized.includes(".")) {
67
+ const result = logoResult(
68
+ normalized.split(".")[0] ?? normalized,
69
+ normalized,
70
+ "domain-guess",
71
+ );
72
+ return result ? [result] : [];
73
+ }
74
+
75
+ const compact = query.toLowerCase().replace(/[^a-z0-9]/g, "");
76
+ const dashed = query
77
+ .toLowerCase()
78
+ .replace(/[^a-z0-9]+/g, "-")
79
+ .replace(/^-|-$/g, "");
80
+ if (!compact) return [];
81
+
82
+ const candidates = [
83
+ ...["com", "io", "co", "dev", "org", "net"].map(
84
+ (tld) => `${compact}.${tld}`,
85
+ ),
86
+ ...(dashed && dashed !== compact ? [`${dashed}.com`] : []),
87
+ ];
88
+ return candidates.flatMap((domain) => {
89
+ const result = logoResult(query, domain, "domain-guess");
90
+ return result ? [result] : [];
91
+ });
92
+ }
93
+
94
+ export async function searchProviderImages(
95
+ query: string,
96
+ count = 10,
97
+ runtime: MediaSearchRuntime = defaultRuntime,
98
+ ): Promise<ImageSearchResult[]> {
99
+ const normalizedQuery = query.trim();
100
+ if (!normalizedQuery) throw new Error("Image search requires a query.");
101
+
102
+ const [apiKey, searchEngineId] = await Promise.all([
103
+ runtime.resolveSecret("GOOGLE_API_KEY"),
104
+ runtime.resolveSecret("GOOGLE_SEARCH_CX"),
105
+ ]);
106
+ if (!apiKey || !searchEngineId) {
107
+ throw new Error(
108
+ "Google Search not configured. Save GOOGLE_API_KEY and GOOGLE_SEARCH_CX in settings.",
109
+ );
110
+ }
111
+
112
+ const params = new URLSearchParams({
113
+ key: apiKey,
114
+ cx: searchEngineId,
115
+ q: normalizedQuery,
116
+ searchType: "image",
117
+ num: String(Math.max(1, Math.min(Math.floor(count), 10))),
118
+ safe: "active",
119
+ });
120
+ const response = await runtime.fetch(
121
+ `${GOOGLE_IMAGE_SEARCH_URL}?${params}`,
122
+ fetchOptions(),
123
+ );
124
+ if (!response.ok) {
125
+ throw new Error(`Google image search failed (${response.status}).`);
126
+ }
127
+
128
+ const data = (await response.json()) as {
129
+ items?: Array<{
130
+ link?: unknown;
131
+ title?: unknown;
132
+ image?: {
133
+ width?: unknown;
134
+ height?: unknown;
135
+ thumbnailLink?: unknown;
136
+ };
137
+ }>;
138
+ };
139
+ return (data.items ?? []).flatMap((item) => {
140
+ if (typeof item.link !== "string" || !item.link) return [];
141
+ const thumbnail =
142
+ typeof item.image?.thumbnailLink === "string"
143
+ ? item.image.thumbnailLink
144
+ : item.link;
145
+ return [
146
+ {
147
+ url: item.link,
148
+ thumbnail,
149
+ title: typeof item.title === "string" ? item.title : "Untitled image",
150
+ ...(typeof item.image?.width === "number"
151
+ ? { width: item.image.width }
152
+ : {}),
153
+ ...(typeof item.image?.height === "number"
154
+ ? { height: item.image.height }
155
+ : {}),
156
+ },
157
+ ];
158
+ });
159
+ }
160
+
161
+ export async function searchProviderLogos(
162
+ query: string,
163
+ runtime: MediaSearchRuntime = defaultRuntime,
164
+ ): Promise<LogoSearchResult[]> {
165
+ const normalizedQuery = query.trim();
166
+ if (!normalizedQuery) throw new Error("Logo search requires a query.");
167
+
168
+ const secretKey = await runtime.resolveSecret("LOGO_DEV_SECRET_KEY");
169
+ if (secretKey?.startsWith("sk_")) {
170
+ try {
171
+ const url = new URL(LOGO_DEV_SEARCH_URL);
172
+ url.searchParams.set("q", normalizedQuery);
173
+ const response = await runtime.fetch(
174
+ url,
175
+ fetchOptions({
176
+ headers: { Authorization: `Bearer ${secretKey}` },
177
+ }),
178
+ );
179
+ if (response.ok) {
180
+ const data = (await response.json()) as Array<{
181
+ name?: unknown;
182
+ domain?: unknown;
183
+ }>;
184
+ const results = data.flatMap((item) => {
185
+ if (typeof item.domain !== "string") return [];
186
+ const result = logoResult(
187
+ typeof item.name === "string" ? item.name : normalizedQuery,
188
+ item.domain,
189
+ "logo.dev",
190
+ );
191
+ return result ? [result] : [];
192
+ });
193
+ if (results.length > 0) return results;
194
+ }
195
+ } catch {
196
+ // The deterministic domain fallback keeps the UI usable during provider outages.
197
+ }
198
+ }
199
+
200
+ return guessedLogoDomains(normalizedQuery);
201
+ }
202
+
203
+ export async function getLogoProviderConfig(
204
+ runtime: MediaSearchRuntime = defaultRuntime,
205
+ ) {
206
+ const [brandfetchId, logoDevToken, logoDevSecret] = await Promise.all([
207
+ runtime.resolveSecret("BRANDFETCH_CLIENT_ID"),
208
+ runtime.resolveSecret("LOGO_DEV_TOKEN"),
209
+ runtime.resolveSecret("LOGO_DEV_SECRET_KEY"),
210
+ ]);
211
+ return {
212
+ brandfetchId: brandfetchId || null,
213
+ logoDevToken: logoDevToken?.startsWith("pk_") ? logoDevToken : null,
214
+ hasLogoDevSecret: logoDevSecret?.startsWith("sk_") === true,
215
+ };
216
+ }
@@ -94,6 +94,36 @@ registerRequiredSecret({
94
94
  required: false,
95
95
  });
96
96
 
97
+ registerRequiredSecret({
98
+ key: "LOGO_DEV_SECRET_KEY",
99
+ label: "Logo.dev Search Key",
100
+ description: "Optional server-side key for company and domain logo search.",
101
+ docsUrl: "https://www.logo.dev/",
102
+ scope: "user",
103
+ kind: "api-key",
104
+ required: false,
105
+ });
106
+
107
+ registerRequiredSecret({
108
+ key: "LOGO_DEV_TOKEN",
109
+ label: "Logo.dev Publishable Token",
110
+ description: "Optional publishable token for rendering Logo.dev images.",
111
+ docsUrl: "https://www.logo.dev/",
112
+ scope: "user",
113
+ kind: "api-key",
114
+ required: false,
115
+ });
116
+
117
+ registerRequiredSecret({
118
+ key: "BRANDFETCH_CLIENT_ID",
119
+ label: "Brandfetch Client ID",
120
+ description: "Optional public client ID for Brandfetch logo rendering.",
121
+ docsUrl: "https://developers.brandfetch.com/",
122
+ scope: "user",
123
+ kind: "api-key",
124
+ required: false,
125
+ });
126
+
97
127
  registerRequiredSecret({
98
128
  key: "GOOGLE_CLIENT_ID",
99
129
  label: "Google OAuth Client ID",
@@ -1,4 +1,4 @@
1
- import type { A2AApprovedAction, AgentCard, Message, Task } from "./types.js";
1
+ import type { A2AApprovedAction, A2AReadOnlyActionResult, AgentCard, Message, Task } from "./types.js";
2
2
  export declare class A2ATaskTimeoutError extends Error {
3
3
  readonly taskId: string;
4
4
  readonly lastTask: Task;
@@ -66,6 +66,12 @@ export declare class A2AClient {
66
66
  * Poll for a task by id. Used in async mode after `send({ async: true })`.
67
67
  */
68
68
  getTask(taskId: string): Promise<Task>;
69
+ /**
70
+ * Execute one receiver-approved read-only action without starting the
71
+ * receiver's agent loop. The receiver still owns validation, credentials,
72
+ * request scoping, and the explicit action exposure decision.
73
+ */
74
+ invokeAction(action: string, input?: Record<string, unknown>): Promise<A2AReadOnlyActionResult>;
69
75
  /**
70
76
  * Send a message in async mode and poll until the task reaches a terminal
71
77
  * state. This is the recommended path on serverless hosts with short
@@ -86,6 +92,20 @@ export declare class A2AClient {
86
92
  /** Called with each polled task — useful for surfacing progress. */
87
93
  onUpdate?: (task: Task) => void;
88
94
  }): Promise<Task>;
95
+ /**
96
+ * Continue waiting for an existing async task without submitting a second
97
+ * message. Use this after a bounded caller-side wait expires but the remote
98
+ * task is still working.
99
+ */
100
+ waitForTask(taskId: string, opts?: {
101
+ /** Total time to wait for completion. Default 5 min. */
102
+ timeoutMs?: number;
103
+ /** Poll interval. Default 2s. */
104
+ pollIntervalMs?: number;
105
+ /** Called with each successfully polled task. */
106
+ onUpdate?: (task: Task) => void;
107
+ }): Promise<Task>;
108
+ private pollTask;
89
109
  stream(message: Message, opts?: {
90
110
  contextId?: string;
91
111
  metadata?: Record<string, unknown>;
@@ -118,6 +138,11 @@ export declare function callAgent(url: string, text: string, opts?: {
118
138
  async?: boolean;
119
139
  /** Total time to wait for the polled task (default 5 min). */
120
140
  timeoutMs?: number;
141
+ /**
142
+ * Existing async task to keep polling. When set, no new message is sent.
143
+ * This prevents a caller-side timeout from duplicating downstream work.
144
+ */
145
+ taskId?: string;
121
146
  /** Poll interval for async calls. Primarily useful for tests/retries. */
122
147
  pollIntervalMs?: number;
123
148
  /**
@@ -137,4 +162,16 @@ export declare function callAgent(url: string, text: string, opts?: {
137
162
  */
138
163
  onUpdate?: (task: Task) => void;
139
164
  }): Promise<string>;
165
+ /**
166
+ * Invoke one receiver-approved read-only action with an audience-bound user
167
+ * token. Unlike conversational delegation, this never starts the receiver's
168
+ * model loop.
169
+ */
170
+ export declare function callAction(url: string, action: string, input?: Record<string, unknown>, opts?: {
171
+ apiKey?: string;
172
+ userEmail?: string;
173
+ orgDomain?: string;
174
+ orgSecret?: string;
175
+ requestTimeoutMs?: number;
176
+ }): Promise<A2AReadOnlyActionResult>;
140
177
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,SAAS,EAGT,OAAO,EACP,IAAI,EACL,MAAM,YAAY,CAAC;AAEpB,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAU5D;CACF;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC,GACA,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,wBAAgB,2BAA2B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,kBAAkB,CAAgB;IAC1C,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAElC,YACE,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EAepE;IAED;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBrC;IAED,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,mBAAmB;YAQb,GAAG;IAyDX,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC,CAUvC;IAEK,IAAI,CACR,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,eAAe,CAAC,EAAE,iBAAiB,EAAE,CAAC;QACtC;;;;;;;WAOG;QACH,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,GACA,OAAO,CAAC,IAAI,CAAC,CAkBf;IAED;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ3C;IAED;;;;OAIG;IACG,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAClC,OAAO,CAAC,uBAAuB,CAAC,CAQlC;IAED;;;;;;;;OAQG;IACG,WAAW,CACf,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,eAAe,CAAC,EAAE,iBAAiB,EAAE,CAAC;QACtC,wDAAwD;QACxD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,iCAAiC;QACjC,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,oEAAoE;QACpE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;KACjC,GACA,OAAO,CAAC,IAAI,CAAC,CAWf;IAED;;;;OAIG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;QACL,wDAAwD;QACxD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,iCAAiC;QACjC,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,iDAAiD;QACjD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;KACjC,GACA,OAAO,CAAC,IAAI,CAAC,CAIf;YAEa,QAAQ;IAmCf,MAAM,CACX,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAChE,cAAc,CAAC,IAAI,CAAC,CAsEtB;YAEa,wBAAwB;YAyBxB,QAAQ;CA2BvB;AAiFD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;IACL,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,mCAAmC,CAAC,EAAE,OAAO,CAAC;IAC9C;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACjC,GACA,OAAO,CAAC,MAAM,CAAC,CAuFjB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,IAAI,CAAC,EAAE;IACL,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACA,OAAO,CAAC,uBAAuB,CAAC,CAmBlC"}
@@ -130,9 +130,15 @@ export class A2AClient {
130
130
  const res = await this.postJson(url, body, this.apiKeyAttempts[i]);
131
131
  console.log(`[A2A Client] Response: ${res.status} in ${Date.now() - startTime}ms`);
132
132
  if (res.ok) {
133
+ const text = await res.text();
134
+ if (i < this.apiKeyAttempts.length - 1 &&
135
+ isA2AAuthRejectionResponse(res.status, text)) {
136
+ lastError = new Error(`A2A request failed (${res.status}): ${text}`);
137
+ continue;
138
+ }
133
139
  this.endpointCandidates = [url];
134
140
  this.markApiKeySucceeded(this.apiKeyAttempts[i]);
135
- return res.json();
141
+ return JSON.parse(text);
136
142
  }
137
143
  const text = await res.text();
138
144
  lastError = new Error(`A2A request failed (${res.status}): ${text}`);
@@ -180,6 +186,18 @@ export class A2AClient {
180
186
  }
181
187
  return response.result;
182
188
  }
189
+ /**
190
+ * Execute one receiver-approved read-only action without starting the
191
+ * receiver's agent loop. The receiver still owns validation, credentials,
192
+ * request scoping, and the explicit action exposure decision.
193
+ */
194
+ async invokeAction(action, input = {}) {
195
+ const response = await this.rpc("actions/invoke", { action, input });
196
+ if (response.error) {
197
+ throw new Error(`A2A error (${response.error.code}): ${response.error.message}`);
198
+ }
199
+ return response.result;
200
+ }
183
201
  /**
184
202
  * Send a message in async mode and poll until the task reaches a terminal
185
203
  * state. This is the recommended path on serverless hosts with short
@@ -198,6 +216,19 @@ export class A2AClient {
198
216
  : {}),
199
217
  async: true,
200
218
  });
219
+ return this.pollTask(submitted, opts);
220
+ }
221
+ /**
222
+ * Continue waiting for an existing async task without submitting a second
223
+ * message. Use this after a bounded caller-side wait expires but the remote
224
+ * task is still working.
225
+ */
226
+ async waitForTask(taskId, opts) {
227
+ const current = await this.getTask(taskId);
228
+ opts?.onUpdate?.(current);
229
+ return this.pollTask(current, opts);
230
+ }
231
+ async pollTask(submitted, opts) {
201
232
  const terminalStates = new Set([
202
233
  "completed",
203
234
  "failed",
@@ -399,6 +430,7 @@ function uniqueAuthTokens(values) {
399
430
  }
400
431
  function isA2AAuthRejectionResponse(status, text) {
401
432
  return (status === 401 ||
433
+ /verified, audience-bound user identity/i.test(text) ||
402
434
  /A2A error \(-32001\): (?:Invalid or expired A2A token|Invalid API key|Authentication required)|Invalid or expired A2A token|Invalid API key|Authentication required/i.test(text));
403
435
  }
404
436
  /**
@@ -438,18 +470,27 @@ export async function callAgent(url, text, opts) {
438
470
  });
439
471
  let task;
440
472
  if (useAsync) {
441
- task = await client.sendAndWait(message, {
442
- contextId: opts?.contextId,
443
- metadata,
444
- ...(opts?.approvedActions?.length
445
- ? { approvedActions: opts.approvedActions }
446
- : {}),
447
- timeoutMs: opts?.timeoutMs,
448
- pollIntervalMs: opts?.pollIntervalMs,
449
- onUpdate: opts?.onUpdate,
450
- });
473
+ task = opts?.taskId
474
+ ? await client.waitForTask(opts.taskId, {
475
+ timeoutMs: opts.timeoutMs,
476
+ pollIntervalMs: opts.pollIntervalMs,
477
+ onUpdate: opts.onUpdate,
478
+ })
479
+ : await client.sendAndWait(message, {
480
+ contextId: opts?.contextId,
481
+ metadata,
482
+ ...(opts?.approvedActions?.length
483
+ ? { approvedActions: opts.approvedActions }
484
+ : {}),
485
+ timeoutMs: opts?.timeoutMs,
486
+ pollIntervalMs: opts?.pollIntervalMs,
487
+ onUpdate: opts?.onUpdate,
488
+ });
451
489
  }
452
490
  else {
491
+ if (opts?.taskId) {
492
+ throw new Error("Polling an existing A2A task requires async mode");
493
+ }
453
494
  task = await client.send(message, {
454
495
  contextId: opts?.contextId,
455
496
  metadata,
@@ -486,7 +527,29 @@ export async function callAgent(url, text, opts) {
486
527
  throw lastAuthError;
487
528
  return "";
488
529
  }
489
- async function buildA2AApiKeyAttempts(opts) {
530
+ /**
531
+ * Invoke one receiver-approved read-only action with an audience-bound user
532
+ * token. Unlike conversational delegation, this never starts the receiver's
533
+ * model loop.
534
+ */
535
+ export async function callAction(url, action, input = {}, opts) {
536
+ const actionName = action.trim();
537
+ if (!actionName)
538
+ throw new Error("A2A action name is required");
539
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
540
+ throw new Error("A2A action input must be an object");
541
+ }
542
+ const apiKeyAttempts = await buildA2AApiKeyAttempts(opts, normalizeA2AAudience(url));
543
+ const fallbackApiKeys = apiKeyAttempts
544
+ .slice(1)
545
+ .filter((token) => token !== undefined);
546
+ const client = new A2AClient(url, apiKeyAttempts[0], {
547
+ fallbackApiKeys,
548
+ requestTimeoutMs: opts?.requestTimeoutMs,
549
+ });
550
+ return client.invokeAction(actionName, input);
551
+ }
552
+ async function buildA2AApiKeyAttempts(opts, audience) {
490
553
  const attempts = [];
491
554
  const add = (token) => {
492
555
  if (token === undefined || attempts.includes(token))
@@ -499,6 +562,7 @@ async function buildA2AApiKeyAttempts(opts) {
499
562
  try {
500
563
  add(await signA2AToken(opts.userEmail, opts.orgDomain, opts.orgSecret, {
501
564
  preferGlobalSecret: true,
565
+ audience,
502
566
  }));
503
567
  }
504
568
  catch {
@@ -509,6 +573,7 @@ async function buildA2AApiKeyAttempts(opts) {
509
573
  try {
510
574
  add(await signA2AToken(opts.userEmail, opts.orgDomain, opts.orgSecret, {
511
575
  preferGlobalSecret: false,
576
+ audience,
512
577
  }));
513
578
  }
514
579
  catch {
@@ -520,6 +585,10 @@ async function buildA2AApiKeyAttempts(opts) {
520
585
  attempts.push(undefined);
521
586
  return attempts;
522
587
  }
588
+ function normalizeA2AAudience(url) {
589
+ const explicit = splitExplicitA2AEndpoint(url.replace(/\/$/, ""));
590
+ return (explicit?.baseUrl ?? url).replace(/\/$/, "");
591
+ }
523
592
  function isA2AAuthRejection(err) {
524
593
  const message = err instanceof Error ? err.message : String(err ?? "");
525
594
  return /A2A request failed \(401\)|A2A error \(-32001\): (?:Invalid or expired A2A token|Invalid API key|Authentication required)|Invalid or expired A2A token|Invalid API key|Authentication required/i.test(message);