@agent-native/core 0.141.6 → 0.144.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/agent-native.eject.json +9 -0
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +3 -14
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +11 -6
- package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +5 -5
- package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/AGENTS.md +37 -40
- package/corpus/templates/analytics/actions/compose-dashboard.ts +1 -1
- package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
- package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
- package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +135 -0
- package/corpus/templates/analytics/actions/navigate.ts +5 -6
- package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +46 -13
- package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
- package/corpus/templates/analytics/actions/update-dashboard.ts +0 -1
- package/corpus/templates/analytics/actions/view-screen.ts +0 -20
- package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
- package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +5 -5
- package/corpus/templates/analytics/app/i18n-data.ts +682 -90
- package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
- package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
- package/corpus/templates/analytics/app/pages/Agents.tsx +0 -3
- package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +22 -43
- package/corpus/templates/analytics/app/pages/settings/settings-search.ts +23 -20
- package/corpus/templates/analytics/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/analytics/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/analytics/app/routes/team.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-08-05-settings-no-longer-includes-an-unnecessary-about-section.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +1 -1
- package/corpus/templates/analytics/netlify.toml +7 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
- package/corpus/templates/analytics/scripts/first-party-analytics-bigquery.sql +104 -0
- package/corpus/templates/analytics/server/db/index.ts +27 -0
- package/corpus/templates/analytics/server/db/schema.ts +10 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -2
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +1147 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +34 -15
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +57 -4
- package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -3
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -4
- package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
- package/corpus/templates/analytics/server/plugins/db.ts +52 -18
- package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +36 -8
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
- package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +16 -1
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/assets/AGENTS.md +1 -0
- package/corpus/templates/assets/actions/_helpers.ts +12 -0
- package/corpus/templates/assets/actions/generate-image.ts +9 -3
- package/corpus/templates/assets/actions/import-style-from-url.ts +115 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
- package/corpus/templates/assets/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/assets/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/assets/app/routes/settings.tsx +5 -0
- package/corpus/templates/assets/app/routes/team.tsx +1 -1
- package/corpus/templates/assets/changelog/2026-08-05-brand-kits-can-import-a-website-s-hydrated-visual-language-a.md +6 -0
- package/corpus/templates/assets/changelog/2026-08-05-generated-images-now-hand-off-embeddable-previews-to-other-w.md +6 -0
- package/corpus/templates/assets/server/lib/generation.ts +58 -0
- package/corpus/templates/assets/shared/api.ts +12 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
- package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
- package/corpus/templates/brain/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/brain/app/routes/sources.tsx +15 -7
- package/corpus/templates/brain/app/routes/team.tsx +1 -1
- package/corpus/templates/brain/app/routes.ts +1 -1
- package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
- package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/AGENTS.md +11 -32
- package/corpus/templates/calendar/actions/update-event.ts +107 -1
- package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
- package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/calendar/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
- package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/chat/app/root.tsx +1 -1
- package/corpus/templates/chat/app/routes/agent.tsx +7 -7
- package/corpus/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/chat/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/chat/app/routes/team.tsx +1 -1
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
- package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
- package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
- package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +48 -20
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
- package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
- package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
- package/corpus/templates/clips/server/plugins/db.ts +214 -26
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/content/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/content/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/content/e2e/global-setup.ts +1 -1
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
- package/corpus/templates/crm/server/plugins/db.ts +11 -8
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -1
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/design/actions/analyze-brand-assets.ts +7 -7
- package/corpus/templates/design/actions/import-from-url.ts +6 -5
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +2 -2
- package/corpus/templates/design/app/pages/Index.tsx +6 -2
- package/corpus/templates/design/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/design/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/design/app/routes/team.tsx +1 -1
- package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
- package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
- package/corpus/templates/design/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-de.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +1 -1
- package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/dispatch/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
- package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/factory/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/factory/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/factory/app/routes/team.tsx +1 -1
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/forms/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/forms/shared/navigation.ts +1 -1
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/macros/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/macros/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/macros/app/routes/team.tsx +1 -1
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/mail/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/mail/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/plan/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/plan/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/plan/app/routes/team.tsx +1 -1
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +40 -2
- package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/slides/AGENTS.md +7 -9
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/actions/analyze-brand-assets.ts +7 -7
- package/corpus/templates/slides/actions/export-pptx.ts +402 -36
- package/corpus/templates/slides/actions/import-file.ts +46 -85
- package/corpus/templates/slides/actions/import-from-url.ts +6 -6
- package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
- package/corpus/templates/slides/actions/import-pptx.ts +85 -60
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +176 -0
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
- package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
- package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +13 -3
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +71 -20
- package/corpus/templates/slides/app/global.css +6 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +10 -6
- package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
- package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
- package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -0
- package/corpus/templates/slides/app/pages/Index.tsx +107 -6
- package/corpus/templates/slides/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/slides/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/slides/app/routes/team.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-08-05-failed-deck-creation-and-reference-uploads-now-recover-clean.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-slides-recover-completed-generation-results-after-a-sync-hic.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-st.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
- package/corpus/templates/slides/server/handlers/import/html-converter.ts +236 -13
- package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
- package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
- package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
- package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -3
- package/corpus/templates/slides/server/lib/emails.ts +7 -2
- package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
- package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
- package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
- package/corpus/templates/slides/shared/upload-types.ts +3 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/app/components/layout/Header.tsx +3 -1
- package/corpus/templates/tasks/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/tasks/app/routes/settings.$.tsx +1 -0
- package/dist/agent/engine/ai-sdk-engine.js +49 -3
- package/dist/agent/production-agent.d.ts +18 -0
- package/dist/agent/production-agent.js +80 -1
- package/dist/agent/types.d.ts +7 -0
- package/dist/cli/agent-plugin.d.ts +112 -0
- package/dist/cli/agent-plugin.js +1081 -0
- package/dist/cli/app-skill.js +39 -1
- package/dist/cli/code-agent-executor.d.ts +3 -0
- package/dist/cli/code-agent-executor.js +51 -13
- package/dist/cli/index.js +13 -0
- package/dist/cli/templates-meta.js +1 -1
- package/dist/client/AgentPanel.d.ts +3 -1
- package/dist/client/AgentPanel.js +9 -2
- package/dist/client/AssistantChat.d.ts +8 -0
- package/dist/client/AssistantChat.js +23 -8
- package/dist/client/NewWorkspaceAppFlow.js +1 -0
- package/dist/client/agent-chat-adapter.d.ts +1 -1
- package/dist/client/agent-chat-adapter.js +153 -7
- package/dist/client/agent-page/AgentWorkspaceContent.d.ts +1 -1
- package/dist/client/agent-page/AgentWorkspaceContent.js +13 -13
- package/dist/client/assistant-ui-recovery.d.ts +2 -1
- package/dist/client/assistant-ui-recovery.js +7 -3
- package/dist/client/chat/run-recovery.js +5 -1
- package/dist/client/embed-auth.js +6 -2
- package/dist/client/error-format.js +12 -0
- package/dist/client/integrations/IntegrationsPanel.js +40 -6
- package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
- package/dist/client/org/OrgSwitcher.js +2 -2
- package/dist/client/org/TeamPage.js +92 -72
- package/dist/client/require-session.d.ts +1 -1
- package/dist/client/require-session.js +4 -4
- package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
- package/dist/client/resources/McpConnectionSuggestion.js +27 -10
- package/dist/client/resources/McpIntegrationDialog.js +77 -45
- package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
- package/dist/client/resources/mcp-integration-catalog.js +255 -2
- package/dist/client/resources/mcp-integration-logos.js +18 -2
- package/dist/client/resources/use-mcp-servers.d.ts +5 -0
- package/dist/client/resources/use-mcp-servers.js +36 -0
- package/dist/client/settings/AccountSettingsCard.js +42 -36
- package/dist/client/settings/AutomationsSection.js +1 -1
- package/dist/client/settings/DemoModeSection.d.ts +3 -1
- package/dist/client/settings/DemoModeSection.js +4 -1
- package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
- package/dist/client/settings/SchedulingTimezoneField.d.ts +3 -1
- package/dist/client/settings/SchedulingTimezoneField.js +9 -5
- package/dist/client/settings/SettingsPanel.d.ts +4 -1
- package/dist/client/settings/SettingsPanel.js +21 -21
- package/dist/client/settings/SettingsTabsPage.d.ts +2 -2
- package/dist/client/settings/SettingsTabsPage.js +98 -45
- package/dist/client/settings/VoiceTranscriptionSection.js +6 -1
- package/dist/client/settings/useSettingsPanelController.js +47 -8
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/client.d.ts +9 -0
- package/dist/db/client.js +51 -16
- package/dist/db/create-get-db.js +2 -2
- package/dist/db/ddl-guard.d.ts +11 -10
- package/dist/db/ddl-guard.js +40 -12
- package/dist/deploy/build.d.ts +2 -0
- package/dist/deploy/build.js +97 -4
- package/dist/deploy/workspace-deploy.js +0 -2
- package/dist/guards/no-env-credentials.js +9 -0
- package/dist/ingestion/index.d.ts +1 -1
- package/dist/ingestion/pptx.d.ts +68 -0
- package/dist/ingestion/pptx.js +660 -213
- package/dist/ingestion/website.d.ts +30 -0
- package/dist/integrations/plugin.js +9 -6
- package/dist/localization/default-messages.d.ts +59 -0
- package/dist/localization/default-messages.js +62 -2
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp-client/oauth-routes.d.ts +2 -0
- package/dist/mcp-client/oauth-routes.js +74 -7
- package/dist/mcp-client/routes.d.ts +1 -0
- package/dist/mcp-client/routes.js +49 -0
- package/dist/navigation/index.js +16 -5
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.js +11 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/resources/store.js +15 -1
- package/dist/scripts/call-agent.js +45 -4
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +36 -1
- package/dist/server/agent-chat-plugin.js +29 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.js +55 -17
- package/dist/server/better-auth-instance.js +5 -3
- package/dist/server/core-routes-plugin.d.ts +8 -1
- package/dist/server/core-routes-plugin.js +28 -3
- package/dist/server/credential-provider.d.ts +3 -3
- package/dist/server/credential-provider.js +90 -4
- package/dist/server/identity-sso.js +2 -1
- package/dist/server/onboarding-html.d.ts +2 -0
- package/dist/server/onboarding-html.js +171 -62
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/self-dispatch.d.ts +5 -4
- package/dist/server/self-dispatch.js +25 -14
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.js +1 -1
- package/dist/server/workspace-provider-oauth.js +1 -1
- package/dist/setup-connections/onboarding.js +1 -1
- package/dist/shared/cache-control.d.ts +26 -2
- package/dist/shared/cache-control.js +43 -2
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/password-policy.d.ts +3 -0
- package/dist/shared/password-policy.js +3 -0
- package/dist/shared/sign-in-journey.d.ts +5 -2
- package/dist/shared/sign-in-journey.js +10 -4
- package/dist/sharing/actions/set-resource-visibility.js +16 -4
- package/dist/sharing/registry.d.ts +14 -0
- package/dist/styles/agent-native.css +6 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/dist/templates/chat/app/root.tsx +1 -1
- package/dist/templates/chat/app/routes/agent.tsx +7 -7
- package/dist/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/dist/templates/chat/app/routes/settings.$.tsx +1 -0
- package/dist/templates/chat/app/routes/team.tsx +1 -1
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-root/AGENTS.md +7 -0
- package/dist/user-profile/actions/change-password.js +8 -3
- package/dist/user-profile/actions/set-password.js +5 -1
- package/dist/vite/action-types-plugin.js +59 -0
- package/docs/content/authentication.mdx +4 -5
- package/docs/content/skills-guide.mdx +13 -0
- package/docs/content/template-analytics-developers.mdx +1 -1
- package/docs/content/template-calendar-developers.mdx +1 -1
- package/docs/content/template-chat-developers.mdx +2 -2
- package/docs/content/template-content-developers.mdx +1 -1
- package/docs/content/template-mail-developers.mdx +1 -1
- package/docs/content/template-plan-developers.mdx +1 -1
- package/docs/content/toolkit-command-navigation.mdx +6 -6
- package/docs/content/toolkit-org-team.mdx +1 -1
- package/docs/content/toolkit-settings.mdx +8 -8
- package/docs/content/toolkit-setup-connections.mdx +1 -1
- package/package.json +6 -2
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/src/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/src/templates/chat/app/root.tsx +1 -1
- package/src/templates/chat/app/routes/agent.tsx +7 -7
- package/src/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/src/templates/chat/app/routes/settings.$.tsx +1 -0
- package/src/templates/chat/app/routes/team.tsx +1 -1
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-root/AGENTS.md +7 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +0 -62
- package/corpus/templates/analytics/actions/install-dashboard-template.ts +0 -369
- package/corpus/templates/analytics/actions/list-dashboard-templates.ts +0 -47
- package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +0 -34
- package/corpus/templates/analytics/app/routes/catalog.tsx +0 -240
- package/src/templates/default/actions/navigate.spec.ts +0 -53
|
@@ -1,50 +1,41 @@
|
|
|
1
1
|
# Analytics — Agent Guide
|
|
2
2
|
|
|
3
|
-
Analytics is an agent-native BI workspace for
|
|
4
|
-
charts, and warehouse integrations. Dashboards are
|
|
5
|
-
|
|
3
|
+
Analytics is an agent-native BI workspace for sources, queries, dashboards,
|
|
4
|
+
charts, and warehouse integrations. Dashboards are canonical; legacy analyses
|
|
5
|
+
remain readable for compatibility.
|
|
6
6
|
|
|
7
|
-
Use
|
|
8
|
-
|
|
7
|
+
Use connected sources and MCP tools; reason over fetched data here, not via
|
|
8
|
+
another AI tool.
|
|
9
9
|
|
|
10
10
|
Prompt cap: 6,000; put detail in `.agents/skills/*`.
|
|
11
11
|
|
|
12
|
-
Before building common workspace or agent UI, read `agent-native-toolkit
|
|
13
|
-
`customizing-agent-native`
|
|
14
|
-
|
|
12
|
+
Before building common workspace or agent UI, read `agent-native-toolkit` to
|
|
13
|
+
discover existing primitives and patterns. Read `customizing-agent-native`
|
|
14
|
+
before adapting shared UI: configure → compose → eject → propose.
|
|
15
15
|
|
|
16
16
|
## How To Answer A Data Question
|
|
17
17
|
|
|
18
|
-
1. **Search existing work first.** Call `search-analytics-query-catalog
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
already-summarized data (≤50 rows); above that, state the total and show the
|
|
32
|
-
top rows.
|
|
33
|
-
5. **Deliver exports in chat.** See `analysis-workspace`; never return only a
|
|
34
|
-
path or tell the user to find a download elsewhere.
|
|
35
|
-
6. **Chunk only for reading.** Group into 5-10 with per-item notes only when 30+
|
|
36
|
-
items each need qualitative reading no query can do (call transcripts, ticket
|
|
37
|
-
threads). Chunking a question a query could answer is the most expensive
|
|
38
|
-
mistake available here. See `adhoc-analysis`.
|
|
18
|
+
1. **Search existing work first.** Call `search-analytics-query-catalog`, adapt
|
|
19
|
+
the closest saved SQL to the requested filters/window, run it once, and stop.
|
|
20
|
+
2. **One bounded call.** List/filter/count/cohort questions are one SQL statement
|
|
21
|
+
or one server-side `run-code` script; never page or fan out per item.
|
|
22
|
+
3. **Escalate on a miss.** If the catalog has no usable result, make one discovery
|
|
23
|
+
pass (`list-data-dictionary`, `search-bigquery-schema`, `data-source-status`),
|
|
24
|
+
then query; don't cross-check or add unasked breakdowns.
|
|
25
|
+
4. **Answer in chat.** Return a short table or inline chart, not a dashboard
|
|
26
|
+
pointer. Native widgets show summarized data (≤50 rows); above that, state the
|
|
27
|
+
total and top rows.
|
|
28
|
+
5. **Deliver exports in chat.** See `analysis-workspace`; don't return only a path.
|
|
29
|
+
6. **Chunk only reading.** Group 5-10 only for 30+ qualitative items when a query
|
|
30
|
+
cannot answer; don't chunk queryable questions. See `adhoc-analysis`.
|
|
39
31
|
|
|
40
32
|
## Core Rules
|
|
41
33
|
|
|
42
|
-
- A sibling app asking over A2A sends a question or shaped input, never SQL.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
not workarounds for delegation; this app still owns the query.
|
|
34
|
+
- A sibling app asking over A2A sends a question or shaped input, never SQL.
|
|
35
|
+
Raw-query actions (`sql`, `code`, `script`, `expression`) are not
|
|
36
|
+
sibling-invocable because this app owns schema, source selection, and tools.
|
|
37
|
+
Prefer natural-language delegation; shaped reads are stable contracts, not
|
|
38
|
+
delegation workarounds.
|
|
48
39
|
- For open-ended delegated requests, choose a safe default and label partial.
|
|
49
40
|
- Data integrity first. Never invent numbers, dimensions, filters, or source
|
|
50
41
|
semantics; only present values you actually retrieved, and state uncertainty.
|
|
@@ -54,9 +45,15 @@ ladder.
|
|
|
54
45
|
access checks with raw SQL for ownable resources.
|
|
55
46
|
- Provider actions are bounded shortcuts, not limits. For broad or
|
|
56
47
|
absence-sensitive Gong work, stage raw API data and use
|
|
57
|
-
`query-staged-dataset` or a Data Program;
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
`query-staged-dataset` or a Data Program; use `provider-corpus-job` for raw
|
|
49
|
+
transcript bodies. See `provider-api`, `data-programs`, and `gong`.
|
|
50
|
+
- Custom APIs use the `provider-api-register` action for public HTTPS provider
|
|
51
|
+
metadata and `test-custom-api-connection` for bounded GET previews. Store
|
|
52
|
+
credential values in Settings, pass only key names to provider actions, and
|
|
53
|
+
hand successful endpoint tests to `save-data-program` for refreshable panels.
|
|
54
|
+
- Hosted Analytics cannot reach localhost or private network APIs. Use a
|
|
55
|
+
deployed HTTPS endpoint or an explicitly supported secure tunnel; never
|
|
56
|
+
weaken the provider runtime's SSRF boundary.
|
|
60
57
|
- Create dashboards, panels, or saved artifacts only when explicitly asked;
|
|
61
58
|
suggest and wait otherwise. Scope them to the question, avoid decorative
|
|
62
59
|
metrics, and never modify existing dashboards without a directive.
|
|
@@ -81,7 +78,7 @@ ladder.
|
|
|
81
78
|
## Application State
|
|
82
79
|
|
|
83
80
|
- `navigation` exposes the current dashboard, analysis, source, chart, and
|
|
84
|
-
selection. `navigate` moves the user
|
|
81
|
+
selection. `navigate` moves the user between supported Analytics surfaces,
|
|
85
82
|
`"sessions"`, `"monitoring"`, and `"agents"`. Use `view-screen` when the
|
|
86
83
|
active context is unclear.
|
|
87
84
|
- Clicking a panel stages it as a chat context chip and writes `selected-object`
|
|
@@ -97,7 +94,7 @@ Read the relevant skill before deeper work:
|
|
|
97
94
|
- `cross-source-analysis` for questions spanning sources (identity stitching,
|
|
98
95
|
de-duplication).
|
|
99
96
|
- `dashboard-management` for dashboard/panel storage, layout, extensions,
|
|
100
|
-
mutation
|
|
97
|
+
mutation and sharing.
|
|
101
98
|
- `adhoc-analysis` and `analysis-workspace` for one-off answers and large
|
|
102
99
|
multi-source work.
|
|
103
100
|
- `provider-api` and `data-programs` for the escape hatch and durable,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Push the saved config through the collab layer so open dashboard editors get
|
|
32
|
-
* the change in real time (mirrors update-dashboard
|
|
32
|
+
* the change in real time (mirrors update-dashboard).
|
|
33
33
|
*/
|
|
34
34
|
async function syncToCollab(
|
|
35
35
|
dashboardId: string,
|
|
@@ -235,7 +235,7 @@ export async function ensureNativeV2Dashboards(
|
|
|
235
235
|
|
|
236
236
|
export default defineAction({
|
|
237
237
|
description:
|
|
238
|
-
"Provision the
|
|
238
|
+
"Provision the reusable native Analytics v2 dashboard patterns, including On Demand Billing, for the active organization from explicit Data Program bindings. " +
|
|
239
239
|
"This is an admin-only post-deploy action: it validates every program exists and exposes the manifest's required output columns, shares the bound programs with the organization, creates deterministic native-* dashboard copies, and never changes the legacy extension dashboards. " +
|
|
240
240
|
"Re-running preserves existing v2 dashboard edits unless overwrite=true.",
|
|
241
241
|
schema: z.object({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core/action";
|
|
2
|
+
import { isPostgres } from "@agent-native/core/db";
|
|
2
3
|
import { buildDeepLink } from "@agent-native/core/server";
|
|
3
4
|
import { and, eq, isNull, like, or, sql } from "drizzle-orm";
|
|
4
5
|
import { z } from "zod";
|
|
@@ -40,24 +41,8 @@ function toNumber(value: unknown): number {
|
|
|
40
41
|
return 0;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
return value as Record<string, unknown>;
|
|
46
|
-
}
|
|
47
|
-
if (typeof value !== "string") return {};
|
|
48
|
-
try {
|
|
49
|
-
const parsed = JSON.parse(value);
|
|
50
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
51
|
-
? parsed
|
|
52
|
-
: {};
|
|
53
|
-
} catch {
|
|
54
|
-
return {};
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function dashboardName(row: { title: string; config: unknown }): string {
|
|
59
|
-
const config = parseConfig(row.config);
|
|
60
|
-
const configName = config.name;
|
|
44
|
+
function dashboardName(row: { title: string; configName: unknown }): string {
|
|
45
|
+
const configName = row.configName;
|
|
61
46
|
if (typeof configName === "string" && configName.trim()) {
|
|
62
47
|
return configName.trim();
|
|
63
48
|
}
|
|
@@ -66,11 +51,10 @@ function dashboardName(row: { title: string; config: unknown }): string {
|
|
|
66
51
|
|
|
67
52
|
function dashboardPanelCount(row: {
|
|
68
53
|
kind: string;
|
|
69
|
-
|
|
54
|
+
panelCount: unknown;
|
|
70
55
|
}): number | null {
|
|
71
56
|
if (row.kind !== "sql") return null;
|
|
72
|
-
|
|
73
|
-
return Array.isArray(panels) ? panels.length : 0;
|
|
57
|
+
return toNumber(row.panelCount);
|
|
74
58
|
}
|
|
75
59
|
|
|
76
60
|
export function dashboardIdFromPath(path: string | null): string | null {
|
|
@@ -143,6 +127,16 @@ export default defineAction({
|
|
|
143
127
|
run: async (_args, ctx) => {
|
|
144
128
|
const admin = await requireDbAdminContextFromRequest(ctx);
|
|
145
129
|
const db = getDb() as any;
|
|
130
|
+
const configName = isPostgres()
|
|
131
|
+
? sql<string | null>`(${schema.dashboards.config}::jsonb ->> 'name')`
|
|
132
|
+
: sql<string | null>`json_extract(${schema.dashboards.config}, '$.name')`;
|
|
133
|
+
const panelCount = isPostgres()
|
|
134
|
+
? sql<
|
|
135
|
+
number | null
|
|
136
|
+
>`CASE WHEN ${schema.dashboards.kind} = 'sql' AND jsonb_typeof(${schema.dashboards.config}::jsonb -> 'panels') = 'array' THEN jsonb_array_length(${schema.dashboards.config}::jsonb -> 'panels') ELSE 0 END`
|
|
137
|
+
: sql<
|
|
138
|
+
number | null
|
|
139
|
+
>`CASE WHEN ${schema.dashboards.kind} = 'sql' AND json_type(json_extract(${schema.dashboards.config}, '$.panels')) = 'array' THEN json_array_length(json_extract(${schema.dashboards.config}, '$.panels')) ELSE 0 END`;
|
|
146
140
|
|
|
147
141
|
// guard:allow-unscoped — org owner/admin audit intentionally spans all
|
|
148
142
|
// dashboard rows in the active org after requireDbAdminContextFromRequest.
|
|
@@ -151,7 +145,8 @@ export default defineAction({
|
|
|
151
145
|
id: schema.dashboards.id,
|
|
152
146
|
kind: schema.dashboards.kind,
|
|
153
147
|
title: schema.dashboards.title,
|
|
154
|
-
|
|
148
|
+
configName,
|
|
149
|
+
panelCount,
|
|
155
150
|
ownerEmail: schema.dashboards.ownerEmail,
|
|
156
151
|
visibility: schema.dashboards.visibility,
|
|
157
152
|
createdAt: schema.dashboards.createdAt,
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import {
|
|
3
|
+
getRequestOrgId,
|
|
4
|
+
getRequestUserEmail,
|
|
5
|
+
} from "@agent-native/core/server";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
import { requireAnalyticsAdminContext } from "../server/lib/db-admin-connections.js";
|
|
9
|
+
import {
|
|
10
|
+
assertFirstPartyAnalyticsBigQueryReady,
|
|
11
|
+
backfillFirstPartyAnalyticsBatch,
|
|
12
|
+
getFirstPartyAnalyticsBackend,
|
|
13
|
+
saveFirstPartyAnalyticsBackend,
|
|
14
|
+
} from "../server/lib/first-party-analytics-backend.js";
|
|
15
|
+
|
|
16
|
+
async function resolveScope() {
|
|
17
|
+
const userEmail = getRequestUserEmail();
|
|
18
|
+
if (!userEmail) throw new Error("no authenticated user");
|
|
19
|
+
const orgId = getRequestOrgId();
|
|
20
|
+
if (!orgId) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
"An active organization is required for the first-party Analytics migration.",
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
const admin = await requireAnalyticsAdminContext({ userEmail, orgId });
|
|
26
|
+
return { userEmail: admin.userEmail, orgId: admin.orgId };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const migrationSchema = z.object({
|
|
30
|
+
mode: z.enum(["status", "prepare", "backfill", "cutover"]),
|
|
31
|
+
table: z
|
|
32
|
+
.string()
|
|
33
|
+
.trim()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe(
|
|
36
|
+
"Optional BigQuery table reference as dataset.table or project.dataset.table. The default is <BIGQUERY_PROJECT_ID>.analytics.first_party_analytics_events_raw.",
|
|
37
|
+
),
|
|
38
|
+
cursor: z.string().trim().optional(),
|
|
39
|
+
limit: z.number().int().min(1).max(500).optional(),
|
|
40
|
+
confirm: z.boolean().optional(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export default defineAction({
|
|
44
|
+
description:
|
|
45
|
+
"UI-only production migration for the current Analytics organization. Run prepare to validate the configured BigQuery table and enter dual-write mode, call backfill repeatedly with the returned cursor until complete, then call cutover with confirm=true. New /track events stay in Postgres during dual-write, so a BigQuery outage does not silently lose live data. Cutover is the only step that stops analytics event and rollup writes to Postgres; public-key metadata, derived exception issues, and session-replay data remain in the SQL store.",
|
|
46
|
+
schema: migrationSchema,
|
|
47
|
+
agentTool: false,
|
|
48
|
+
needsApproval: ({ mode }) => mode === "cutover",
|
|
49
|
+
run: async ({ mode, table, cursor, limit, confirm }) => {
|
|
50
|
+
const scope = await resolveScope();
|
|
51
|
+
const current = await getFirstPartyAnalyticsBackend(scope);
|
|
52
|
+
const configuredTable = table ?? current.table;
|
|
53
|
+
|
|
54
|
+
if (mode === "status") {
|
|
55
|
+
const ready =
|
|
56
|
+
current.sink === "postgres"
|
|
57
|
+
? null
|
|
58
|
+
: await assertFirstPartyAnalyticsBigQueryReady(current.table);
|
|
59
|
+
return {
|
|
60
|
+
...current,
|
|
61
|
+
ready: Boolean(ready),
|
|
62
|
+
rowCount: ready?.rowCount ?? null,
|
|
63
|
+
table: ready?.table.fullyQualified ?? current.table,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (mode === "prepare") {
|
|
68
|
+
const ready =
|
|
69
|
+
await assertFirstPartyAnalyticsBigQueryReady(configuredTable);
|
|
70
|
+
await saveFirstPartyAnalyticsBackend(scope, {
|
|
71
|
+
sink: "dual",
|
|
72
|
+
table: ready.table.fullyQualified,
|
|
73
|
+
backfillCursor: null,
|
|
74
|
+
backfillCompleted: false,
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
sink: "dual" as const,
|
|
78
|
+
table: ready.table.fullyQualified,
|
|
79
|
+
existingBigQueryRows: ready.rowCount,
|
|
80
|
+
next: "backfill",
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (mode === "backfill") {
|
|
85
|
+
if (current.sink !== "dual") {
|
|
86
|
+
throw new Error(
|
|
87
|
+
"Prepare the organization for dual-write before starting the BigQuery backfill.",
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
const result = await backfillFirstPartyAnalyticsBatch(
|
|
91
|
+
scope,
|
|
92
|
+
cursor ?? current.backfillCursor ?? null,
|
|
93
|
+
limit ?? 500,
|
|
94
|
+
current.table,
|
|
95
|
+
);
|
|
96
|
+
await saveFirstPartyAnalyticsBackend(scope, {
|
|
97
|
+
sink: "dual",
|
|
98
|
+
table: current.table,
|
|
99
|
+
backfillCursor: result.nextCursor,
|
|
100
|
+
backfillCompleted: result.complete,
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
...result,
|
|
104
|
+
sink: "dual" as const,
|
|
105
|
+
table: current.table,
|
|
106
|
+
next: result.complete ? "cutover" : "backfill",
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!confirm) {
|
|
111
|
+
throw new Error(
|
|
112
|
+
"Cutover requires confirm=true because it stops first-party event and rollup writes to Postgres for this organization.",
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
if (current.sink !== "dual" || current.backfillCompleted !== true) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
"Complete the dual-write backfill before cutting over to BigQuery.",
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
const ready = await assertFirstPartyAnalyticsBigQueryReady(current.table);
|
|
121
|
+
await saveFirstPartyAnalyticsBackend(scope, {
|
|
122
|
+
sink: "bigquery",
|
|
123
|
+
table: ready.table.fullyQualified,
|
|
124
|
+
backfillCursor: current.backfillCursor,
|
|
125
|
+
backfillCompleted: true,
|
|
126
|
+
});
|
|
127
|
+
return {
|
|
128
|
+
sink: "bigquery" as const,
|
|
129
|
+
table: ready.table.fullyQualified,
|
|
130
|
+
existingBigQueryRows: ready.rowCount,
|
|
131
|
+
postgresEventWrites: "stopped",
|
|
132
|
+
next: "verify dashboards",
|
|
133
|
+
};
|
|
134
|
+
},
|
|
135
|
+
});
|
|
@@ -6,11 +6,10 @@ import {
|
|
|
6
6
|
} from "@agent-native/core/server";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
9
|
+
import {
|
|
10
|
+
listDashboardSummaries,
|
|
11
|
+
normalizeDashboardName,
|
|
12
|
+
} from "../server/lib/dashboards-store";
|
|
14
13
|
|
|
15
14
|
async function resolveDashboardIdByName(name: string): Promise<string> {
|
|
16
15
|
const email = getRequestUserEmail();
|
|
@@ -50,7 +49,7 @@ export default defineAction({
|
|
|
50
49
|
.string()
|
|
51
50
|
.optional()
|
|
52
51
|
.describe(
|
|
53
|
-
"View to navigate to (ask, adhoc, analyses, extensions, sessions, monitoring, agents,
|
|
52
|
+
"View to navigate to (ask, adhoc, analyses, extensions, sessions, monitoring, agents, data-dictionary, data-sources, settings)",
|
|
54
53
|
),
|
|
55
54
|
dashboardId: z
|
|
56
55
|
.string()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { getDbExec } from "@agent-native/core/db";
|
|
2
|
+
import {
|
|
3
|
+
createCustomProviderRegistrationAction,
|
|
4
|
+
CustomProviderRegistrationSchema,
|
|
5
|
+
} from "@agent-native/core/provider-api/actions/custom-provider-registration";
|
|
6
|
+
import { getCredentialContext } from "@agent-native/core/server/request-context";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
|
|
9
|
+
async function resolveCallerOrgRole(orgId: string, email: string) {
|
|
10
|
+
try {
|
|
11
|
+
const { rows } = await getDbExec().execute({
|
|
12
|
+
sql: `SELECT role FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,
|
|
13
|
+
args: [orgId, email.toLowerCase()],
|
|
14
|
+
});
|
|
15
|
+
const role = (rows[0] as { role?: unknown } | undefined)?.role;
|
|
16
|
+
return typeof role === "string" && role ? role : null;
|
|
17
|
+
} catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const schema = CustomProviderRegistrationSchema.superRefine((value, ctx) => {
|
|
23
|
+
if (value.operation === "upsert" && value.baseUrl) {
|
|
24
|
+
try {
|
|
25
|
+
const url = new URL(value.baseUrl);
|
|
26
|
+
if (url.protocol !== "https:") {
|
|
27
|
+
ctx.addIssue({
|
|
28
|
+
code: z.ZodIssueCode.custom,
|
|
29
|
+
path: ["baseUrl"],
|
|
30
|
+
message: "baseUrl must use public HTTPS.",
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
} catch {
|
|
34
|
+
// The shared schema reports malformed URLs.
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const action = createCustomProviderRegistrationAction({
|
|
40
|
+
schema,
|
|
41
|
+
getContext: getCredentialContext,
|
|
42
|
+
resolveOrgRole: resolveCallerOrgRole,
|
|
43
|
+
description:
|
|
44
|
+
"Register or update an Analytics custom API provider. Stores credential key names only, never secret values. Requires a public HTTPS base URL and owner/admin organization access.",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// The shared factory owns registration, validation, and mutation authorization;
|
|
48
|
+
// this wrapper only adds Analytics' transport contract and base URL policy.
|
|
49
|
+
// Static action registry marker: createCustomProviderRegistrationAction returns defineAction.
|
|
50
|
+
export default { ...action, http: { method: "POST" as const } };
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ACTION_CHAT_UI_DATA_TABLE_RENDERER,
|
|
3
|
+
dataTableWidgetResultSchema,
|
|
4
|
+
defineAction,
|
|
5
|
+
} from "@agent-native/core";
|
|
6
|
+
import { createDataTableWidgetResult } from "@agent-native/core/data-widgets";
|
|
2
7
|
import {
|
|
3
8
|
getRequestOrgId,
|
|
4
9
|
getRequestUserEmail,
|
|
@@ -13,25 +18,50 @@ function resolveScope() {
|
|
|
13
18
|
return { userEmail, orgId: getRequestOrgId() || null };
|
|
14
19
|
}
|
|
15
20
|
|
|
21
|
+
function toDataTableResult(result: {
|
|
22
|
+
rows: Record<string, unknown>[];
|
|
23
|
+
schema: { name: string; type: string }[];
|
|
24
|
+
}) {
|
|
25
|
+
const numericTypes = new Set([
|
|
26
|
+
"number",
|
|
27
|
+
"integer",
|
|
28
|
+
"float",
|
|
29
|
+
"double",
|
|
30
|
+
"decimal",
|
|
31
|
+
"numeric",
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
return createDataTableWidgetResult({
|
|
35
|
+
widgetId: "analytics.query.v1",
|
|
36
|
+
title: "Analytics query result",
|
|
37
|
+
table: {
|
|
38
|
+
title: "Analytics query result",
|
|
39
|
+
columns: result.schema.map(({ name, type }) => ({
|
|
40
|
+
key: name,
|
|
41
|
+
label: name,
|
|
42
|
+
...(numericTypes.has(type.toLowerCase()) ? { align: "right" } : {}),
|
|
43
|
+
})),
|
|
44
|
+
rows: result.rows,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
16
49
|
export default defineAction({
|
|
17
50
|
description:
|
|
18
|
-
"Query the built-in first-party Analytics source: events recorded through this app's analytics collector endpoint (/track), compact daily rollups, identifiable user-day rollups, and session replay summaries recorded through /api/analytics/replay. This source does not require an external provider connection. Use it for questions about app/site traffic, product events, template/app usage, conversions, session recordings, LLM/agent observability, model cost, token volume, latency, and other first-party data collected by this analytics app. Use source-specific actions such as BigQuery, GA4, Mixpanel, PostHog, or Amplitude when the user asks for those sources or the relevant data lives there. SQL may read analytics_events, analytics_event_daily_rollups, analytics_user_days, and session_recordings; session_replay_chunks is intentionally unavailable, and reads are automatically scoped to the current user/org. Prefer analytics_event_daily_rollups for event counts and analytics_user_days for active-user or retention questions.
|
|
51
|
+
"Query the built-in first-party Analytics source: events recorded through this app's analytics collector endpoint (/track), compact daily rollups updated transactionally with new ingest, identifiable user-day rollups, and session replay summaries recorded through /api/analytics/replay. This source does not require an external provider connection. Use it for questions about app/site traffic, product events, template/app usage, conversions, session recordings, LLM/agent observability, model cost, token volume, latency, and other first-party data collected by this analytics app. Use source-specific actions such as BigQuery, GA4, Mixpanel, PostHog, or Amplitude when the user asks for those sources or the relevant data lives there. SQL may read analytics_events, analytics_event_daily_rollups, analytics_user_days, and session_recordings; session_replay_chunks is intentionally unavailable, and reads are automatically scoped to the current user/org. Prefer analytics_event_daily_rollups for event counts and analytics_user_days for active-user or retention questions. On the Builder.io production organization after the explicit BigQuery cutover, event and rollup reads use partitioned BigQuery tables/views while session_recordings remains in the SQL store; cross-backend joins are not supported. Before a large or historical query, call get-first-party-analytics-health and use a configured external backend when it recommends one: BigQuery supports warehouse SQL and historical analysis, while Amplitude supports product analytics, funnels, and retention. Connecting a backend does not automatically reroute /track events or copy existing Neon events; the migration action performs that explicit prepare, backfill, and cutover sequence. Aggregate, project only needed columns, use bounded recent drill-downs, and add a LIMIT for raw or high-cardinality reads; do not issue an unbounded raw-event scan or paginate a large cohort. An explicit all-time or lifetime request remains all-time, so do not invent a default lower time bound. Safe scoped results are cached for up to five minutes for this agent action. analytics_events columns include event_name, timestamp, event_date, user_id, anonymous_id, user_key, session_id, app, template, signed_in, url, path, hostname, referrer, properties, and context. analytics_event_daily_rollups columns include tenant_key, owner_email, org_id, event_date, event_name, app, template, and event_count. analytics_user_days columns include tenant_key, owner_email, org_id, event_date, and user_key. LLM observability events use event_name = '$ai_generation'; useful properties include $ai_trace_id/run_id, $ai_session_id/thread_id, $ai_model/model, $ai_provider/provider, $ai_input_tokens/input_tokens, $ai_output_tokens/output_tokens, cache_read_tokens, cache_write_tokens, cost_cents_x100, $ai_total_cost_usd/cost_usd, duration_ms/$ai_latency, status, tool_calls, successful_tools, failed_tools, tools, tools_truncated, delegated, delegation_protocol, caller_app, delegation_task_id, a2a_task_id, parent_run_id, parent_turn_id, and error_message/$ai_error. Agent Teams child runs use delegation_protocol = 'agent-team' and retain their own run_id while linking to the launching run through parent_run_id. The bounded tools array contains names, relative start times, durations, statuses, and coarse error classes only, never args or results; failed runs and interrupted tools remain queryable. session_recordings columns include id, session_id, user_id, anonymous_id, user_key, started_at, ended_at, duration_ms, chunk_count, event_count, page_count, error_count, rage_click_count, app, template, status, first_url, last_url, path, hostname, referrer, and metadata.",
|
|
19
52
|
schema: z.object({
|
|
20
53
|
sql: z
|
|
21
54
|
.string()
|
|
22
55
|
.describe(
|
|
23
|
-
"Read-only SQL over analytics_events, analytics_event_daily_rollups, analytics_user_days, and session_recordings. Use literal values, not bind placeholders. Prefer the daily rollups for counts, active-user, and retention questions.
|
|
56
|
+
"Read-only SQL over analytics_events, analytics_event_daily_rollups, analytics_user_days, and session_recordings. Use literal values, not bind placeholders. Prefer the daily rollups for counts, active-user, and retention questions. On the Builder.io production organization after the explicit BigQuery cutover, event and rollup reads use partitioned BigQuery tables/views while session_recordings remains in the SQL store; cross-backend joins are not supported. Before a large or historical query, call get-first-party-analytics-health and use a configured external backend when recommended: BigQuery for warehouse SQL and complete history, or Amplitude for product analytics, funnels, and retention. Connecting one does not automatically reroute /track events or backfill existing Neon data; the migration action performs that explicit prepare, backfill, and cutover sequence. Aggregate or project only needed columns and add a LIMIT for raw or high-cardinality reads; do not issue an unbounded raw-event scan or paginate a large cohort. An explicit all-time or lifetime request remains all-time, so do not invent a default lower time bound. Example: SELECT event_date, event_name, SUM(event_count) AS events FROM analytics_event_daily_rollups WHERE event_date >= '2026-05-01' AND event_date < '2026-06-01' GROUP BY event_date, event_name ORDER BY event_date, events DESC",
|
|
24
57
|
),
|
|
25
58
|
}),
|
|
26
|
-
outputSchema:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}),
|
|
33
|
-
),
|
|
34
|
-
}),
|
|
59
|
+
outputSchema: dataTableWidgetResultSchema,
|
|
60
|
+
chatUI: {
|
|
61
|
+
renderer: ACTION_CHAT_UI_DATA_TABLE_RENDERER,
|
|
62
|
+
title: "Analytics query result",
|
|
63
|
+
description: "Render query rows as a native table with CSV download.",
|
|
64
|
+
},
|
|
35
65
|
readOnly: true,
|
|
36
66
|
// No raw HTTP or connector-catalog route: SQL would land in query strings,
|
|
37
67
|
// logs, or a caller that lacks this app's schema and data dictionary. This
|
|
@@ -40,6 +70,9 @@ export default defineAction({
|
|
|
40
70
|
http: false,
|
|
41
71
|
publicAgent: { expose: true, readOnly: true, requiresAuth: true },
|
|
42
72
|
run: async (args) => {
|
|
43
|
-
|
|
73
|
+
const result = await queryFirstPartyAnalytics(args.sql, resolveScope(), {
|
|
74
|
+
cache: true,
|
|
75
|
+
});
|
|
76
|
+
return toDataTableResult(result);
|
|
44
77
|
},
|
|
45
78
|
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import { extractItemsArray } from "@agent-native/core/provider-api/staging";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { getAnalyticsProviderApiRuntime } from "../server/lib/provider-api";
|
|
6
|
+
|
|
7
|
+
const secretKey = /pass(word)?|secret|token|api[-_]?key|authorization/i;
|
|
8
|
+
const Input = z.object({
|
|
9
|
+
provider: z.string().min(1),
|
|
10
|
+
path: z.string().min(1),
|
|
11
|
+
query: z.record(z.string(), z.unknown()).optional(),
|
|
12
|
+
itemsPath: z.string().min(1).optional(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
function redact(value: unknown): unknown {
|
|
16
|
+
if (Array.isArray(value)) return value.map(redact);
|
|
17
|
+
if (!value || typeof value !== "object") return value;
|
|
18
|
+
return Object.fromEntries(
|
|
19
|
+
Object.entries(value).map(([key, entry]) => [
|
|
20
|
+
key,
|
|
21
|
+
secretKey.test(key) ? "[redacted]" : redact(entry),
|
|
22
|
+
]),
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default defineAction({
|
|
27
|
+
description:
|
|
28
|
+
"Test an Analytics custom API connection with a bounded authenticated GET and return a safe row preview.",
|
|
29
|
+
schema: Input,
|
|
30
|
+
agentTool: false,
|
|
31
|
+
http: { method: "POST" },
|
|
32
|
+
readOnly: true,
|
|
33
|
+
run: async ({ provider, path, query, itemsPath }) => {
|
|
34
|
+
try {
|
|
35
|
+
const result = (await getAnalyticsProviderApiRuntime().executeRequest({
|
|
36
|
+
provider,
|
|
37
|
+
method: "GET",
|
|
38
|
+
path,
|
|
39
|
+
...(query ? { query } : {}),
|
|
40
|
+
auth: "default",
|
|
41
|
+
maxBytes: 1_000_000,
|
|
42
|
+
timeoutMs: 10_000,
|
|
43
|
+
})) as {
|
|
44
|
+
response?: {
|
|
45
|
+
ok?: boolean;
|
|
46
|
+
status?: number;
|
|
47
|
+
statusText?: string;
|
|
48
|
+
json?: unknown;
|
|
49
|
+
truncated?: boolean;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
const response = result.response;
|
|
53
|
+
const status = response?.status ?? 0;
|
|
54
|
+
const statusText = response?.statusText ?? "";
|
|
55
|
+
if (!response?.ok) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
status,
|
|
59
|
+
statusText,
|
|
60
|
+
rowCount: 0,
|
|
61
|
+
columns: [],
|
|
62
|
+
sampleRows: [],
|
|
63
|
+
itemsPath: itemsPath ?? null,
|
|
64
|
+
truncated: false,
|
|
65
|
+
error: `Custom API request failed with HTTP ${status}${statusText ? ` ${statusText}` : ""}.`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const rows = extractItemsArray(response.json, itemsPath ?? "auto");
|
|
69
|
+
const sampleRows = rows.slice(0, 5).map((row) => redact(row));
|
|
70
|
+
const columns = Array.from(
|
|
71
|
+
new Set(
|
|
72
|
+
rows.flatMap((row) =>
|
|
73
|
+
row && typeof row === "object" && !Array.isArray(row)
|
|
74
|
+
? Object.keys(row)
|
|
75
|
+
: [],
|
|
76
|
+
),
|
|
77
|
+
),
|
|
78
|
+
);
|
|
79
|
+
return {
|
|
80
|
+
ok: true,
|
|
81
|
+
status,
|
|
82
|
+
statusText,
|
|
83
|
+
rowCount: rows.length,
|
|
84
|
+
columns,
|
|
85
|
+
sampleRows,
|
|
86
|
+
itemsPath: itemsPath ?? "auto",
|
|
87
|
+
truncated: Boolean(response.truncated),
|
|
88
|
+
};
|
|
89
|
+
} catch (error) {
|
|
90
|
+
return {
|
|
91
|
+
ok: false,
|
|
92
|
+
status: 0,
|
|
93
|
+
statusText: "",
|
|
94
|
+
rowCount: 0,
|
|
95
|
+
columns: [],
|
|
96
|
+
sampleRows: [],
|
|
97
|
+
itemsPath: itemsPath ?? null,
|
|
98
|
+
truncated: false,
|
|
99
|
+
error:
|
|
100
|
+
error instanceof Error
|
|
101
|
+
? `Custom API connection failed: ${error.message}`
|
|
102
|
+
: "Custom API connection failed.",
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
});
|
|
@@ -576,7 +576,6 @@ export default defineAction({
|
|
|
576
576
|
"Do not use `ops` or `panelOrder` for ordinary agent edits like moving charts, adding panels to an existing dashboard, changing widths, or updating panel config; call `mutate-dashboard` once with the full edit script. " +
|
|
577
577
|
"When this action is appropriate, provide only one of `ops`, `panelOrder`, or `config`; `config` replaces the whole dashboard config. " +
|
|
578
578
|
"First-party event panels must bind to a declared dashboard time filter with `{{timeRange}}` or date-range variables. Intentional fixed-window, cohort-history, and all-time exceptions must be explicit in `panel.config.timeScope`; unbounded first-party SQL is rejected at save time. " +
|
|
579
|
-
"To add a shipped catalog template's panels to an existing dashboard, prefer `install-dashboard-template` with `mergePanels: true` — it appends the template's panels in one call without you having to author each panel. " +
|
|
580
579
|
"The result is compact by default: `panelCount`, `appliedOps`, `panelOrder`, `firstPanelIds`, and `summary`. Set `returnConfig: true` only when you truly need the full config in the tool result. " +
|
|
581
580
|
"The UI auto-refreshes after this action — do NOT call `refresh-screen`.",
|
|
582
581
|
schema: z.object({
|