@lightdash/cli 2.243.5 → 2.245.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.
@@ -21,6 +21,7 @@ Users describe features by what they see in the Lightdash editor. Translate:
21
21
  | thumbnails / screenshots / scheduled deliveries | `screenshot` | required — see below |
22
22
  | drill down, click into a chart | `drill-down` | app code opt-in |
23
23
  | drill into a viz data point (reusable visualization) | `viz-drill-down` | app code opt-in |
24
+ | "ask the AI", one-line takeaway, explain this row | `ai-prompt` | app code opt-in |
24
25
  | "share this view", URL that restores state | `url-state` | app code opt-in |
25
26
  | Google Sheets export | `gsheet-export` | app code opt-in |
26
27
  | "delivery has all tabs", full data in scheduled deliveries | `delivery-render` | app code opt-in |
@@ -122,6 +123,12 @@ order, `sortBy` describes result ordering, `totalColumnCount` exposes truncation
122
123
  points can be marked, with `investigate(id)` / `continueInAskAi(id)` for the
123
124
  action menu. Render a summary block and markers; render nothing when
124
125
  `status === 'unavailable'`. Full contract in `/app/references/ai-analysis.md`.
126
+ - `ai-prompt`: `useAiPrompt()` returns `{ available, ask, loading, text, error }`;
127
+ `ask({ prompt, sources: [{ result, label }], focus?: { row } })` sends an
128
+ author-written question over loaded `useLightdash` results and resolves to
129
+ plain text. `result` is the object `useLightdash` returns (keep a reference
130
+ to it even when destructuring), never a rebuilt `{ data, columns }`. Hide the control when `available` is false; trigger from a user
131
+ action. Full contract in `/app/references/ai-analysis.md`.
125
132
  - `delivery-render`: `useDeliveryRender()` is `true` during scheduled-delivery
126
133
  and delivery-preview capture renders. Gate tab/slide DATA mounting on it so
127
134
  every tab's queries execute during capture while only the active tab stays
@@ -201,9 +201,51 @@ Then render the investigation state wherever the anomaly is shown (a card under
201
201
 
202
202
  Never open a dialog for the investigation yourself; the app renders state, Lightdash owns the run.
203
203
 
204
+ ## Free-form prompts (`useAiPrompt`)
205
+
206
+ `useInsights` is the host's analysis; `useAiPrompt` lets the app ask its own question about results it already loaded. Use it for an author-written takeaway under a chart, a "what stands out in this row" explanation, or a narrative tailored to the app's domain. Answers are short plain text, not Markdown.
207
+
208
+ ```tsx
209
+ import { useAiPrompt, useLightdash } from '@lightdash/query-sdk';
210
+
211
+ function RevenueTakeaway() {
212
+ // Keep the hook result itself: `sources` needs the object useLightdash
213
+ // returns, not a rebuilt { data, columns, ... }.
214
+ const revenue = useLightdash(revenueByMonth);
215
+ const { data, loading } = revenue;
216
+ const ai = useAiPrompt();
217
+
218
+ if (!ai.available || loading) return null;
219
+
220
+ return (
221
+ <div>
222
+ <button
223
+ disabled={ai.loading}
224
+ onClick={() =>
225
+ ai.ask({
226
+ prompt: 'In two sentences, what should a sales lead take away from the last six months of revenue?',
227
+ sources: [{ result: revenue, label: 'Revenue by month' }],
228
+ })
229
+ }
230
+ >
231
+ {ai.loading ? 'Thinking…' : 'Summarise'}
232
+ </button>
233
+ {ai.text && <p>{ai.text}</p>}
234
+ {ai.error && <p role="alert">{ai.error.message}</p>}
235
+ </div>
236
+ );
237
+ }
238
+ ```
239
+
240
+ - `sources` take the object `useLightdash` returns, as `{ result, label? }` (the `label` is the section title the model sees). If the component destructures the hook, keep a reference to the whole result (`const orders = useLightdash(q); const { data, loading } = orders;`) and pass `orders`; a rebuilt `{ data, columns }` object has no query uuid and `ask` throws. Only these rows reach the model; Lightdash reads them from the viewer's own query history, so the app sends no data.
241
+ - `focus: { row }` narrows the question to one row of a source, for example from a clicked data point: `ai.ask({ prompt: 'Why is this month unusual?', sources: [{ result: revenue }], focus: { row } })`.
242
+ - `available` is false outside a Lightdash host or when the organisation has not turned AI on for data apps. Hide the control; do not fall back to another provider.
243
+ - Trigger `ask` from a user action, or at most once per loaded view. Never on a timer, never per row. Prompts are rate limited per viewer.
244
+ - Prompts are capped at 2000 characters; write them as instructions to an analyst, and name the audience and the length you want.
245
+
204
246
  ## What the app must not do
205
247
 
206
- - Do not send prompts, rows or field values anywhere. The hook exposes results; Lightdash already has the data.
248
+ - Do not send rows or field values anywhere. The hooks expose results; Lightdash already has the data.
207
249
  - Do not add an external connection to a model provider for summaries or explanations. Use this hook.
208
250
  - Do not fabricate insights when the status is `idle` or `unavailable`; render the state.
209
251
  - Do not render `explanation` as HTML. It is Markdown; render it as text or through a Markdown component.
@@ -693,7 +693,7 @@ For any external HTTP API call, read `/app/references/external-apis.md` and use
693
693
 
694
694
  ### AI analysis — executive summary and anomalies
695
695
 
696
- When the user asks for an executive summary, "what changed and why", anomaly callouts, or any AI-generated insight about the data on the page, read `/app/references/ai-analysis.md` and use `useInsights` from the SDK. Lightdash runs the analysis over the queries the app already loaded and pushes the result in; the app renders it (a summary block, markers on flagged points, an Investigate action) and never sends prompts, rows or keys. Render nothing when `status === 'unavailable'`.
696
+ When the user asks for an executive summary, "what changed and why", anomaly callouts, or any AI-generated insight about the data on the page, read `/app/references/ai-analysis.md` and use `useInsights` from the SDK. Lightdash runs the analysis over the queries the app already loaded and pushes the result in; the app renders it (a summary block, markers on flagged points, an Investigate action) and never sends rows or keys. Render nothing when `status === 'unavailable'`. For an author-written question over loaded results (a takeaway under a chart, "explain this row"), use `useAiPrompt` from the same reference.
697
697
 
698
698
  ## Visual Design
699
699
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/cli",
3
- "version": "2.243.5",
3
+ "version": "2.245.0",
4
4
  "description": "Lightdash CLI tool",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,8 +22,8 @@
22
22
  "@actions/core": "1.11.1",
23
23
  "@aws-sdk/credential-providers": "3.995.0",
24
24
  "@casl/ability": "6.8.0",
25
- "@lightdash/common": "2.243.5",
26
- "@lightdash/warehouses": "2.243.5",
25
+ "@lightdash/common": "2.245.0",
26
+ "@lightdash/warehouses": "2.245.0",
27
27
  "@sidvind/better-ajv-errors": "7.0.0",
28
28
  "@types/columnify": "1.5.1",
29
29
  "ajv": "8.18.0",