@agent-native/core 0.131.7 → 0.132.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 +123 -0
- package/corpus/core/docs/content/durable-background-runs.mdx +15 -6
- package/corpus/core/docs/design/durable-agent-runs.md +15 -11
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/activity.ts +127 -10
- package/corpus/core/src/a2a/index.ts +3 -0
- package/corpus/core/src/agent/durable-background.ts +38 -28
- package/corpus/core/src/agent/harness/background.ts +12 -2
- package/corpus/core/src/agent/production-agent.ts +18 -15
- package/corpus/core/src/agent/run-store.ts +45 -3
- package/corpus/core/src/application-state/handlers.ts +45 -0
- package/corpus/core/src/application-state/index.ts +3 -0
- package/corpus/core/src/application-state/store.ts +38 -34
- package/corpus/core/src/audit/redact.ts +104 -18
- package/corpus/core/src/cli/create.ts +115 -16
- package/corpus/core/src/client/AgentPanel.tsx +2 -7
- package/corpus/core/src/client/AssistantChat.tsx +10 -2
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +3 -0
- package/corpus/core/src/client/RunStuckBanner.tsx +29 -6
- package/corpus/core/src/client/agent-chat.ts +4 -9
- package/corpus/core/src/client/application-state.ts +115 -12
- package/corpus/core/src/client/dynamic-suggestions.ts +4 -12
- package/corpus/core/src/client/frame-protocol.ts +5 -1
- package/corpus/core/src/client/guided-questions.tsx +12 -23
- package/corpus/core/src/db/client.ts +148 -28
- package/corpus/core/src/db/create-get-db.ts +39 -6
- package/corpus/core/src/db/runtime-diagnostics.ts +41 -6
- package/corpus/core/src/deploy/build.ts +26 -33
- package/corpus/core/src/feature-flags/store.ts +10 -5
- package/corpus/core/src/integrations/a2a-continuations-store.ts +11 -0
- package/corpus/core/src/integrations/config-store.ts +13 -0
- package/corpus/core/src/integrations/google-docs-poller.ts +26 -2
- package/corpus/core/src/mcp-client/routes.ts +33 -2
- package/corpus/core/src/onboarding/plugin.ts +31 -25
- package/corpus/core/src/org/accept-pending.ts +2 -0
- package/corpus/core/src/org/auto-join-domain.ts +2 -0
- package/corpus/core/src/org/context.ts +35 -10
- package/corpus/core/src/org/handlers.ts +6 -0
- package/corpus/core/src/org/request-org-cache.ts +71 -0
- package/corpus/core/src/resources/store.ts +10 -9
- package/corpus/core/src/scripts/runner.ts +6 -3
- package/corpus/core/src/secrets/storage.ts +97 -5
- package/corpus/core/src/server/action-change.ts +33 -0
- package/corpus/core/src/server/action-routes.ts +11 -9
- package/corpus/core/src/server/agent-teams.ts +10 -2
- package/corpus/core/src/server/better-auth-instance.ts +39 -12
- package/corpus/core/src/server/core-routes-plugin.ts +19 -2
- package/corpus/core/src/server/credential-provider.ts +57 -14
- package/corpus/core/src/server/http-response-telemetry.ts +1 -0
- package/corpus/core/src/server/poll.ts +95 -57
- package/corpus/core/src/server/voice-providers-status.ts +19 -4
- package/corpus/core/src/workspace-files/tool.ts +18 -11
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +38 -0
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +1 -1
- package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +299 -0
- package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +34 -0
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +82 -0
- package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +2 -2
- package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +40 -34
- package/corpus/templates/analytics/app/hooks/use-user-pref.ts +3 -3
- package/corpus/templates/analytics/app/i18n-data.ts +40 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +18 -10
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +14 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +1 -0
- package/corpus/templates/analytics/app/routes/chart.tsx +3 -0
- package/corpus/templates/analytics/changelog/2026-07-30-analytics-dashboards-now-expose-native-funnel-heatmap-callou.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-30-analytics-now-ships-reusable-native-v2-dashboard-manifests-w.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboard-report-render.ts +81 -1
- package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +457 -0
- package/corpus/templates/analytics/server/lib/report-chart-svg.ts +73 -2
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/analytics/shared/dashboard-funnel.ts +83 -0
- package/corpus/templates/clips/actions/generate-workflow.ts +6 -4
- package/corpus/templates/clips/actions/reconcile-workflow-generation.ts +257 -0
- package/corpus/templates/clips/app/hooks/use-auto-title.ts +166 -4
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -1
- package/corpus/templates/clips/changelog/2026-07-27-stopped-agent-runs-no-longer-leave-generated-workflow-cards-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-30-workflow-generation-now-stops-retrying-after-repeated-failur.md +6 -0
- package/corpus/templates/clips/shared/workflow.ts +5 -0
- package/corpus/templates/content/changelog/2026-07-30-long-running-delegated-requests-now-continue-reliably.md +6 -0
- package/corpus/templates/content/netlify.toml +3 -0
- package/corpus/templates/content/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -1
- package/corpus/templates/slides/actions/patch-deck.ts +25 -1
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +17 -4
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +9 -1
- package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +11 -3
- package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +39 -11
- package/corpus/templates/slides/app/pages/Index.tsx +2 -2
- package/corpus/templates/slides/changelog/2026-07-30-slide-previews-keep-their-aspect-ratio-isolate-embedded-styl.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-slides-no-longer-lose-decks-while-organization-access-is-loa.md +6 -0
- package/corpus/toolkit/CHANGELOG.md +8 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/composer/runtime-adapters.tsx +16 -11
- package/dist/a2a/activity.d.ts +22 -4
- package/dist/a2a/activity.d.ts.map +1 -1
- package/dist/a2a/activity.js +97 -11
- package/dist/a2a/activity.js.map +1 -1
- package/dist/a2a/index.d.ts +1 -1
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/agent/durable-background.d.ts +13 -8
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +36 -28
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/harness/background.d.ts.map +1 -1
- package/dist/agent/harness/background.js +12 -2
- package/dist/agent/harness/background.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +18 -15
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-store.d.ts +2 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +44 -3
- package/dist/agent/run-store.js.map +1 -1
- package/dist/application-state/handlers.d.ts +15 -0
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/application-state/handlers.js +42 -2
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/application-state/index.d.ts +2 -2
- package/dist/application-state/index.d.ts.map +1 -1
- package/dist/application-state/index.js +2 -2
- package/dist/application-state/index.js.map +1 -1
- package/dist/application-state/store.d.ts +11 -0
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js +37 -40
- package/dist/application-state/store.js.map +1 -1
- package/dist/audit/redact.d.ts +25 -2
- package/dist/audit/redact.d.ts.map +1 -1
- package/dist/audit/redact.js +85 -21
- package/dist/audit/redact.js.map +1 -1
- package/dist/cli/create.d.ts +8 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +98 -16
- package/dist/cli/create.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +2 -7
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +10 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +1 -1
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/RunStuckBanner.d.ts +11 -1
- package/dist/client/RunStuckBanner.d.ts.map +1 -1
- package/dist/client/RunStuckBanner.js +20 -7
- package/dist/client/RunStuckBanner.js.map +1 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +4 -6
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/application-state.d.ts +11 -0
- package/dist/client/application-state.d.ts.map +1 -1
- package/dist/client/application-state.js +87 -9
- package/dist/client/application-state.js.map +1 -1
- package/dist/client/dynamic-suggestions.d.ts.map +1 -1
- package/dist/client/dynamic-suggestions.js +4 -13
- package/dist/client/dynamic-suggestions.js.map +1 -1
- package/dist/client/frame-protocol.d.ts +1 -0
- package/dist/client/frame-protocol.d.ts.map +1 -1
- package/dist/client/frame-protocol.js.map +1 -1
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +6 -22
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/client.d.ts +57 -10
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +122 -31
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +31 -7
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/runtime-diagnostics.d.ts +1 -0
- package/dist/db/runtime-diagnostics.d.ts.map +1 -1
- package/dist/db/runtime-diagnostics.js +31 -6
- package/dist/db/runtime-diagnostics.js.map +1 -1
- package/dist/deploy/build.d.ts +5 -20
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +18 -30
- package/dist/deploy/build.js.map +1 -1
- package/dist/feature-flags/store.d.ts.map +1 -1
- package/dist/feature-flags/store.js +10 -5
- package/dist/feature-flags/store.js.map +1 -1
- package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
- package/dist/integrations/a2a-continuations-store.js +12 -0
- package/dist/integrations/a2a-continuations-store.js.map +1 -1
- package/dist/integrations/config-store.d.ts +1 -0
- package/dist/integrations/config-store.d.ts.map +1 -1
- package/dist/integrations/config-store.js +11 -0
- package/dist/integrations/config-store.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +19 -2
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +30 -2
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/notifications/routes.d.ts +6 -6
- package/dist/onboarding/plugin.d.ts.map +1 -1
- package/dist/onboarding/plugin.js +12 -8
- package/dist/onboarding/plugin.js.map +1 -1
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +2 -0
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/auto-join-domain.d.ts.map +1 -1
- package/dist/org/auto-join-domain.js +2 -0
- package/dist/org/auto-join-domain.js.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +29 -9
- package/dist/org/context.js.map +1 -1
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +5 -0
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/request-org-cache.d.ts +16 -0
- package/dist/org/request-org-cache.d.ts.map +1 -0
- package/dist/org/request-org-cache.js +62 -0
- package/dist/org/request-org-cache.js.map +1 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +11 -9
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +3 -3
- package/dist/scripts/runner.js.map +1 -1
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +82 -5
- package/dist/secrets/storage.js.map +1 -1
- package/dist/server/action-change.d.ts +20 -0
- package/dist/server/action-change.d.ts.map +1 -1
- package/dist/server/action-change.js +29 -0
- package/dist/server/action-change.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +7 -8
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +10 -2
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +31 -14
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +1 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +18 -4
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +16 -0
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +49 -13
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/http-response-telemetry.d.ts.map +1 -1
- package/dist/server/http-response-telemetry.js +1 -0
- package/dist/server/http-response-telemetry.js.map +1 -1
- package/dist/server/poll.d.ts +6 -0
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +84 -47
- package/dist/server/poll.js.map +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/voice-providers-status.d.ts.map +1 -1
- package/dist/server/voice-providers-status.js +12 -3
- package/dist/server/voice-providers-status.js.map +1 -1
- package/dist/workspace-files/tool.d.ts.map +1 -1
- package/dist/workspace-files/tool.js +18 -11
- package/dist/workspace-files/tool.js.map +1 -1
- package/docs/content/durable-background-runs.mdx +15 -6
- package/docs/design/durable-agent-runs.md +15 -11
- package/package.json +3 -3
- package/src/a2a/activity.ts +127 -10
- package/src/a2a/index.ts +3 -0
- package/src/agent/durable-background.ts +38 -28
- package/src/agent/harness/background.ts +12 -2
- package/src/agent/production-agent.ts +18 -15
- package/src/agent/run-store.ts +45 -3
- package/src/application-state/handlers.ts +45 -0
- package/src/application-state/index.ts +3 -0
- package/src/application-state/store.ts +38 -34
- package/src/audit/redact.ts +104 -18
- package/src/cli/create.ts +115 -16
- package/src/client/AgentPanel.tsx +2 -7
- package/src/client/AssistantChat.tsx +10 -2
- package/src/client/MultiTabAssistantChat.tsx +3 -0
- package/src/client/RunStuckBanner.tsx +29 -6
- package/src/client/agent-chat.ts +4 -9
- package/src/client/application-state.ts +115 -12
- package/src/client/dynamic-suggestions.ts +4 -12
- package/src/client/frame-protocol.ts +5 -1
- package/src/client/guided-questions.tsx +12 -23
- package/src/db/client.ts +148 -28
- package/src/db/create-get-db.ts +39 -6
- package/src/db/runtime-diagnostics.ts +41 -6
- package/src/deploy/build.ts +26 -33
- package/src/feature-flags/store.ts +10 -5
- package/src/integrations/a2a-continuations-store.ts +11 -0
- package/src/integrations/config-store.ts +13 -0
- package/src/integrations/google-docs-poller.ts +26 -2
- package/src/mcp-client/routes.ts +33 -2
- package/src/onboarding/plugin.ts +31 -25
- package/src/org/accept-pending.ts +2 -0
- package/src/org/auto-join-domain.ts +2 -0
- package/src/org/context.ts +35 -10
- package/src/org/handlers.ts +6 -0
- package/src/org/request-org-cache.ts +71 -0
- package/src/resources/store.ts +10 -9
- package/src/scripts/runner.ts +6 -3
- package/src/secrets/storage.ts +97 -5
- package/src/server/action-change.ts +33 -0
- package/src/server/action-routes.ts +11 -9
- package/src/server/agent-teams.ts +10 -2
- package/src/server/better-auth-instance.ts +39 -12
- package/src/server/core-routes-plugin.ts +19 -2
- package/src/server/credential-provider.ts +57 -14
- package/src/server/http-response-telemetry.ts +1 -0
- package/src/server/poll.ts +95 -57
- package/src/server/voice-providers-status.ts +19 -4
- package/src/workspace-files/tool.ts +18 -11
|
@@ -947,6 +947,10 @@ const enUS = {
|
|
|
947
947
|
chartTypePie: "Pie",
|
|
948
948
|
chartTypeMetric: "Metric",
|
|
949
949
|
chartTypeTable: "Table",
|
|
950
|
+
chartTypeFunnel: "Funnel",
|
|
951
|
+
chartTypeHeatmap: "Heatmap",
|
|
952
|
+
chartTypeCallout: "Callout",
|
|
953
|
+
chartTypeSection: "Section",
|
|
950
954
|
chartTypeExtension: "Custom visualization",
|
|
951
955
|
failedToSavePanel: "Failed to save panel",
|
|
952
956
|
failedToFormatSql: "Failed to format SQL",
|
|
@@ -1416,6 +1420,10 @@ const analyticsSliceTranslations: {
|
|
|
1416
1420
|
chartTypePie: "馅饼",
|
|
1417
1421
|
chartTypeMetric: "公制",
|
|
1418
1422
|
chartTypeTable: "桌子",
|
|
1423
|
+
chartTypeFunnel: "漏斗",
|
|
1424
|
+
chartTypeHeatmap: "热力图",
|
|
1425
|
+
chartTypeCallout: "提示",
|
|
1426
|
+
chartTypeSection: "分区",
|
|
1419
1427
|
chartTypeExtension: "自定义可视化",
|
|
1420
1428
|
failedToSavePanel: "保存面板失败",
|
|
1421
1429
|
failedToFormatSql: "格式化SQL失败",
|
|
@@ -1716,6 +1724,10 @@ const analyticsSliceTranslations: {
|
|
|
1716
1724
|
chartTypePie: "Pastel",
|
|
1717
1725
|
chartTypeMetric: "Métrico",
|
|
1718
1726
|
chartTypeTable: "Mesa",
|
|
1727
|
+
chartTypeFunnel: "Embudo",
|
|
1728
|
+
chartTypeHeatmap: "Mapa de calor",
|
|
1729
|
+
chartTypeCallout: "Aviso",
|
|
1730
|
+
chartTypeSection: "Sección",
|
|
1719
1731
|
chartTypeExtension: "Visualización personalizada",
|
|
1720
1732
|
failedToSavePanel: "No se pudo guardar el panel",
|
|
1721
1733
|
failedToFormatSql: "No se pudo formatear SQL",
|
|
@@ -2033,6 +2045,10 @@ const analyticsSliceTranslations: {
|
|
|
2033
2045
|
chartTypePie: "Tarte",
|
|
2034
2046
|
chartTypeMetric: "Métrique",
|
|
2035
2047
|
chartTypeTable: "Tableau",
|
|
2048
|
+
chartTypeFunnel: "Entonnoir",
|
|
2049
|
+
chartTypeHeatmap: "Carte thermique",
|
|
2050
|
+
chartTypeCallout: "Alerte",
|
|
2051
|
+
chartTypeSection: "Section",
|
|
2036
2052
|
chartTypeExtension: "Visualisation personnalisée",
|
|
2037
2053
|
failedToSavePanel: "Échec de l'enregistrement du panneau",
|
|
2038
2054
|
failedToFormatSql: "Échec du formatage du SQL",
|
|
@@ -2348,6 +2364,10 @@ const analyticsSliceTranslations: {
|
|
|
2348
2364
|
chartTypePie: "Torte",
|
|
2349
2365
|
chartTypeMetric: "Metrisch",
|
|
2350
2366
|
chartTypeTable: "Tisch",
|
|
2367
|
+
chartTypeFunnel: "Trichter",
|
|
2368
|
+
chartTypeHeatmap: "Heatmap",
|
|
2369
|
+
chartTypeCallout: "Hinweis",
|
|
2370
|
+
chartTypeSection: "Abschnitt",
|
|
2351
2371
|
chartTypeExtension: "Benutzerdefinierte Visualisierung",
|
|
2352
2372
|
failedToSavePanel: "Das Panel konnte nicht gespeichert werden",
|
|
2353
2373
|
failedToFormatSql: "SQL konnte nicht formatiert werden",
|
|
@@ -2658,6 +2678,10 @@ const analyticsSliceTranslations: {
|
|
|
2658
2678
|
chartTypePie: "パイ",
|
|
2659
2679
|
chartTypeMetric: "メトリック",
|
|
2660
2680
|
chartTypeTable: "テーブル",
|
|
2681
|
+
chartTypeFunnel: "ファネル",
|
|
2682
|
+
chartTypeHeatmap: "ヒートマップ",
|
|
2683
|
+
chartTypeCallout: "コールアウト",
|
|
2684
|
+
chartTypeSection: "セクション",
|
|
2661
2685
|
chartTypeExtension: "カスタム可視化",
|
|
2662
2686
|
failedToSavePanel: "パネルの保存に失敗しました",
|
|
2663
2687
|
failedToFormatSql: "SQLのフォーマットに失敗しました",
|
|
@@ -2962,6 +2986,10 @@ const analyticsSliceTranslations: {
|
|
|
2962
2986
|
chartTypePie: "파이",
|
|
2963
2987
|
chartTypeMetric: "미터법",
|
|
2964
2988
|
chartTypeTable: "테이블",
|
|
2989
|
+
chartTypeFunnel: "퍼널",
|
|
2990
|
+
chartTypeHeatmap: "히트맵",
|
|
2991
|
+
chartTypeCallout: "콜아웃",
|
|
2992
|
+
chartTypeSection: "섹션",
|
|
2965
2993
|
chartTypeExtension: "사용자 지정 시각화",
|
|
2966
2994
|
failedToSavePanel: "패널을 저장하지 못했습니다.",
|
|
2967
2995
|
failedToFormatSql: "SQL 포맷 실패",
|
|
@@ -3266,6 +3294,10 @@ const analyticsSliceTranslations: {
|
|
|
3266
3294
|
chartTypePie: "Torta",
|
|
3267
3295
|
chartTypeMetric: "Métrica",
|
|
3268
3296
|
chartTypeTable: "Mesa",
|
|
3297
|
+
chartTypeFunnel: "Funil",
|
|
3298
|
+
chartTypeHeatmap: "Mapa de calor",
|
|
3299
|
+
chartTypeCallout: "Destaque",
|
|
3300
|
+
chartTypeSection: "Seção",
|
|
3269
3301
|
chartTypeExtension: "Visualização personalizada",
|
|
3270
3302
|
failedToSavePanel: "Falha ao salvar painel",
|
|
3271
3303
|
failedToFormatSql: "Falha ao formatar SQL",
|
|
@@ -3572,6 +3604,10 @@ const analyticsSliceTranslations: {
|
|
|
3572
3604
|
chartTypePie: "पाई",
|
|
3573
3605
|
chartTypeMetric: "मीट्रिक",
|
|
3574
3606
|
chartTypeTable: "मेज़",
|
|
3607
|
+
chartTypeFunnel: "फ़नल",
|
|
3608
|
+
chartTypeHeatmap: "हीटमैप",
|
|
3609
|
+
chartTypeCallout: "कॉलआउट",
|
|
3610
|
+
chartTypeSection: "अनुभाग",
|
|
3575
3611
|
chartTypeExtension: "कस्टम विज़ुअलाइज़ेशन",
|
|
3576
3612
|
failedToSavePanel: "पैनल सहेजने में विफल",
|
|
3577
3613
|
failedToFormatSql: "SQL को फ़ॉर्मेट करने में विफल",
|
|
@@ -3871,6 +3907,10 @@ const analyticsSliceTranslations: {
|
|
|
3871
3907
|
chartTypePie: "فطيرة",
|
|
3872
3908
|
chartTypeMetric: "متري",
|
|
3873
3909
|
chartTypeTable: "طاولة",
|
|
3910
|
+
chartTypeFunnel: "مسار تحويل",
|
|
3911
|
+
chartTypeHeatmap: "خريطة حرارية",
|
|
3912
|
+
chartTypeCallout: "تنبيه",
|
|
3913
|
+
chartTypeSection: "قسم",
|
|
3874
3914
|
chartTypeExtension: "عرض مرئي مخصص",
|
|
3875
3915
|
failedToSavePanel: "فشل حفظ اللوحة",
|
|
3876
3916
|
failedToFormatSql: "فشل تهيئة SQL",
|
|
@@ -57,6 +57,10 @@ const CHART_TYPES: { value: ChartType; labelKey: string }[] = [
|
|
|
57
57
|
{ value: "pie", labelKey: "panelEditor.chartTypePie" },
|
|
58
58
|
{ value: "metric", labelKey: "panelEditor.chartTypeMetric" },
|
|
59
59
|
{ value: "table", labelKey: "panelEditor.chartTypeTable" },
|
|
60
|
+
{ value: "funnel", labelKey: "panelEditor.chartTypeFunnel" },
|
|
61
|
+
{ value: "heatmap", labelKey: "panelEditor.chartTypeHeatmap" },
|
|
62
|
+
{ value: "callout", labelKey: "panelEditor.chartTypeCallout" },
|
|
63
|
+
{ value: "section", labelKey: "panelEditor.chartTypeSection" },
|
|
60
64
|
{ value: "extension", labelKey: "panelEditor.chartTypeExtension" },
|
|
61
65
|
];
|
|
62
66
|
|
|
@@ -290,6 +294,7 @@ function PanelEditorContent({
|
|
|
290
294
|
|
|
291
295
|
const isEdit = !!panel;
|
|
292
296
|
const isExtensionPanel = form.chartType === "extension";
|
|
297
|
+
const isSectionPanel = form.chartType === "section";
|
|
293
298
|
const isProgramSource = form.source === "program";
|
|
294
299
|
const { programId, paramsText: initialParamsText } = useMemo(
|
|
295
300
|
() =>
|
|
@@ -332,10 +337,13 @@ function PanelEditorContent({
|
|
|
332
337
|
const canSave = isExtensionPanel
|
|
333
338
|
? form.title.trim().length > 0 &&
|
|
334
339
|
(form.extensionMode === "slot" || form.extensionId.trim().length > 0)
|
|
335
|
-
:
|
|
336
|
-
? form.title.trim().length > 0
|
|
337
|
-
:
|
|
338
|
-
|
|
340
|
+
: isSectionPanel
|
|
341
|
+
? form.title.trim().length > 0
|
|
342
|
+
: isProgramSource
|
|
343
|
+
? form.title.trim().length > 0 && selectedProgramId.trim().length > 0
|
|
344
|
+
: form.title.trim().length > 0 && form.sql.trim().length > 0;
|
|
345
|
+
const canFormat =
|
|
346
|
+
!isExtensionPanel && !isSectionPanel && canFormatPanelSql(form.source);
|
|
339
347
|
|
|
340
348
|
const handleSubmit = async () => {
|
|
341
349
|
if (!canSave || saving) return;
|
|
@@ -343,7 +351,7 @@ function PanelEditorContent({
|
|
|
343
351
|
setError(null);
|
|
344
352
|
try {
|
|
345
353
|
let sqlForSave = form.sql;
|
|
346
|
-
if (isProgramSource) {
|
|
354
|
+
if (isProgramSource && !isSectionPanel) {
|
|
347
355
|
try {
|
|
348
356
|
sqlForSave = serializeProgramDescriptor(
|
|
349
357
|
selectedProgramId,
|
|
@@ -388,7 +396,7 @@ function PanelEditorContent({
|
|
|
388
396
|
`If no source can answer, report the exact unavailable/error result instead of saving a panel with guessed schema or metrics. ` +
|
|
389
397
|
`Use the \`mutate-dashboard\` action with code like \`dashboard.insertPanel({"id":"new-panel","title":"New Panel","source":"first-party","chartType":"metric","width":1,"sql":"SELECT COUNT(*) AS value FROM analytics_events"}).atBottom();\` ` +
|
|
390
398
|
`to append, or \`.nextTo("panel-id")\`, \`.atRow(2)\`, \`.atRowStart(2)\`, \`.before("panel-id")\`, \`.after("panel-id")\`, or \`.atIndex(n)\` to place the panel. Prefer \`.nextTo("panel-id")\` or \`.atRow(rowNumber)\` for visible row placement requests; they keep the chart in the intended rendered row and expand/rebalance that row when needed. ` +
|
|
391
|
-
`Panel shape: { id (unique slug), title, sql, source ('bigquery'|'ga4'|'amplitude'|'first-party'|'demo'|'prometheus'|'program'), chartType ('line'|'area'|'bar'|'metric'|'table'|'pie'|'section'|'extension'), width (legacy integer 1..6; set to 1 unless editing existing data), tab? (use 'Group / Tab' for grouped tabs), columns? (section panels only - 1..6 max panels per row for panels following this section), config? }. ` +
|
|
399
|
+
`Panel shape: { id (unique slug), title, sql, source ('bigquery'|'ga4'|'amplitude'|'first-party'|'demo'|'prometheus'|'program'), chartType ('line'|'area'|'bar'|'metric'|'table'|'pie'|'funnel'|'heatmap'|'callout'|'section'|'extension'), width (legacy integer 1..6; set to 1 unless editing existing data), tab? (use 'Group / Tab' for grouped tabs), columns? (section panels only - 1..6 max panels per row for panels following this section), config? }. ` +
|
|
392
400
|
`Visible layout auto-fits by row: one panel in a row spans the row, two split it, three split it into thirds, up to the section column limit. ` +
|
|
393
401
|
`For amplitude panels, sql is a JSON descriptor: {"event":"event name","groupBy":"property","days":30}. ` +
|
|
394
402
|
`For first-party panels, sql is read-only SQL over analytics_events only; use source 'first-party' and do not call db-query for this datasource. ` +
|
|
@@ -396,8 +404,8 @@ function PanelEditorContent({
|
|
|
396
404
|
`For prometheus panels, sql is a JSON descriptor: {"promql":"rate(http_requests_total[5m])","mode":"range","range":"1h","step":"30s"}. mode defaults to "range"; range defaults to "1h"; step is auto if omitted. Returned rows have shape {timestamp, series, value} — set config.xKey="timestamp", config.yKey="value", and a single series in config.yKeys for clean charting. ` +
|
|
397
405
|
`For program panels (arbitrary provider data joins/cohorts not expressible in the other sources), first save-data-program (or reuse an existing one via list-data-programs), then set sql to a JSON descriptor: {"programId":"<id>","params":{...}}. See the data-programs skill for the emit(rows, schema) contract and the Risk Meeting worked example. ` +
|
|
398
406
|
`Native dashboard panels and Data Programs come first. Add an extension panel only when the user explicitly asks for a genuinely bespoke, one-off Custom Block for this dashboard and native panels cannot represent it faithfully. For a reusable/native capability call connect-builder instead. New agent-authored Custom Blocks use config.extensionId plus config.customBlock={authoredBy:"agent",intent:"one-off",scope:"dashboard",nativeGapReason:"custom-visualization"|"custom-interaction"|"custom-layout"|"other"}; never put prompt/customer text in that metadata. Use config.extensionSlotId only when the user explicitly asks for a personal/per-viewer slot; slot installs are per-user and automated report identities may have no install. ` +
|
|
399
|
-
`Config is optional: { xKey, yKey, yKeys, yFormatter ('number'|'currency'|'percent'), rightYKeys, rightYFormatter, description, columns, pivot, limit, color, colors, stacked, legend, valueLabels }. ` +
|
|
400
|
-
`For line/area/bar series that share an x-axis but not a unit (a count next to a rate), put the smaller-unit series on a second y-axis with config.rightYKeys (a subset of yKeys) and an optional config.rightYFormatter — do not build an extension for a dual-axis chart. ` +
|
|
407
|
+
`Config is optional: { xKey, yKey, yKeys, yFormatter ('number'|'currency'|'percent'), rightYKeys, rightYFormatter, description, columns, pivot, limit, color, colors, stacked, legend, valueLabels }. For funnel panels, use config.xKey for the stage label, config.yKey for the non-negative count/value, and keep the SQL ORDER BY in the intended funnel order. ` +
|
|
408
|
+
`For line/area/bar series that share an x-axis but not a unit (a count next to a rate), put the smaller-unit series on a second y-axis with config.rightYKeys (a subset of yKeys) and an optional config.rightYFormatter — do not build an extension for a dual-axis chart. Use heatmap, callout, and section panels when their native contracts fit; do not create a Custom Block for a supported native panel. ` +
|
|
401
409
|
`Chart legends render automatically; set config.legend=false only when the user explicitly asks to hide the legend. ` +
|
|
402
410
|
`Use \`get-sql-dashboard.layout.groups[].rows[].rowNumber/panelIds\` to identify and verify visible rows. ` +
|
|
403
411
|
`Consult the data dictionary first via \`list-data-dictionary --search <topic>\`, then use AGENTS.md, .agents/skills, and connected data-source instructions before writing SQL. ` +
|
|
@@ -455,7 +463,7 @@ function PanelEditorContent({
|
|
|
455
463
|
</Select>
|
|
456
464
|
</div>
|
|
457
465
|
|
|
458
|
-
{!isExtensionPanel ? (
|
|
466
|
+
{!isExtensionPanel && !isSectionPanel ? (
|
|
459
467
|
<div className="grid gap-1.5">
|
|
460
468
|
<Label htmlFor="panel-source">{t("panelEditor.source")}</Label>
|
|
461
469
|
<Select
|
|
@@ -600,7 +608,7 @@ function PanelEditorContent({
|
|
|
600
608
|
</div>
|
|
601
609
|
)}
|
|
602
610
|
</div>
|
|
603
|
-
) : isProgramSource ? (
|
|
611
|
+
) : isSectionPanel ? null : isProgramSource ? (
|
|
604
612
|
<div className="grid gap-4">
|
|
605
613
|
<div className="grid gap-1.5">
|
|
606
614
|
<Label htmlFor="panel-program">
|
|
@@ -178,6 +178,15 @@ type DashboardTabGroup = {
|
|
|
178
178
|
tabs: Array<{ value: string; label: string }>;
|
|
179
179
|
};
|
|
180
180
|
|
|
181
|
+
function sameFilterMap(
|
|
182
|
+
a: Record<string, string> | undefined,
|
|
183
|
+
b: Record<string, string>,
|
|
184
|
+
): boolean {
|
|
185
|
+
const aKeys = Object.keys(a ?? {});
|
|
186
|
+
if (aKeys.length !== Object.keys(b).length) return false;
|
|
187
|
+
return aKeys.every((key) => a![key] === b[key]);
|
|
188
|
+
}
|
|
189
|
+
|
|
181
190
|
function groupDashboardTabs(tabs: string[]): {
|
|
182
191
|
groups: DashboardTabGroup[];
|
|
183
192
|
hasNestedTabs: boolean;
|
|
@@ -1013,6 +1022,10 @@ function SqlDashboardPageContent({
|
|
|
1013
1022
|
currentFilters[k] = v;
|
|
1014
1023
|
}
|
|
1015
1024
|
});
|
|
1025
|
+
// Opening a dashboard restores the saved filters into the URL, so
|
|
1026
|
+
// without this the mere act of loading a page writes the value back —
|
|
1027
|
+
// one round-trip plus a sync event that invalidates every mounted query.
|
|
1028
|
+
if (sameFilterMap(savedFilters?.filters, currentFilters)) return;
|
|
1016
1029
|
saveFilterPref({ filters: currentFilters });
|
|
1017
1030
|
}, 1500);
|
|
1018
1031
|
return () => clearTimeout(saveTimer.current);
|
|
@@ -1021,6 +1034,7 @@ function SqlDashboardPageContent({
|
|
|
1021
1034
|
loaded,
|
|
1022
1035
|
dashboard?.filters,
|
|
1023
1036
|
dashboardId,
|
|
1037
|
+
savedFilters,
|
|
1024
1038
|
saveFilterPref,
|
|
1025
1039
|
reportScreenshot,
|
|
1026
1040
|
]);
|
|
@@ -16,6 +16,9 @@ const VALID_CHART_TYPES = new Set([
|
|
|
16
16
|
"metric",
|
|
17
17
|
"table",
|
|
18
18
|
"pie",
|
|
19
|
+
"funnel",
|
|
20
|
+
"heatmap",
|
|
21
|
+
"callout",
|
|
19
22
|
]);
|
|
20
23
|
// Embed URLs accept external sources plus the restricted first-party analytics
|
|
21
24
|
// source. They intentionally do not expose arbitrary app database querying.
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
SqlPanel,
|
|
14
14
|
TableColumnConfig,
|
|
15
15
|
} from "../../app/pages/adhoc/sql-dashboard/types";
|
|
16
|
+
import { resolveDashboardFunnelRows } from "../../shared/dashboard-funnel";
|
|
16
17
|
import { DASHBOARD_REPORT_ACTION_TIMEOUT_MS } from "../../shared/dashboard-report-timeouts.js";
|
|
17
18
|
import {
|
|
18
19
|
MAX_CONCURRENT_FIRST_PARTY_SQL_QUERIES,
|
|
@@ -25,6 +26,7 @@ import {
|
|
|
25
26
|
import { resolveAnalyticsPanelSource } from "./dashboard-panel-source-resolver";
|
|
26
27
|
import {
|
|
27
28
|
renderReportChartSvg,
|
|
29
|
+
renderFunnelChartSvg,
|
|
28
30
|
REPORT_CHART_FONT_FAMILY,
|
|
29
31
|
type ReportChartSeries,
|
|
30
32
|
type ReportChartType,
|
|
@@ -534,6 +536,7 @@ const REPORT_CHART_TYPES: Record<string, ReportChartType> = {
|
|
|
534
536
|
line: "line",
|
|
535
537
|
area: "area",
|
|
536
538
|
pie: "pie",
|
|
539
|
+
funnel: "funnel",
|
|
537
540
|
"stacked-bar": "bar",
|
|
538
541
|
"stacked-area": "area",
|
|
539
542
|
};
|
|
@@ -923,7 +926,7 @@ async function renderChartBlock(args: {
|
|
|
923
926
|
panel: SqlPanel;
|
|
924
927
|
rows: Array<Record<string, unknown>>;
|
|
925
928
|
forcedYKeys?: string[];
|
|
926
|
-
chartType: ReportChartType
|
|
929
|
+
chartType: Exclude<ReportChartType, "funnel">;
|
|
927
930
|
index: number;
|
|
928
931
|
description: string;
|
|
929
932
|
}): Promise<PanelBlock> {
|
|
@@ -997,6 +1000,72 @@ async function renderChartBlock(args: {
|
|
|
997
1000
|
}
|
|
998
1001
|
}
|
|
999
1002
|
|
|
1003
|
+
async function renderFunnelChartBlock(args: {
|
|
1004
|
+
panel: SqlPanel;
|
|
1005
|
+
rows: Array<Record<string, unknown>>;
|
|
1006
|
+
index: number;
|
|
1007
|
+
description: string;
|
|
1008
|
+
}): Promise<PanelBlock> {
|
|
1009
|
+
const { panel, rows, index, description } = args;
|
|
1010
|
+
const funnel = resolveDashboardFunnelRows(
|
|
1011
|
+
rows,
|
|
1012
|
+
panel.config?.xKey,
|
|
1013
|
+
panel.config?.yKey,
|
|
1014
|
+
);
|
|
1015
|
+
if (funnel.items.length === 0) {
|
|
1016
|
+
const table = renderTableHtml(panel, rows);
|
|
1017
|
+
return {
|
|
1018
|
+
panelId: panel.id,
|
|
1019
|
+
html: panelCardHtml(
|
|
1020
|
+
panel,
|
|
1021
|
+
`${table.html}${noteHtml("No funnel stages were returned, so the rows are shown as a table.")}`,
|
|
1022
|
+
),
|
|
1023
|
+
text: `${panel.title}\n${table.text}`,
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
const subtitle = description;
|
|
1028
|
+
const alt = `funnel chart of ${funnel.items.map((item) => item.label).join(", ")}`;
|
|
1029
|
+
try {
|
|
1030
|
+
const svg = renderFunnelChartSvg({
|
|
1031
|
+
title: "",
|
|
1032
|
+
subtitle,
|
|
1033
|
+
rows: funnel.items,
|
|
1034
|
+
width: CHART_WIDTH,
|
|
1035
|
+
height: CHART_HEIGHT,
|
|
1036
|
+
formatter: panel.config?.yFormatter,
|
|
1037
|
+
colors: panel.config?.colors,
|
|
1038
|
+
});
|
|
1039
|
+
const png = await rasterizeChartPng(svg, CHART_WIDTH * CHART_RASTER_SCALE);
|
|
1040
|
+
const slug =
|
|
1041
|
+
panel.id.replace(/[^A-Za-z0-9_-]/g, "-").slice(0, 40) || "panel";
|
|
1042
|
+
const contentId = `dashboard-report-panel-${index}-${slug}`;
|
|
1043
|
+
return {
|
|
1044
|
+
panelId: panel.id,
|
|
1045
|
+
html: panelCardHtml(
|
|
1046
|
+
panel,
|
|
1047
|
+
`<img src="cid:${contentId}" alt="${escapeHtml(alt)}" width="${CHART_WIDTH}" style="display:block;width:100%;max-width:${CHART_WIDTH}px;height:auto;border:0;" />`,
|
|
1048
|
+
),
|
|
1049
|
+
text: `${panel.title}: chart attached${subtitle ? ` (${subtitle})` : ""}`,
|
|
1050
|
+
attachment: {
|
|
1051
|
+
filename: `${slug}.png`,
|
|
1052
|
+
content: png,
|
|
1053
|
+
contentType: "image/png",
|
|
1054
|
+
contentId,
|
|
1055
|
+
disposition: "inline",
|
|
1056
|
+
},
|
|
1057
|
+
};
|
|
1058
|
+
} catch (error) {
|
|
1059
|
+
return failureBlock(
|
|
1060
|
+
panel,
|
|
1061
|
+
"Chart rendering failed",
|
|
1062
|
+
error instanceof Error
|
|
1063
|
+
? error.message
|
|
1064
|
+
: "The funnel image could not be rendered.",
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1000
1069
|
function enforceAttachmentBudget(blocks: PanelBlock[]): void {
|
|
1001
1070
|
const totalBytes = () =>
|
|
1002
1071
|
blocks.reduce(
|
|
@@ -1093,6 +1162,17 @@ export async function renderReportEmail(args: {
|
|
|
1093
1162
|
const chartType: ReportChartType | undefined =
|
|
1094
1163
|
REPORT_CHART_TYPES[panel.chartType];
|
|
1095
1164
|
if (chartType) {
|
|
1165
|
+
if (chartType === "funnel") {
|
|
1166
|
+
const block = await renderFunnelChartBlock({
|
|
1167
|
+
panel,
|
|
1168
|
+
rows,
|
|
1169
|
+
index: chartIndex++,
|
|
1170
|
+
description,
|
|
1171
|
+
});
|
|
1172
|
+
if (truncatedNote) block.html += truncatedNote;
|
|
1173
|
+
blocks.push(block);
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1096
1176
|
const block = await renderChartBlock({
|
|
1097
1177
|
panel,
|
|
1098
1178
|
rows,
|