@agent-native/core 0.136.0 → 0.136.3

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.
Files changed (120) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +31 -5
  3. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +7 -0
  4. package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +52 -19
  5. package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +25 -3
  6. package/corpus/templates/analytics/AGENTS.md +6 -7
  7. package/corpus/templates/analytics/actions/gong-calls.ts +3 -3
  8. package/corpus/templates/analytics/actions/provider-api-catalog.ts +1 -1
  9. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  10. package/corpus/templates/analytics/app/i18n-data.ts +46 -0
  11. package/corpus/templates/analytics/app/pages/Settings.tsx +67 -1
  12. package/corpus/templates/analytics/app/pages/settings/settings-search.ts +6 -0
  13. package/corpus/templates/analytics/changelog/2026-08-03-dashboard-builds-now-finish-without-an-extra-confirmation.md +6 -0
  14. package/corpus/templates/analytics/changelog/2026-08-03-error-alert-emails-are-opt-in.md +6 -0
  15. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +10 -9
  16. package/corpus/templates/analytics/server/lib/error-capture.ts +38 -10
  17. package/corpus/templates/analytics/server/lib/gong.ts +27 -4
  18. package/corpus/templates/analytics/server/plugins/agent-chat.ts +64 -4
  19. package/corpus/templates/analytics/shared/analytics-user-prefs.ts +7 -0
  20. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +15 -6
  21. package/corpus/templates/clips/actions/apply-rewind-extension.ts +9 -0
  22. package/corpus/templates/clips/actions/cleanup-dictation.ts +2 -2
  23. package/corpus/templates/clips/actions/cleanup-transcript.ts +8 -11
  24. package/corpus/templates/clips/actions/clear-edits.ts +15 -2
  25. package/corpus/templates/clips/actions/create-recording-agent-link.ts +10 -0
  26. package/corpus/templates/clips/actions/finalize-meeting.ts +6 -6
  27. package/corpus/templates/clips/actions/finalize-recording.ts +33 -8
  28. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +1 -3
  29. package/corpus/templates/clips/actions/list-recordings.ts +39 -24
  30. package/corpus/templates/clips/actions/list-transactional-email-ai-requests.ts +4 -1
  31. package/corpus/templates/clips/actions/regenerate-title.ts +2 -2
  32. package/corpus/templates/clips/actions/stitch-recordings.ts +36 -7
  33. package/corpus/templates/clips/app/components/editor/rewind-extension-dialog.tsx +1 -4
  34. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +3 -1
  35. package/corpus/templates/clips/app/components/library/recording-card.tsx +9 -0
  36. package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +52 -7
  37. package/corpus/templates/clips/app/hooks/use-library.ts +1 -0
  38. package/corpus/templates/clips/app/hooks/use-transactional-email-bridge.ts +17 -10
  39. package/corpus/templates/clips/app/i18n/en-US.ts +3 -0
  40. package/corpus/templates/clips/app/lib/timestamp-mapping.ts +5 -0
  41. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -0
  42. package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -0
  43. package/corpus/templates/clips/changelog/2026-07-31-agent-views-now-show-the-agent-s-name-from-the-link-it-was-g.md +6 -0
  44. package/corpus/templates/clips/changelog/2026-07-31-clip-cards-and-the-watch-share-page-header-now-show-agent-vi.md +6 -0
  45. package/corpus/templates/clips/changelog/2026-08-01-recordings-stored-in-private-s3-compatible-buckets-finalize-.md +6 -0
  46. package/corpus/templates/clips/changelog/2026-08-03-clip-cleanup-titles-and-meeting-summaries-now-use-luna-by-de.md +6 -0
  47. package/corpus/templates/clips/changelog/2026-08-03-get-a-monthly-recap-email-showing-how-many-people-and-ai-age.md +6 -0
  48. package/corpus/templates/clips/changelog/2026-08-03-get-an-email-the-first-time-an-ai-agent-reads-one-of-your-cl.md +6 -0
  49. package/corpus/templates/clips/learnings.defaults.md +2 -2
  50. package/corpus/templates/clips/package.json +1 -1
  51. package/corpus/templates/clips/scripts/send-real-recap.ts +165 -0
  52. package/corpus/templates/clips/scripts/send-test-emails.ts +60 -0
  53. package/corpus/templates/clips/server/db/schema.ts +4 -0
  54. package/corpus/templates/clips/server/jobs/transactional-emails.ts +256 -0
  55. package/corpus/templates/clips/server/lib/agent-views.ts +38 -11
  56. package/corpus/templates/clips/server/lib/media-storage-provenance.ts +16 -0
  57. package/corpus/templates/clips/server/lib/public-agent-context.ts +3 -1
  58. package/corpus/templates/clips/server/lib/recap-metrics.ts +373 -0
  59. package/corpus/templates/clips/server/lib/s3-upload-provider.ts +84 -4
  60. package/corpus/templates/clips/server/lib/transactional-email-store.ts +41 -2
  61. package/corpus/templates/clips/server/lib/transactional-email-templates.ts +245 -3
  62. package/corpus/templates/clips/server/plugins/db.ts +16 -0
  63. package/corpus/templates/clips/server/register-secrets.ts +2 -2
  64. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +7 -2
  65. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +42 -1
  66. package/corpus/templates/design/actions/take-design-screenshot.ts +5 -3
  67. package/corpus/templates/design/package.json +1 -1
  68. package/corpus/templates/design/server/lib/playwright-runtime.ts +13 -5
  69. package/corpus/templates/mail/actions/get-automation-settings.ts +4 -12
  70. package/corpus/templates/mail/app/pages/SettingsPage.tsx +1 -1
  71. package/corpus/templates/mail/changelog/2026-08-03-inbox-automations-now-prefer-the-lowest-cost-luna-model-when.md +6 -0
  72. package/corpus/templates/mail/server/lib/automation-engine.ts +19 -14
  73. package/corpus/templates/mail/server/lib/automation-model.ts +110 -0
  74. package/corpus/templates/mail/server/plugins/agent-chat.ts +1 -1
  75. package/corpus/templates/slides/actions/generate-slides-ai.ts +92 -24
  76. package/corpus/templates/slides/changelog/2026-08-03-legacy-slide-outlines-now-prefer-the-lowest-cost-luna-model-.md +6 -0
  77. package/corpus/templates/tasks/package.json +2 -2
  78. package/dist/agent/production-agent.d.ts +2 -2
  79. package/dist/agent/production-agent.js +1 -1
  80. package/dist/catalog.json +2 -0
  81. package/dist/client/AgentTaskCard.js +4 -2
  82. package/dist/client/i18n.js +3 -0
  83. package/dist/client/settings/VoiceTranscriptionSection.js +2 -2
  84. package/dist/collab/awareness.d.ts +2 -2
  85. package/dist/collab/routes.d.ts +1 -1
  86. package/dist/collab/struct-routes.d.ts +1 -1
  87. package/dist/localization/default-messages.d.ts +5 -0
  88. package/dist/localization/default-messages.js +5 -0
  89. package/dist/mcp/oauth-client-metadata.d.ts +7 -0
  90. package/dist/mcp/oauth-client-metadata.js +47 -0
  91. package/dist/mcp/oauth-route.js +7 -3
  92. package/dist/mcp/oauth-store.d.ts +2 -0
  93. package/dist/mcp/oauth-store.js +25 -3
  94. package/dist/notifications/routes.d.ts +1 -1
  95. package/dist/observability/routes.d.ts +3 -3
  96. package/dist/observability/traces.d.ts +1 -1
  97. package/dist/observability/traces.js +2 -1
  98. package/dist/progress/routes.d.ts +1 -1
  99. package/dist/provider-api/index.js +29 -1
  100. package/dist/secrets/routes.d.ts +6 -6
  101. package/dist/server/agent-access.d.ts +3 -1
  102. package/dist/server/agent-access.js +2 -1
  103. package/dist/server/agent-chat/browser-team-tools.d.ts +1 -0
  104. package/dist/server/agent-chat/browser-team-tools.js +5 -4
  105. package/dist/server/agent-chat/context-tools.js +2 -2
  106. package/dist/server/agent-chat-plugin.js +13 -6
  107. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  108. package/dist/server/agent-teams-run-queue.d.ts +2 -0
  109. package/dist/server/agent-teams.d.ts +2 -0
  110. package/dist/server/agent-teams.js +45 -2
  111. package/dist/server/request-context.d.ts +2 -0
  112. package/dist/server/short-lived-token.d.ts +7 -0
  113. package/dist/server/short-lived-token.js +7 -1
  114. package/dist/server/ssr-handler.js +19 -1
  115. package/dist/server/transcribe-voice.d.ts +1 -1
  116. package/dist/server/transcribe-voice.js +24 -16
  117. package/dist/vite/client.d.ts +37 -1
  118. package/dist/vite/client.js +110 -1
  119. package/docs/content/template-assets.mdx +14 -4
  120. package/package.json +3 -4
package/corpus/README.md CHANGED
@@ -31,4 +31,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
31
31
 
32
32
  ## Generated Counts
33
33
 
34
- - template files: 7499
34
+ - template files: 7515
@@ -48,6 +48,28 @@ window, then read them back selectively for synthesis.
48
48
  `timed_out`, chunk the work or persist intermediate progress with
49
49
  `workspaceWrite` and re-run.
50
50
 
51
+ ## Delegated Analysis Handoff
52
+
53
+ Background sub-agents start with a clean context. A handoff for a large
54
+ analysis must include the exact staged dataset id or workspace path, the
55
+ records/chunk range to process, the output path, and the checkpoint or resume
56
+ operation. The child must read that staged input before making provider calls.
57
+
58
+ - If a readable staged file or dataset already exists, process it in place. Do
59
+ not re-page the provider endpoint to recreate the same corpus.
60
+ - If the named staged input is missing or unreadable, stop with an explicit
61
+ missing-input error. Do not silently fall back to a full provider sweep.
62
+ - For more than 500 Gong records, do not use `gong-calls(exhaustive=true)`, a
63
+ per-call transcript loop, or a single `provider-api-request` `fetchAllPages`
64
+ call as the analysis itself. If the term is a configured keyword tracker,
65
+ stage `/calls/extensive` tracker results and reduce them with a Data Program
66
+ or `query-staged-dataset`. Otherwise use `provider-corpus-job` with a staged
67
+ call-id input and continue raw transcript retrieval in bounded, checkpointed
68
+ batches.
69
+ - Write a compact result or progress marker after every completed chunk. A
70
+ final answer written only after the whole corpus is processed is not a
71
+ checkpoint.
72
+
51
73
  ## Workspace File Helpers
52
74
 
53
75
  Inside `run-code`, use the workspace helper functions:
@@ -105,11 +127,15 @@ narrow, where records must be joined across systems, or where absence matters:
105
127
 
106
128
  1. Discover the provider surface with `provider-api-catalog` and
107
129
  `provider-api-docs` when endpoint/filter/pagination details are uncertain.
108
- 2. Pull the relevant records with `provider-api-request`. Use `fetchAllPages`
109
- for cursor pagination, `stageAs` for queryable staged datasets, and
110
- `saveToFile` for large raw responses.
111
- 3. Use `run-code` to call `providerFetch` or `appAction` in loops, write
112
- intermediate files, normalize records, join identity fields, and aggregate.
130
+ 2. For a broad or absence-sensitive corpus, start with the provider's native
131
+ search or indexed tracker surface when one exists. Otherwise use
132
+ `provider-api-request` as the raw ingestion step with `stageAs` or
133
+ `saveToFile`, then reduce the staged data with `query-staged-dataset` or a
134
+ Data Program. Use `provider-corpus-job` for durable paginated or batched
135
+ transcript/body scans so each page or batch is checkpointed durably.
136
+ 3. Use `run-code` to read staged data, write intermediate files, normalize
137
+ records, join identity fields, and aggregate. For long code, use
138
+ `background: true` and persist progress after each chunk.
113
139
  4. Validate coverage before synthesis. Track pages fetched, records inspected,
114
140
  truncation flags, aborted calls, and records skipped for missing joins.
115
141
  5. Finalize with the answer plus coverage and caveats. If coverage is partial,
@@ -111,6 +111,13 @@ When the user asks for a dashboard:
111
111
  6. Persist with `update-dashboard`, not raw SQL or settings writes.
112
112
  7. Navigate to it with `pnpm action navigate --view=adhoc --dashboardId=<id>`.
113
113
 
114
+ An explicit dashboard request authorizes the complete non-destructive build in
115
+ the same turn. After querying or scaffolding, continue through extension-data
116
+ seeding/refresh, dashboard save/embed, and navigation; do not ask whether to
117
+ proceed or leave an empty Custom Block shell. Ask only when metric scope/grain
118
+ is materially ambiguous, the change is destructive, or it has an external side
119
+ effect such as sending email or outreach.
120
+
114
121
  Layout is always **1 column when the available content width is below the `md` threshold** (panels stack), then expands to the configured column count at/above it. The grid uses a container query, so it also stacks when the agent sidebar narrows the content pane — not only at narrow viewports. So picking 3 or 4 columns is fine — the renderer keeps narrow layouts readable automatically.
115
122
 
116
123
  ```bash
@@ -24,9 +24,18 @@ dive that asks what happened in customer conversations.
24
24
  - `account-deep-dive` — first choice for named account/deal deep dives that
25
25
  need HubSpot plus Gong. It searches by account/deal/company/contact domain,
26
26
  loads Gong call details, and returns compact transcript excerpts for synthesis.
27
- - `gong-calls` — list recent calls, search by company/domain/person/email, fetch
28
- a single transcript by call ID, or return transcript excerpts for matching
29
- calls.
27
+ - `gong-calls` — bounded convenience reads: list recent calls, search by
28
+ company/domain/person/email, fetch a single transcript by call ID, or return
29
+ transcript excerpts for a small matching cohort. Its `transcriptQuery` is a
30
+ local scan after batched transcript retrieval, not Gong's server-side
31
+ keyword search.
32
+
33
+ For broad or absence-sensitive Gong work, prefer the raw provider API surface:
34
+ use `provider-api-catalog` / `provider-api-docs`, then stage `/calls/extensive`
35
+ or another raw endpoint with `provider-api-request`. Reduce staged tracker or
36
+ call data with `query-staged-dataset` or a Data Program. Use
37
+ `provider-corpus-job` only when raw transcript bodies are required and no
38
+ native/indexed search can answer the question.
30
39
 
31
40
  ## Route Synthesis and Evidence Separately
32
41
 
@@ -97,10 +106,12 @@ For account or deal deep dives:
97
106
  quoting, debugging, or export.
98
107
  6. Ground qualitative findings in the transcript excerpts and state how many
99
108
  calls were inspected.
100
- 7. Page through calls using `cursor`/offset when you need broad coverage — for
101
- large accounts with many calls, do NOT stop at the first page. For very large
102
- pulls (100+ calls), prefer chunked background processing rather than a single
103
- blocking fetch.
109
+ 7. Page through calls using `cursor`/offset when you need bounded account
110
+ coverage do NOT stop at the first page. For broad scans, do not use
111
+ `gong-calls(exhaustive=true)` or one blocking `provider-api-request` call as
112
+ the analysis. Stage the raw response and reduce it with a Data Program or
113
+ `query-staged-dataset`; use `provider-corpus-job` for checkpointed transcript
114
+ batches when raw bodies are necessary.
104
115
 
105
116
  Example:
106
117
 
@@ -113,6 +124,9 @@ emails, and domains through `/calls/extensive`. Treat call details and transcrip
113
124
  excerpts as evidence; treat missing coverage as a gap, not proof that the topic
114
125
  never came up.
115
126
 
127
+ Title/party matching is discovery only. Never use a title pre-filter as proof
128
+ that a phrase is absent from transcripts.
129
+
116
130
  If transcript loading fails for a call, report that gap instead of inferring the
117
131
  conversation content from title, date, or participants.
118
132
 
@@ -127,28 +141,46 @@ this cohort mention X?" — where missing a single call makes the answer wrong
127
141
  NOT conclude absence from a sampled `includeTranscripts` result. Choose the
128
142
  smallest complete path for the bounded cohort:
129
143
 
130
- 1. **Named account, up to 50 calls, qualitative review.** Make one `gong-calls`
144
+ 1. **Configured keyword tracker.** If the requested term is already a Gong
145
+ keyword tracker exposed in API results, use `provider-api-request` against
146
+ `/calls/extensive` with `contentSelector.exposedFields.content.trackers`.
147
+ Stage the paginated calls, then flatten and filter tracker ids, names, or
148
+ phrases with `query-staged-dataset` or a Data Program. This is the preferred
149
+ broad keyword path because Gong has already indexed the tracker. It does not
150
+ answer arbitrary terms that are not configured as trackers.
151
+
152
+ 2. **Named account, up to 50 calls, qualitative review.** Make one `gong-calls`
131
153
  call with `exhaustive=true`, a bounded `after`/`before` window, and
132
154
  `includeTranscripts=true`. The action discovers every matching call and
133
155
  fetches transcript excerpts in batches, returning `transcriptCoverage`. Do
134
156
  not fetch the same call IDs one at a time afterward.
135
157
 
136
- 2. **Bounded mention/absence search, up to 200 calls.** Make one `gong-calls`
158
+ 3. **Bounded arbitrary mention/absence search, up to 200 calls.** Make one
159
+ `gong-calls`
137
160
  call with `exhaustive=true`, the date window, `transcriptQuery`, and an
138
- adequate `transcriptScanLimit`. Report its coverage fields and only make an
139
- absence claim when coverage is complete.
161
+ adequate `transcriptScanLimit`. This is a bounded local scan after batched
162
+ transcript retrieval. Report its coverage fields and only make an absence
163
+ claim when coverage is complete.
140
164
 
141
- 3. **Larger or multi-account corpus.** Prefer `provider-corpus-job` with
142
- `mode: "batch-search"` over one-call-at-a-time loops. Use
165
+ 4. **Larger or multi-account arbitrary corpus.** Use
143
166
  `provider-api-catalog(provider: "gong")` and its `corpusRecipes` if you need
144
- the exact shape. The canonical request is `POST /calls/transcript` with
167
+ the exact shape. Stage call ids with the raw API, then use
168
+ `provider-corpus-job` with `mode: "batch-search"` and 20-call transcript
169
+ batches. The canonical request is `POST /calls/transcript` with
145
170
  `batch.itemBodyPath: "filter.callIds"`, `batch.responseItemsPath:
146
171
  "callTranscripts"`, `batch.batchSize: 20`, `search.textPaths:
147
172
  ["transcript"]`, and `search.idPaths: ["callId"]`. Feed the staged/discovered
148
- call IDs through `batch.inputDatasetId` + `batch.inputValuePath` or through
149
- `batch.items`.
173
+ call ids through `batch.inputDatasetId` + `batch.inputValuePath` or through
174
+ `batch.items`. This is a durable full scan, not a server-side keyword query;
175
+ do not implement it as a per-call loop in `run-code` or a delegated agent.
176
+
177
+ When delegating a corpus chunk to an Agent Teams sub-agent, include the exact
178
+ staged dataset id or `scratch/...` path and the output/checkpoint path in the
179
+ task brief. The child starts with a clean context and must read the staged
180
+ input before making any provider request. If that input is unavailable, it
181
+ must report the missing input rather than re-fetching the entire Gong corpus.
150
182
 
151
- 4. **Use `run-code` only for joins/reductions around the corpus path.** After
183
+ 5. **Use `run-code` only for joins/reductions around the corpus path.** After
152
184
  the transcript job exists, use `run-code`, `query-staged-dataset`, or job
153
185
  results to join hits back to deals/accounts, compute variants, dedupe, and
154
186
  format evidence. A `run-code` loop over `gong-calls(transcript: id)` is a
@@ -166,5 +198,6 @@ matches found. Never turn "I inspected a sample" into "no call mentions X".
166
198
  | `transcriptMaxChars` | 8 000 | 100 000 |
167
199
 
168
200
  For large account deep-dives or competitive analyses spanning many calls, use
169
- `limit: 50-200` and `transcriptLimit: 20-50`. For very large datasets, the
170
- `provider-api-request` escape hatch can page through the full Gong call list.
201
+ `limit: 50-200` and `transcriptLimit: 20-50`. For very large datasets, use the
202
+ checkpointed `provider-corpus-job` path rather than paging the full Gong call
203
+ list inside one agent action.
@@ -54,6 +54,24 @@ It is not required for hosted Agent Native provider access. Do not install or
54
54
  vendor that plugin by default; its public repository currently declares no
55
55
  license.
56
56
 
57
+ ## Gong
58
+
59
+ Gong's UI has indexed Words or phrases search, but the public REST endpoints
60
+ used here do not expose an arbitrary transcript-text filter. The efficient API
61
+ path is a configured keyword tracker: request `content.trackers` from
62
+ `POST /calls/extensive`, stage the paginated calls, and flatten/filter tracker
63
+ hits with `query-staged-dataset` or a Data Program. This only works for terms
64
+ already configured as trackers and exposed in API results.
65
+
66
+ For an arbitrary term, use Gong native Search when that connected surface is
67
+ available. If raw transcript evidence is required, stage call IDs with the raw
68
+ API and use `provider-corpus-job`'s 20-call transcript batches. Do not loop over
69
+ `gong-calls(transcript: id)` from `run-code` or a delegated agent. A corpus job
70
+ improves durability and checkpointing, but it still scans transcript bodies and
71
+ should be described as an expensive fallback. For recurring tracker-based
72
+ reports, save the staged fetch and reduction as a Data Program instead of
73
+ creating a new provider-specific action.
74
+
57
75
  ## Workflow
58
76
 
59
77
  1. Use a first-class action when it exactly fits the request.
@@ -61,7 +79,9 @@ license.
61
79
  shape, or pagination mode, switch to `provider-api-catalog` for that
62
80
  provider. Check `corpusRecipes` first when the user asks for broad body-text
63
81
  searches across transcripts, messages, tickets, issues, notes, documents, or
64
- conversation logs.
82
+ conversation logs. For Gong, use the configured keyword-tracker recipe when
83
+ it covers the requested term; otherwise use the raw transcript recipe only
84
+ when the provider's native search surface is unavailable or insufficient.
65
85
  3. If the endpoint or payload is not obvious, use `provider-api-docs` to fetch
66
86
  the official docs/spec URL from the catalog.
67
87
  4. Call `provider-api-request` with the exact provider method, path, query, and
@@ -72,8 +92,10 @@ license.
72
92
  charge history), **add `stageAs`** to avoid context-window truncation.
73
93
  - For multi-page results, **also add `pagination`** config to fetch all pages
74
94
  server-side in one call (cursor / page / offset modes supported).
75
- 5. After staging, call `query-staged-dataset` to aggregate. Only the compact
76
- summary (counts, sums, sample rows) needs to flow into the context window.
95
+ 5. After staging, call `query-staged-dataset` to aggregate, or save a Data
96
+ Program when the provider pull should become a cached, refreshable source.
97
+ Only the compact summary (counts, sums, sample rows) needs to flow into the
98
+ context window. Treat the raw request as ingestion, not the final analysis.
77
99
  6. For source-record body searches, use the raw body endpoint or native search
78
100
  endpoint for that record type. Parent/container metadata such as call lists,
79
101
  channel lists, ticket titles, summaries, or briefs is discovery evidence, not
@@ -7,7 +7,7 @@ artifact; legacy analyses remain readable only for compatibility.
7
7
  **This agent is Claude with BigQuery/Gong/HubSpot/Prometheus access.** Reason
8
8
  over fetched data here; do not suggest another AI tool.
9
9
 
10
- Prompt cap: ~6,000 characters; put detail in `.agents/skills/*`.
10
+ Prompt cap: 6,000; put detail in `.agents/skills/*`.
11
11
 
12
12
  Before building common workspace or agent UI, read `agent-native-toolkit`; use
13
13
  `customizing-agent-native` for the configure → compose → eject → propose
@@ -37,9 +37,6 @@ ladder.
37
37
  threads). Chunking a question a query could answer is the most expensive
38
38
  mistake available here. See `adhoc-analysis`.
39
39
 
40
- Use `ask-question` at most once when an ambiguous metric, range, or grain would
41
- change the numbers.
42
-
43
40
  ## Core Rules
44
41
 
45
42
  - A sibling app asking over A2A sends a question or shaped input, never SQL. It
@@ -55,9 +52,11 @@ change the numbers.
55
52
  filters, row count/sample size, join method, caveats.
56
53
  - Use actions for sources, queries, charts, dashboards, and sharing. Don't bypass
57
54
  access checks with raw SQL for ownable resources.
58
- - Provider actions are shortcuts, not limits escalate to
59
- `provider-api-catalog` / `provider-api-docs` / `provider-api-request` when a
60
- canned action is too narrow. See `provider-api`.
55
+ - Provider actions are bounded shortcuts, not limits. For broad or
56
+ absence-sensitive Gong work, stage raw API data and use
57
+ `query-staged-dataset` or a Data Program; if raw transcript bodies are
58
+ required, use `provider-corpus-job`. See `provider-api`, `data-programs`, and
59
+ `gong`.
61
60
  - Create dashboards, panels, or saved artifacts only when explicitly asked;
62
61
  suggest and wait otherwise. Scope them to the question, avoid decorative
63
62
  metrics, and never modify existing dashboards without a directive.
@@ -485,7 +485,7 @@ export default defineAction({
485
485
  // model round trips while still staying well below the model context limit.
486
486
  maxResultChars: 100_000,
487
487
  description:
488
- "Query Gong sales calls, transcripts, and users. Pass --users for user list, --transcript for one transcript, --company to search by company/domain/person/email. For bounded account-level transcript mention/search questions, set transcriptQuery to search matching transcripts server-side and return coverage counts plus snippets instead of large transcript blobs. For deal, customer, objection, next-step, or deep-dive analysis, set includeTranscripts=true only when you need broad qualitative context rather than a specific term search. For an 'all calls' transcript review in a bounded account/date window, use exhaustive=true with after/before and includeTranscripts=true; the action batches transcript retrieval and reports complete/partial coverage instead of forcing one tool call per transcript. For very broad cohorts or defensible absence searches, use provider-api-catalog(provider='gong') and provider-corpus-job mode='batch-search' against /calls/transcript after call-id discovery.",
488
+ "Query bounded Gong sales-call evidence. Pass --users for the user list, --transcript for one transcript, or --company for a bounded search by company/domain/person/email. For account-level transcript mention questions, transcriptQuery performs a case-insensitive local scan after batched transcript retrieval and returns coverage counts plus snippets; it is not Gong's server-side keyword search. Use includeTranscripts=true for bounded qualitative context. For broad keyword, tracker, cross-account, or absence-sensitive work, use provider-api-catalog/provider-api-docs, stage the raw Gong API response, then use query-staged-dataset or a Data Program; use provider-corpus-job only when raw transcript bodies are required.",
489
489
  schema: z.object({
490
490
  users: cliBoolean.optional().describe("Set to true to list Gong users"),
491
491
  transcript: z.string().optional().describe("Call ID to get transcript"),
@@ -538,7 +538,7 @@ export default defineAction({
538
538
  .string()
539
539
  .optional()
540
540
  .describe(
541
- "Case-insensitive phrase to search inside matching call transcripts. Use this for bounded account/call searches where the matching set is already small. For broad cohort or exhaustive absence research, stage Gong calls/transcripts through provider-api-request and run-code instead. Returns coverage counts and short snippets only, not full transcripts.",
541
+ "Case-insensitive phrase to search inside matching call transcripts after batched retrieval. Use only for bounded account/call searches where the matching set is already small. For broad cohort or exhaustive absence research, use the raw Gong API tracker/staging path plus query-staged-dataset or a Data Program, or provider-corpus-job when raw transcript bodies are required. Returns coverage counts and short snippets only, not full transcripts.",
542
542
  ),
543
543
  transcriptScanLimit: z.coerce
544
544
  .number()
@@ -552,7 +552,7 @@ export default defineAction({
552
552
  exhaustive: cliBoolean
553
553
  .optional()
554
554
  .describe(
555
- "Return EVERY matching call in the window instead of stopping at `limit` — use this for complete cohort/account coverage when 'how many' or absence matters. By default this is metadata-only. With includeTranscripts=true, transcripts are fetched in batches up to transcriptLimit (all matched calls by default when there are 50 or fewer) and explicit coverage is returned. Always bound it with after/before or a small days window: an unbounded exhaustive scan pages the whole Gong org and can hit the function timeout.",
555
+ "Return EVERY matching call in the window instead of stopping at `limit` — use this only for bounded account/cohort coverage. By default this is metadata-only. With includeTranscripts=true, transcripts are fetched in batches and explicit coverage is returned. For broad or absence-sensitive work, prefer the raw Gong API tracker/staging path plus query-staged-dataset or a Data Program; use provider-corpus-job for durable raw-transcript scans. Always bound this with after/before or a small days window.",
556
556
  ),
557
557
  after: z
558
558
  .string()
@@ -20,6 +20,6 @@ export default createProviderApiCatalogAction(
20
20
  }),
21
21
  http: { method: "GET" },
22
22
  guidance:
23
- "First-class provider actions in this app are convenience shortcuts, not capability limits. When an action cannot express the needed endpoint, object type, filter, request body, pagination mode, API version, or source-record body coverage, inspect docs/spec URLs and corpusRecipes here, then call provider-api-request or provider-corpus-job with the exact provider API method/path/query/body.",
23
+ "First-class provider actions in this app are bounded convenience shortcuts, not capability limits. When an action cannot express the needed endpoint, object type, filter, request body, pagination mode, API version, or source-record body coverage, inspect docs/spec URLs and corpusRecipes here. Use provider-api-request as the raw ingestion/staging step, then query-staged-dataset or save-data-program for broad searches, joins, and reusable aggregates; use provider-corpus-job for durable paginated or batched body scans.",
24
24
  },
25
25
  );
@@ -15,7 +15,7 @@ function resolveScope() {
15
15
 
16
16
  export default defineAction({
17
17
  description:
18
- "Query the built-in first-party Analytics source: events recorded through this app's analytics collector endpoint (/track) and session replay summaries recorded through /api/analytics/replay. This source does not require an external provider connection. Use it for questions about app/site traffic, product events, template/app usage, conversions, session recordings, LLM/agent observability, model cost, token volume, latency, and other first-party data collected by this analytics app. Use source-specific actions such as BigQuery, GA4, Mixpanel, PostHog, or Amplitude when the user asks for those sources or the relevant data lives there. SQL may read analytics_events and session_recordings only; session_replay_chunks is intentionally unavailable, and reads are automatically scoped to the current user/org. analytics_events columns include event_name, timestamp, event_date, user_id, anonymous_id, user_key, session_id, app, template, signed_in, url, path, hostname, referrer, properties, and context. LLM observability events use event_name = '$ai_generation'; useful properties include $ai_trace_id/run_id, $ai_session_id/thread_id, $ai_model/model, $ai_provider/provider, $ai_input_tokens/input_tokens, $ai_output_tokens/output_tokens, cache_read_tokens, cache_write_tokens, cost_cents_x100, $ai_total_cost_usd/cost_usd, duration_ms/$ai_latency, status, tool_calls, successful_tools, failed_tools, tools, tools_truncated, delegated, delegation_protocol, caller_app, a2a_task_id, parent_run_id, parent_turn_id, and error_message/$ai_error. The bounded tools array contains names, relative start times, durations, statuses, and coarse error classes only, never args or results; failed runs and interrupted tools remain queryable. session_recordings columns include id, session_id, user_id, anonymous_id, user_key, started_at, ended_at, duration_ms, chunk_count, event_count, page_count, error_count, rage_click_count, app, template, status, first_url, last_url, path, hostname, referrer, and metadata.",
18
+ "Query the built-in first-party Analytics source: events recorded through this app's analytics collector endpoint (/track) and session replay summaries recorded through /api/analytics/replay. This source does not require an external provider connection. Use it for questions about app/site traffic, product events, template/app usage, conversions, session recordings, LLM/agent observability, model cost, token volume, latency, and other first-party data collected by this analytics app. Use source-specific actions such as BigQuery, GA4, Mixpanel, PostHog, or Amplitude when the user asks for those sources or the relevant data lives there. SQL may read analytics_events and session_recordings only; session_replay_chunks is intentionally unavailable, and reads are automatically scoped to the current user/org. analytics_events columns include event_name, timestamp, event_date, user_id, anonymous_id, user_key, session_id, app, template, signed_in, url, path, hostname, referrer, properties, and context. LLM observability events use event_name = '$ai_generation'; useful properties include $ai_trace_id/run_id, $ai_session_id/thread_id, $ai_model/model, $ai_provider/provider, $ai_input_tokens/input_tokens, $ai_output_tokens/output_tokens, cache_read_tokens, cache_write_tokens, cost_cents_x100, $ai_total_cost_usd/cost_usd, duration_ms/$ai_latency, status, tool_calls, successful_tools, failed_tools, tools, tools_truncated, delegated, delegation_protocol, caller_app, delegation_task_id, a2a_task_id, parent_run_id, parent_turn_id, and error_message/$ai_error. Agent Teams child runs use delegation_protocol = 'agent-team' and retain their own run_id while linking to the launching run through parent_run_id. The bounded tools array contains names, relative start times, durations, statuses, and coarse error classes only, never args or results; failed runs and interrupted tools remain queryable. session_recordings columns include id, session_id, user_id, anonymous_id, user_key, started_at, ended_at, duration_ms, chunk_count, event_count, page_count, error_count, rage_click_count, app, template, status, first_url, last_url, path, hostname, referrer, and metadata.",
19
19
  schema: z.object({
20
20
  sql: z
21
21
  .string()
@@ -194,6 +194,10 @@ const enUS = {
194
194
  openDashboardTemplates: "Open catalog",
195
195
  languageTitle: "Language",
196
196
  languageLabel: "Interface language",
197
+ errorEmailNotifications: "Email new error alerts",
198
+ errorEmailNotificationsDescription:
199
+ "Send an email when a new JavaScript error is captured. Off by default.",
200
+ errorEmailNotificationsSaveFailed: "Couldn't save the email preference.",
197
201
  about: "About",
198
202
  aboutDescription:
199
203
  "Analytics is a tool for connecting data sources and building custom dashboards. Connect Google Analytics, BigQuery, Stripe, and more, then ask the agent to create dashboards.",
@@ -4253,6 +4257,10 @@ export const messagesByLocale = {
4253
4257
  openDashboardTemplates: "打开目录",
4254
4258
  languageTitle: "语言",
4255
4259
  languageLabel: "界面语言",
4260
+ errorEmailNotifications: "通过电子邮件接收新的错误提醒",
4261
+ errorEmailNotificationsDescription:
4262
+ "捕获新的 JavaScript 错误时发送电子邮件。默认关闭。",
4263
+ errorEmailNotificationsSaveFailed: "无法保存电子邮件偏好设置。",
4256
4264
  about: "关于",
4257
4265
  aboutDescription:
4258
4266
  "Analytics 用于连接数据源并构建自定义仪表板。连接 Google Analytics、BigQuery、Stripe 等,然后让代理创建仪表板。",
@@ -4471,6 +4479,11 @@ export const messagesByLocale = {
4471
4479
  openDashboardTemplates: "Abrir catálogo",
4472
4480
  languageTitle: "Idioma",
4473
4481
  languageLabel: "Idioma de la interfaz",
4482
+ errorEmailNotifications: "Recibir nuevas alertas de errores por email",
4483
+ errorEmailNotificationsDescription:
4484
+ "Envía un email cuando se capture un nuevo error de JavaScript. Desactivado de forma predeterminada.",
4485
+ errorEmailNotificationsSaveFailed:
4486
+ "No se pudo guardar la preferencia de email.",
4474
4487
  about: "Acerca de",
4475
4488
  aboutDescription:
4476
4489
  "Analytics conecta fuentes de datos y crea paneles personalizados. Conecta Google Analytics, BigQuery, Stripe y más, y pide al agente que cree paneles.",
@@ -4693,6 +4706,12 @@ export const messagesByLocale = {
4693
4706
  openDashboardTemplates: "Ouvrir le catalogue",
4694
4707
  languageTitle: "Langue",
4695
4708
  languageLabel: "Langue de l'interface",
4709
+ errorEmailNotifications:
4710
+ "Recevoir les nouvelles alertes d’erreur par e-mail",
4711
+ errorEmailNotificationsDescription:
4712
+ "Envoyer un e-mail lorsqu’une nouvelle erreur JavaScript est capturée. Désactivé par défaut.",
4713
+ errorEmailNotificationsSaveFailed:
4714
+ "Impossible d’enregistrer la préférence e-mail.",
4696
4715
  about: "À propos",
4697
4716
  aboutDescription:
4698
4717
  "Analytics connecte des sources de données et crée des tableaux de bord personnalisés. Connectez Google Analytics, BigQuery, Stripe et plus encore, puis demandez à l'agent de créer des tableaux de bord.",
@@ -4922,6 +4941,11 @@ export const messagesByLocale = {
4922
4941
  openDashboardTemplates: "Katalog öffnen",
4923
4942
  languageTitle: "Sprache",
4924
4943
  languageLabel: "Oberflächensprache",
4944
+ errorEmailNotifications: "Neue Fehlerwarnungen per E-Mail erhalten",
4945
+ errorEmailNotificationsDescription:
4946
+ "Eine E-Mail senden, wenn ein neuer JavaScript-Fehler erfasst wird. Standardmäßig deaktiviert.",
4947
+ errorEmailNotificationsSaveFailed:
4948
+ "Die E-Mail-Einstellung konnte nicht gespeichert werden.",
4925
4949
  about: "Info",
4926
4950
  aboutDescription:
4927
4951
  "Analytics verbindet Datenquellen und erstellt benutzerdefinierte Dashboards. Verbinde Google Analytics, BigQuery, Stripe und mehr und bitte den Agenten, Dashboards zu erstellen.",
@@ -5142,6 +5166,10 @@ export const messagesByLocale = {
5142
5166
  openDashboardTemplates: "カタログを開く",
5143
5167
  languageTitle: "言語",
5144
5168
  languageLabel: "インターフェース言語",
5169
+ errorEmailNotifications: "新しいエラーアラートをメールで受け取る",
5170
+ errorEmailNotificationsDescription:
5171
+ "新しい JavaScript エラーが記録されたときにメールを送信します。デフォルトではオフです。",
5172
+ errorEmailNotificationsSaveFailed: "メール設定を保存できませんでした。",
5145
5173
  about: "概要",
5146
5174
  aboutDescription:
5147
5175
  "Analytics はデータソースを接続し、カスタムダッシュボードを作成するツールです。Google Analytics、BigQuery、Stripe などを接続し、エージェントにダッシュボード作成を依頼できます。",
@@ -5361,6 +5389,10 @@ export const messagesByLocale = {
5361
5389
  openDashboardTemplates: "카탈로그 열기",
5362
5390
  languageTitle: "언어",
5363
5391
  languageLabel: "인터페이스 언어",
5392
+ errorEmailNotifications: "새 오류 알림을 이메일로 받기",
5393
+ errorEmailNotificationsDescription:
5394
+ "새 JavaScript 오류가 캡처되면 이메일을 보냅니다. 기본값은 꺼져 있습니다.",
5395
+ errorEmailNotificationsSaveFailed: "이메일 설정을 저장하지 못했습니다.",
5364
5396
  about: "정보",
5365
5397
  aboutDescription:
5366
5398
  "Analytics는 데이터 소스를 연결하고 사용자 지정 대시보드를 만드는 도구입니다. Google Analytics, BigQuery, Stripe 등을 연결한 뒤 에이전트에게 대시보드를 만들게 하세요.",
@@ -5584,6 +5616,11 @@ export const messagesByLocale = {
5584
5616
  openDashboardTemplates: "Abrir catálogo",
5585
5617
  languageTitle: "Idioma",
5586
5618
  languageLabel: "Idioma da interface",
5619
+ errorEmailNotifications: "Receber novos alertas de erro por e-mail",
5620
+ errorEmailNotificationsDescription:
5621
+ "Envie um e-mail quando um novo erro de JavaScript for capturado. Desativado por padrão.",
5622
+ errorEmailNotificationsSaveFailed:
5623
+ "Não foi possível salvar a preferência de e-mail.",
5587
5624
  about: "Sobre",
5588
5625
  aboutDescription:
5589
5626
  "Analytics conecta fontes de dados e cria dashboards personalizados. Conecte Google Analytics, BigQuery, Stripe e outros, depois peça ao agente para criar dashboards.",
@@ -5802,6 +5839,10 @@ export const messagesByLocale = {
5802
5839
  openDashboardTemplates: "कैटलॉग खोलें",
5803
5840
  languageTitle: "भाषा",
5804
5841
  languageLabel: "इंटरफ़ेस भाषा",
5842
+ errorEmailNotifications: "नए त्रुटि अलर्ट ईमेल से प्राप्त करें",
5843
+ errorEmailNotificationsDescription:
5844
+ "नया JavaScript त्रुटि कैप्चर होने पर ईमेल भेजें। डिफ़ॉल्ट रूप से बंद।",
5845
+ errorEmailNotificationsSaveFailed: "ईमेल प्राथमिकता सहेजी नहीं जा सकी।",
5805
5846
  about: "परिचय",
5806
5847
  aboutDescription:
5807
5848
  "Analytics डेटा स्रोतों को जोड़ने और कस्टम डैशबोर्ड बनाने का टूल है। Google Analytics, BigQuery, Stripe आदि जोड़ें, फिर एजेंट से डैशबोर्ड बनवाएं।",
@@ -6019,6 +6060,11 @@ export const messagesByLocale = {
6019
6060
  openDashboardTemplates: "افتح الكتالوج",
6020
6061
  languageTitle: "اللغة",
6021
6062
  languageLabel: "لغة الواجهة",
6063
+ errorEmailNotifications:
6064
+ "تلقي تنبيهات الأخطاء الجديدة عبر البريد الإلكتروني",
6065
+ errorEmailNotificationsDescription:
6066
+ "إرسال بريد إلكتروني عند التقاط خطأ JavaScript جديد. معطّل افتراضيًا.",
6067
+ errorEmailNotificationsSaveFailed: "تعذّر حفظ تفضيل البريد الإلكتروني.",
6022
6068
  about: "حول",
6023
6069
  aboutDescription:
6024
6070
  "Analytics أداة لربط مصادر البيانات وبناء لوحات معلومات مخصصة. اربط Google Analytics وBigQuery وStripe وغيرها، ثم اطلب من الوكيل إنشاء اللوحات.",
@@ -1,4 +1,8 @@
1
1
  import { ChangelogSettingsCard } from "@agent-native/core/client/changelog";
2
+ import {
3
+ useActionMutation,
4
+ useActionQuery,
5
+ } from "@agent-native/core/client/hooks";
2
6
  import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
3
7
  import { TeamPage } from "@agent-native/core/client/org";
4
8
  import {
@@ -10,8 +14,9 @@ import {
10
14
  type SettingsTabItem,
11
15
  } from "@agent-native/core/client/settings";
12
16
  import { IconBell } from "@tabler/icons-react";
13
- import { useMemo } from "react";
17
+ import { useEffect, useMemo, useState } from "react";
14
18
  import { Link } from "react-router";
19
+ import { toast } from "sonner";
15
20
 
16
21
  import { Button } from "@/components/ui/button";
17
22
  import {
@@ -22,8 +27,13 @@ import {
22
27
  CardTitle,
23
28
  } from "@/components/ui/card";
24
29
  import { Label } from "@/components/ui/label";
30
+ import { Switch } from "@/components/ui/switch";
25
31
 
26
32
  import changelog from "../../CHANGELOG.md?raw";
33
+ import {
34
+ ANALYTICS_USER_PREFS_KEY,
35
+ type AnalyticsUserPrefs,
36
+ } from "../../shared/analytics-user-prefs";
27
37
  import { useReplayStorageStatus } from "../hooks/use-replay-storage-status";
28
38
  import { ReplayStorageHint } from "./sessions/SessionsPage";
29
39
  import { AlertRulesSettingsCard } from "./settings/AlertRulesSettingsCard";
@@ -33,6 +43,47 @@ export default function Settings() {
33
43
  const t = useT();
34
44
  const agentSettingsTabs = useAgentSettingsTabs();
35
45
  const replayStorageStatus = useReplayStorageStatus();
46
+ const { data: analyticsPrefs, isLoading: analyticsPrefsLoading } =
47
+ useActionQuery<AnalyticsUserPrefs>("get-user-pref", {
48
+ key: ANALYTICS_USER_PREFS_KEY,
49
+ });
50
+ const saveAnalyticsPrefs = useActionMutation<
51
+ { success: boolean },
52
+ { key: string; value: Record<string, unknown> }
53
+ >("set-user-pref");
54
+ const [errorEmailEnabledOverride, setErrorEmailEnabledOverride] = useState<
55
+ boolean | null
56
+ >(null);
57
+
58
+ useEffect(() => {
59
+ if (analyticsPrefs) {
60
+ setErrorEmailEnabledOverride(
61
+ analyticsPrefs.errorEmailNotifications === true,
62
+ );
63
+ }
64
+ }, [analyticsPrefs]);
65
+
66
+ const errorEmailEnabled =
67
+ errorEmailEnabledOverride ??
68
+ analyticsPrefs?.errorEmailNotifications === true;
69
+
70
+ const saveErrorEmailPreference = (enabled: boolean) => {
71
+ const previous = errorEmailEnabled;
72
+ setErrorEmailEnabledOverride(enabled);
73
+ void saveAnalyticsPrefs
74
+ .mutateAsync({
75
+ key: ANALYTICS_USER_PREFS_KEY,
76
+ value: { errorEmailNotifications: enabled },
77
+ })
78
+ .catch((error) => {
79
+ setErrorEmailEnabledOverride(previous);
80
+ toast.error(
81
+ error instanceof Error
82
+ ? error.message
83
+ : t("settings.errorEmailNotificationsSaveFailed"),
84
+ );
85
+ });
86
+ };
36
87
 
37
88
  const extraTabs = useMemo<SettingsTabItem[]>(
38
89
  () => [
@@ -104,6 +155,21 @@ export default function Settings() {
104
155
  </div>
105
156
  }
106
157
  />
158
+ <SettingsRow
159
+ id="error-email-notifications"
160
+ label={t("settings.errorEmailNotifications")}
161
+ description={t("settings.errorEmailNotificationsDescription")}
162
+ control={
163
+ <Switch
164
+ aria-label={t("settings.errorEmailNotifications")}
165
+ checked={errorEmailEnabled}
166
+ disabled={
167
+ analyticsPrefsLoading || saveAnalyticsPrefs.isPending
168
+ }
169
+ onCheckedChange={saveErrorEmailPreference}
170
+ />
171
+ }
172
+ />
107
173
  </SettingsGroup>
108
174
 
109
175
  {replayStorageStatus.data?.configured ? (
@@ -51,6 +51,12 @@ export function buildAnalyticsGeneralSettingsSearchEntries(
51
51
  keywords: "language locale translation i18n",
52
52
  hash: "language",
53
53
  },
54
+ {
55
+ id: "analytics-error-email-notifications",
56
+ label: t("settings.errorEmailNotifications"),
57
+ keywords: "email notifications errors alerts javascript monitoring",
58
+ hash: "error-email-notifications",
59
+ },
54
60
  {
55
61
  id: "analytics-about",
56
62
  label: t("settings.about"),
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-03
4
+ ---
5
+
6
+ Dashboard requests now continue through data setup, saving, embedding, and navigation without stopping for an extra confirmation.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: changed
3
+ date: 2026-08-03
4
+ ---
5
+
6
+ New error alert emails are now off by default and can be enabled in Settings.
@@ -13,20 +13,21 @@ export const INITIAL_TOOL_NAMES = [
13
13
  "list-session-recordings",
14
14
  "list-analyses",
15
15
  "get-analysis",
16
- // Dashboard/extension INSPECTION stays on the initial surface so a
17
- // template-clone request can resolve and inspect the source on the first
18
- // turn. The MUTATING writers (update-dashboard, mutate-dashboard,
19
- // create-extension, update-extension) are intentionally left off: the
20
- // dashboard-construction final-response guard retries with
21
- // `expandToolSurface: true` (see server/plugins/agent-chat.ts), which opens
22
- // the full run registry exactly when a save is needed, and tool-search can
23
- // surface them otherwise. This keeps the first-request surface under the
24
- // 40-tool ceiling enforced by scripts/guard-agent-chat-context.ts.
16
+ // Keep the complete dashboard build path on the initial surface. An explicit
17
+ // build request should not stop at inspection or an empty extension shell
18
+ // while the agent lazily discovers the next mutating action.
25
19
  "get-sql-dashboard",
26
20
  "list-sql-dashboards",
27
21
  "list-dashboard-templates",
28
22
  "list-extensions",
29
23
  "get-extension",
24
+ "update-dashboard",
25
+ "mutate-dashboard",
26
+ "compose-dashboard",
27
+ "install-dashboard-template",
28
+ "create-extension",
29
+ "update-extension",
30
+ "extension-data-set",
30
31
  "generate-chart",
31
32
  "search-analytics-query-catalog",
32
33
  "query-agent-native-analytics",