@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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +18 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +140 -17
- package/corpus/core/src/a2a/handlers.ts +60 -0
- package/corpus/core/src/a2a/index.ts +6 -1
- package/corpus/core/src/a2a/invoke.ts +68 -1
- package/corpus/core/src/a2a/server.ts +13 -1
- package/corpus/core/src/a2a/types.ts +16 -0
- package/corpus/core/src/action.ts +3 -2
- package/corpus/core/src/agent/production-agent.ts +10 -4
- package/corpus/core/src/client/AssistantChat.tsx +648 -603
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -4
- package/corpus/core/src/client/agent-chat-adapter.ts +23 -37
- package/corpus/core/src/client/agent-sidebar-state.ts +4 -0
- package/corpus/core/src/client/analytics.ts +84 -0
- package/corpus/core/src/client/chat/message-components.tsx +94 -22
- package/corpus/core/src/client/chat/tool-call-display.tsx +170 -47
- package/corpus/core/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
- package/corpus/core/src/client/chat-thread-url.ts +11 -0
- package/corpus/core/src/client/error-capture.ts +12 -0
- package/corpus/core/src/client/extensions/ExtensionSlot.tsx +37 -1
- package/corpus/core/src/client/index.ts +2 -0
- package/corpus/core/src/client/route-chunk-recovery.ts +20 -8
- package/corpus/core/src/client/session-replay.ts +31 -0
- package/corpus/core/src/extensions/actions.ts +2 -14
- package/corpus/core/src/extensions/store.ts +1 -1
- package/corpus/core/src/localization/default-messages.ts +3 -0
- package/corpus/core/src/mcp/build-server.ts +2 -2
- package/corpus/core/src/progress/actions.ts +4 -2
- package/corpus/core/src/provider-api/index.ts +205 -105
- package/corpus/core/src/scripts/call-agent.ts +137 -17
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +40 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +31 -0
- package/corpus/core/src/styles/agent-conversation.css +7 -0
- package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -10
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +54 -23
- package/corpus/templates/analytics/.builder/skills/apollo/SKILL.md +19 -41
- package/corpus/templates/analytics/.builder/skills/commonroom/SKILL.md +20 -35
- package/corpus/templates/analytics/.builder/skills/github/SKILL.md +23 -67
- package/corpus/templates/analytics/.builder/skills/pylon/SKILL.md +25 -43
- package/corpus/templates/analytics/AGENTS.md +22 -13
- package/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
- package/corpus/templates/analytics/actions/configure-gong-native-insights.ts +29 -0
- package/corpus/templates/analytics/actions/content-calendar-schema.ts +8 -4
- package/corpus/templates/analytics/actions/content-calendar.ts +12 -4
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -1
- package/corpus/templates/analytics/actions/gong-calls.ts +113 -22
- package/corpus/templates/analytics/actions/gong-native-insights.ts +166 -0
- package/corpus/templates/analytics/actions/hubspot-deals.ts +190 -46
- package/corpus/templates/analytics/actions/pylon-issues.ts +123 -0
- package/corpus/templates/analytics/actions/slack-messages.ts +179 -27
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +48 -152
- package/corpus/templates/analytics/app/components/ui/chart.tsx +1 -1
- package/corpus/templates/analytics/app/hooks/use-chart-tooltip-flip.ts +21 -6
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +13 -0
- package/corpus/templates/analytics/app/i18n-data.ts +134 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +181 -30
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +4 -3
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-editors-can-add-shared-extensions-or-opt-into-per-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extensions-show-a-loading-skeleton.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-errors-now-group-repeat-failures-consistently-and-keep-priva.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-gong-transcript-reviews-now-batch-bounded-call-windows-for-f.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-hubspot-deal-filters-now-run-in-hubspot-before-paging-result.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-notion-content-calendars-now-discover-the-matching-database-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-pylon-dashboard-reads-now-use-the-paginated-issue-search-api.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-slack-reads-no-longer-join-channels-and-report-pagination-coverage.md +6 -0
- package/corpus/templates/analytics/server/handlers/notion.ts +14 -3
- package/corpus/templates/analytics/server/handlers/slack.ts +182 -29
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -6
- package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +6 -2
- package/corpus/templates/analytics/server/lib/error-capture.ts +75 -8
- package/corpus/templates/analytics/server/lib/gong-native-policy.ts +72 -0
- package/corpus/templates/analytics/server/lib/gong.ts +54 -66
- package/corpus/templates/analytics/server/lib/hubspot.ts +40 -3
- package/corpus/templates/analytics/server/lib/notion.ts +83 -8
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +4 -0
- package/corpus/templates/analytics/server/lib/slack.ts +242 -90
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -3
- package/corpus/templates/analytics/server/routes/api/pylon/accounts.get.ts +42 -1
- package/corpus/templates/analytics/server/routes/api/pylon/issues.get.ts +71 -1
- package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +44 -4
- package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +19 -1
- package/corpus/templates/clips/app/components/library/create-folder-dialog.tsx +123 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +42 -4
- package/corpus/templates/clips/app/components/library/recording-card.tsx +30 -0
- package/corpus/templates/clips/app/entry.client.tsx +6 -1
- package/corpus/templates/clips/app/i18n/ar-SA.ts +12 -1
- package/corpus/templates/clips/app/i18n/de-DE.ts +12 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +12 -1
- package/corpus/templates/clips/app/i18n/es-ES.ts +11 -1
- package/corpus/templates/clips/app/i18n/fr-FR.ts +11 -1
- package/corpus/templates/clips/app/i18n/hi-IN.ts +10 -1
- package/corpus/templates/clips/app/i18n/ja-JP.ts +12 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +11 -1
- package/corpus/templates/clips/app/i18n/pt-BR.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-CN.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-TW.ts +11 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +72 -1
- package/corpus/templates/clips/changelog/2026-07-17-choose-which-workspace-receives-new-clips-recordings-and-des.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-create-folders-directly-from-the-move-menu.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-failed-desktop-uploads-now-offer-a-direct-way-to-reopen-clip.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +1 -1
- package/corpus/templates/content/app/entry.client.tsx +6 -1
- package/corpus/templates/dispatch/AGENTS.md +5 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-apps-page-links-to-other-available-apps.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-curated-template-remixes.md +6 -0
- package/corpus/templates/mail/app/entry.client.tsx +6 -1
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +11 -7
- package/corpus/templates/slides/.env.example +0 -1
- package/corpus/templates/slides/AGENTS.md +4 -0
- package/corpus/templates/slides/DEVELOPING.md +2 -2
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
- package/corpus/templates/slides/actions/logo-config.ts +6 -7
- package/corpus/templates/slides/actions/search-images.ts +11 -39
- package/corpus/templates/slides/actions/search-logos.ts +5 -52
- package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/LogoSearchPanel.tsx +16 -26
- package/corpus/templates/slides/app/entry.client.tsx +6 -1
- package/corpus/templates/slides/server/lib/media-search-providers.ts +216 -0
- package/corpus/templates/slides/server/register-secrets.ts +30 -0
- package/dist/a2a/client.d.ts +38 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +81 -12
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +47 -0
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/index.d.ts +4 -4
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +2 -2
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/invoke.d.ts +26 -2
- package/dist/a2a/invoke.d.ts.map +1 -1
- package/dist/a2a/invoke.js +30 -1
- package/dist/a2a/invoke.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +14 -1
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/types.d.ts +12 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/action.d.ts +3 -2
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +5 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +5 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +158 -136
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +27 -4
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +21 -39
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +1 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -1
- package/dist/client/agent-sidebar-state.js +4 -0
- package/dist/client/agent-sidebar-state.js.map +1 -1
- package/dist/client/analytics.d.ts +14 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +67 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +8 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +62 -19
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +6 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +83 -14
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts +8 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts.map +1 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js +51 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js.map +1 -0
- package/dist/client/chat-thread-url.d.ts +2 -0
- package/dist/client/chat-thread-url.d.ts.map +1 -0
- package/dist/client/chat-thread-url.js +12 -0
- package/dist/client/chat-thread-url.js.map +1 -0
- package/dist/client/error-capture.d.ts.map +1 -1
- package/dist/client/error-capture.js +7 -0
- package/dist/client/error-capture.js.map +1 -1
- package/dist/client/extensions/ExtensionSlot.d.ts +3 -1
- package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionSlot.js +28 -3
- package/dist/client/extensions/ExtensionSlot.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/route-chunk-recovery.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery.js +14 -9
- package/dist/client/route-chunk-recovery.js.map +1 -1
- package/dist/client/session-replay.d.ts +15 -0
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +20 -0
- package/dist/client/session-replay.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +2 -10
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/store.js +1 -1
- package/dist/extensions/store.js.map +1 -1
- package/dist/localization/default-messages.d.ts +3 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +3 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/build-server.d.ts +2 -0
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +2 -2
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +1 -1
- package/dist/progress/actions.d.ts.map +1 -1
- package/dist/progress/actions.js +3 -2
- package/dist/progress/actions.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +91 -8
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +107 -16
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.d.ts +6 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +27 -0
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +27 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/agent-conversation.css +7 -0
- package/dist/templates/default/app/i18n/ar-SA.ts +20 -0
- package/dist/templates/default/app/i18n/de-DE.ts +20 -0
- package/dist/templates/default/app/i18n/en-US.ts +20 -0
- package/dist/templates/default/app/i18n/es-ES.ts +20 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +19 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +20 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +19 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +20 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +19 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
- package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/package.json +1 -1
- package/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/src/templates/default/app/i18n/en-US.ts +20 -0
- package/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
- package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/corpus/templates/analytics/server/handlers/github.ts +0 -200
- package/corpus/templates/analytics/server/handlers/pylon.ts +0 -43
- package/corpus/templates/analytics/server/lib/apollo.ts +0 -167
- package/corpus/templates/analytics/server/lib/commonroom.ts +0 -149
- package/corpus/templates/analytics/server/lib/github.ts +0 -660
- package/corpus/templates/analytics/server/lib/mixpanel.ts +0 -156
- package/corpus/templates/analytics/server/lib/posthog.ts +0 -194
- package/corpus/templates/analytics/server/lib/pylon.ts +0 -109
- package/corpus/templates/analytics/server/routes/api/github/graphql.post.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/issue.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/org-prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/pr.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/search.get.ts +0 -1
- package/corpus/templates/slides/actions/fetch-logos.ts +0 -90
- package/corpus/templates/slides/actions/image-search.ts +0 -64
- package/corpus/templates/slides/actions/import-github.ts +0 -182
- 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",
|
package/dist/a2a/client.d.ts
CHANGED
|
@@ -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
|
package/dist/a2a/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EACjB,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;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"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"}
|
package/dist/a2a/client.js
CHANGED
|
@@ -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
|
|
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 =
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
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
|
-
|
|
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);
|