@agent-native/core 0.189.0 → 0.190.0-nightly-20260925215540
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 +1 -1
- package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +10 -0
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +1 -1
- package/corpus/templates/analytics/AGENTS.md +11 -22
- package/corpus/templates/analytics/actions/list-data-dictionary.ts +7 -9
- package/corpus/templates/analytics/actions/search-analytics-query-catalog.ts +1 -1
- package/corpus/templates/analytics/app/components/AnalyticsReviewArtifactPreview.tsx +201 -0
- package/corpus/templates/analytics/app/i18n/en-US.ts +2 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +50 -3
- package/corpus/templates/analytics/changelog/2026-09-25-first-run-onboarding-records-setup-choices-and-builder-conne.md +6 -0
- package/corpus/templates/analytics/changelog/2026-09-25-human-review-previews-analytics-dashboards-as-real-charts.md +6 -0
- package/corpus/templates/analytics/changelog/2026-09-25-org-admins-can-review-agent-runs-from-settings.md +6 -0
- package/corpus/templates/analytics/changelog/2026-09-25-proactive-query-context.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +98 -2
- package/corpus/templates/analytics/server/lib/analytics-agent-context.ts +557 -0
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +217 -46
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +2 -2
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +39 -5
- package/corpus/templates/analytics/server/lib/data-dictionary-context.ts +4 -0
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +268 -2
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +44 -9
- package/corpus/templates/calendar/AGENTS.md +5 -0
- package/corpus/templates/calendar/CHANGELOG.md +6 -0
- package/corpus/templates/calendar/actions/get-event-rules-status.ts +47 -0
- package/corpus/templates/calendar/actions/list-events.ts +50 -4
- package/corpus/templates/calendar/actions/undo-calendar-event-rule.ts +229 -0
- package/corpus/templates/calendar/actions/update-settings.ts +8 -0
- package/corpus/templates/calendar/app/i18n/en-US.ts +27 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +196 -1
- package/corpus/templates/calendar/changelog/2026-09-25-calendar-feeds-with-the-same-url-keep-their-own-names-and-co.md +6 -0
- package/corpus/templates/calendar/changelog/2026-09-25-calendar-invitation-rules-surface-expired-connections-and-un.md +6 -0
- package/corpus/templates/calendar/changelog/2026-09-25-restore-locally-hidden-events-from-activity-after-disconnect.md +6 -0
- package/corpus/templates/calendar/server/lib/calendar-settings.ts +44 -10
- package/corpus/templates/calendar/server/lib/google-api.ts +15 -1
- package/corpus/templates/calendar/server/lib/google-calendar.ts +1 -1
- package/corpus/templates/calendar/server/plugins/event-rules.ts +628 -0
- package/corpus/templates/calendar/shared/api.ts +13 -0
- package/corpus/templates/calendar/shared/settings.ts +71 -1
- package/corpus/templates/clips/actions/create-recording.ts +83 -2
- package/corpus/templates/clips/actions/finalize-recording.ts +610 -110
- package/corpus/templates/clips/actions/get-recording-player-data.ts +6 -0
- package/corpus/templates/clips/actions/import-loom-recording.ts +2 -0
- package/corpus/templates/clips/actions/lib/create-recording-schema.ts +7 -0
- package/corpus/templates/clips/actions/lib/loom-import-job.ts +15 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +126 -26
- package/corpus/templates/clips/app/hooks/use-drop-video-upload.ts +75 -15
- package/corpus/templates/clips/app/routes/_app.r.$recordingId.tsx +5 -1
- package/corpus/templates/clips/app/routes/record.tsx +134 -40
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +13 -1
- package/corpus/templates/clips/changelog/2026-09-25-signed-in-viewers-who-hit-an-unavailable-expired-or-private-.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +3 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +73 -16
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +188 -18
- package/corpus/templates/clips/desktop/src/lib/recording-request.ts +1 -0
- package/corpus/templates/clips/server/db/schema.ts +4 -0
- package/corpus/templates/clips/server/jobs/media-verification.ts +78 -4
- package/corpus/templates/clips/server/jobs/recording-failure-backfill.ts +142 -0
- package/corpus/templates/clips/server/lib/media-verification-state.ts +29 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +2 -0
- package/corpus/templates/clips/server/lib/recording-failures.ts +111 -0
- package/corpus/templates/clips/server/lib/recordings.ts +6 -1
- package/corpus/templates/clips/server/lib/s3-upload-provider.ts +8 -3
- package/corpus/templates/clips/server/lib/upload-lease.ts +25 -6
- package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
- package/corpus/templates/clips/server/plugins/db.ts +18 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +48 -5
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +322 -31
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +223 -61
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +62 -4
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +74 -7
- package/corpus/templates/clips/shared/recording-core.ts +27 -0
- package/corpus/templates/design/actions/get-design.ts +35 -6
- package/corpus/templates/mail/.agents/skills/inbox-automations/SKILL.md +4 -0
- package/corpus/templates/mail/actions/consolidate-ai-filter-rules.ts +41 -0
- package/corpus/templates/mail/actions/get-ai-priority.ts +48 -8
- package/corpus/templates/mail/actions/record-ai-priority-feedback.ts +69 -0
- package/corpus/templates/mail/actions/update-mail-preferences.ts +2 -0
- package/corpus/templates/mail/app/components/email/EmailList.tsx +179 -32
- package/corpus/templates/mail/app/components/email/EmailListItem.tsx +97 -9
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +55 -1
- package/corpus/templates/mail/app/components/email/ImportanceFeedbackMenu.tsx +52 -0
- package/corpus/templates/mail/app/components/email/compose-autocomplete.ts +2 -1
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +219 -188
- package/corpus/templates/mail/app/components/onboarding/AiInboxSetup.tsx +338 -0
- package/corpus/templates/mail/app/components/settings/AiFilterSection.tsx +597 -781
- package/corpus/templates/mail/app/components/settings/AiRulePromptField.tsx +37 -0
- package/corpus/templates/mail/app/global.css +42 -26
- package/corpus/templates/mail/app/hooks/use-ai-priority-feedback.ts +43 -0
- package/corpus/templates/mail/app/hooks/use-automations.ts +23 -0
- package/corpus/templates/mail/app/i18n/en-US.ts +58 -3
- package/corpus/templates/mail/app/pages/InboxPage.tsx +47 -10
- package/corpus/templates/mail/changelog/2026-09-25-editing-importance-rules-preserves-disabled-instructions-and.md +6 -0
- package/corpus/templates/mail/changelog/2026-09-25-handle-astral-unicode-letters-in-autocomplete-word-boundarie.md +6 -0
- package/corpus/templates/mail/changelog/2026-09-25-jev-priority-feedback-and-inbox-settings.md +6 -0
- package/corpus/templates/mail/changelog/2026-09-25-keep-existing-ai-filter-rules-intact-when-saving-a-prompt.md +6 -0
- package/corpus/templates/mail/server/lib/automation-engine.ts +21 -12
- package/corpus/templates/mail/server/lib/automations.ts +100 -1
- package/corpus/templates/mail/shared/types.ts +3 -0
- package/corpus/templates/plan/app/i18n/en-US.ts +6 -0
- package/corpus/templates/plan/app/lib/plan-invite-suggestion.ts +43 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +249 -4
- package/corpus/templates/slides/actions/create-deck.ts +11 -1
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +117 -1
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +373 -330
- package/corpus/templates/slides/app/components/design-system/builder-index-response.ts +36 -5
- package/corpus/templates/slides/app/components/editor/BlockBubbleMenu.tsx +21 -53
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +347 -671
- package/corpus/templates/slides/app/components/editor/bullet-editing.ts +55 -8
- package/corpus/templates/slides/app/components/editor/in-place-text-session.ts +2082 -0
- package/corpus/templates/slides/app/components/editor/list-editing.ts +174 -16
- package/corpus/templates/slides/app/components/editor/rich-text-selection.ts +497 -62
- package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +102 -20
- package/corpus/templates/slides/app/context/DeckContext.tsx +9 -4
- package/corpus/templates/slides/app/global.css +7 -219
- package/corpus/templates/slides/app/i18n/en-US.ts +3 -0
- package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +7 -0
- package/corpus/templates/slides/app/lib/slide-image-replacement.ts +203 -1
- package/corpus/templates/slides/app/lib/slide-source-map.ts +43 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +182 -4
- package/corpus/templates/slides/app/routes/settings.tsx +33 -2
- package/corpus/templates/slides/changelog/2026-09-25-improve-slides-design-system-setup-feedback.md +6 -0
- package/corpus/templates/slides/changelog/2026-09-25-org-admins-can-review-agent-runs-from-settings.md +6 -0
- package/corpus/templates/slides/changelog/2026-09-25-text-on-a-slide-is-now-edited-in-place-clicking-into-it-chan.md +6 -0
- package/corpus/templates/slides/package.json +0 -12
- package/corpus/templates/slides/scripts/edit-fidelity/README.md +4 -2
- package/corpus/templates/slides/scripts/edit-fidelity/run.ts +12 -3
- package/corpus/templates/slides/vite.config.ts +1 -10
- package/dist/agent/jev-tool-prefetch.d.ts +29 -3
- package/dist/agent/jev-tool-prefetch.js +161 -34
- package/dist/agent/production-agent.d.ts +11 -0
- package/dist/agent/production-agent.js +39 -8
- package/dist/app-config/runtime.d.ts +1 -0
- package/dist/app-config/runtime.js +4 -0
- package/dist/app-config/schema.d.ts +1 -0
- package/dist/client/AgentSidebar.d.ts +3 -1
- package/dist/client/AgentSidebar.js +8 -12
- package/dist/client/analytics/index.d.ts +1 -1
- package/dist/client/analytics/index.js +1 -1
- package/dist/client/analytics.d.ts +2 -0
- package/dist/client/analytics.js +9 -0
- package/dist/client/api-path.js +5 -2
- package/dist/client/chat/run-recovery.d.ts +0 -3
- package/dist/client/chat/run-recovery.js +13 -23
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/observability/ObservabilityDashboard.d.ts +3 -0
- package/dist/client/observability/ObservabilityDashboard.js +366 -71
- package/dist/client/observability/ObservabilityReviewSummaryButton.d.ts +4 -1
- package/dist/client/observability/ObservabilityReviewSummaryButton.js +13 -9
- package/dist/client/observability/OutputPreview.d.ts +9 -4
- package/dist/client/observability/OutputPreview.js +230 -52
- package/dist/client/onboarding/FirstRunOnboarding.js +67 -4
- package/dist/client/onboarding/use-onboarding.js +2 -0
- package/dist/client/sharing/ShareButton.d.ts +2 -0
- package/dist/client/sharing/ShareButton.js +1 -0
- package/dist/client/sharing/useShareButtonController.d.ts +1 -0
- package/dist/client/sharing/useShareButtonController.js +29 -8
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.js +9 -1
- package/dist/embeddings/index.d.ts +3 -1
- package/dist/embeddings/index.js +20 -10
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/jobs/sweep-hooks.d.ts +7 -0
- package/dist/jobs/sweep-hooks.js +28 -0
- package/dist/localization/default-messages.d.ts +1 -0
- package/dist/localization/default-messages.js +1 -0
- package/dist/notifications/routes.d.ts +6 -6
- package/dist/observability/actions/authorization.d.ts +1 -0
- package/dist/observability/actions/authorization.js +22 -0
- package/dist/observability/actions/get-observability-review-detail.d.ts +5 -0
- package/dist/observability/actions/get-observability-review-detail.js +10 -2
- package/dist/observability/actions/get-observability-review-summary-source.d.ts +2 -0
- package/dist/observability/actions/get-observability-review-summary-source.js +3 -2
- package/dist/observability/actions/save-observability-instruction-update.js +2 -1
- package/dist/observability/actions/save-observability-review-summary.js +21 -10
- package/dist/observability/migrations.js +25 -0
- package/dist/observability/reviews.d.ts +3 -1
- package/dist/observability/reviews.js +410 -53
- package/dist/observability/routes.d.ts +6 -6
- package/dist/observability/store.d.ts +15 -0
- package/dist/observability/store.js +131 -11
- package/dist/observability/types.d.ts +18 -0
- package/dist/org/handlers.d.ts +1 -1
- package/dist/org/index.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/server/agent-chat/plugin-options.d.ts +4 -20
- package/dist/server/agent-chat/prompt-resources.d.ts +16 -0
- package/dist/server/agent-chat/prompt-resources.js +385 -22
- package/dist/server/agent-chat-plugin.d.ts +3 -1
- package/dist/server/agent-chat-plugin.js +149 -27
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +3 -0
- package/dist/server/prompts/framework-core-compact.js +1 -1
- package/dist/server/prompts/framework-core.js +1 -1
- package/dist/server/request-context.d.ts +6 -3
- package/dist/settings/org-settings.d.ts +4 -2
- package/dist/settings/org-settings.js +3 -3
- package/dist/settings/store.d.ts +3 -1
- package/dist/settings/store.js +8 -3
- package/dist/styles/agent-native.css +5 -0
- package/dist/templates/default/app/i18n/ar-SA.ts +1 -0
- package/dist/templates/default/app/i18n/de-DE.ts +1 -0
- package/dist/templates/default/app/i18n/en-US.ts +1 -0
- package/dist/templates/default/app/i18n/es-ES.ts +1 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +1 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +1 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +1 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +1 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +1 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +1 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +1 -0
- package/dist/tracking/registry.js +11 -4
- package/dist/vite/client.js +6 -0
- package/package.json +4 -3
- package/src/templates/default/app/i18n/ar-SA.ts +1 -0
- package/src/templates/default/app/i18n/de-DE.ts +1 -0
- package/src/templates/default/app/i18n/en-US.ts +1 -0
- package/src/templates/default/app/i18n/es-ES.ts +1 -0
- package/src/templates/default/app/i18n/fr-FR.ts +1 -0
- package/src/templates/default/app/i18n/hi-IN.ts +1 -0
- package/src/templates/default/app/i18n/ja-JP.ts +1 -0
- package/src/templates/default/app/i18n/ko-KR.ts +1 -0
- package/src/templates/default/app/i18n/pt-BR.ts +1 -0
- package/src/templates/default/app/i18n/zh-CN.ts +1 -0
- package/src/templates/default/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/slides/app/components/editor/SlideBubbleMenu.tsx +0 -488
- package/corpus/templates/slides/app/components/editor/SlideInlineEditor.tsx +0 -589
- package/corpus/templates/slides/app/components/editor/SlideRichTextEditor.tsx +0 -1347
- package/corpus/templates/slides/app/components/editor/SlideSlashMenu.tsx +0 -373
package/corpus/README.md
CHANGED
|
@@ -92,6 +92,16 @@ Inside `run-code`, use the workspace helper functions:
|
|
|
92
92
|
download must appear in chat; do not answer with only a path or navigation
|
|
93
93
|
instructions.
|
|
94
94
|
|
|
95
|
+
## CSV and XLSX Exports
|
|
96
|
+
|
|
97
|
+
- For a compact result, use `query-agent-native-analytics` and its Download
|
|
98
|
+
CSV control. For a durable CSV, use `run-code` with `workspaceWrite` in a
|
|
99
|
+
normal Resources folder, then call `show-workspace-file` with that path. If
|
|
100
|
+
`run-code` is not available, discover it once with tool search.
|
|
101
|
+
- For an explicit `.xlsx` request, call `docs-search` once for `xlsx export`
|
|
102
|
+
and follow the returned workflow. The QuickJS `run-code` sandbox has no Node
|
|
103
|
+
imports; do not try to load `xlsx` or `exceljs` there.
|
|
104
|
+
|
|
95
105
|
## Chunked Batch Analysis (30+ items)
|
|
96
106
|
|
|
97
107
|
For large fan-outs (account deep dives, Gong call reviews, deal cohorts):
|
|
@@ -11,7 +11,7 @@ The analytics app connects to multiple data sources. This skill covers general p
|
|
|
11
11
|
|
|
12
12
|
## Approach
|
|
13
13
|
|
|
14
|
-
0. **
|
|
14
|
+
0. **Use retrieved references first** — data questions may start with a small set of relevant data-dictionary entries and saved dashboard panels in `<resource scope="analytics-catalog">`. Treat them as definitions and query examples, never live results. If they do not fit, call `search-analytics-query-catalog` before querying; use data-source status when provider availability matters.
|
|
15
15
|
1. **Route named account health deliberately** — for a customer/org health, QBR, renewal, contract-utilization, risk, or adoption request, read `account-health` before writing SQL. It adds identity-lock and metric-definition checks that an ordinary lookup does not need.
|
|
16
16
|
2. **Read the relevant provider skill first** — check `.agents/skills/<provider>/SKILL.md` for table names, column mappings, auth, and gotchas. For BigQuery, read `.agents/skills/bigquery/SKILL.md` and use `search-bigquery-schema` before guessing table or column names.
|
|
17
17
|
3. **Clarify if ambiguous** — if the metric definition, date range, or grain is unclear and a wrong guess would change the numbers, use the `ask-question` clarifying tool (multiple-choice) before querying. Ask at most once per turn; skip it when the dictionary or the user already answered.
|
|
@@ -17,8 +17,8 @@ Read the relevant skill before deeper work:
|
|
|
17
17
|
de-duplication).
|
|
18
18
|
- `dashboard-management` for dashboard/panel storage, layout, extensions,
|
|
19
19
|
mutation and sharing.
|
|
20
|
-
- `adhoc-analysis`
|
|
21
|
-
|
|
20
|
+
- `adhoc-analysis` for one-off answers; `analysis-workspace` for large work and
|
|
21
|
+
CSV/XLSX exports.
|
|
22
22
|
- `provider-api` and `data-programs` for the escape hatch and durable,
|
|
23
23
|
refreshable data sources.
|
|
24
24
|
- `creative-context` for governed contexts and immutable dashboard revisions.
|
|
@@ -26,13 +26,13 @@ Read the relevant skill before deeper work:
|
|
|
26
26
|
|
|
27
27
|
## How To Answer A Data Question
|
|
28
28
|
|
|
29
|
-
1. **
|
|
30
|
-
`search-analytics-query-catalog
|
|
31
|
-
call `search-dashboard-references`
|
|
32
|
-
with `get-sql-dashboard` or
|
|
33
|
-
is context, not
|
|
34
|
-
to the requested filters/window, run it once,
|
|
35
|
-
`certified` dashboard
|
|
29
|
+
1. **Use the closest query example.** For a metric question, adapt a relevant
|
|
30
|
+
preloaded reference; if none fits, call `search-analytics-query-catalog`.
|
|
31
|
+
For dashboard replication or adaptation, call `search-dashboard-references`
|
|
32
|
+
first and inspect each result with `get-sql-dashboard` or
|
|
33
|
+
`get-explorer-dashboard` by its `kind`. A match is context, not live data.
|
|
34
|
+
Adapt the closest saved SQL to the requested filters/window, run it once,
|
|
35
|
+
and stop. Prefer a current `certified` dashboard; a favorite is a weaker
|
|
36
36
|
relevance signal. Certification becomes stale after a dashboard edit.
|
|
37
37
|
2. **One bounded call.** List/filter/count/cohort questions are one SQL statement
|
|
38
38
|
or one server-side `run-code` script; never page or fan out per item.
|
|
@@ -66,9 +66,8 @@ certified ones); label figures "Unverified" when no live query ran.
|
|
|
66
66
|
absence-sensitive Gong work, stage raw API data and use `query-staged-dataset`
|
|
67
67
|
or a Data Program; see `provider-api`, `data-programs`, and `gong` for secure
|
|
68
68
|
provider and hosted-endpoint boundaries.
|
|
69
|
-
- Create dashboards
|
|
70
|
-
|
|
71
|
-
metrics, and never modify existing dashboards without a directive.
|
|
69
|
+
- Create dashboards or saved artifacts only when asked; keep them focused and
|
|
70
|
+
never modify existing dashboards without direction.
|
|
72
71
|
- For named account/deal deep dives, call `account-deep-dive` first.
|
|
73
72
|
- For named account health, read `account-health` before querying.
|
|
74
73
|
- When the user challenges coverage or asks why records are missing, rerun from
|
|
@@ -85,16 +84,6 @@ certified ones); label figures "Unverified" when no live query ran.
|
|
|
85
84
|
multi-step work, unavailable actions, or unsupported writes.
|
|
86
85
|
- Reports/alerts use SQL actions; cap at five recipients.
|
|
87
86
|
|
|
88
|
-
## Actions
|
|
89
|
-
|
|
90
|
-
| Action | Use |
|
|
91
|
-
| --- | --- |
|
|
92
|
-
| `search-analytics-query-catalog` | Search saved metric examples first. |
|
|
93
|
-
| `search-dashboard-references` | Find dashboards to replicate. |
|
|
94
|
-
| `get-sql-dashboard` | Read the dashboard and exact panel SQL. |
|
|
95
|
-
| `certify-dashboard` | Admin-only approval of its current version. |
|
|
96
|
-
| DB | `list-db-admin-connections`, `list-connected-database-tables`, `db-admin-federated-read`: registry, schema, bounded joins. |
|
|
97
|
-
|
|
98
87
|
## Application State
|
|
99
88
|
|
|
100
89
|
- `navigation` exposes the current dashboard, analysis, source, chart, and
|
|
@@ -3,7 +3,10 @@ import {
|
|
|
3
3
|
getRequestUserEmail,
|
|
4
4
|
getRequestOrgId,
|
|
5
5
|
} from "@agent-native/core/server";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
listOrgSettings,
|
|
8
|
+
listSettingsByPrefix,
|
|
9
|
+
} from "@agent-native/core/settings";
|
|
7
10
|
import { z } from "zod";
|
|
8
11
|
|
|
9
12
|
const KEY_PREFIX = "data-dict-";
|
|
@@ -46,15 +49,10 @@ export default defineAction({
|
|
|
46
49
|
for (const value of Object.values(orgEntries)) collect(value);
|
|
47
50
|
}
|
|
48
51
|
|
|
49
|
-
//
|
|
50
|
-
// See list-analyses.ts for the rationale (substring matches leak across
|
|
51
|
-
// users).
|
|
52
|
+
// Scope the read in SQL so other users' settings never enter this action.
|
|
52
53
|
const userPrefix = `u:${email}:${KEY_PREFIX}`;
|
|
53
|
-
const
|
|
54
|
-
for (const
|
|
55
|
-
if (!fullKey.startsWith(userPrefix)) continue;
|
|
56
|
-
collect(value);
|
|
57
|
-
}
|
|
54
|
+
const userEntries = await listSettingsByPrefix(userPrefix);
|
|
55
|
+
for (const { value } of userEntries) collect(value);
|
|
58
56
|
|
|
59
57
|
const q = (args.search ?? "").trim().toLowerCase();
|
|
60
58
|
const dept = (args.department ?? "").trim().toLowerCase();
|
|
@@ -10,7 +10,7 @@ import { searchAnalyticsQueryCatalog } from "../server/lib/analytics-query-catal
|
|
|
10
10
|
export default defineAction({
|
|
11
11
|
description:
|
|
12
12
|
"Prefer a current certified dashboard panel before other matches; a dashboard starred by the requesting user is a weaker relevance signal. " +
|
|
13
|
-
"Search Analytics' existing query knowledge before writing a new query. This is the analytics equivalent of grepping for similar code: one bounded call searches accessible saved dashboard names, chart titles/descriptions/queries, shipped dashboard patterns, and data-dictionary definitions. Use it first for an ordinary metric lookup unless the user supplied an exact source and query. Prefer the highest-trust close match, adapt its saved query only for the requested filters/time window, run one authoritative source query, and stop on success. Do not separately list every dashboard or scan provider catalogs after a strong match.",
|
|
13
|
+
"Search Analytics' existing query knowledge before writing a new query. This is the analytics equivalent of grepping for similar code: one bounded call searches accessible saved dashboard names, chart titles/descriptions/queries, shipped dashboard patterns, and data-dictionary definitions. The result reports `searchedDashboardCount`, `dashboardSearchTruncated`, `dashboardSearchStatus`, `searchedDictionaryEntryCount`, `dictionarySearchTruncated`, and `dictionarySearchStatus`. If dashboard search is truncated or unavailable and no close saved-dashboard match appears, use `search-dashboard-references` with focused terms; if dictionary search is truncated, partial, or unavailable and no close definition appears, use `list-data-dictionary` with focused terms before concluding there is no saved example. Use it first for an ordinary metric lookup unless the user supplied an exact source and query. Prefer the highest-trust close match, adapt its saved query only for the requested filters/time window, run one authoritative source query, and stop on success. Do not separately list every dashboard or scan provider catalogs after a strong match.",
|
|
14
14
|
schema: z.object({
|
|
15
15
|
search: z
|
|
16
16
|
.string()
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { useActionQuery } from "@agent-native/core/client/hooks";
|
|
2
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
3
|
+
|
|
4
|
+
import { SqlChart } from "@/components/dashboard/SqlChart";
|
|
5
|
+
import { resolveFilterVars } from "@/pages/adhoc/sql-dashboard/DashboardFilterBar";
|
|
6
|
+
import { interpolate } from "@/pages/adhoc/sql-dashboard/interpolate";
|
|
7
|
+
import { serializePanelSql } from "@/pages/adhoc/sql-dashboard/panel-sql";
|
|
8
|
+
import { timeRangeDays } from "@/pages/adhoc/sql-dashboard/pivot";
|
|
9
|
+
import type {
|
|
10
|
+
DashboardFilter,
|
|
11
|
+
DataSourceType,
|
|
12
|
+
ChartType,
|
|
13
|
+
SqlPanel,
|
|
14
|
+
} from "@/pages/adhoc/sql-dashboard/types";
|
|
15
|
+
|
|
16
|
+
const DATA_SOURCES: DataSourceType[] = [
|
|
17
|
+
"bigquery",
|
|
18
|
+
"ga4",
|
|
19
|
+
"amplitude",
|
|
20
|
+
"first-party",
|
|
21
|
+
"demo",
|
|
22
|
+
"prometheus",
|
|
23
|
+
"program",
|
|
24
|
+
];
|
|
25
|
+
const CHART_TYPES: ChartType[] = [
|
|
26
|
+
"line",
|
|
27
|
+
"area",
|
|
28
|
+
"bar",
|
|
29
|
+
"metric",
|
|
30
|
+
"table",
|
|
31
|
+
"pie",
|
|
32
|
+
"section",
|
|
33
|
+
"funnel",
|
|
34
|
+
"heatmap",
|
|
35
|
+
"callout",
|
|
36
|
+
"extension",
|
|
37
|
+
];
|
|
38
|
+
const FILTER_TYPES: DashboardFilter["type"][] = [
|
|
39
|
+
"date",
|
|
40
|
+
"date-range",
|
|
41
|
+
"select",
|
|
42
|
+
"toggle",
|
|
43
|
+
"text",
|
|
44
|
+
"toggle-date",
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
48
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function isSqlPanel(value: unknown): value is SqlPanel {
|
|
52
|
+
if (!isRecord(value)) return false;
|
|
53
|
+
return (
|
|
54
|
+
typeof value.id === "string" &&
|
|
55
|
+
typeof value.title === "string" &&
|
|
56
|
+
typeof value.sql === "string" &&
|
|
57
|
+
typeof value.width === "number" &&
|
|
58
|
+
DATA_SOURCES.includes(value.source as DataSourceType) &&
|
|
59
|
+
CHART_TYPES.includes(value.chartType as ChartType) &&
|
|
60
|
+
(value.config === undefined || isRecord(value.config))
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function isDashboardFilter(value: unknown): value is DashboardFilter {
|
|
65
|
+
if (
|
|
66
|
+
!isRecord(value) ||
|
|
67
|
+
typeof value.id !== "string" ||
|
|
68
|
+
!value.id ||
|
|
69
|
+
typeof value.label !== "string" ||
|
|
70
|
+
!FILTER_TYPES.includes(value.type as DashboardFilter["type"]) ||
|
|
71
|
+
(value.default !== undefined && typeof value.default !== "string")
|
|
72
|
+
) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return (
|
|
76
|
+
value.options === undefined ||
|
|
77
|
+
(Array.isArray(value.options) &&
|
|
78
|
+
value.options.length <= 100 &&
|
|
79
|
+
value.options.every(
|
|
80
|
+
(option) =>
|
|
81
|
+
isRecord(option) &&
|
|
82
|
+
typeof option.value === "string" &&
|
|
83
|
+
typeof option.label === "string",
|
|
84
|
+
))
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function reviewDashboardFilters(
|
|
89
|
+
value: unknown,
|
|
90
|
+
): DashboardFilter[] | undefined {
|
|
91
|
+
if (!isRecord(value) || value.filters === undefined) return [];
|
|
92
|
+
return Array.isArray(value.filters) &&
|
|
93
|
+
value.filters.length <= 100 &&
|
|
94
|
+
value.filters.every(isDashboardFilter)
|
|
95
|
+
? value.filters
|
|
96
|
+
: undefined;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function reviewDashboardVariables(
|
|
100
|
+
value: unknown,
|
|
101
|
+
): Record<string, string> | undefined {
|
|
102
|
+
if (!isRecord(value) || value.variables === undefined) return {};
|
|
103
|
+
if (!isRecord(value.variables)) return undefined;
|
|
104
|
+
const entries = Object.entries(value.variables);
|
|
105
|
+
if (
|
|
106
|
+
entries.length > 100 ||
|
|
107
|
+
entries.some(([, variable]) => typeof variable !== "string")
|
|
108
|
+
) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
return Object.fromEntries(entries) as Record<string, string>;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function firstReviewDashboardPanel(
|
|
115
|
+
value: unknown,
|
|
116
|
+
): SqlPanel | undefined {
|
|
117
|
+
if (!isRecord(value) || !Array.isArray(value.panels)) return undefined;
|
|
118
|
+
const panels = value.panels.filter(isSqlPanel);
|
|
119
|
+
const byId = new Map(panels.map((panel) => [panel.id, panel]));
|
|
120
|
+
const preferredIds =
|
|
121
|
+
isRecord(value.layout) && Array.isArray(value.layout.firstPanelIds)
|
|
122
|
+
? value.layout.firstPanelIds.filter(
|
|
123
|
+
(id): id is string => typeof id === "string",
|
|
124
|
+
)
|
|
125
|
+
: [];
|
|
126
|
+
const preferred = preferredIds.flatMap((id) => {
|
|
127
|
+
const panel = byId.get(id);
|
|
128
|
+
return panel ? [panel] : [];
|
|
129
|
+
});
|
|
130
|
+
const ordered = [
|
|
131
|
+
...preferred,
|
|
132
|
+
...panels.filter((panel) => !preferredIds.includes(panel.id)),
|
|
133
|
+
];
|
|
134
|
+
return ordered.find(
|
|
135
|
+
(panel) => panel.chartType !== "section" && panel.chartType !== "extension",
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function AnalyticsReviewArtifactPreview({
|
|
140
|
+
artifactId,
|
|
141
|
+
compact,
|
|
142
|
+
}: {
|
|
143
|
+
artifactId: string;
|
|
144
|
+
compact: boolean;
|
|
145
|
+
}) {
|
|
146
|
+
const t = useT();
|
|
147
|
+
const { data, isLoading, isError } = useActionQuery<Record<string, unknown>>(
|
|
148
|
+
"get-sql-dashboard",
|
|
149
|
+
{ id: artifactId, includeConfig: true },
|
|
150
|
+
{ staleTime: 5 * 60_000 },
|
|
151
|
+
);
|
|
152
|
+
const panel = firstReviewDashboardPanel(data);
|
|
153
|
+
const filters = reviewDashboardFilters(data);
|
|
154
|
+
const variables = reviewDashboardVariables(data);
|
|
155
|
+
if (isLoading) {
|
|
156
|
+
return (
|
|
157
|
+
<div
|
|
158
|
+
aria-hidden="true"
|
|
159
|
+
className={
|
|
160
|
+
compact
|
|
161
|
+
? "size-full animate-pulse bg-muted"
|
|
162
|
+
: "h-full min-h-64 w-full animate-pulse bg-muted"
|
|
163
|
+
}
|
|
164
|
+
/>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
if (isError || !panel || !filters || !variables) {
|
|
168
|
+
return (
|
|
169
|
+
<div
|
|
170
|
+
className="flex size-full items-center justify-center bg-muted px-2 text-center text-xs text-muted-foreground"
|
|
171
|
+
data-preview-state="unavailable"
|
|
172
|
+
role="status"
|
|
173
|
+
>
|
|
174
|
+
{t("settings.reviewPreviewUnavailable")}
|
|
175
|
+
</div>
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const vars = { ...variables, ...resolveFilterVars(filters, () => "") };
|
|
180
|
+
const resolvedSql = interpolate(serializePanelSql(panel.sql), vars, {
|
|
181
|
+
failClosedTimeVariables: true,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<div
|
|
186
|
+
className={
|
|
187
|
+
compact
|
|
188
|
+
? "pointer-events-none h-[600%] w-[600%] origin-top-left scale-[0.166667] overflow-hidden"
|
|
189
|
+
: "h-full min-h-64 w-full overflow-hidden"
|
|
190
|
+
}
|
|
191
|
+
data-preview-kind="analytics-sql-chart"
|
|
192
|
+
>
|
|
193
|
+
<SqlChart
|
|
194
|
+
panel={panel}
|
|
195
|
+
resolvedSql={resolvedSql}
|
|
196
|
+
timeRange={timeRangeDays(vars.timeRange)}
|
|
197
|
+
dashboardId={artifactId}
|
|
198
|
+
/>
|
|
199
|
+
</div>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
@@ -337,6 +337,8 @@ export default {
|
|
|
337
337
|
untitledDashboard: "Untitled dashboard",
|
|
338
338
|
},
|
|
339
339
|
settings: {
|
|
340
|
+
agentObservability: "Agent Observability",
|
|
341
|
+
reviewPreviewUnavailable: "Preview unavailable",
|
|
340
342
|
agentTitle: "Manage agent",
|
|
341
343
|
agentDescription:
|
|
342
344
|
"Manage the agent's model, API keys, automations, voice, and other controls.",
|
|
@@ -4,7 +4,9 @@ import {
|
|
|
4
4
|
useActionQuery,
|
|
5
5
|
} from "@agent-native/core/client/hooks";
|
|
6
6
|
import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
|
|
7
|
-
import {
|
|
7
|
+
import { buildSettingsRoute } from "@agent-native/core/client/navigation";
|
|
8
|
+
import { ObservabilityDashboard } from "@agent-native/core/client/observability";
|
|
9
|
+
import { TeamPage, useOrg } from "@agent-native/core/client/org";
|
|
8
10
|
import {
|
|
9
11
|
AccountSettingsCard,
|
|
10
12
|
SettingsGroup,
|
|
@@ -18,7 +20,7 @@ import {
|
|
|
18
20
|
createCreativeContextAgentTab,
|
|
19
21
|
useCreativeContextLab,
|
|
20
22
|
} from "@agent-native/creative-context/client";
|
|
21
|
-
import { IconBell } from "@tabler/icons-react";
|
|
23
|
+
import { IconActivity, IconBell } from "@tabler/icons-react";
|
|
22
24
|
import { useEffect, useMemo, useState } from "react";
|
|
23
25
|
import { Link } from "react-router";
|
|
24
26
|
import { toast } from "sonner";
|
|
@@ -31,6 +33,7 @@ import {
|
|
|
31
33
|
ANALYTICS_USER_PREFS_KEY,
|
|
32
34
|
type AnalyticsUserPrefs,
|
|
33
35
|
} from "../../shared/analytics-user-prefs";
|
|
36
|
+
import { AnalyticsReviewArtifactPreview } from "../components/AnalyticsReviewArtifactPreview";
|
|
34
37
|
import { useReplayStorageStatus } from "../hooks/use-replay-storage-status";
|
|
35
38
|
import { ReplayStorageHint } from "./sessions/SessionsPage";
|
|
36
39
|
import { AlertRulesSettingsCard } from "./settings/AlertRulesSettingsCard";
|
|
@@ -40,6 +43,11 @@ export default function Settings() {
|
|
|
40
43
|
const t = useT();
|
|
41
44
|
const creativeContextEnabled = useCreativeContextLab();
|
|
42
45
|
const replayStorageStatus = useReplayStorageStatus();
|
|
46
|
+
const {
|
|
47
|
+
data: activeOrg,
|
|
48
|
+
isLoading: orgLoading,
|
|
49
|
+
isError: orgError,
|
|
50
|
+
} = useOrg();
|
|
43
51
|
const { data: analyticsPrefs, isLoading: analyticsPrefsLoading } =
|
|
44
52
|
useActionQuery<AnalyticsUserPrefs>("get-user-pref", {
|
|
45
53
|
key: ANALYTICS_USER_PREFS_KEY,
|
|
@@ -142,6 +150,44 @@ export default function Settings() {
|
|
|
142
150
|
agentAdditionalContent,
|
|
143
151
|
agentAdditionalTabFactories,
|
|
144
152
|
});
|
|
153
|
+
const observabilityBasePath = buildSettingsRoute("observability");
|
|
154
|
+
const observabilityTabs = useMemo<SettingsTabItem[]>(
|
|
155
|
+
() =>
|
|
156
|
+
!orgLoading &&
|
|
157
|
+
!orgError &&
|
|
158
|
+
activeOrg?.orgId &&
|
|
159
|
+
(activeOrg.role === "owner" || activeOrg.role === "admin")
|
|
160
|
+
? [
|
|
161
|
+
{
|
|
162
|
+
id: "observability",
|
|
163
|
+
label: t("settings.agentObservability"),
|
|
164
|
+
icon: IconActivity,
|
|
165
|
+
group: "agent",
|
|
166
|
+
href: `${observabilityBasePath}/overview`,
|
|
167
|
+
content: (
|
|
168
|
+
<ObservabilityDashboard
|
|
169
|
+
routeBasePath={observabilityBasePath}
|
|
170
|
+
showHumanReview
|
|
171
|
+
renderArtifactPreview={(artifact, compact) => (
|
|
172
|
+
<AnalyticsReviewArtifactPreview
|
|
173
|
+
artifactId={artifact.artifactId}
|
|
174
|
+
compact={compact}
|
|
175
|
+
/>
|
|
176
|
+
)}
|
|
177
|
+
/>
|
|
178
|
+
),
|
|
179
|
+
},
|
|
180
|
+
]
|
|
181
|
+
: [],
|
|
182
|
+
[
|
|
183
|
+
activeOrg?.orgId,
|
|
184
|
+
activeOrg?.role,
|
|
185
|
+
observabilityBasePath,
|
|
186
|
+
orgError,
|
|
187
|
+
orgLoading,
|
|
188
|
+
t,
|
|
189
|
+
],
|
|
190
|
+
);
|
|
145
191
|
const labs = useMemo(
|
|
146
192
|
() => [
|
|
147
193
|
{
|
|
@@ -167,8 +213,9 @@ export default function Settings() {
|
|
|
167
213
|
),
|
|
168
214
|
},
|
|
169
215
|
...agentSettingsTabs,
|
|
216
|
+
...observabilityTabs,
|
|
170
217
|
],
|
|
171
|
-
[agentSettingsTabs, t],
|
|
218
|
+
[agentSettingsTabs, observabilityTabs, t],
|
|
172
219
|
);
|
|
173
220
|
|
|
174
221
|
const generalSearchEntries = useMemo(
|