@agent-native/core 0.108.0 → 0.109.1
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 +25 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +162 -17
- package/corpus/core/src/a2a/correlation.ts +50 -0
- package/corpus/core/src/a2a/handlers.ts +200 -14
- package/corpus/core/src/a2a/index.ts +7 -1
- package/corpus/core/src/a2a/invoke.ts +77 -1
- package/corpus/core/src/a2a/server.ts +13 -1
- package/corpus/core/src/a2a/task-store.ts +146 -6
- package/corpus/core/src/a2a/types.ts +32 -0
- package/corpus/core/src/action.ts +5 -2
- package/corpus/core/src/agent/production-agent.ts +33 -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/client/use-run-stuck-detection.ts +27 -1
- package/corpus/core/src/db/client.ts +55 -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/observability/traces.ts +172 -19
- 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 +190 -19
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +112 -25
- package/corpus/core/src/server/agent-chat-plugin.ts +136 -4
- 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 +49 -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/observability/SKILL.md +7 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- 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/query-agent-native-analytics.ts +1 -1
- 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-analytics-now-includes-a-default-alert-for-spikes-in-stuck-agent-chats.md +6 -0
- 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/docs/schemas/first-party-analytics.md +23 -14
- package/corpus/templates/analytics/docs/schemas/tracked-events.md +5 -1
- 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/jobs/analytics-alerts.ts +3 -3
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -6
- package/corpus/templates/analytics/server/lib/analytics-alerts.ts +209 -87
- 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/actions/finalize-recording.ts +541 -62
- 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/components/player/playback-comment-overlay.tsx +17 -2
- package/corpus/templates/clips/app/components/player/video-player.tsx +14 -2
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +2 -2
- 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/app/routes/r.$recordingId.tsx +1 -1
- package/corpus/templates/clips/app/routes/record.tsx +3 -3
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -3
- 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-clips-now-retries-storage-verification-in-the-background-ins.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/changelog/2026-07-17-fixed-broken-thumbnail-icons-appearing-over-playable-clip-em.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-playback-comments-stay-readable-at-faster-playback-speeds.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +3 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +3 -3
- package/corpus/templates/clips/desktop/src/app.tsx +19 -7
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +111 -13
- package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +16 -7
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -4
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +32 -15
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +45 -18
- package/corpus/templates/clips/server/jobs/media-verification.ts +130 -0
- package/corpus/templates/clips/server/lib/builder-media-compression.ts +15 -0
- package/corpus/templates/clips/server/lib/media-verification-state.ts +38 -0
- package/corpus/templates/clips/server/lib/player-thumbnail-url.ts +31 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +10 -3
- package/corpus/templates/clips/server/plugins/auth.ts +5 -5
- package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +12 -2
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +6 -1
- package/corpus/templates/clips/server/routes/api/thumbnail/[recordingId].get.ts +340 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +24 -7
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +91 -7
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +14 -0
- package/corpus/templates/clips/shared/finalize-recovery.ts +61 -2
- package/corpus/templates/clips/shared/share-meta.ts +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 +47 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +94 -12
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/correlation.d.ts +10 -0
- package/dist/a2a/correlation.d.ts.map +1 -0
- package/dist/a2a/correlation.js +40 -0
- package/dist/a2a/correlation.js.map +1 -0
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +147 -15
- 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 +29 -2
- package/dist/a2a/invoke.d.ts.map +1 -1
- package/dist/a2a/invoke.js +33 -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/task-store.d.ts +12 -1
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +96 -6
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/a2a/types.d.ts +27 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/action.d.ts +5 -2
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +14 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +19 -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/client/use-run-stuck-detection.d.ts.map +1 -1
- package/dist/client/use-run-stuck-detection.js +25 -1
- package/dist/client/use-run-stuck-detection.js.map +1 -1
- package/dist/db/client.d.ts +7 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +33 -0
- package/dist/db/client.js.map +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 +5 -5
- package/dist/observability/traces.d.ts +9 -0
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +137 -19
- package/dist/observability/traces.js.map +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/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +140 -17
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/action-filters-a2a.d.ts +24 -2
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +62 -7
- 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 +118 -5
- 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 +49 -0
- package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- 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 +49 -0
- package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- 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, A2ACorrelationMetadata, 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;
|
|
@@ -51,6 +51,7 @@ export declare class A2AClient {
|
|
|
51
51
|
send(message: Message, opts?: {
|
|
52
52
|
contextId?: string;
|
|
53
53
|
metadata?: Record<string, unknown>;
|
|
54
|
+
idempotencyKey?: string;
|
|
54
55
|
approvedActions?: A2AApprovedAction[];
|
|
55
56
|
/**
|
|
56
57
|
* If true, ask the server to return the task immediately in `working`
|
|
@@ -66,6 +67,14 @@ export declare class A2AClient {
|
|
|
66
67
|
* Poll for a task by id. Used in async mode after `send({ async: true })`.
|
|
67
68
|
*/
|
|
68
69
|
getTask(taskId: string): Promise<Task>;
|
|
70
|
+
/**
|
|
71
|
+
* Execute one receiver-approved read-only action without starting the
|
|
72
|
+
* receiver's agent loop. The receiver still owns validation, credentials,
|
|
73
|
+
* request scoping, and the explicit action exposure decision.
|
|
74
|
+
*/
|
|
75
|
+
invokeAction(action: string, input?: Record<string, unknown>, opts?: {
|
|
76
|
+
metadata?: A2ACorrelationMetadata;
|
|
77
|
+
}): Promise<A2AReadOnlyActionResult>;
|
|
69
78
|
/**
|
|
70
79
|
* Send a message in async mode and poll until the task reaches a terminal
|
|
71
80
|
* state. This is the recommended path on serverless hosts with short
|
|
@@ -78,6 +87,7 @@ export declare class A2AClient {
|
|
|
78
87
|
sendAndWait(message: Message, opts?: {
|
|
79
88
|
contextId?: string;
|
|
80
89
|
metadata?: Record<string, unknown>;
|
|
90
|
+
idempotencyKey?: string;
|
|
81
91
|
approvedActions?: A2AApprovedAction[];
|
|
82
92
|
/** Total time to wait for completion. Default 5 min. */
|
|
83
93
|
timeoutMs?: number;
|
|
@@ -86,6 +96,20 @@ export declare class A2AClient {
|
|
|
86
96
|
/** Called with each polled task — useful for surfacing progress. */
|
|
87
97
|
onUpdate?: (task: Task) => void;
|
|
88
98
|
}): Promise<Task>;
|
|
99
|
+
/**
|
|
100
|
+
* Continue waiting for an existing async task without submitting a second
|
|
101
|
+
* message. Use this after a bounded caller-side wait expires but the remote
|
|
102
|
+
* task is still working.
|
|
103
|
+
*/
|
|
104
|
+
waitForTask(taskId: string, opts?: {
|
|
105
|
+
/** Total time to wait for completion. Default 5 min. */
|
|
106
|
+
timeoutMs?: number;
|
|
107
|
+
/** Poll interval. Default 2s. */
|
|
108
|
+
pollIntervalMs?: number;
|
|
109
|
+
/** Called with each successfully polled task. */
|
|
110
|
+
onUpdate?: (task: Task) => void;
|
|
111
|
+
}): Promise<Task>;
|
|
112
|
+
private pollTask;
|
|
89
113
|
stream(message: Message, opts?: {
|
|
90
114
|
contextId?: string;
|
|
91
115
|
metadata?: Record<string, unknown>;
|
|
@@ -110,6 +134,10 @@ export declare function callAgent(url: string, text: string, opts?: {
|
|
|
110
134
|
requestOrigin?: string;
|
|
111
135
|
/** Exact downstream actions explicitly authorized in the caller's chat. */
|
|
112
136
|
approvedActions?: A2AApprovedAction[];
|
|
137
|
+
/** Bounded telemetry-only lineage forwarded to the receiving app. */
|
|
138
|
+
correlation?: A2ACorrelationMetadata;
|
|
139
|
+
/** Stable caller-generated key for one message submission. */
|
|
140
|
+
idempotencyKey?: string;
|
|
113
141
|
/**
|
|
114
142
|
* Use async/poll instead of a single blocking POST. Recommended for
|
|
115
143
|
* cross-app calls that may exceed a synchronous serverless request budget.
|
|
@@ -118,6 +146,11 @@ export declare function callAgent(url: string, text: string, opts?: {
|
|
|
118
146
|
async?: boolean;
|
|
119
147
|
/** Total time to wait for the polled task (default 5 min). */
|
|
120
148
|
timeoutMs?: number;
|
|
149
|
+
/**
|
|
150
|
+
* Existing async task to keep polling. When set, no new message is sent.
|
|
151
|
+
* This prevents a caller-side timeout from duplicating downstream work.
|
|
152
|
+
*/
|
|
153
|
+
taskId?: string;
|
|
121
154
|
/** Poll interval for async calls. Primarily useful for tests/retries. */
|
|
122
155
|
pollIntervalMs?: number;
|
|
123
156
|
/**
|
|
@@ -137,4 +170,17 @@ export declare function callAgent(url: string, text: string, opts?: {
|
|
|
137
170
|
*/
|
|
138
171
|
onUpdate?: (task: Task) => void;
|
|
139
172
|
}): Promise<string>;
|
|
173
|
+
/**
|
|
174
|
+
* Invoke one receiver-approved read-only action with an audience-bound user
|
|
175
|
+
* token. Unlike conversational delegation, this never starts the receiver's
|
|
176
|
+
* model loop.
|
|
177
|
+
*/
|
|
178
|
+
export declare function callAction(url: string, action: string, input?: Record<string, unknown>, opts?: {
|
|
179
|
+
apiKey?: string;
|
|
180
|
+
userEmail?: string;
|
|
181
|
+
orgDomain?: string;
|
|
182
|
+
orgSecret?: string;
|
|
183
|
+
requestTimeoutMs?: number;
|
|
184
|
+
correlation?: A2ACorrelationMetadata;
|
|
185
|
+
}): Promise<A2AReadOnlyActionResult>;
|
|
140
186
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,iBAAiB,EACjB,sBAAsB,EACtB,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,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,iBAAiB,EAAE,CAAC;QACtC;;;;;;;WAOG;QACH,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,GACA,OAAO,CAAC,IAAI,CAAC,CAmBf;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,EACnC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,sBAAsB,CAAA;KAAE,GAC3C,OAAO,CAAC,uBAAuB,CAAC,CAalC;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,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,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,CAYf;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,qEAAqE;IACrE,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;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,CA0FjB;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;IAC1B,WAAW,CAAC,EAAE,sBAAsB,CAAC;CACtC,GACA,OAAO,CAAC,uBAAuB,CAAC,CAqBlC"}
|
package/dist/a2a/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as jose from "jose";
|
|
2
2
|
import { ssrfSafeFetch } from "../extensions/url-safety.js";
|
|
3
|
+
import { sanitizeA2ACorrelationMetadata } from "./correlation.js";
|
|
3
4
|
export class A2ATaskTimeoutError extends Error {
|
|
4
5
|
taskId;
|
|
5
6
|
lastTask;
|
|
@@ -130,9 +131,15 @@ export class A2AClient {
|
|
|
130
131
|
const res = await this.postJson(url, body, this.apiKeyAttempts[i]);
|
|
131
132
|
console.log(`[A2A Client] Response: ${res.status} in ${Date.now() - startTime}ms`);
|
|
132
133
|
if (res.ok) {
|
|
134
|
+
const text = await res.text();
|
|
135
|
+
if (i < this.apiKeyAttempts.length - 1 &&
|
|
136
|
+
isA2AAuthRejectionResponse(res.status, text)) {
|
|
137
|
+
lastError = new Error(`A2A request failed (${res.status}): ${text}`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
133
140
|
this.endpointCandidates = [url];
|
|
134
141
|
this.markApiKeySucceeded(this.apiKeyAttempts[i]);
|
|
135
|
-
return
|
|
142
|
+
return JSON.parse(text);
|
|
136
143
|
}
|
|
137
144
|
const text = await res.text();
|
|
138
145
|
lastError = new Error(`A2A request failed (${res.status}): ${text}`);
|
|
@@ -160,6 +167,7 @@ export class A2AClient {
|
|
|
160
167
|
message,
|
|
161
168
|
contextId: opts?.contextId,
|
|
162
169
|
metadata: opts?.metadata,
|
|
170
|
+
...(opts?.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}),
|
|
163
171
|
...(opts?.approvedActions?.length
|
|
164
172
|
? { approvedActions: opts.approvedActions }
|
|
165
173
|
: {}),
|
|
@@ -180,6 +188,23 @@ export class A2AClient {
|
|
|
180
188
|
}
|
|
181
189
|
return response.result;
|
|
182
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Execute one receiver-approved read-only action without starting the
|
|
193
|
+
* receiver's agent loop. The receiver still owns validation, credentials,
|
|
194
|
+
* request scoping, and the explicit action exposure decision.
|
|
195
|
+
*/
|
|
196
|
+
async invokeAction(action, input = {}, opts) {
|
|
197
|
+
const metadata = sanitizeA2ACorrelationMetadata(opts?.metadata);
|
|
198
|
+
const response = await this.rpc("actions/invoke", {
|
|
199
|
+
action,
|
|
200
|
+
input,
|
|
201
|
+
...(Object.keys(metadata).length > 0 ? { metadata } : {}),
|
|
202
|
+
});
|
|
203
|
+
if (response.error) {
|
|
204
|
+
throw new Error(`A2A error (${response.error.code}): ${response.error.message}`);
|
|
205
|
+
}
|
|
206
|
+
return response.result;
|
|
207
|
+
}
|
|
183
208
|
/**
|
|
184
209
|
* Send a message in async mode and poll until the task reaches a terminal
|
|
185
210
|
* state. This is the recommended path on serverless hosts with short
|
|
@@ -193,11 +218,25 @@ export class A2AClient {
|
|
|
193
218
|
const submitted = await this.send(message, {
|
|
194
219
|
contextId: opts?.contextId,
|
|
195
220
|
metadata: opts?.metadata,
|
|
221
|
+
idempotencyKey: opts?.idempotencyKey,
|
|
196
222
|
...(opts?.approvedActions?.length
|
|
197
223
|
? { approvedActions: opts.approvedActions }
|
|
198
224
|
: {}),
|
|
199
225
|
async: true,
|
|
200
226
|
});
|
|
227
|
+
return this.pollTask(submitted, opts);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Continue waiting for an existing async task without submitting a second
|
|
231
|
+
* message. Use this after a bounded caller-side wait expires but the remote
|
|
232
|
+
* task is still working.
|
|
233
|
+
*/
|
|
234
|
+
async waitForTask(taskId, opts) {
|
|
235
|
+
const current = await this.getTask(taskId);
|
|
236
|
+
opts?.onUpdate?.(current);
|
|
237
|
+
return this.pollTask(current, opts);
|
|
238
|
+
}
|
|
239
|
+
async pollTask(submitted, opts) {
|
|
201
240
|
const terminalStates = new Set([
|
|
202
241
|
"completed",
|
|
203
242
|
"failed",
|
|
@@ -399,6 +438,7 @@ function uniqueAuthTokens(values) {
|
|
|
399
438
|
}
|
|
400
439
|
function isA2AAuthRejectionResponse(status, text) {
|
|
401
440
|
return (status === 401 ||
|
|
441
|
+
/verified, audience-bound user identity/i.test(text) ||
|
|
402
442
|
/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
443
|
}
|
|
404
444
|
/**
|
|
@@ -416,6 +456,7 @@ export async function callAgent(url, text, opts) {
|
|
|
416
456
|
metadata.orgDomain = opts.orgDomain;
|
|
417
457
|
if (opts?.requestOrigin)
|
|
418
458
|
metadata.requestOrigin = opts.requestOrigin;
|
|
459
|
+
Object.assign(metadata, sanitizeA2ACorrelationMetadata(opts?.correlation));
|
|
419
460
|
// Default to async + poll. The receiving A2A server's `_process-task` route
|
|
420
461
|
// runs the handler in a fresh function execution (cross-platform queue
|
|
421
462
|
// pattern), so async mode now works on every host instead of relying on
|
|
@@ -438,21 +479,32 @@ export async function callAgent(url, text, opts) {
|
|
|
438
479
|
});
|
|
439
480
|
let task;
|
|
440
481
|
if (useAsync) {
|
|
441
|
-
task =
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
482
|
+
task = opts?.taskId
|
|
483
|
+
? await client.waitForTask(opts.taskId, {
|
|
484
|
+
timeoutMs: opts.timeoutMs,
|
|
485
|
+
pollIntervalMs: opts.pollIntervalMs,
|
|
486
|
+
onUpdate: opts.onUpdate,
|
|
487
|
+
})
|
|
488
|
+
: await client.sendAndWait(message, {
|
|
489
|
+
contextId: opts?.contextId,
|
|
490
|
+
metadata,
|
|
491
|
+
idempotencyKey: opts?.idempotencyKey,
|
|
492
|
+
...(opts?.approvedActions?.length
|
|
493
|
+
? { approvedActions: opts.approvedActions }
|
|
494
|
+
: {}),
|
|
495
|
+
timeoutMs: opts?.timeoutMs,
|
|
496
|
+
pollIntervalMs: opts?.pollIntervalMs,
|
|
497
|
+
onUpdate: opts?.onUpdate,
|
|
498
|
+
});
|
|
451
499
|
}
|
|
452
500
|
else {
|
|
501
|
+
if (opts?.taskId) {
|
|
502
|
+
throw new Error("Polling an existing A2A task requires async mode");
|
|
503
|
+
}
|
|
453
504
|
task = await client.send(message, {
|
|
454
505
|
contextId: opts?.contextId,
|
|
455
506
|
metadata,
|
|
507
|
+
idempotencyKey: opts?.idempotencyKey,
|
|
456
508
|
...(opts?.approvedActions?.length
|
|
457
509
|
? { approvedActions: opts.approvedActions }
|
|
458
510
|
: {}),
|
|
@@ -486,7 +538,31 @@ export async function callAgent(url, text, opts) {
|
|
|
486
538
|
throw lastAuthError;
|
|
487
539
|
return "";
|
|
488
540
|
}
|
|
489
|
-
|
|
541
|
+
/**
|
|
542
|
+
* Invoke one receiver-approved read-only action with an audience-bound user
|
|
543
|
+
* token. Unlike conversational delegation, this never starts the receiver's
|
|
544
|
+
* model loop.
|
|
545
|
+
*/
|
|
546
|
+
export async function callAction(url, action, input = {}, opts) {
|
|
547
|
+
const actionName = action.trim();
|
|
548
|
+
if (!actionName)
|
|
549
|
+
throw new Error("A2A action name is required");
|
|
550
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
551
|
+
throw new Error("A2A action input must be an object");
|
|
552
|
+
}
|
|
553
|
+
const apiKeyAttempts = await buildA2AApiKeyAttempts(opts, normalizeA2AAudience(url));
|
|
554
|
+
const fallbackApiKeys = apiKeyAttempts
|
|
555
|
+
.slice(1)
|
|
556
|
+
.filter((token) => token !== undefined);
|
|
557
|
+
const client = new A2AClient(url, apiKeyAttempts[0], {
|
|
558
|
+
fallbackApiKeys,
|
|
559
|
+
requestTimeoutMs: opts?.requestTimeoutMs,
|
|
560
|
+
});
|
|
561
|
+
return client.invokeAction(actionName, input, {
|
|
562
|
+
metadata: sanitizeA2ACorrelationMetadata(opts?.correlation),
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
async function buildA2AApiKeyAttempts(opts, audience) {
|
|
490
566
|
const attempts = [];
|
|
491
567
|
const add = (token) => {
|
|
492
568
|
if (token === undefined || attempts.includes(token))
|
|
@@ -499,6 +575,7 @@ async function buildA2AApiKeyAttempts(opts) {
|
|
|
499
575
|
try {
|
|
500
576
|
add(await signA2AToken(opts.userEmail, opts.orgDomain, opts.orgSecret, {
|
|
501
577
|
preferGlobalSecret: true,
|
|
578
|
+
audience,
|
|
502
579
|
}));
|
|
503
580
|
}
|
|
504
581
|
catch {
|
|
@@ -509,6 +586,7 @@ async function buildA2AApiKeyAttempts(opts) {
|
|
|
509
586
|
try {
|
|
510
587
|
add(await signA2AToken(opts.userEmail, opts.orgDomain, opts.orgSecret, {
|
|
511
588
|
preferGlobalSecret: false,
|
|
589
|
+
audience,
|
|
512
590
|
}));
|
|
513
591
|
}
|
|
514
592
|
catch {
|
|
@@ -520,6 +598,10 @@ async function buildA2AApiKeyAttempts(opts) {
|
|
|
520
598
|
attempts.push(undefined);
|
|
521
599
|
return attempts;
|
|
522
600
|
}
|
|
601
|
+
function normalizeA2AAudience(url) {
|
|
602
|
+
const explicit = splitExplicitA2AEndpoint(url.replace(/\/$/, ""));
|
|
603
|
+
return (explicit?.baseUrl ?? url).replace(/\/$/, "");
|
|
604
|
+
}
|
|
523
605
|
function isA2AAuthRejection(err) {
|
|
524
606
|
const message = err instanceof Error ? err.message : String(err ?? "");
|
|
525
607
|
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);
|