@agent-native/core 0.121.1 → 0.122.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +145 -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/getting-started.mdx +477 -115
- 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/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/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/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/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -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 +5 -0
- 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/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/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/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/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/_gitignore +1 -0
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/calendar/_gitignore +1 -0
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/chat/_gitignore +1 -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/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/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.meetings.$meetingId.tsx +27 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +46 -15
- package/corpus/templates/clips/app/routes/record.tsx +77 -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/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 +25 -0
- package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
- 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/db.ts +23 -0
- 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/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/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/dispatch/_gitignore +1 -0
- package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/forms/_gitignore +1 -0
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/macros/_gitignore +1 -0
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/mail/_gitignore +1 -0
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/plan/_gitignore +1 -0
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/slides/_gitignore +1 -0
- 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/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/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/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/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 +3 -3
- 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/resources/handlers.d.ts +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/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/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -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 +2 -0
- 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/getting-started.mdx +477 -115
- 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/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/sse-event-processor.ts +3 -0
- package/src/data-widgets/index.ts +41 -0
- package/src/deploy/build.ts +11 -9
- 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/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -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 +5 -0
|
@@ -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;
|
|
@@ -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: [
|
|
@@ -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
|
}
|
|
@@ -73,6 +73,11 @@ export const NON_ANALYTICS_FALLBACK_FINAL_MESSAGE =
|
|
|
73
73
|
export function analyticsSourceGuidanceOpening(): string {
|
|
74
74
|
return (
|
|
75
75
|
"<data-source-guidance>\n" +
|
|
76
|
+
// Measured in production: this ran in under 1% of data threads while the
|
|
77
|
+
// equivalent instruction sat ~7000 words deep. Threads that did call it used
|
|
78
|
+
// roughly a third the tool calls. Keep it first and keep it imperative.
|
|
79
|
+
"START HERE — For any question about a metric, cohort, list, count, or trend, your FIRST tool call is `search-analytics-query-catalog`. This is the analytics equivalent of grepping a codebase before writing new code: someone has very likely already built and saved the query you need, and its saved SQL tells you the exact source, table, and column names so you do not have to discover them. Adapt the closest saved query to the requested filters and time window, run it once, and stop. Only fall back to schema discovery or provider catalogs when the catalog search returns nothing usable — and never run more than one schema-discovery pass before querying. " +
|
|
80
|
+
'ONE BOUNDED CALL — List, filter, count, and cohort questions ("which X, excluding Y") are a single query, not a loop. Express the include filter, the exclude filter, and the aggregation in one SQL statement or one `run-code` script that filters server-side. Never page through a cohort across separate tool calls and never fan out per item to apply a filter; that is what turns a ten-second answer into a twenty-minute one. ' +
|
|
76
81
|
"Apply real-data requirements only when presenting analytics results, source records, or derived metrics. Do not call data-source tools for workflow migration, recurring-job setup, UI/code fixes, settings help, conceptual planning, or other non-data tasks unless the user explicitly asks for data. " +
|
|
77
82
|
NON_ANALYTICS_REQUEST_GUIDANCE +
|
|
78
83
|
BOUNDED_STRUCTURED_LOOKUP_GUIDANCE +
|
|
@@ -734,6 +739,11 @@ export default createAgentChatPlugin({
|
|
|
734
739
|
"Analytics has one user-facing artifact type: dashboards. Dashboards are JSON configs rendered by the built-in dashboard components, and an extension is a dashboard block—not a separate Analytics result. " +
|
|
735
740
|
'If the user\'s requested dashboard, saved analysis/report, visualization, interaction model, custom layout, or bespoke workflow cannot be faithfully represented within the native dashboard components/config fields, do not hand-wave, force an approximate JSON dashboard, or route to source-code changes. In production mode, automatically create a sandboxed extension with `create-extension`, then immediately call `update-dashboard` to embed it as one or more `chartType: "extension"` panels with `config.extensionId`. ' +
|
|
736
741
|
"After creating the dashboard, briefly tell the user that a dashboard block uses an embedded extension because the request needed bespoke UI/code. Never leave a newly created extension standalone, never create a separate saved analysis for the same request, and never direct the user to an Extensions page from Analytics. Legacy analyses may be read or updated only for compatibility with an existing deep link.\n" +
|
|
742
|
+
// The extension-first default above is deliberate, but it must not swallow
|
|
743
|
+
// an explicit ask for a code change: without this carve-out the agent
|
|
744
|
+
// silently substitutes an extension for "open a PR adding a dual-axis
|
|
745
|
+
// chart type" and the user never learns the handoff exists.
|
|
746
|
+
"That extension-first default governs what you build on your own initiative. It does not override an explicit request for a source-code change: when the user asks for the capability natively in the product, asks to change app chrome or a shared component, or asks for a PR, branch, or code change in so many words, call `connect-builder` with their request verbatim instead of substituting an extension. When you have just built an extension for something that plainly belongs in the product — a chart type or interaction other dashboards would reuse — add one sentence offering the `connect-builder` handoff, and only call it if they take you up on it.\n" +
|
|
737
747
|
"</analytics-artifact-guidance>";
|
|
738
748
|
|
|
739
749
|
return `${sourceGuidance}\n\n${artifactGuidance}\n\n${analyticsDataDictionaryRoutingContext()}`;
|
|
@@ -56,7 +56,29 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
56
56
|
- Runs `skills update scaffold --project`
|
|
57
57
|
- Runs `typecheck` when the project has that script
|
|
58
58
|
|
|
59
|
-
3. **
|
|
59
|
+
3. **Pull upstream template changes (optional, separate from the bump)**
|
|
60
|
+
|
|
61
|
+
`agent-native upgrade` moves package versions. It never touches files that
|
|
62
|
+
were copied out of a template at scaffold time, so template fixes and
|
|
63
|
+
improvements do not arrive with a bump.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
agent-native template status # recorded ref vs latest, drift counts
|
|
67
|
+
agent-native template diff # what upstream changed, read-only
|
|
68
|
+
agent-native template sync # 3-way merge it into the app
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`sync` defaults to the ref matching the installed `@agent-native/core`, so
|
|
72
|
+
run it after `upgrade`. It merges per file against a pristine baseline
|
|
73
|
+
stored in `refs/agent-native/template-baseline/<app-path>`; files upstream
|
|
74
|
+
did not touch are left alone, and real collisions get conflict markers.
|
|
75
|
+
After resolving markers, run `agent-native template accept` — the baseline
|
|
76
|
+
deliberately does not advance past an unresolved merge.
|
|
77
|
+
|
|
78
|
+
Apps scaffolded before provenance existed have no baseline. Create one
|
|
79
|
+
with `agent-native template baseline` before the first sync.
|
|
80
|
+
|
|
81
|
+
4. **If upgrade or typecheck fails**
|
|
60
82
|
|
|
61
83
|
- Read the concrete error
|
|
62
84
|
- Fix **app** source, actions, config, or env — not framework packages
|
|
@@ -68,7 +90,7 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
68
90
|
copied component; do not use that path to reproduce framework runtime
|
|
69
91
|
behavior or hide version skew.
|
|
70
92
|
|
|
71
|
-
|
|
93
|
+
5. **Dry-run / partial runs**
|
|
72
94
|
|
|
73
95
|
```bash
|
|
74
96
|
agent-native upgrade --dry-run
|
|
@@ -56,7 +56,29 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
56
56
|
- Runs `skills update scaffold --project`
|
|
57
57
|
- Runs `typecheck` when the project has that script
|
|
58
58
|
|
|
59
|
-
3. **
|
|
59
|
+
3. **Pull upstream template changes (optional, separate from the bump)**
|
|
60
|
+
|
|
61
|
+
`agent-native upgrade` moves package versions. It never touches files that
|
|
62
|
+
were copied out of a template at scaffold time, so template fixes and
|
|
63
|
+
improvements do not arrive with a bump.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
agent-native template status # recorded ref vs latest, drift counts
|
|
67
|
+
agent-native template diff # what upstream changed, read-only
|
|
68
|
+
agent-native template sync # 3-way merge it into the app
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`sync` defaults to the ref matching the installed `@agent-native/core`, so
|
|
72
|
+
run it after `upgrade`. It merges per file against a pristine baseline
|
|
73
|
+
stored in `refs/agent-native/template-baseline/<app-path>`; files upstream
|
|
74
|
+
did not touch are left alone, and real collisions get conflict markers.
|
|
75
|
+
After resolving markers, run `agent-native template accept` — the baseline
|
|
76
|
+
deliberately does not advance past an unresolved merge.
|
|
77
|
+
|
|
78
|
+
Apps scaffolded before provenance existed have no baseline. Create one
|
|
79
|
+
with `agent-native template baseline` before the first sync.
|
|
80
|
+
|
|
81
|
+
4. **If upgrade or typecheck fails**
|
|
60
82
|
|
|
61
83
|
- Read the concrete error
|
|
62
84
|
- Fix **app** source, actions, config, or env — not framework packages
|
|
@@ -68,7 +90,7 @@ install → refresh scaffold skills → verify, then fix **app** code only.
|
|
|
68
90
|
copied component; do not use that path to reproduce framework runtime
|
|
69
91
|
behavior or hide version skew.
|
|
70
92
|
|
|
71
|
-
|
|
93
|
+
5. **Dry-run / partial runs**
|
|
72
94
|
|
|
73
95
|
```bash
|
|
74
96
|
agent-native upgrade --dry-run
|