@agent-native/core 0.121.2 → 0.122.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -12
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +148 -0
- package/corpus/core/docs/content/actions.mdx +2 -2
- package/corpus/core/docs/content/agent-surfaces.mdx +1 -1
- package/corpus/core/docs/content/authentication.mdx +2 -0
- package/corpus/core/docs/content/deployment.mdx +36 -0
- package/corpus/core/docs/content/http-api.mdx +266 -0
- package/corpus/core/docs/content/syncing-template-changes.mdx +159 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/a2a/activity.ts +38 -27
- package/corpus/core/src/a2a/client.ts +57 -4
- package/corpus/core/src/agent/engine/builder-engine.ts +35 -4
- package/corpus/core/src/agent/run-manager.ts +20 -1
- package/corpus/core/src/agent/run-store.ts +4 -1
- package/corpus/core/src/agent/types.ts +28 -8
- package/corpus/core/src/chat-threads/store.ts +45 -0
- package/corpus/core/src/checkpoints/index.ts +2 -0
- package/corpus/core/src/checkpoints/route-match.ts +13 -0
- package/corpus/core/src/cli/create.ts +105 -17
- package/corpus/core/src/cli/index.ts +20 -0
- package/corpus/core/src/cli/template-baseline.ts +410 -0
- package/corpus/core/src/cli/template-sync.ts +1004 -0
- package/corpus/core/src/cli/templates-meta.ts +1 -0
- package/corpus/core/src/client/AssistantChat.tsx +38 -12
- package/corpus/core/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/corpus/core/src/client/chat/message-components.tsx +127 -66
- package/corpus/core/src/client/chat/tool-call-display.tsx +29 -5
- package/corpus/core/src/client/error-format.ts +18 -0
- package/corpus/core/src/client/org/OrgSwitcher.tsx +30 -8
- package/corpus/core/src/client/org/TeamPage.tsx +7 -6
- package/corpus/core/src/client/settings/SettingsPanel.tsx +9 -9
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +12 -2
- package/corpus/core/src/client/sse-event-processor.ts +3 -0
- package/corpus/core/src/data-widgets/index.ts +41 -0
- package/corpus/core/src/deploy/build.ts +11 -9
- package/corpus/core/src/extensions/url-safety.ts +67 -4
- package/corpus/core/src/integrations/webhook-handler.ts +63 -9
- package/corpus/core/src/org/auto-join-domain.ts +4 -3
- package/corpus/core/src/org/context.ts +108 -39
- package/corpus/core/src/org/index.ts +5 -0
- package/corpus/core/src/org/service-identity.ts +60 -0
- package/corpus/core/src/provider-api/index.ts +22 -1
- package/corpus/core/src/scripts/docs/search.ts +12 -1
- package/corpus/core/src/server/agent-chat/context-tools.ts +9 -4
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +38 -66
- package/corpus/core/src/server/agent-chat-plugin.ts +17 -10
- package/corpus/core/src/server/agents-bundle.ts +84 -5
- package/corpus/core/src/server/auth.ts +4 -3
- package/corpus/core/src/server/builder-browser.ts +47 -19
- package/corpus/core/src/server/core-routes-plugin.ts +2 -2
- package/corpus/core/src/server/credential-provider.ts +209 -68
- package/corpus/core/src/server/index.ts +3 -0
- package/corpus/core/src/server/prompts/framework-core-compact.ts +6 -13
- package/corpus/core/src/server/prompts/framework-core.ts +9 -21
- package/corpus/core/src/server/prompts/index.ts +0 -1
- package/corpus/core/src/server/prompts/shared-rules.ts +19 -11
- package/corpus/core/src/server/ssr-handler.ts +13 -2
- package/corpus/core/src/settings/user-settings.ts +13 -1
- package/corpus/core/src/shared/cache-control.ts +141 -0
- package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/chat/_gitignore +1 -0
- package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/default/app/root.tsx +1 -1
- package/corpus/core/src/templates/default/public/manifest.json +2 -2
- package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/corpus/core/src/vite/agents-bundle-plugin.ts +7 -6
- package/corpus/core/src/vite/client.ts +69 -3
- package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +4 -5
- package/corpus/templates/analytics/.agents/skills/admin-surfaces/SKILL.md +55 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +62 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +85 -0
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +27 -2
- package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +139 -0
- package/corpus/templates/analytics/.agents/skills/monitoring/SKILL.md +77 -0
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/analytics/AGENTS.md +91 -563
- package/corpus/templates/analytics/_gitignore +1 -0
- package/corpus/templates/analytics/actions/bigquery.ts +12 -4
- package/corpus/templates/analytics/actions/generate-chart.ts +5 -5
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -23
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +1 -0
- package/corpus/templates/analytics/app/routes/_index.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-07-24-analytics-finds-saved-dashboards-and-queries-far-more-reliab.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-24-notion-access-errors-now-explain-that-a-page-needs-sharing-w.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/analytics/package.json +1 -1
- package/corpus/templates/analytics/public/manifest.json +1 -1
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +7 -0
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +191 -30
- package/corpus/templates/analytics/server/lib/bigquery.ts +11 -1
- package/corpus/templates/analytics/server/lib/notion.ts +15 -4
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +10 -0
- package/corpus/templates/analytics/server/plugins/auth.ts +1 -1
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/assets/app/routes/_index.tsx +1 -1
- package/corpus/templates/assets/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/assets/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/assets/server/plugins/auth.ts +1 -1
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/_gitignore +1 -0
- package/corpus/templates/brain/app/lib/brain.ts +0 -7
- package/corpus/templates/brain/app/routes/_index.tsx +1 -2
- package/corpus/templates/brain/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/brain/package.json +1 -1
- package/corpus/templates/brain/public/manifest.json +1 -1
- package/corpus/templates/brain/server/plugins/auth.ts +1 -1
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/calendar/_gitignore +1 -0
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +0 -6
- package/corpus/templates/calendar/app/routes/_app._index.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/calendar/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/calendar/package.json +1 -1
- package/corpus/templates/calendar/public/manifest.json +1 -1
- package/corpus/templates/calendar/server/plugins/auth.ts +1 -1
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/chat/_gitignore +1 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/corpus/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +34 -0
- package/corpus/templates/clips/AGENTS.md +5 -4
- package/corpus/templates/clips/_gitignore +1 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +5 -0
- package/corpus/templates/clips/actions/get-recording-insights.ts +44 -8
- package/corpus/templates/clips/actions/get-recording-player-data.ts +39 -70
- package/corpus/templates/clips/actions/import-loom-recording.ts +53 -98
- package/corpus/templates/clips/actions/lib/loom-import-job.ts +260 -0
- package/corpus/templates/clips/actions/list-clip-views.ts +2 -4
- package/corpus/templates/clips/actions/list-recordings.ts +69 -19
- package/corpus/templates/clips/actions/list-viewers.ts +5 -2
- package/corpus/templates/clips/actions/regenerate-summary.ts +5 -1
- package/corpus/templates/clips/actions/request-transcript.ts +28 -1
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +21 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +0 -7
- package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +14 -1
- package/corpus/templates/clips/app/components/player/insights-panel.tsx +8 -20
- package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +335 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +13 -8
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +2 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +13 -2
- package/corpus/templates/clips/app/lib/capture-permissions.ts +110 -0
- package/corpus/templates/clips/app/lib/recording-link.ts +32 -0
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +27 -0
- package/corpus/templates/clips/app/routes/_index.tsx +1 -1
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +52 -15
- package/corpus/templates/clips/app/routes/record.tsx +82 -31
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +42 -31
- package/corpus/templates/clips/changelog/2026-07-24-clip-pages-now-show-a-view-count-with-viewer-avatars-next-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-summaries-read-like-a-description-you-d-write-yourself-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-view-counts-now-separate-human-views-from-agent-views-s.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-actions-can-now-be-called-by-org-service-tokens-so-ext.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-no-longer-briefly-shows-a-dock-icon-while-launching.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-fixed-owner-and-editor-share-links-redirecting-to-the-record.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-meeting-and-note-recordings-now-start-as-a-compact-pill-on-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-new-clips-now-copy-a-shareable-link-instead-of-the-owner-onl.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-opening-a-share-link-as-the-clip-s-owner-now-goes-straight-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-permissions-and-rewind-controls-now-use-compact-consistent-h.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-quitting-the-desktop-app-no-longer-shows-a-false-macos-crash.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-screen-recording-permission-errors-now-name-the-exact-app-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-desktop-app-now-copies-a-new-clip-s-share-link-to-your-c.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-recording-toolbar-now-stays-above-other-apps-including-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-transcript-captions-now-use-real-speech-timings-instead-of-a.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-video-playback-no-longer-stutters-and-replays-the-last-momen.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +17 -1
- package/corpus/templates/clips/desktop/package.json +2 -0
- package/corpus/templates/clips/desktop/src/app.tsx +89 -0
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -3
- package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +51 -0
- package/corpus/templates/clips/desktop/src/lib/native-notification.ts +44 -0
- package/corpus/templates/clips/desktop/src/lib/recording-link.ts +67 -0
- package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +35 -35
- package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +3 -2
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +47 -46
- package/corpus/templates/clips/desktop/src/styles.css +127 -78
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +7 -0
- package/corpus/templates/clips/desktop/src-tauri/Info.plist +6 -0
- package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -3
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -1
- package/corpus/templates/clips/desktop/src-tauri/src/main.rs +8 -0
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -10
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +40 -0
- package/corpus/templates/clips/server/db/schema.ts +27 -0
- package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +2 -1
- package/corpus/templates/clips/server/lib/public-agent-context.ts +7 -0
- package/corpus/templates/clips/server/lib/recording-share-grant.ts +79 -0
- package/corpus/templates/clips/server/lib/recordings.ts +51 -3
- package/corpus/templates/clips/server/plugins/auth.ts +1 -1
- package/corpus/templates/clips/server/plugins/db.ts +31 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +56 -3
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +49 -17
- package/corpus/templates/clips/shared/recording-link.ts +43 -0
- package/corpus/templates/clips/shared/share-attribution.ts +4 -0
- package/corpus/templates/clips/shared/share-dashboard-redirect.ts +42 -0
- package/corpus/templates/clips/shared/view-analytics.ts +26 -0
- package/corpus/templates/content/.agents/skills/content/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/content/references/local-file-mode.md +135 -0
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +12 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +238 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/document-behavior.md +91 -0
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/content/AGENTS.md +62 -583
- package/corpus/templates/content/_gitignore +1 -0
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -39
- package/corpus/templates/content/app/routes/_app._index.tsx +1 -2
- package/corpus/templates/content/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/content/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/content/package.json +1 -1
- package/corpus/templates/content/public/manifest.json +1 -1
- package/corpus/templates/content/server/plugins/auth.ts +1 -1
- package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +50 -8
- package/corpus/templates/design/.agents/skills/design-generation/references/code-layers.md +81 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/code-workspace.md +42 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/editor-extensions.md +34 -0
- package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +4 -1
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +8196 -0
- package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +265 -0
- package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +642 -0
- package/corpus/templates/design/.generated/bridge/motion-preview.generated.ts +571 -0
- package/corpus/templates/design/.generated/bridge/nav.generated.ts +91 -0
- package/corpus/templates/design/.generated/bridge/sample.generated.ts +23 -0
- package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +263 -0
- package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +518 -0
- package/corpus/templates/design/.generated/bridge/tweak.generated.ts +20 -0
- package/corpus/templates/design/.generated/bridge/zoom.generated.ts +32 -0
- package/corpus/templates/design/AGENTS.md +88 -503
- package/corpus/templates/design/_gitignore +1 -0
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/design/app/routes/_index.tsx +1 -1
- package/corpus/templates/design/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/design/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/design/server/plugins/auth.ts +1 -1
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/dispatch/_gitignore +1 -0
- package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -10
- package/corpus/templates/dispatch/app/routes/overview.tsx +1 -1
- package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/dispatch/package.json +1 -1
- package/corpus/templates/dispatch/public/manifest.json +1 -1
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/forms/_gitignore +1 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +0 -35
- package/corpus/templates/forms/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/forms/package.json +1 -1
- package/corpus/templates/forms/public/manifest.json +1 -1
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
- package/corpus/templates/forms/server/plugins/auth.ts +1 -1
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/macros/_gitignore +1 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -2
- package/corpus/templates/macros/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/macros/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/macros/package.json +1 -1
- package/corpus/templates/macros/server/plugins/auth.ts +2 -2
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/mail/_gitignore +1 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +0 -39
- package/corpus/templates/mail/app/routes/$view.$threadId.tsx +1 -1
- package/corpus/templates/mail/app/routes/$view.tsx +1 -1
- package/corpus/templates/mail/app/routes/_index.tsx +1 -1
- package/corpus/templates/mail/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/mail/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/mail/package.json +1 -1
- package/corpus/templates/mail/public/manifest.json +1 -1
- package/corpus/templates/mail/server/plugins/auth.ts +1 -1
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/plan/_gitignore +1 -0
- package/corpus/templates/plan/agent-native.app-skill.json +1 -1
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +4 -9
- package/corpus/templates/plan/app/lib/app-config.ts +1 -1
- package/corpus/templates/plan/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/plan/package.json +1 -1
- package/corpus/templates/plan/public/manifest.json +1 -1
- package/corpus/templates/plan/server/plugins/auth.ts +1 -1
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/slides/app/routes/_index.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/slides/package.json +1 -1
- package/corpus/templates/slides/public/manifest.json +1 -1
- package/corpus/templates/slides/server/plugins/auth.ts +1 -1
- package/corpus/templates/slides/server/plugins/db.ts +4 -0
- package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/tasks/AGENTS.md +1 -1
- package/corpus/templates/tasks/_gitignore +1 -0
- package/dist/a2a/activity.d.ts +4 -1
- package/dist/a2a/activity.d.ts.map +1 -1
- package/dist/a2a/activity.js +27 -16
- package/dist/a2a/activity.js.map +1 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +58 -4
- package/dist/a2a/client.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts +1 -0
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +31 -4
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +18 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +1 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +2 -1
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +12 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +21 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/chat-threads/store.d.ts +10 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +41 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/checkpoints/index.d.ts +1 -0
- package/dist/checkpoints/index.d.ts.map +1 -1
- package/dist/checkpoints/index.js +1 -0
- package/dist/checkpoints/index.js.map +1 -1
- package/dist/checkpoints/route-match.d.ts +8 -0
- package/dist/checkpoints/route-match.d.ts.map +1 -0
- package/dist/checkpoints/route-match.js +13 -0
- package/dist/checkpoints/route-match.js.map +1 -0
- package/dist/cli/create.d.ts +35 -4
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +69 -19
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/template-baseline.d.ts +54 -0
- package/dist/cli/template-baseline.d.ts.map +1 -0
- package/dist/cli/template-baseline.js +334 -0
- package/dist/cli/template-baseline.js.map +1 -0
- package/dist/cli/template-sync.d.ts +57 -0
- package/dist/cli/template-sync.d.ts.map +1 -0
- package/dist/cli/template-sync.js +787 -0
- package/dist/cli/template-sync.js.map +1 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +1 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +38 -10
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +32 -2
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +20 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +81 -46
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +14 -6
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +13 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +8 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +3 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +1 -1
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/settings/SettingsPanel.js +9 -9
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/client/settings/SettingsTabsPage.js +7 -4
- package/dist/client/settings/SettingsTabsPage.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +3 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/data-widgets/index.d.ts +3 -0
- package/dist/data-widgets/index.d.ts.map +1 -1
- package/dist/data-widgets/index.js +33 -0
- package/dist/data-widgets/index.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +11 -7
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/provider-api-definitions.d.ts +1 -0
- package/dist/eject/provider-api-definitions.d.ts.map +1 -1
- package/dist/extensions/url-safety.d.ts +9 -16
- package/dist/extensions/url-safety.d.ts.map +1 -1
- package/dist/extensions/url-safety.js +48 -4
- package/dist/extensions/url-safety.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +46 -9
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/auto-join-domain.d.ts +3 -2
- package/dist/org/auto-join-domain.d.ts.map +1 -1
- package/dist/org/auto-join-domain.js +1 -1
- package/dist/org/auto-join-domain.js.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +84 -28
- package/dist/org/context.js.map +1 -1
- package/dist/org/index.d.ts +1 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/org/service-identity.d.ts +43 -0
- package/dist/org/service-identity.d.ts.map +1 -0
- package/dist/org/service-identity.js +34 -0
- package/dist/org/service-identity.js.map +1 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +13 -11
- package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
- package/dist/provider-api/index.d.ts +4 -0
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +17 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/scripts/docs/search.d.ts.map +1 -1
- package/dist/scripts/docs/search.js +12 -1
- package/dist/scripts/docs/search.js.map +1 -1
- package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
- package/dist/server/agent-chat/context-tools.js +3 -3
- package/dist/server/agent-chat/context-tools.js.map +1 -1
- package/dist/server/agent-chat/framework-prompts.d.ts +8 -3
- package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +33 -62
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +16 -10
- 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/agents-bundle.d.ts +18 -0
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +70 -4
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +4 -3
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +43 -19
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.js +2 -2
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +38 -2
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +142 -64
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +7 -13
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts +1 -1
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +10 -21
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/dist/server/prompts/index.d.ts +1 -1
- package/dist/server/prompts/index.d.ts.map +1 -1
- package/dist/server/prompts/index.js +1 -1
- package/dist/server/prompts/index.js.map +1 -1
- package/dist/server/prompts/shared-rules.d.ts +16 -10
- package/dist/server/prompts/shared-rules.d.ts.map +1 -1
- package/dist/server/prompts/shared-rules.js +19 -10
- package/dist/server/prompts/shared-rules.js.map +1 -1
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +10 -3
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/settings/user-settings.d.ts.map +1 -1
- package/dist/settings/user-settings.js +13 -1
- package/dist/settings/user-settings.js.map +1 -1
- package/dist/shared/cache-control.d.ts +52 -0
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +107 -0
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/chat/_gitignore +1 -0
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/dist/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/default/app/root.tsx +1 -1
- package/dist/templates/default/public/manifest.json +2 -2
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
- package/dist/vite/agents-bundle-plugin.js +8 -7
- package/dist/vite/agents-bundle-plugin.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +66 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.mdx +2 -2
- package/docs/content/agent-surfaces.mdx +1 -1
- package/docs/content/authentication.mdx +2 -0
- package/docs/content/deployment.mdx +36 -0
- package/docs/content/http-api.mdx +266 -0
- package/docs/content/syncing-template-changes.mdx +159 -0
- package/package.json +4 -3
- package/src/a2a/activity.ts +38 -27
- package/src/a2a/client.ts +57 -4
- package/src/agent/engine/builder-engine.ts +35 -4
- package/src/agent/run-manager.ts +20 -1
- package/src/agent/run-store.ts +4 -1
- package/src/agent/types.ts +28 -8
- package/src/chat-threads/store.ts +45 -0
- package/src/checkpoints/index.ts +2 -0
- package/src/checkpoints/route-match.ts +13 -0
- package/src/cli/create.ts +105 -17
- package/src/cli/index.ts +20 -0
- package/src/cli/template-baseline.ts +410 -0
- package/src/cli/template-sync.ts +1004 -0
- package/src/cli/templates-meta.ts +1 -0
- package/src/client/AssistantChat.tsx +38 -12
- package/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/src/client/chat/message-components.tsx +127 -66
- package/src/client/chat/tool-call-display.tsx +29 -5
- package/src/client/error-format.ts +18 -0
- package/src/client/org/OrgSwitcher.tsx +30 -8
- package/src/client/org/TeamPage.tsx +7 -6
- package/src/client/settings/SettingsPanel.tsx +9 -9
- package/src/client/settings/SettingsTabsPage.tsx +12 -2
- package/src/client/sse-event-processor.ts +3 -0
- package/src/data-widgets/index.ts +41 -0
- package/src/deploy/build.ts +11 -9
- package/src/extensions/url-safety.ts +67 -4
- package/src/integrations/webhook-handler.ts +63 -9
- package/src/org/auto-join-domain.ts +4 -3
- package/src/org/context.ts +108 -39
- package/src/org/index.ts +5 -0
- package/src/org/service-identity.ts +60 -0
- package/src/provider-api/index.ts +22 -1
- package/src/scripts/docs/search.ts +12 -1
- package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +25 -36
- package/src/server/agent-chat/context-tools.ts +9 -4
- package/src/server/agent-chat/framework-prompts.ts +38 -66
- package/src/server/agent-chat-plugin.ts +17 -10
- package/src/server/agents-bundle.ts +84 -5
- package/src/server/auth.ts +4 -3
- package/src/server/builder-browser.ts +47 -19
- package/src/server/core-routes-plugin.ts +2 -2
- package/src/server/credential-provider.ts +209 -68
- package/src/server/index.ts +3 -0
- package/src/server/prompts/framework-core-compact.ts +6 -13
- package/src/server/prompts/framework-core.ts +9 -21
- package/src/server/prompts/index.ts +0 -1
- package/src/server/prompts/shared-rules.ts +19 -11
- package/src/server/ssr-handler.ts +13 -2
- package/src/settings/user-settings.ts +13 -1
- package/src/shared/cache-control.ts +141 -0
- package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/chat/_gitignore +1 -0
- package/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/default/app/root.tsx +1 -1
- package/src/templates/default/public/manifest.json +2 -2
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/src/vite/agents-bundle-plugin.ts +7 -6
- package/src/vite/client.ts +69 -3
|
@@ -96,10 +96,18 @@ export default defineAction({
|
|
|
96
96
|
"BigQuery isn't connected for this workspace yet. Open Settings -> Data sources and add BIGQUERY_PROJECT_ID + GOOGLE_APPLICATION_CREDENTIALS_JSON (a service-account JSON key).",
|
|
97
97
|
);
|
|
98
98
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
) {
|
|
99
|
+
// A timeout means the SQL was valid but slow. Routing it through the schema-error
|
|
100
|
+
// branch below told the model to go re-inspect the schema and rerun, which turns
|
|
101
|
+
// one slow query into a loop of 60-second attempts.
|
|
102
|
+
if (/BigQuery query timed out/i.test(msg)) {
|
|
103
|
+
return {
|
|
104
|
+
error: "bigquery_query_timeout",
|
|
105
|
+
message: extractBigQueryMessage(msg),
|
|
106
|
+
recoverable: true,
|
|
107
|
+
hint: "The SQL was valid but exceeded the 60-second warehouse budget. Do NOT inspect the schema and do NOT rerun this query as-is. Make it cheaper: narrow the date range, add a LIMIT, aggregate in SQL instead of returning raw rows, or filter on a partition/cluster column. If the full scan is genuinely required, run it through run-code with background: true instead of retrying here.",
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (/BigQuery (API|poll) error/i.test(msg)) {
|
|
103
111
|
// Recoverable: hand the real error back to the model so it can inspect
|
|
104
112
|
// the schema and self-correct, instead of force-ending the turn.
|
|
105
113
|
return {
|
|
@@ -303,16 +303,16 @@ export function renderStaticChartSvg({
|
|
|
303
303
|
* user's chair, the chat said "I'll do something else" and no chart appeared.
|
|
304
304
|
*
|
|
305
305
|
* For in-chat data questions the right answer is always the live `/chart`
|
|
306
|
-
* embed (see
|
|
307
|
-
* artifacts need a static image, and
|
|
308
|
-
* before they call here.
|
|
306
|
+
* embed (see the `data-querying` skill's "Inline Charts In Chat" section for
|
|
307
|
+
* the full shape). Only `save-analysis` artifacts need a static image, and
|
|
308
|
+
* those flows have full data in hand before they call here.
|
|
309
309
|
*/
|
|
310
310
|
const CHART_FALLBACK_HINT =
|
|
311
|
-
"If you're answering an in-chat data question, do not retry generate-chart. Switch to the live /chart embed
|
|
311
|
+
"If you're answering an in-chat data question, do not retry generate-chart. Switch to the live /chart embed instead — it accepts a SqlPanel object directly and doesn't require pre-stringified JSON params. See the data-querying skill's \"Inline Charts In Chat\" section for the embed syntax. Only use generate-chart when you're building a save-analysis artifact.";
|
|
312
312
|
|
|
313
313
|
export default defineAction({
|
|
314
314
|
description:
|
|
315
|
-
|
|
315
|
+
'Render a static chart image to the media directory **for save-analysis artifacts only**. Uses PNG when the native renderer is available and a portable SVG fallback otherwise. For an in-chat answer to a data question, do NOT call this — emit a live `/chart` embed instead (see the data-querying skill\'s "Inline Charts In Chat" section for the embed syntax). The static image path exists for analyses that need to render outside this app (exports, archived reports). If validation here fails, switch to the live embed rather than retrying.',
|
|
316
316
|
schema: z.object({
|
|
317
317
|
title: z.string().optional().describe("Chart title (required)"),
|
|
318
318
|
labels: z.string().optional().describe("JSON array of x-axis labels"),
|
|
@@ -119,6 +119,9 @@ const CHART_LEGEND_PROPS = {
|
|
|
119
119
|
} as const;
|
|
120
120
|
|
|
121
121
|
const CHART_RESIZE_DEBOUNCE_MS = 50;
|
|
122
|
+
// Recharts' default series animation duration, plus room for the debounced
|
|
123
|
+
// resize callback that follows a lazy-loaded panel's first layout pass.
|
|
124
|
+
const CHART_ENTRY_ANIMATION_MS = 1500 + CHART_RESIZE_DEBOUNCE_MS * 2;
|
|
122
125
|
const LEGEND_ACTION_CLOSE_DELAY_MS = 600;
|
|
123
126
|
|
|
124
127
|
type ChartSize = {
|
|
@@ -136,12 +139,38 @@ export function hasChartSizeChanged(
|
|
|
136
139
|
);
|
|
137
140
|
}
|
|
138
141
|
|
|
142
|
+
export function shouldDisableChartAnimation(
|
|
143
|
+
entryAnimationSettled: boolean,
|
|
144
|
+
previous: ChartSize | null,
|
|
145
|
+
next: ChartSize,
|
|
146
|
+
): boolean {
|
|
147
|
+
return entryAnimationSettled && hasChartSizeChanged(previous, next);
|
|
148
|
+
}
|
|
149
|
+
|
|
139
150
|
function useChartResizeAnimation() {
|
|
140
151
|
const [isAnimationActive, setIsAnimationActive] = useState(true);
|
|
141
152
|
const firstSizeRef = useRef<ChartSize | null>(null);
|
|
153
|
+
// Switching Recharts to isAnimationActive=false mid-flight freezes the line's
|
|
154
|
+
// stroke-dasharray at whatever partial length it reached, leaving the series
|
|
155
|
+
// invisible forever. Lazy-loaded panels reflow right after mounting, so the
|
|
156
|
+
// entry animation has to be allowed to finish before a resize can disable it.
|
|
157
|
+
const entryAnimationSettledRef = useRef(false);
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
const timer = setTimeout(() => {
|
|
160
|
+
entryAnimationSettledRef.current = true;
|
|
161
|
+
}, CHART_ENTRY_ANIMATION_MS);
|
|
162
|
+
return () => clearTimeout(timer);
|
|
163
|
+
}, []);
|
|
164
|
+
|
|
142
165
|
const handleResize = useCallback((width: number, height: number) => {
|
|
143
166
|
const nextSize = { width, height };
|
|
144
|
-
if (
|
|
167
|
+
if (
|
|
168
|
+
shouldDisableChartAnimation(
|
|
169
|
+
entryAnimationSettledRef.current,
|
|
170
|
+
firstSizeRef.current,
|
|
171
|
+
nextSize,
|
|
172
|
+
)
|
|
173
|
+
) {
|
|
145
174
|
setIsAnimationActive(false);
|
|
146
175
|
}
|
|
147
176
|
firstSizeRef.current = nextSize;
|
|
@@ -19,14 +19,12 @@ import {
|
|
|
19
19
|
IconLock,
|
|
20
20
|
IconLink,
|
|
21
21
|
IconMessageCircle,
|
|
22
|
-
IconHierarchy2,
|
|
23
22
|
IconUsersGroup,
|
|
24
23
|
IconEye,
|
|
25
24
|
IconEyeOff,
|
|
26
25
|
IconPlayerPlay,
|
|
27
26
|
IconLayoutSidebarLeftCollapse,
|
|
28
27
|
IconLayoutSidebarLeftExpand,
|
|
29
|
-
IconArrowUpRight,
|
|
30
28
|
} from "@tabler/icons-react";
|
|
31
29
|
import {
|
|
32
30
|
useQuery,
|
|
@@ -183,12 +181,6 @@ import {
|
|
|
183
181
|
import { CSS } from "@dnd-kit/utilities";
|
|
184
182
|
|
|
185
183
|
const bottomItems = [
|
|
186
|
-
{
|
|
187
|
-
icon: IconHierarchy2,
|
|
188
|
-
labelKey: "settings.agentTitle",
|
|
189
|
-
href: "/agent",
|
|
190
|
-
showExternalLinkIcon: true,
|
|
191
|
-
},
|
|
192
184
|
{ icon: IconSettings, labelKey: "navigation.settings", href: "/settings" },
|
|
193
185
|
];
|
|
194
186
|
|
|
@@ -2098,12 +2090,6 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2098
2090
|
href: "/data-dictionary",
|
|
2099
2091
|
active: location.pathname.startsWith("/data-dictionary"),
|
|
2100
2092
|
},
|
|
2101
|
-
{
|
|
2102
|
-
icon: IconHierarchy2,
|
|
2103
|
-
label: t("settings.agentTitle"),
|
|
2104
|
-
href: "/agent",
|
|
2105
|
-
active: location.pathname === "/agent",
|
|
2106
|
-
},
|
|
2107
2093
|
{
|
|
2108
2094
|
icon: IconSettings,
|
|
2109
2095
|
label: t("navigation.settings"),
|
|
@@ -2572,15 +2558,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2572
2558
|
)}
|
|
2573
2559
|
>
|
|
2574
2560
|
<Icon className="h-4 w-4" />
|
|
2575
|
-
<span className="
|
|
2576
|
-
<span className="truncate">{t(item.labelKey)}</span>
|
|
2577
|
-
{item.showExternalLinkIcon && (
|
|
2578
|
-
<IconArrowUpRight
|
|
2579
|
-
aria-hidden="true"
|
|
2580
|
-
className="h-3.5 w-3.5 shrink-0 text-muted-foreground/70"
|
|
2581
|
-
/>
|
|
2582
|
-
)}
|
|
2583
|
-
</span>
|
|
2561
|
+
<span className="truncate">{t(item.labelKey)}</span>
|
|
2584
2562
|
</Link>
|
|
2585
2563
|
);
|
|
2586
2564
|
})}
|
|
@@ -259,6 +259,9 @@ export function DashboardFilterBar({
|
|
|
259
259
|
className="group rounded-lg bg-card px-3 py-2"
|
|
260
260
|
>
|
|
261
261
|
<div className="flex flex-wrap items-end justify-between gap-3">
|
|
262
|
+
<span className="self-center text-xs font-medium text-muted-foreground group-data-[state=open]:hidden">
|
|
263
|
+
{t("sqlDashboard.filters")}
|
|
264
|
+
</span>
|
|
262
265
|
<CollapsibleContent className="min-w-0 flex-1">
|
|
263
266
|
<div className="flex flex-wrap gap-3 items-end">
|
|
264
267
|
{uniqueFilters.map((f) => (
|
|
@@ -272,7 +272,7 @@ export function SqlChartCard({
|
|
|
272
272
|
data-dragging={isDragSource ? "true" : undefined}
|
|
273
273
|
className="dashboard-section-card group relative mt-2 first:mt-0"
|
|
274
274
|
>
|
|
275
|
-
<div className="flex items-center gap-2
|
|
275
|
+
<div className="flex items-center gap-2 pb-2">
|
|
276
276
|
<h2 className="text-base font-semibold flex-1">{panel.title}</h2>
|
|
277
277
|
{editable ? (
|
|
278
278
|
<div className="flex items-center gap-1 opacity-0 group-hover:opacity-100">
|
|
@@ -1538,6 +1538,7 @@ function SqlDashboardPageContent({
|
|
|
1538
1538
|
resourceId={dashboardId}
|
|
1539
1539
|
resourceTitle={dashboard.name}
|
|
1540
1540
|
variant="compact"
|
|
1541
|
+
triggerClassName="border-0 bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground"
|
|
1541
1542
|
shareUrl={dashboardShareUrl}
|
|
1542
1543
|
shareTabs={{
|
|
1543
1544
|
tabs: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { redirect, type LoaderFunctionArgs } from "react-router";
|
|
2
2
|
|
|
3
3
|
const SEO_TITLE =
|
|
4
|
-
"
|
|
4
|
+
"Analytics - Open Source Alternative to Amplitude & FullStory";
|
|
5
5
|
const SEO_DESCRIPTION =
|
|
6
6
|
"Open Source analytics app and alternative to Amplitude and FullStory where AI agents connect to warehouses, product analytics, and CRM data to answer questions and build dashboards.";
|
|
7
7
|
|
|
@@ -35,6 +35,13 @@ export const INITIAL_TOOL_NAMES = [
|
|
|
35
35
|
"bigquery",
|
|
36
36
|
"search-bigquery-schema",
|
|
37
37
|
"list-data-dictionary",
|
|
38
|
+
// Bulk/cohort readers. Without these on the first surface a "list X excluding Y"
|
|
39
|
+
// question cannot reach any tool that answers it in one call, so the agent pays a
|
|
40
|
+
// tool-search round trip (~15 KB of results) before it can even start — or worse,
|
|
41
|
+
// enumerates the cohort page by page through whatever it can already see.
|
|
42
|
+
"provider-api-request",
|
|
43
|
+
"query-staged-dataset",
|
|
44
|
+
"hubspot-records",
|
|
38
45
|
"navigate",
|
|
39
46
|
];
|
|
40
47
|
|
|
@@ -68,7 +68,8 @@ export type AnalyticsQueryCatalogCandidate =
|
|
|
68
68
|
panelTitle: string;
|
|
69
69
|
panelDescription?: string;
|
|
70
70
|
source?: string;
|
|
71
|
-
|
|
71
|
+
/** Absent for extension/embed panels, which are matched on title and description. */
|
|
72
|
+
query?: string | Record<string, unknown>;
|
|
72
73
|
timeScope?: string;
|
|
73
74
|
}
|
|
74
75
|
| {
|
|
@@ -105,43 +106,135 @@ function compactQuery(value: unknown): string | Record<string, unknown> | null {
|
|
|
105
106
|
return null;
|
|
106
107
|
}
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
// Analytics vocabulary the corpus spells out but users abbreviate (or vice versa).
|
|
110
|
+
// Expansions match at reduced weight so they break ties without outranking a literal hit.
|
|
111
|
+
const SYNONYM_EXPANSIONS: Record<string, string[]> = {
|
|
112
|
+
account: ["company", "customer", "org"],
|
|
113
|
+
active: ["engaged"],
|
|
114
|
+
arr: ["annual", "recurring", "revenue"],
|
|
115
|
+
churn: ["cancel", "attrition", "downgrade"],
|
|
116
|
+
csql: ["sale", "qualified", "lead", "opportunity"],
|
|
117
|
+
customer: ["account", "company"],
|
|
118
|
+
dau: ["daily", "active", "user"],
|
|
119
|
+
deal: ["opportunity", "pipeline"],
|
|
120
|
+
error: ["5xx", "4xx", "exception", "failure", "fault"],
|
|
121
|
+
icp: ["ideal", "customer", "profile"],
|
|
122
|
+
mau: ["monthly", "active", "user"],
|
|
123
|
+
mql: ["marketing", "qualified", "lead"],
|
|
124
|
+
mrr: ["monthly", "recurring", "revenue"],
|
|
125
|
+
pageview: ["page", "view", "traffic", "session"],
|
|
126
|
+
pipeline: ["deal", "opportunity", "forecast"],
|
|
127
|
+
poc: ["proof", "concept", "trial", "pilot"],
|
|
128
|
+
revenue: ["bookings", "arr", "mrr", "won"],
|
|
129
|
+
signup: ["registration", "created", "onboard"],
|
|
130
|
+
traffic: ["pageview", "session", "visit"],
|
|
131
|
+
usage: ["active", "engagement"],
|
|
132
|
+
user: ["member", "person", "seat"],
|
|
133
|
+
wau: ["weekly", "active", "user"],
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// Metric-shaped words that appear in a large share of titles and so discriminate
|
|
137
|
+
// almost nothing on their own. Scored down rather than dropped: "error rate" must
|
|
138
|
+
// still beat "rate", but four unrelated "... Rate" entries must not tie above the
|
|
139
|
+
// panel that actually matches "error".
|
|
140
|
+
const LOW_INFORMATION_TERMS = new Set([
|
|
141
|
+
"average",
|
|
142
|
+
"percent",
|
|
143
|
+
"percentage",
|
|
144
|
+
"rate",
|
|
145
|
+
"ratio",
|
|
146
|
+
"score",
|
|
147
|
+
"value",
|
|
148
|
+
"volume",
|
|
149
|
+
]);
|
|
150
|
+
|
|
151
|
+
// Cheap plural folding. The corpus writes "Template"/"Deal" while users type
|
|
152
|
+
// "templates"/"deals"; exact substring matching missed every one of those.
|
|
153
|
+
function stem(token: string): string {
|
|
154
|
+
if (token.length > 4 && token.endsWith("ies"))
|
|
155
|
+
return `${token.slice(0, -3)}y`;
|
|
156
|
+
if (token.length > 4 && token.endsWith("sses")) return token.slice(0, -2);
|
|
157
|
+
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss")) {
|
|
158
|
+
return token.slice(0, -1);
|
|
159
|
+
}
|
|
160
|
+
return token;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Splits camelCase and snake_case so warehouse identifiers are searchable:
|
|
164
|
+
// `dim_hs_deals` -> dim, hs, deal.
|
|
165
|
+
function tokenize(value: string): string[] {
|
|
166
|
+
return value
|
|
167
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
110
168
|
.toLowerCase()
|
|
111
169
|
.replace(/[^a-z0-9]+/g, " ")
|
|
112
|
-
.trim()
|
|
113
|
-
if (!normalized) return [];
|
|
114
|
-
const meaningful = normalized
|
|
170
|
+
.trim()
|
|
115
171
|
.split(/\s+/)
|
|
116
|
-
.filter(
|
|
117
|
-
|
|
172
|
+
.filter(Boolean)
|
|
173
|
+
.map(stem);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function searchTerms(search: string): string[] {
|
|
177
|
+
const tokens = tokenize(search);
|
|
178
|
+
if (!tokens.length) return [];
|
|
179
|
+
const meaningful = tokens.filter(
|
|
180
|
+
(term) => term.length > 1 && !STOP_WORDS.has(term),
|
|
181
|
+
);
|
|
182
|
+
return Array.from(new Set(meaningful.length ? meaningful : tokens));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function expandedTerms(primary: string[]): string[] {
|
|
186
|
+
const primarySet = new Set(primary);
|
|
187
|
+
const expanded = new Set<string>();
|
|
188
|
+
for (const term of primary) {
|
|
189
|
+
for (const synonym of SYNONYM_EXPANSIONS[term] ?? []) {
|
|
190
|
+
const stemmed = stem(synonym);
|
|
191
|
+
if (!primarySet.has(stemmed)) expanded.add(stemmed);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return [...expanded];
|
|
118
195
|
}
|
|
119
196
|
|
|
197
|
+
// SQL bodies run to 12k chars; scoring only needs the leading identifiers.
|
|
198
|
+
const MAX_SCORED_FIELD_CHARS = 4_000;
|
|
199
|
+
|
|
120
200
|
function matchScore(
|
|
121
201
|
search: string,
|
|
122
202
|
weightedFields: Array<{ value: unknown; weight: number }>,
|
|
123
203
|
): { score: number; matchedTerms: string[] } {
|
|
124
204
|
const terms = searchTerms(search);
|
|
125
205
|
if (!terms.length) return { score: 0, matchedTerms: [] };
|
|
206
|
+
const synonyms = expandedTerms(terms);
|
|
126
207
|
|
|
127
208
|
const normalizedSearch = search.toLowerCase().trim();
|
|
128
209
|
const matched = new Set<string>();
|
|
129
210
|
let score = 0;
|
|
130
211
|
for (const field of weightedFields) {
|
|
131
|
-
const
|
|
132
|
-
if (!
|
|
133
|
-
|
|
212
|
+
const raw = text(field.value).slice(0, MAX_SCORED_FIELD_CHARS);
|
|
213
|
+
if (!raw) continue;
|
|
214
|
+
const lowered = raw.toLowerCase();
|
|
215
|
+
const tokens = new Set(tokenize(raw));
|
|
216
|
+
|
|
217
|
+
if (normalizedSearch.length > 2 && lowered.includes(normalizedSearch)) {
|
|
134
218
|
score += field.weight * 4;
|
|
135
219
|
}
|
|
136
220
|
for (const term of terms) {
|
|
137
|
-
if (!
|
|
221
|
+
if (!tokens.has(term) && !lowered.includes(term)) continue;
|
|
138
222
|
matched.add(term);
|
|
139
|
-
score += field.weight;
|
|
223
|
+
score += field.weight * (LOW_INFORMATION_TERMS.has(term) ? 0.3 : 1);
|
|
224
|
+
}
|
|
225
|
+
for (const synonym of synonyms) {
|
|
226
|
+
if (!tokens.has(synonym)) continue;
|
|
227
|
+
score += field.weight * 0.4;
|
|
140
228
|
}
|
|
141
229
|
}
|
|
142
230
|
|
|
143
|
-
|
|
144
|
-
|
|
231
|
+
// Proportional, not all-or-nothing: a 7-word question could never hit the old
|
|
232
|
+
// full-coverage bonus, so long real questions collapsed to near-random scores.
|
|
233
|
+
// Damped for short queries — at full strength every one-of-one-token match tied
|
|
234
|
+
// at the same score, so generic "... Rate" entries mass-tied above exact panels.
|
|
235
|
+
const coverageWeight = Math.min(terms.length, 3) / 3;
|
|
236
|
+
score += 40 * (matched.size / terms.length) * coverageWeight;
|
|
237
|
+
return { score: Math.round(score), matchedTerms: [...matched] };
|
|
145
238
|
}
|
|
146
239
|
|
|
147
240
|
function dashboardPanelCandidates(args: {
|
|
@@ -156,9 +249,15 @@ function dashboardPanelCandidates(args: {
|
|
|
156
249
|
? (args.config.panels as DashboardPanel[])
|
|
157
250
|
: [];
|
|
158
251
|
|
|
252
|
+
const wantsDemo = /\bdemo\b|node exporter/i.test(args.search);
|
|
253
|
+
|
|
159
254
|
return panels.flatMap((panel) => {
|
|
255
|
+
// 38k of the ~39k indexed panels are clones of the demo Node Exporter dashboard.
|
|
256
|
+
// They drown real saved work and are never the answer to a real data question.
|
|
257
|
+
if (!wantsDemo && text(panel.source) === "demo") return [];
|
|
258
|
+
// Panels without SQL (extensions, embeds) used to be dropped outright, which hid
|
|
259
|
+
// 61% of real dashboards from search even when their titles matched exactly.
|
|
160
260
|
const query = compactQuery(panel.sql);
|
|
161
|
-
if (!query) return [];
|
|
162
261
|
const panelConfig =
|
|
163
262
|
panel.config &&
|
|
164
263
|
typeof panel.config === "object" &&
|
|
@@ -174,20 +273,49 @@ function dashboardPanelCandidates(args: {
|
|
|
174
273
|
{ value: args.dashboardDescription, weight: 6 },
|
|
175
274
|
{ value: panel.source, weight: 5 },
|
|
176
275
|
{
|
|
177
|
-
|
|
178
|
-
|
|
276
|
+
// Weighted 2 against a title's 24, this 12x discount hid every panel whose
|
|
277
|
+
// match lived only in its SQL — the majority of them.
|
|
278
|
+
value: query
|
|
279
|
+
? typeof query === "string"
|
|
280
|
+
? query
|
|
281
|
+
: JSON.stringify(query)
|
|
282
|
+
: "",
|
|
283
|
+
weight: 8,
|
|
179
284
|
},
|
|
180
285
|
]);
|
|
286
|
+
// Prefer the general panel over a narrower variant ("Signups" over "Clip Share
|
|
287
|
+
// Signups 30d"), but cap it: the original uncapped -12/token buried long,
|
|
288
|
+
// well-named panels under short vague ones.
|
|
181
289
|
const requestedTerms = new Set(searchTerms(args.search));
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
290
|
+
const unmatchedTitleTerms = searchTerms(panelTitle).filter(
|
|
291
|
+
(term) => !requestedTerms.has(term),
|
|
292
|
+
).length;
|
|
293
|
+
const titleSpecificityPenalty = Math.min(unmatchedTitleTerms, 4) * 4;
|
|
294
|
+
// A panel with no SQL costs the agent another call to become useful, so it must
|
|
295
|
+
// not outrank an equally-relevant runnable one. Waived when the title is clearly
|
|
296
|
+
// on-topic: real questions carry clause words no title contains, so requiring
|
|
297
|
+
// full coverage here never fires and buries exact-topic panels.
|
|
298
|
+
const titleMatchedTerms = matchScore(args.search, [
|
|
299
|
+
{ value: panelTitle, weight: 1 },
|
|
300
|
+
]).matchedTerms;
|
|
301
|
+
const strongTitleTerms = titleMatchedTerms.filter(
|
|
302
|
+
(term) => !LOW_INFORMATION_TERMS.has(term),
|
|
303
|
+
).length;
|
|
304
|
+
const titleIsOnTopic =
|
|
305
|
+
requestedTerms.size > 0 &&
|
|
306
|
+
(strongTitleTerms >= 2 ||
|
|
307
|
+
titleMatchedTerms.length / requestedTerms.size >= 0.6);
|
|
308
|
+
const missingQueryPenalty = query || titleIsOnTopic ? 0 : 10;
|
|
185
309
|
const aggregateIntent =
|
|
186
310
|
/\b(how many|count|number|total)\b/i.test(args.search) &&
|
|
187
311
|
text(panel.chartType) === "metric"
|
|
188
312
|
? 20
|
|
189
313
|
: 0;
|
|
190
|
-
const score =
|
|
314
|
+
const score =
|
|
315
|
+
rawScore -
|
|
316
|
+
titleSpecificityPenalty -
|
|
317
|
+
missingQueryPenalty +
|
|
318
|
+
aggregateIntent;
|
|
191
319
|
if (score <= 0) return [];
|
|
192
320
|
|
|
193
321
|
return [
|
|
@@ -205,7 +333,7 @@ function dashboardPanelCandidates(args: {
|
|
|
205
333
|
panelTitle,
|
|
206
334
|
...(panelDescription ? { panelDescription } : {}),
|
|
207
335
|
...(text(panel.source) ? { source: text(panel.source) } : {}),
|
|
208
|
-
query,
|
|
336
|
+
...(query ? { query } : {}),
|
|
209
337
|
...(text(panelConfig.timeScope)
|
|
210
338
|
? { timeScope: text(panelConfig.timeScope) }
|
|
211
339
|
: {}),
|
|
@@ -270,6 +398,26 @@ function dictionaryCandidates(
|
|
|
270
398
|
});
|
|
271
399
|
}
|
|
272
400
|
|
|
401
|
+
function candidateIsRunnable(
|
|
402
|
+
candidate: AnalyticsQueryCatalogCandidate,
|
|
403
|
+
): boolean {
|
|
404
|
+
return candidate.kind === "dashboard-panel"
|
|
405
|
+
? Boolean(candidate.query)
|
|
406
|
+
: Boolean(candidate.queryTemplate);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function candidateDedupeKey(candidate: AnalyticsQueryCatalogCandidate): string {
|
|
410
|
+
if (candidate.kind === "data-dictionary") return `dict:${candidate.id}`;
|
|
411
|
+
const query =
|
|
412
|
+
typeof candidate.query === "string"
|
|
413
|
+
? candidate.query
|
|
414
|
+
: JSON.stringify(candidate.query ?? "");
|
|
415
|
+
return `panel:${candidate.panelTitle.toLowerCase()}:${query
|
|
416
|
+
.replace(/\s+/g, " ")
|
|
417
|
+
.trim()
|
|
418
|
+
.toLowerCase()}`;
|
|
419
|
+
}
|
|
420
|
+
|
|
273
421
|
export function rankAnalyticsQueryCatalog(args: {
|
|
274
422
|
search: string;
|
|
275
423
|
dashboards: Array<{
|
|
@@ -296,13 +444,26 @@ export function rankAnalyticsQueryCatalog(args: {
|
|
|
296
444
|
...dictionaryCandidates(args.dictionaryEntries, args.search),
|
|
297
445
|
];
|
|
298
446
|
|
|
299
|
-
|
|
300
|
-
.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
.
|
|
447
|
+
const ranked = candidates.sort((a, b) => {
|
|
448
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
449
|
+
// Prefer something the agent can run over something it must look up again.
|
|
450
|
+
const aRunnable = candidateIsRunnable(a);
|
|
451
|
+
const bRunnable = candidateIsRunnable(b);
|
|
452
|
+
if (aRunnable !== bRunnable) return aRunnable ? -1 : 1;
|
|
453
|
+
if (a.kind !== b.kind) return a.kind === "data-dictionary" ? -1 : 1;
|
|
454
|
+
return JSON.stringify(a).localeCompare(JSON.stringify(b));
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// Cloned dashboards produce near-identical panels that otherwise eat every slot.
|
|
458
|
+
const seen = new Set<string>();
|
|
459
|
+
const deduped: AnalyticsQueryCatalogCandidate[] = [];
|
|
460
|
+
for (const candidate of ranked) {
|
|
461
|
+
if (deduped.length >= args.limit) break;
|
|
462
|
+
if (seen.has(candidateDedupeKey(candidate))) continue;
|
|
463
|
+
seen.add(candidateDedupeKey(candidate));
|
|
464
|
+
deduped.push(candidate);
|
|
465
|
+
}
|
|
466
|
+
return deduped;
|
|
306
467
|
}
|
|
307
468
|
|
|
308
469
|
async function listDictionaryEntries(args: {
|
|
@@ -239,6 +239,8 @@ export interface QueryResult {
|
|
|
239
239
|
schema: { name: string; type: string }[];
|
|
240
240
|
bytesProcessed: number;
|
|
241
241
|
cached?: boolean;
|
|
242
|
+
/** True when BigQuery matched more rows than this first page returned. */
|
|
243
|
+
truncated?: boolean;
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
export interface RunQueryOptions {
|
|
@@ -516,11 +518,19 @@ export async function runQuery(
|
|
|
516
518
|
const rows = data.rows ? rowsToObjects(data.rows, fields) : [];
|
|
517
519
|
const bytesProcessed = parseInt(data.totalBytesProcessed || "0", 10);
|
|
518
520
|
|
|
521
|
+
// BigQuery reports the full match count; `rows` only holds the first page. Reporting
|
|
522
|
+
// rows.length as the total made every partial result look complete to the agent.
|
|
523
|
+
const reportedTotal = Number.parseInt(data.totalRows || "", 10);
|
|
524
|
+
const totalRows = Number.isFinite(reportedTotal)
|
|
525
|
+
? reportedTotal
|
|
526
|
+
: rows.length;
|
|
527
|
+
|
|
519
528
|
const result: QueryResult = {
|
|
520
529
|
rows,
|
|
521
|
-
totalRows
|
|
530
|
+
totalRows,
|
|
522
531
|
schema,
|
|
523
532
|
bytesProcessed,
|
|
533
|
+
...(totalRows > rows.length ? { truncated: true } : {}),
|
|
524
534
|
};
|
|
525
535
|
|
|
526
536
|
setL1(cacheKey, result);
|
|
@@ -39,6 +39,19 @@ async function getApiKey(): Promise<string> {
|
|
|
39
39
|
return credential.value;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
// The name Notion reports for a token is whatever label its creator typed in, so it
|
|
43
|
+
// routinely names an unrelated product. Never restate it as the current workspace.
|
|
44
|
+
const NOTION_ACCESS_HINT =
|
|
45
|
+
"This usually means the page or database was never shared with the Notion integration behind NOTION_API_KEY, not that the id is wrong. Fix it in Notion: open the page, then ••• → Connections → add the integration. The integration's Notion-side label may not match this app or workspace.";
|
|
46
|
+
|
|
47
|
+
function notionApiError(status: number, body: string): Error {
|
|
48
|
+
const suffix =
|
|
49
|
+
status === 401 || status === 403 || status === 404
|
|
50
|
+
? ` ${NOTION_ACCESS_HINT}`
|
|
51
|
+
: "";
|
|
52
|
+
return new Error(`Notion API error ${status}: ${body}${suffix}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
async function notionGet(path: string): Promise<unknown> {
|
|
43
56
|
const res = await fetch(`${NOTION_API}${path}`, {
|
|
44
57
|
headers: {
|
|
@@ -47,8 +60,7 @@ async function notionGet(path: string): Promise<unknown> {
|
|
|
47
60
|
},
|
|
48
61
|
});
|
|
49
62
|
if (!res.ok) {
|
|
50
|
-
|
|
51
|
-
throw new Error(`Notion API error ${res.status}: ${text}`);
|
|
63
|
+
throw notionApiError(res.status, await res.text());
|
|
52
64
|
}
|
|
53
65
|
return res.json();
|
|
54
66
|
}
|
|
@@ -64,8 +76,7 @@ async function notionPost(path: string, body: unknown): Promise<unknown> {
|
|
|
64
76
|
body: JSON.stringify(body),
|
|
65
77
|
});
|
|
66
78
|
if (!res.ok) {
|
|
67
|
-
|
|
68
|
-
throw new Error(`Notion API error ${res.status}: ${text}`);
|
|
79
|
+
throw notionApiError(res.status, await res.text());
|
|
69
80
|
}
|
|
70
81
|
return res.json();
|
|
71
82
|
}
|