@agent-native/core 0.107.2 → 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 +24 -0
- package/corpus/core/docs/content/actions.mdx +48 -0
- package/corpus/core/docs/content/locales/ar-SA/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/de-DE/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/es-ES/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/fr-FR/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/hi-IN/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/ja-JP/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/ko-KR/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/pt-BR/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/zh-CN/actions.mdx +38 -0
- package/corpus/core/docs/content/locales/zh-TW/actions.mdx +38 -0
- package/corpus/core/package.json +5 -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/a2a-claims.ts +52 -0
- package/corpus/core/src/action.ts +7 -2
- package/corpus/core/src/agent/production-agent.ts +10 -4
- package/corpus/core/src/audit/record.ts +6 -0
- 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/feature-flags/FeatureFlagsPanel.tsx +519 -0
- package/corpus/core/src/client/feature-flags/helpers.ts +77 -0
- package/corpus/core/src/client/feature-flags/index.ts +13 -0
- package/corpus/core/src/client/feature-flags/types.ts +29 -0
- package/corpus/core/src/client/feature-flags/use-feature-flag.ts +26 -0
- package/corpus/core/src/client/index.ts +13 -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/routes.ts +1 -1
- package/corpus/core/src/extensions/store.ts +1 -1
- package/corpus/core/src/feature-flags/a2a-action-route.ts +56 -0
- package/corpus/core/src/feature-flags/actions/get-feature-flags.ts +24 -0
- package/corpus/core/src/feature-flags/actions/list-feature-flags.ts +69 -0
- package/corpus/core/src/feature-flags/actions/set-feature-flag.ts +89 -0
- package/corpus/core/src/feature-flags/index.ts +21 -0
- package/corpus/core/src/feature-flags/permissions.ts +53 -0
- package/corpus/core/src/feature-flags/plugin.ts +44 -0
- package/corpus/core/src/feature-flags/registry.ts +96 -0
- package/corpus/core/src/feature-flags/store.ts +176 -0
- package/corpus/core/src/index.ts +15 -0
- package/corpus/core/src/localization/default-messages.ts +50 -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/action-discovery.ts +12 -0
- package/corpus/core/src/server/action-routes.ts +47 -5
- 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/server/index.ts +1 -0
- package/corpus/core/src/settings/org-settings.ts +13 -0
- package/corpus/core/src/settings/store.ts +57 -0
- package/corpus/core/src/styles/agent-conversation.css +7 -0
- package/corpus/core/src/templates/default/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/core/src/templates/default/AGENTS.md +1 -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/headless/.agents/skills/feature-flags/SKILL.md +169 -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/feature-flags/SKILL.md +169 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/corpus/core/src/templates/workspace-core/AGENTS.md +1 -1
- package/corpus/core/src/templates/workspace-root/AGENTS.md +1 -1
- package/corpus/core/src/vite/action-types-plugin.ts +12 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -10
- package/corpus/templates/analytics/.agents/skills/feature-flags/SKILL.md +169 -0
- 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 +37 -16
- 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/list-workspace-feature-flags.ts +15 -0
- package/corpus/templates/analytics/actions/navigate.ts +2 -2
- package/corpus/templates/analytics/actions/pylon-issues.ts +123 -0
- package/corpus/templates/analytics/actions/set-workspace-feature-flag.ts +45 -0
- package/corpus/templates/analytics/actions/slack-messages.ts +179 -27
- package/corpus/templates/analytics/actions/view-screen.ts +13 -0
- package/corpus/templates/analytics/app/components/agents/FeatureFlagsFleetPanel.tsx +243 -0
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +48 -152
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +11 -3
- 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/hooks/use-navigation-state.ts +3 -1
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +30 -0
- package/corpus/templates/analytics/app/i18n-data.ts +385 -0
- package/corpus/templates/analytics/app/pages/Agents.tsx +22 -2
- 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-manage-feature-flag-rollouts-across-your-organization-s-apps.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/db-admin-connections.ts +13 -5
- 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/lib/workspace-feature-flags.ts +347 -0
- 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/assets/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/brain/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/calendar/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/chat/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/clips/.agents/skills/feature-flags/SKILL.md +169 -0
- 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/clips/server/plugins/feature-flags.ts +11 -0
- package/corpus/templates/clips/shared/feature-flags.ts +30 -37
- package/corpus/templates/content/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/content/app/entry.client.tsx +6 -1
- package/corpus/templates/design/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/design/AGENTS.md +5 -3
- package/corpus/templates/design/actions/add-fusion-screens.ts +4 -6
- package/corpus/templates/design/actions/apply-fusion-edits.ts +4 -6
- package/corpus/templates/design/actions/create-fusion-app.ts +5 -4
- package/corpus/templates/design/actions/deploy-fusion-app.ts +4 -3
- package/corpus/templates/design/actions/get-fusion-deploy-status.ts +4 -6
- package/corpus/templates/design/actions/list-fusion-edits.ts +4 -3
- package/corpus/templates/design/actions/push-fusion-app.ts +4 -6
- package/corpus/templates/design/actions/queue-fusion-edit.ts +4 -3
- package/corpus/templates/design/actions/send-fusion-message.ts +4 -6
- package/corpus/templates/design/actions/sync-fusion-app.ts +4 -3
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +1 -1
- package/corpus/templates/design/app/pages/Index.tsx +8 -6
- package/corpus/templates/design/server/plugins/feature-flags.ts +5 -0
- package/corpus/templates/design/shared/full-app.ts +10 -7
- package/corpus/templates/dispatch/.agents/skills/feature-flags/SKILL.md +169 -0
- 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/forms/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/macros/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/mail/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/mail/app/entry.client.tsx +6 -1
- package/corpus/templates/plan/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/slides/.agents/skills/feature-flags/SKILL.md +169 -0
- 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/corpus/templates/tasks/.agents/skills/feature-flags/SKILL.md +169 -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/a2a-claims.d.ts +10 -0
- package/dist/a2a-claims.d.ts.map +1 -0
- package/dist/a2a-claims.js +41 -0
- package/dist/a2a-claims.js.map +1 -0
- package/dist/action.d.ts +7 -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/audit/record.d.ts +3 -0
- package/dist/audit/record.d.ts.map +1 -1
- package/dist/audit/record.js +3 -0
- package/dist/audit/record.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/feature-flags/FeatureFlagsPanel.d.ts +10 -0
- package/dist/client/feature-flags/FeatureFlagsPanel.d.ts.map +1 -0
- package/dist/client/feature-flags/FeatureFlagsPanel.js +143 -0
- package/dist/client/feature-flags/FeatureFlagsPanel.js.map +1 -0
- package/dist/client/feature-flags/helpers.d.ts +16 -0
- package/dist/client/feature-flags/helpers.d.ts.map +1 -0
- package/dist/client/feature-flags/helpers.js +50 -0
- package/dist/client/feature-flags/helpers.js.map +1 -0
- package/dist/client/feature-flags/index.d.ts +5 -0
- package/dist/client/feature-flags/index.d.ts.map +1 -0
- package/dist/client/feature-flags/index.js +4 -0
- package/dist/client/feature-flags/index.js.map +1 -0
- package/dist/client/feature-flags/types.d.ts +27 -0
- package/dist/client/feature-flags/types.d.ts.map +1 -0
- package/dist/client/feature-flags/types.js +2 -0
- package/dist/client/feature-flags/types.js.map +1 -0
- package/dist/client/feature-flags/use-feature-flag.d.ts +8 -0
- package/dist/client/feature-flags/use-feature-flag.d.ts.map +1 -0
- package/dist/client/feature-flags/use-feature-flag.js +15 -0
- package/dist/client/feature-flags/use-feature-flag.js.map +1 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -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/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/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +1 -1
- package/dist/extensions/routes.js.map +1 -1
- package/dist/extensions/store.js +1 -1
- package/dist/extensions/store.js.map +1 -1
- package/dist/feature-flags/a2a-action-route.d.ts +14 -0
- package/dist/feature-flags/a2a-action-route.d.ts.map +1 -0
- package/dist/feature-flags/a2a-action-route.js +50 -0
- package/dist/feature-flags/a2a-action-route.js.map +1 -0
- package/dist/feature-flags/actions/get-feature-flags.d.ts +3 -0
- package/dist/feature-flags/actions/get-feature-flags.d.ts.map +1 -0
- package/dist/feature-flags/actions/get-feature-flags.js +18 -0
- package/dist/feature-flags/actions/get-feature-flags.js.map +1 -0
- package/dist/feature-flags/actions/list-feature-flags.d.ts +28 -0
- package/dist/feature-flags/actions/list-feature-flags.d.ts.map +1 -0
- package/dist/feature-flags/actions/list-feature-flags.js +60 -0
- package/dist/feature-flags/actions/list-feature-flags.js.map +1 -0
- package/dist/feature-flags/actions/set-feature-flag.d.ts +26 -0
- package/dist/feature-flags/actions/set-feature-flag.d.ts.map +1 -0
- package/dist/feature-flags/actions/set-feature-flag.js +78 -0
- package/dist/feature-flags/actions/set-feature-flag.js.map +1 -0
- package/dist/feature-flags/index.d.ts +5 -0
- package/dist/feature-flags/index.d.ts.map +1 -0
- package/dist/feature-flags/index.js +5 -0
- package/dist/feature-flags/index.js.map +1 -0
- package/dist/feature-flags/permissions.d.ts +13 -0
- package/dist/feature-flags/permissions.d.ts.map +1 -0
- package/dist/feature-flags/permissions.js +37 -0
- package/dist/feature-flags/permissions.js.map +1 -0
- package/dist/feature-flags/plugin.d.ts +17 -0
- package/dist/feature-flags/plugin.d.ts.map +1 -0
- package/dist/feature-flags/plugin.js +29 -0
- package/dist/feature-flags/plugin.js.map +1 -0
- package/dist/feature-flags/registry.d.ts +23 -0
- package/dist/feature-flags/registry.d.ts.map +1 -0
- package/dist/feature-flags/registry.js +59 -0
- package/dist/feature-flags/registry.js.map +1 -0
- package/dist/feature-flags/store.d.ts +31 -0
- package/dist/feature-flags/store.d.ts.map +1 -0
- package/dist/feature-flags/store.js +124 -0
- package/dist/feature-flags/store.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/localization/default-messages.d.ts +45 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +45 -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/progress/actions.d.ts.map +1 -1
- package/dist/progress/actions.js +3 -2
- package/dist/progress/actions.js.map +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 +3 -3
- 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/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +12 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts +3 -0
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +45 -5
- package/dist/server/action-routes.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/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/settings/org-settings.d.ts +2 -0
- package/dist/settings/org-settings.d.ts.map +1 -1
- package/dist/settings/org-settings.js +5 -1
- package/dist/settings/org-settings.js.map +1 -1
- package/dist/settings/store.d.ts +8 -0
- package/dist/settings/store.d.ts.map +1 -1
- package/dist/settings/store.js +48 -0
- package/dist/settings/store.js.map +1 -1
- package/dist/styles/agent-conversation.css +7 -0
- package/dist/templates/chat/.agents/skills/feature-flags/SKILL.md +169 -0
- package/dist/templates/default/.agents/skills/feature-flags/SKILL.md +169 -0
- package/dist/templates/default/AGENTS.md +1 -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/headless/.agents/skills/feature-flags/SKILL.md +169 -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/feature-flags/SKILL.md +169 -0
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/dist/templates/workspace-core/AGENTS.md +1 -1
- package/dist/templates/workspace-root/AGENTS.md +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +12 -0
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/docs/content/actions.mdx +48 -0
- package/docs/content/locales/ar-SA/actions.mdx +38 -0
- package/docs/content/locales/de-DE/actions.mdx +38 -0
- package/docs/content/locales/es-ES/actions.mdx +38 -0
- package/docs/content/locales/fr-FR/actions.mdx +38 -0
- package/docs/content/locales/hi-IN/actions.mdx +38 -0
- package/docs/content/locales/ja-JP/actions.mdx +38 -0
- package/docs/content/locales/ko-KR/actions.mdx +38 -0
- package/docs/content/locales/pt-BR/actions.mdx +38 -0
- package/docs/content/locales/zh-CN/actions.mdx +38 -0
- package/docs/content/locales/zh-TW/actions.mdx +38 -0
- package/package.json +5 -1
- package/src/templates/chat/.agents/skills/feature-flags/SKILL.md +169 -0
- package/src/templates/default/.agents/skills/feature-flags/SKILL.md +169 -0
- package/src/templates/default/AGENTS.md +1 -0
- 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/headless/.agents/skills/feature-flags/SKILL.md +169 -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/feature-flags/SKILL.md +169 -0
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/src/templates/workspace-core/AGENTS.md +1 -1
- package/src/templates/workspace-root/AGENTS.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/clips/actions/get-feature-flags.ts +0 -30
- 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
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
shouldPreferGlobalA2ASecret,
|
|
7
7
|
signA2AToken,
|
|
8
8
|
} from "../a2a/client.js";
|
|
9
|
+
import { invokeAgentAction } from "../a2a/invoke.js";
|
|
9
10
|
import type { A2AApprovedAction, Task } from "../a2a/types.js";
|
|
10
11
|
import {
|
|
11
12
|
formatLlmCredentialErrorMessage,
|
|
@@ -94,12 +95,13 @@ function formatDownstreamLlmCredentialFailure(
|
|
|
94
95
|
|
|
95
96
|
export const tool: ActionTool = {
|
|
96
97
|
description:
|
|
97
|
-
"Call a DIFFERENT, separately-deployed
|
|
98
|
+
"Call a DIFFERENT, separately-deployed app over A2A. When you know the exact exposed read-only action, pass action + input and omit message; this invokes it directly without starting the other app's model and is the fastest path for bounded data reads. Use message only for natural-language investigation, synthesis, mutations, or multi-step work that needs the other agent. NEVER use this to call your own app or perform actions you can do with your own tools. Using call-agent on yourself will fail and waste time. " +
|
|
98
99
|
'For brand-consistent generated media, the first-party Assets agent is available as agent="assets"; use it when another app needs generated heroes, diagrams, product shots, thumbnails, videos, or design imagery, unless the current app has its own generation action that already delegates there. ' +
|
|
99
100
|
"IMPORTANT — handling the response: " +
|
|
100
101
|
"(a) If it contains a URL or ID, copy it VERBATIM into your reply. Do not 'correct' or pluralize the path (e.g. /deck/ → /decks/), normalize casing, or change the slug — any edit breaks the link. " +
|
|
101
102
|
'(b) If it does NOT contain a URL/ID and the user asked for one, say so explicitly (e.g. "the agent created the deck/image but didn\'t return a link — open the app directly to view it"). NEVER invent a URL, slug, or path — guessing produces broken links that look real. ' +
|
|
102
|
-
"(c) If the downstream response reports missing credentials, never repeat raw env var names, Vault key names, token names, secret names, or other credential identifiers. Tell the user the target app needs its LLM/provider connection configured."
|
|
103
|
+
"(c) If the downstream response reports missing credentials, never repeat raw env var names, Vault key names, token names, secret names, or other credential identifiers. Tell the user the target app needs its LLM/provider connection configured. " +
|
|
104
|
+
"(d) A bounded wait can expire while the remote task is still healthy. The result will include its taskId and exact retry instructions. Continue polling that SAME task with taskId; NEVER send a new check-in/follow-up message, because that starts duplicate downstream work.",
|
|
103
105
|
parameters: {
|
|
104
106
|
type: "object",
|
|
105
107
|
properties: {
|
|
@@ -110,7 +112,24 @@ export const tool: ActionTool = {
|
|
|
110
112
|
},
|
|
111
113
|
message: {
|
|
112
114
|
type: "string",
|
|
113
|
-
description:
|
|
115
|
+
description:
|
|
116
|
+
"The message/question to send when starting a new task. Omit when taskId is provided.",
|
|
117
|
+
},
|
|
118
|
+
taskId: {
|
|
119
|
+
type: "string",
|
|
120
|
+
description:
|
|
121
|
+
"Existing A2A task ID returned by a timed-out call. Polls that exact task without sending a new message. Never create a fresh check-in message for work that already has a taskId.",
|
|
122
|
+
},
|
|
123
|
+
action: {
|
|
124
|
+
type: "string",
|
|
125
|
+
description:
|
|
126
|
+
"Exact read-only action exposed by the target app. Use with input and omit message/taskId to skip the downstream agent loop.",
|
|
127
|
+
},
|
|
128
|
+
input: {
|
|
129
|
+
type: "object",
|
|
130
|
+
description:
|
|
131
|
+
"Complete input object for action. The target app validates it and refuses actions that are not explicitly exposed read-only operations.",
|
|
132
|
+
additionalProperties: true,
|
|
114
133
|
},
|
|
115
134
|
approvedActions: {
|
|
116
135
|
type: "array",
|
|
@@ -126,7 +145,7 @@ export const tool: ActionTool = {
|
|
|
126
145
|
},
|
|
127
146
|
},
|
|
128
147
|
},
|
|
129
|
-
required: ["agent"
|
|
148
|
+
required: ["agent"],
|
|
130
149
|
},
|
|
131
150
|
};
|
|
132
151
|
|
|
@@ -137,12 +156,23 @@ export async function run(
|
|
|
137
156
|
): Promise<string> {
|
|
138
157
|
const agentIdOrName = String(args.agent ?? "");
|
|
139
158
|
const message = String(args.message ?? "");
|
|
159
|
+
const taskId = String(args.taskId ?? "").trim();
|
|
160
|
+
const action = String(args.action ?? "").trim();
|
|
161
|
+
const input = args.input ?? {};
|
|
140
162
|
const approvedActions = Array.isArray(args.approvedActions)
|
|
141
163
|
? (args.approvedActions as A2AApprovedAction[])
|
|
142
164
|
: undefined;
|
|
143
165
|
|
|
144
166
|
if (!agentIdOrName) return "Error: --agent is required";
|
|
145
|
-
if (!message
|
|
167
|
+
if (!message && !taskId && !action) {
|
|
168
|
+
return "Error: --message, --taskId, or --action is required";
|
|
169
|
+
}
|
|
170
|
+
if (action && (message || taskId)) {
|
|
171
|
+
return "Error: --action direct-invoke mode cannot be combined with --message or --taskId";
|
|
172
|
+
}
|
|
173
|
+
if (action && (!input || typeof input !== "object" || Array.isArray(input))) {
|
|
174
|
+
return "Error: --input must be an object when --action is provided";
|
|
175
|
+
}
|
|
146
176
|
|
|
147
177
|
// Prevent self-calls — the agent must use its own registered tools instead
|
|
148
178
|
if (selfAppId && agentIdOrName.toLowerCase() === selfAppId.toLowerCase()) {
|
|
@@ -157,16 +187,36 @@ export async function run(
|
|
|
157
187
|
return `Error: Agent "${agentIdOrName}" not found. Available agents: ${available || "(none)"}`;
|
|
158
188
|
}
|
|
159
189
|
|
|
190
|
+
if (action) {
|
|
191
|
+
if (context?.send) {
|
|
192
|
+
context.send({ type: "agent_call", agent: agent.name, status: "start" });
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
const output = await invokeReadOnlyAppAction(
|
|
196
|
+
agent,
|
|
197
|
+
action,
|
|
198
|
+
input as Record<string, unknown>,
|
|
199
|
+
);
|
|
200
|
+
return output;
|
|
201
|
+
} finally {
|
|
202
|
+
if (context?.send) {
|
|
203
|
+
context.send({ type: "agent_call", agent: agent.name, status: "done" });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
160
208
|
// Append a small cross-app hint to the outgoing message so the receiving
|
|
161
209
|
// agent (which may be on an older deploy without the receiver-side hint
|
|
162
210
|
// in handlers.ts) still emits fully-qualified URLs. This is belt-and-
|
|
163
211
|
// suspenders with the receiver hint — but it works against any current
|
|
164
212
|
// deployment, no redeploy required.
|
|
165
|
-
const messageWithHint =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
213
|
+
const messageWithHint = taskId
|
|
214
|
+
? ""
|
|
215
|
+
: `${message}${integrationSourceContextHint()}\n\n` +
|
|
216
|
+
`[Note: this request comes from another app via A2A. The caller cannot see your local UI, deck list, or navigation — only the literal text you put in your reply. ` +
|
|
217
|
+
`If you create or reference a deck/document/design/dashboard, include its FULLY-QUALIFIED URL (e.g. ${agent.url}/deck/<id>) in your reply, not a relative path. ` +
|
|
218
|
+
`Use only artifact IDs and URL paths returned by successful actions — never invent slugs, IDs, or hosts. ` +
|
|
219
|
+
`Return a concise caller-ready synthesis rather than raw tool output or full transcripts; preserve source counts, IDs, short supporting quotes, and URLs needed to substantiate the answer.]`;
|
|
170
220
|
|
|
171
221
|
try {
|
|
172
222
|
// If we have a send context, use streaming so the UI shows progressive text
|
|
@@ -228,8 +278,9 @@ export async function run(
|
|
|
228
278
|
|
|
229
279
|
let responseText = "";
|
|
230
280
|
let lastSentLength = 0;
|
|
231
|
-
const existingContinuationText =
|
|
232
|
-
|
|
281
|
+
const existingContinuationText = taskId
|
|
282
|
+
? null
|
|
283
|
+
: await formatExistingIntegrationContinuationIfRetry(agent, message);
|
|
233
284
|
if (existingContinuationText) return existingContinuationText;
|
|
234
285
|
|
|
235
286
|
context.send({
|
|
@@ -338,13 +389,12 @@ export async function run(
|
|
|
338
389
|
orgDomain: callerOrgDomain,
|
|
339
390
|
orgSecret: callerOrgSecret,
|
|
340
391
|
approvedActions,
|
|
392
|
+
...(taskId ? { taskId } : {}),
|
|
341
393
|
onUpdate: onRemotePollUpdate,
|
|
394
|
+
returnRecoverableArtifactsOnTimeout: false,
|
|
342
395
|
...(callTimeoutMs
|
|
343
396
|
? {
|
|
344
397
|
timeoutMs: callTimeoutMs,
|
|
345
|
-
// Integration callers must keep the timeout task id so the
|
|
346
|
-
// catch below can enqueue durable continuation polling.
|
|
347
|
-
returnRecoverableArtifactsOnTimeout: false,
|
|
348
398
|
}
|
|
349
399
|
: {}),
|
|
350
400
|
});
|
|
@@ -387,8 +437,11 @@ export async function run(
|
|
|
387
437
|
agent.url,
|
|
388
438
|
);
|
|
389
439
|
} else {
|
|
390
|
-
|
|
391
|
-
|
|
440
|
+
responseText = formatExistingTaskWaitInstruction(
|
|
441
|
+
agent.name,
|
|
442
|
+
timeoutTaskId,
|
|
443
|
+
agentIdOrName,
|
|
444
|
+
);
|
|
392
445
|
}
|
|
393
446
|
}
|
|
394
447
|
} else {
|
|
@@ -427,6 +480,8 @@ export async function run(
|
|
|
427
480
|
orgDomain: domain,
|
|
428
481
|
orgSecret,
|
|
429
482
|
approvedActions,
|
|
483
|
+
...(taskId ? { taskId } : {}),
|
|
484
|
+
returnRecoverableArtifactsOnTimeout: false,
|
|
430
485
|
});
|
|
431
486
|
const sanitized =
|
|
432
487
|
formatDownstreamLlmCredentialFailure(agent.name, response) ?? response;
|
|
@@ -438,6 +493,14 @@ export async function run(
|
|
|
438
493
|
err,
|
|
439
494
|
);
|
|
440
495
|
if (credentialMessage) return credentialMessage;
|
|
496
|
+
const timeoutTaskId = getA2ATaskTimeoutTaskId(err);
|
|
497
|
+
if (timeoutTaskId) {
|
|
498
|
+
return formatExistingTaskWaitInstruction(
|
|
499
|
+
agent.name,
|
|
500
|
+
timeoutTaskId,
|
|
501
|
+
agentIdOrName,
|
|
502
|
+
);
|
|
503
|
+
}
|
|
441
504
|
// Friendlier message for the common timeout case so the calling agent can
|
|
442
505
|
// decide whether to give up or retry.
|
|
443
506
|
if (/timeout|did not complete|Inactivity|504/i.test(msg)) {
|
|
@@ -447,6 +510,63 @@ export async function run(
|
|
|
447
510
|
}
|
|
448
511
|
}
|
|
449
512
|
|
|
513
|
+
async function invokeReadOnlyAppAction(
|
|
514
|
+
agent: { name: string; url: string },
|
|
515
|
+
action: string,
|
|
516
|
+
input: Record<string, unknown>,
|
|
517
|
+
): Promise<string> {
|
|
518
|
+
const callerEmail = getRequestUserEmail();
|
|
519
|
+
if (!callerEmail) {
|
|
520
|
+
return `Error calling ${agent.name} action ${action}: a signed-in user identity is required`;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
let callerOrgDomain: string | undefined;
|
|
524
|
+
let callerOrgSecret: string | undefined;
|
|
525
|
+
const orgId = getRequestOrgId();
|
|
526
|
+
if (orgId) {
|
|
527
|
+
try {
|
|
528
|
+
callerOrgDomain = (await getOrgDomain(orgId)) ?? undefined;
|
|
529
|
+
} catch {}
|
|
530
|
+
try {
|
|
531
|
+
callerOrgSecret = (await getOrgA2ASecret(orgId)) ?? undefined;
|
|
532
|
+
} catch {}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (!callerOrgSecret && !process.env.A2A_SECRET) {
|
|
536
|
+
return `Error calling ${agent.name} action ${action}: direct cross-app reads require A2A identity verification`;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
try {
|
|
540
|
+
const invocation = await invokeAgentAction({
|
|
541
|
+
target: agent.url,
|
|
542
|
+
action,
|
|
543
|
+
input,
|
|
544
|
+
userEmail: callerEmail,
|
|
545
|
+
orgDomain: callerOrgDomain,
|
|
546
|
+
orgSecret: callerOrgSecret,
|
|
547
|
+
});
|
|
548
|
+
return invocation.result.status === "completed"
|
|
549
|
+
? invocation.result.output
|
|
550
|
+
: `Error calling ${agent.name} action ${action}: ${invocation.result.output}`;
|
|
551
|
+
} catch (error) {
|
|
552
|
+
return `Error calling ${agent.name} action ${action}: ${
|
|
553
|
+
error instanceof Error ? error.message : String(error)
|
|
554
|
+
}`;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
function formatExistingTaskWaitInstruction(
|
|
559
|
+
agentName: string,
|
|
560
|
+
taskId: string,
|
|
561
|
+
agentIdOrName: string,
|
|
562
|
+
): string {
|
|
563
|
+
return (
|
|
564
|
+
`The ${agentName} task is still running under taskId "${taskId}". ` +
|
|
565
|
+
`Do not send ${agentName} a new check-in or follow-up message; that would start duplicate work. ` +
|
|
566
|
+
`Call call-agent again with agent="${agentIdOrName}" and taskId="${taskId}" (omit message) to continue waiting for this same task.`
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
|
|
450
570
|
async function enqueueIntegrationContinuationIfPossible(
|
|
451
571
|
taskId: string,
|
|
452
572
|
agent: { name: string; url: string },
|
|
@@ -595,6 +595,18 @@ export async function mergeCoreSharingActions(
|
|
|
595
595
|
() => import("../sharing/actions/create-agent-resource-link.js"),
|
|
596
596
|
],
|
|
597
597
|
["upload-image", () => import("../file-upload/actions/upload-image.js")],
|
|
598
|
+
[
|
|
599
|
+
"get-feature-flags",
|
|
600
|
+
() => import("../feature-flags/actions/get-feature-flags.js"),
|
|
601
|
+
],
|
|
602
|
+
[
|
|
603
|
+
"list-feature-flags",
|
|
604
|
+
() => import("../feature-flags/actions/list-feature-flags.js"),
|
|
605
|
+
],
|
|
606
|
+
[
|
|
607
|
+
"set-feature-flag",
|
|
608
|
+
() => import("../feature-flags/actions/set-feature-flag.js"),
|
|
609
|
+
],
|
|
598
610
|
// Agent Jobs page — UI-only scoped reads and mutations for resource-backed
|
|
599
611
|
// recurring jobs and personal automations. The agent-facing native tools
|
|
600
612
|
// remain the canonical conversational surface.
|
|
@@ -9,8 +9,10 @@ import {
|
|
|
9
9
|
getRequestURL,
|
|
10
10
|
} from "h3";
|
|
11
11
|
|
|
12
|
+
import { verifyA2ATokenWithClaims } from "../a2a-claims.js";
|
|
12
13
|
import { isAgentActionStopError } from "../action.js";
|
|
13
14
|
import type { ActionEntry } from "../agent/production-agent.js";
|
|
15
|
+
import { declaresFeatureFlagDelegation } from "../feature-flags/a2a-action-route.js";
|
|
14
16
|
import { resolveOrgIdForEmail } from "../org/context.js";
|
|
15
17
|
import { readBody } from "../server/h3-helpers.js";
|
|
16
18
|
import { EMBED_TARGET_HEADER } from "../shared/embed-auth.js";
|
|
@@ -39,6 +41,30 @@ import { runWithRequestContext } from "./request-context.js";
|
|
|
39
41
|
|
|
40
42
|
const ROUTE_PREFIX = "/_agent-native/actions";
|
|
41
43
|
|
|
44
|
+
async function resolveFeatureFlagA2ACaller(event: any, actionName: string) {
|
|
45
|
+
const required =
|
|
46
|
+
actionName === "list-feature-flags"
|
|
47
|
+
? "flags:read"
|
|
48
|
+
: actionName === "set-feature-flag"
|
|
49
|
+
? "flags:write"
|
|
50
|
+
: null;
|
|
51
|
+
if (!required) return null;
|
|
52
|
+
const authorization = getHeader(event, "authorization");
|
|
53
|
+
if (!authorization?.startsWith("Bearer ")) return null;
|
|
54
|
+
const token = authorization.slice(7);
|
|
55
|
+
if (!declaresFeatureFlagDelegation(token)) return null;
|
|
56
|
+
const claims = await verifyA2ATokenWithClaims(token, event);
|
|
57
|
+
if (!claims || !claims.scope.includes(required))
|
|
58
|
+
throw new Error("Invalid feature flag delegation");
|
|
59
|
+
return {
|
|
60
|
+
owner: claims.email,
|
|
61
|
+
orgId: claims.orgId,
|
|
62
|
+
anonymous: false,
|
|
63
|
+
delegationJti: claims.jti,
|
|
64
|
+
delegationIssuer: claims.issuer,
|
|
65
|
+
} as ActionRouteResolvedCaller;
|
|
66
|
+
}
|
|
67
|
+
|
|
42
68
|
export function parseActionSearchParams(
|
|
43
69
|
searchParams: URLSearchParams,
|
|
44
70
|
): Record<string, any> {
|
|
@@ -189,6 +215,9 @@ export type ActionRouteResolvedCaller = AgentRunOwnerContext & {
|
|
|
189
215
|
* must not leak into the token caller's request context.
|
|
190
216
|
*/
|
|
191
217
|
orgId?: string;
|
|
218
|
+
/** Verified A2A correlation and issuer metadata for the audit row. */
|
|
219
|
+
delegationJti?: string;
|
|
220
|
+
delegationIssuer?: string;
|
|
192
221
|
};
|
|
193
222
|
|
|
194
223
|
export interface ActionRouteAuthAdapter {
|
|
@@ -336,10 +365,14 @@ export function mountActionRoutes(
|
|
|
336
365
|
// through, so a live same-origin session cookie can't silently execute
|
|
337
366
|
// the request as the logged-in user.
|
|
338
367
|
let resolvedCaller: ActionRouteResolvedCaller | null = null;
|
|
339
|
-
|
|
368
|
+
{
|
|
340
369
|
let caller: ActionRouteResolvedCaller | null;
|
|
341
370
|
try {
|
|
342
|
-
caller =
|
|
371
|
+
caller = options?.actionRouteAuth?.resolveCaller
|
|
372
|
+
? await options.actionRouteAuth.resolveCaller(event)
|
|
373
|
+
: null;
|
|
374
|
+
if (!caller)
|
|
375
|
+
caller = await resolveFeatureFlagA2ACaller(event, name);
|
|
343
376
|
} catch {
|
|
344
377
|
throw createError({
|
|
345
378
|
statusCode: 401,
|
|
@@ -463,14 +496,23 @@ export function mountActionRoutes(
|
|
|
463
496
|
// userEmail / orgId mirror the request context resolved above (do
|
|
464
497
|
// NOT inject a dev identity — leave undefined when unauthenticated).
|
|
465
498
|
try {
|
|
466
|
-
const caller =
|
|
467
|
-
? "
|
|
468
|
-
:
|
|
499
|
+
const caller = resolvedCaller
|
|
500
|
+
? "a2a"
|
|
501
|
+
: isFrontendActionRequest(event)
|
|
502
|
+
? "frontend"
|
|
503
|
+
: "http";
|
|
469
504
|
const result = await entry.run(params, {
|
|
470
505
|
userEmail,
|
|
471
506
|
orgId: orgId ?? null,
|
|
472
507
|
caller,
|
|
473
508
|
actionName: name,
|
|
509
|
+
...(resolvedCaller?.delegationJti
|
|
510
|
+
? {
|
|
511
|
+
networkProtocol: "a2a",
|
|
512
|
+
networkId: resolvedCaller.delegationJti,
|
|
513
|
+
networkPeer: resolvedCaller.delegationIssuer,
|
|
514
|
+
}
|
|
515
|
+
: {}),
|
|
474
516
|
});
|
|
475
517
|
|
|
476
518
|
// Auto-refresh the UI after a successful mutating action. GET
|
|
@@ -15,6 +15,10 @@ import {
|
|
|
15
15
|
} from "../../agent/production-agent.js";
|
|
16
16
|
import { runAgentLoopDirectWithSoftTimeout } from "../../agent/run-loop-with-resume.js";
|
|
17
17
|
import type { AgentChatEvent } from "../../agent/types.js";
|
|
18
|
+
import {
|
|
19
|
+
isAuthenticatedReadAction,
|
|
20
|
+
isAutoReadExcludedActionName,
|
|
21
|
+
} from "../../mcp/build-server.js";
|
|
18
22
|
import { withConfiguredAppBasePath } from "../app-base-path.js";
|
|
19
23
|
import type { AgentChatPluginOptions } from "./plugin-options.js";
|
|
20
24
|
|
|
@@ -61,6 +65,42 @@ export function filterPublicAgentActions(
|
|
|
61
65
|
);
|
|
62
66
|
}
|
|
63
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Direct A2A action calls share the authenticated external-agent policy with
|
|
70
|
+
* MCP, but remain stricter: only explicitly exposed, authenticated read-only
|
|
71
|
+
* actions can skip the receiver's model loop.
|
|
72
|
+
*/
|
|
73
|
+
export function filterDirectA2AActions(
|
|
74
|
+
actions: Record<string, ActionEntry>,
|
|
75
|
+
options: Pick<AgentChatPluginOptions, "connectorCatalog" | "externalAgents">,
|
|
76
|
+
): Record<string, ActionEntry> {
|
|
77
|
+
const catalog = new Set(options.connectorCatalog ?? []);
|
|
78
|
+
const denied = new Set(options.externalAgents?.denyActions ?? []);
|
|
79
|
+
const autoReads = options.externalAgents?.authenticatedReads === "auto";
|
|
80
|
+
|
|
81
|
+
return Object.fromEntries(
|
|
82
|
+
Object.entries(actions).filter(([name, entry]) => {
|
|
83
|
+
const exposure = entry.publicAgent;
|
|
84
|
+
const selected =
|
|
85
|
+
catalog.has(name) ||
|
|
86
|
+
(autoReads &&
|
|
87
|
+
isAuthenticatedReadAction(entry) &&
|
|
88
|
+
!isAutoReadExcludedActionName(name));
|
|
89
|
+
return (
|
|
90
|
+
selected &&
|
|
91
|
+
!denied.has(name) &&
|
|
92
|
+
entry.agentTool !== false &&
|
|
93
|
+
entry.readOnly === true &&
|
|
94
|
+
exposure?.expose === true &&
|
|
95
|
+
exposure.readOnly === true &&
|
|
96
|
+
exposure.requiresAuth === true &&
|
|
97
|
+
(entry.needsApproval === undefined || entry.needsApproval === false) &&
|
|
98
|
+
exposure.isConsequential !== true
|
|
99
|
+
);
|
|
100
|
+
}),
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
64
104
|
export function buildPublicAgentA2ASkills(
|
|
65
105
|
actions: Record<string, ActionEntry>,
|
|
66
106
|
): Array<{
|
|
@@ -210,6 +210,7 @@ import {
|
|
|
210
210
|
createA2AEngineToolSurface,
|
|
211
211
|
filterAgentTools,
|
|
212
212
|
filterPublicAgentActions,
|
|
213
|
+
filterDirectA2AActions,
|
|
213
214
|
filterReadOnlyActions,
|
|
214
215
|
resolveInitialToolNames,
|
|
215
216
|
runA2AAgentLoop,
|
|
@@ -1216,6 +1217,36 @@ export function createAgentChatPlugin(
|
|
|
1216
1217
|
publicSkillsOnly: true,
|
|
1217
1218
|
streaming: true,
|
|
1218
1219
|
durableBackgroundRuns: options?.durableBackgroundRuns,
|
|
1220
|
+
executeReadOnlyAction: async ({ action, input }) => {
|
|
1221
|
+
const actions = filterDirectA2AActions(
|
|
1222
|
+
mcpFullActions ?? allScripts,
|
|
1223
|
+
options ?? {},
|
|
1224
|
+
);
|
|
1225
|
+
const entry = actions[action];
|
|
1226
|
+
if (!entry) {
|
|
1227
|
+
return {
|
|
1228
|
+
status: "failed" as const,
|
|
1229
|
+
output: "Unknown or unavailable read-only action",
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
const result = await executeAgentToolCall({
|
|
1234
|
+
actions: { [action]: entry },
|
|
1235
|
+
name: action,
|
|
1236
|
+
input,
|
|
1237
|
+
callId: `a2a-action-${crypto.randomUUID()}`,
|
|
1238
|
+
ownerEmail: getRequestUserEmail(),
|
|
1239
|
+
orgId: getRequestOrgId() ?? null,
|
|
1240
|
+
caller: "a2a",
|
|
1241
|
+
});
|
|
1242
|
+
if (result.status === "approval_required") {
|
|
1243
|
+
return {
|
|
1244
|
+
status: "failed" as const,
|
|
1245
|
+
output: "Read-only action unexpectedly requires approval",
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
return { status: result.status, output: result.output };
|
|
1249
|
+
},
|
|
1219
1250
|
executeApproval: async (approval) => {
|
|
1220
1251
|
const result = await executeAgentToolCall({
|
|
1221
1252
|
actions: mcpFullActions ?? allScripts,
|
|
@@ -180,6 +180,7 @@ export { createSentryPlugin, defaultSentryPlugin } from "./sentry-plugin.js";
|
|
|
180
180
|
// (which references "defaultOrgPlugin" from @agent-native/core/server) can
|
|
181
181
|
// resolve it during the deploy build worker-entry generation.
|
|
182
182
|
export { createOrgPlugin, defaultOrgPlugin } from "../org/plugin.js";
|
|
183
|
+
export { createFeatureFlagsPlugin } from "../feature-flags/plugin.js";
|
|
183
184
|
export {
|
|
184
185
|
createContextXrayPlugin,
|
|
185
186
|
defaultContextXrayPlugin,
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
getSetting,
|
|
13
|
+
mutateSetting,
|
|
13
14
|
putSetting,
|
|
14
15
|
deleteSetting,
|
|
15
16
|
getAllSettings,
|
|
@@ -40,6 +41,18 @@ export async function putOrgSetting(
|
|
|
40
41
|
return putSetting(orgKey(orgId, key), value, options);
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
/** Atomically derive and persist an org-scoped setting. */
|
|
45
|
+
export async function mutateOrgSetting(
|
|
46
|
+
orgId: string,
|
|
47
|
+
key: string,
|
|
48
|
+
updater: (
|
|
49
|
+
current: Record<string, unknown> | null,
|
|
50
|
+
) => Record<string, unknown> | Promise<Record<string, unknown>>,
|
|
51
|
+
options?: StoreWriteOptions,
|
|
52
|
+
): Promise<Record<string, unknown>> {
|
|
53
|
+
return mutateSetting(orgKey(orgId, key), updater, options);
|
|
54
|
+
}
|
|
55
|
+
|
|
43
56
|
/** Delete an org-scoped setting. */
|
|
44
57
|
export async function deleteOrgSetting(
|
|
45
58
|
orgId: string,
|
|
@@ -128,6 +128,63 @@ export interface StoreWriteOptions {
|
|
|
128
128
|
requestSource?: string;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
const SETTINGS_MUTATION_ATTEMPTS = 25;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Atomically derive and persist one setting with an optimistic raw-value CAS.
|
|
135
|
+
* This works across SQLite/libSQL and Postgres and remains safe across
|
|
136
|
+
* horizontally scaled processes where an in-memory mutex would not.
|
|
137
|
+
* The updater may run more than once after contention and must not perform
|
|
138
|
+
* external side effects.
|
|
139
|
+
*/
|
|
140
|
+
export async function mutateSetting(
|
|
141
|
+
key: string,
|
|
142
|
+
updater: (
|
|
143
|
+
current: Record<string, unknown> | null,
|
|
144
|
+
) => Record<string, unknown> | Promise<Record<string, unknown>>,
|
|
145
|
+
options?: StoreWriteOptions,
|
|
146
|
+
): Promise<Record<string, unknown>> {
|
|
147
|
+
await ensureTable();
|
|
148
|
+
const client = getDbExec();
|
|
149
|
+
const table = settingsTable();
|
|
150
|
+
for (let attempt = 0; attempt < SETTINGS_MUTATION_ATTEMPTS; attempt += 1) {
|
|
151
|
+
// Deliberately bypass the request cache: a failed CAS means another
|
|
152
|
+
// request committed a newer value and the next attempt must reread it.
|
|
153
|
+
const snapshot = await client.execute({
|
|
154
|
+
sql: `SELECT value FROM ${table} WHERE key = ?`,
|
|
155
|
+
args: [key],
|
|
156
|
+
});
|
|
157
|
+
const raw =
|
|
158
|
+
snapshot.rows.length === 0 ? null : (snapshot.rows[0]?.value as string);
|
|
159
|
+
const current = raw == null ? null : JSON.parse(raw);
|
|
160
|
+
const next = await updater(current);
|
|
161
|
+
const nextRaw = JSON.stringify(next);
|
|
162
|
+
const timestamp = Date.now();
|
|
163
|
+
const result =
|
|
164
|
+
raw == null
|
|
165
|
+
? await client.execute({
|
|
166
|
+
sql: isPostgres()
|
|
167
|
+
? `INSERT INTO ${table} (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT (key) DO NOTHING`
|
|
168
|
+
: `INSERT OR IGNORE INTO ${table} (key, value, updated_at) VALUES (?, ?, ?)`,
|
|
169
|
+
args: [key, nextRaw, timestamp],
|
|
170
|
+
})
|
|
171
|
+
: await client.execute({
|
|
172
|
+
sql: `UPDATE ${table} SET value = ?, updated_at = ? WHERE key = ? AND value = ?`,
|
|
173
|
+
args: [nextRaw, timestamp, key, raw],
|
|
174
|
+
});
|
|
175
|
+
if (result.rowsAffected === 0) continue;
|
|
176
|
+
requestSettingsCache()?.set(key, nextRaw);
|
|
177
|
+
_emitter.emit("settings", {
|
|
178
|
+
source: "settings",
|
|
179
|
+
type: "change",
|
|
180
|
+
key,
|
|
181
|
+
...(options?.requestSource && { requestSource: options.requestSource }),
|
|
182
|
+
});
|
|
183
|
+
return JSON.parse(nextRaw);
|
|
184
|
+
}
|
|
185
|
+
throw new Error(`Setting ${key} changed too many times; retry the mutation.`);
|
|
186
|
+
}
|
|
187
|
+
|
|
131
188
|
export async function putSetting(
|
|
132
189
|
key: string,
|
|
133
190
|
value: Record<string, unknown>,
|
|
@@ -502,6 +502,13 @@
|
|
|
502
502
|
opacity 150ms ease-out;
|
|
503
503
|
}
|
|
504
504
|
|
|
505
|
+
@starting-style {
|
|
506
|
+
.agent-chat-collapse[data-state="open"] {
|
|
507
|
+
grid-template-rows: 0fr;
|
|
508
|
+
opacity: 0;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
505
512
|
.agent-chat-collapse[data-state="closed"] {
|
|
506
513
|
grid-template-rows: 0fr;
|
|
507
514
|
opacity: 0;
|