/** * Pro AI feature pack * ------------------- * * Three jobs every analyst wishes a data grid could do: * * 1. Natural-language filter / sort (`aiFilter`) * "show me deals closing this quarter over $50k owned by Sasha" * -> { filters: [...], sort: [...] } * * 2. Smart fill (`aiSmartFill`) * User edits two cells in a column with example values; the * Grid proposes the rest. Excel "Flash Fill" pattern. * * 3. Summarise rows (`aiSummarize`) * Single row, the current selection, a group key, or the whole * filtered view -> a one-paragraph summary. * * The grid stays headless / model-agnostic. The consumer supplies an * `AIProvider` that knows how to call OpenAI / Anthropic / a local * model / a server-side proxy. We never bundle a model client. * * Built-in + free: the AI helpers live in `@svgrid/grid`. They ship no model * client and do nothing until you register a provider with `setAIProvider(...)`, * so they add nothing to the base bundle unless you actually use them. */ import type { RowData, SvGridApi, TableFeatures } from './index'; type ExportFormat = 'xlsx' | 'xls' | 'pdf' | 'csv' | 'tsv' | 'html' | 'json' | 'xml' | 'md'; /** * Shape every consumer-provided model adapter must implement. Keeping this * tiny (one async call, two response formats) lets the same adapter drive * OpenAI's `chat.completions`, Anthropic's `messages`, a self-hosted * llama.cpp endpoint, or a server-side proxy. The grid only cares that the * provider eventually returns a string we can parse. */ export type AIProvider = (request: AIRequest) => Promise; export type AIRequest = { /** Full prompt the grid built for the model. Already includes column * schema and any sampled rows where applicable. */ prompt: string; /** When 'json', the provider should ask the model to return strict * JSON only - no prose. We parse the response with JSON.parse and * throw a typed error on failure. */ responseFormat?: 'text' | 'json'; /** Honored if the underlying transport supports cancellation. */ signal?: AbortSignal; /** Free-form tag for telemetry / logging. One of: 'filter', * 'smart-fill', 'summarize', 'classify'. */ task: AITask; /** Soft hint to the provider about how many tokens we expect back. * Useful for routing small jobs to a cheaper model. */ maxOutputTokens?: number; }; export type AITask = 'filter' | 'smart-fill' | 'summarize' | 'classify' | 'export' | 'anomaly' | 'chart'; /** * Register the model adapter every AI call will route through. Call once * at app boot. Passing `null` clears the provider and AI calls revert to * throwing "no provider" errors. */ export declare function setAIProvider(p: AIProvider | null): void; export declare function getAIProvider(): AIProvider | null; export declare function hasAIProvider(): boolean; export type AIFilterClause = { field: string; operator: 'contains' | 'equals' | 'startsWith' | 'greaterThan' | 'lessThan' | 'isBlank'; value?: string; }; export type AISortClause = { field: string; desc: boolean; }; export type AIFilterResult = { filters: AIFilterClause[]; sort: AISortClause[]; /** Plain-English explanation of how the model interpreted the query. * Surface this in the UI so the user can confirm or undo. */ rationale: string; }; export type AIFilterOptions = { /** * When true, the helper not only RETURNS the plan but also applies it * to the grid via `api.setFilter` / `api.setSort`. Defaults to false * so callers can show a preview before committing. */ apply?: boolean; signal?: AbortSignal; }; /** * Translate a natural-language query into a filter+sort plan against * the current grid's columns. The grid passes the column schema (names, * types, sample values) to the model so it can pick the right field * names without hallucinating. */ export declare function aiFilter(api: SvGridApi, query: string, opts?: AIFilterOptions): Promise; export type AISmartFillExample = { input: Record; output: unknown; }; export type AISmartFillResult = { field: string; predictions: Array<{ rowIndex: number; value: TValue; confidence: number; }>; rationale: string; }; export type AISmartFillOptions = { /** Target column - the one whose values we want filled. */ field: string; /** Index of rows the model should propose values for. If omitted, every * row whose current `field` value is `null`, `undefined` or `''` is * selected automatically. */ targetRowIndices?: number[]; /** * Worked examples the user has already filled in. Required - the * model needs at least one to know the pattern, two or more to lock * the schema. We don't pull these from the grid automatically because * "edited" vs "untouched" isn't a state SvGrid exposes today. */ examples: AISmartFillExample[]; signal?: AbortSignal; }; /** * Given a column and a few user-provided examples, propose values for the * untouched rows. Returns predictions only - the caller chooses whether to * commit them via `api.setCellValue`. This is the right shape for an * accept-per-cell UX with confidence-coloured highlights. */ export declare function aiSmartFill(api: SvGridApi, opts: AISmartFillOptions): Promise>; export type AISummarizeTarget = { kind: 'row'; rowIndex: number; } | { kind: 'all'; } | { kind: 'selection'; rowIndices: number[]; } | { kind: 'group'; field: string; value: unknown; }; export type AISummary = { text: string; bullets: string[]; /** Field names the model thinks are the most load-bearing for the * story it just told. UI can highlight those columns. */ highlightedFields: string[]; }; export type AISummarizeOptions = { target: AISummarizeTarget; /** Optional question the user is trying to answer. Helps the model * bias the summary toward the relevant columns. */ question?: string; signal?: AbortSignal; }; /** * Ask the model to summarise a slice of the grid. Caps the row sample at * a model-friendly size; for huge selections it samples uniformly so the * summary stays representative without blowing the context window. */ export declare function aiSummarize(api: SvGridApi, opts: AISummarizeOptions): Promise; export type AIClassifyOptions = { /** Column whose free-text we're classifying. */ inputField: string; /** Target column the model should write to. */ outputField: string; /** Allowed values. The model is constrained to pick one. */ classes: string[]; /** Optional one-line description of each class (acts as a labeling rubric). */ classDescriptions?: Record; /** Rows to classify. Defaults to all. */ targetRowIndices?: number[]; signal?: AbortSignal; }; export type AIClassifyResult = { inputField: string; outputField: string; predictions: Array<{ rowIndex: number; value: string; confidence: number; }>; }; /** * Bucket free-text cells into one of a known set of classes. The model * is constrained to pick from `opts.classes`; predictions outside the set * are dropped so the caller can rely on the output being clean enum * values it can write straight back into the grid. */ export declare function aiClassify(api: SvGridApi, opts: AIClassifyOptions): Promise; export type AIExportPlan = { format: ExportFormat; filters: AIFilterClause[]; sort: AISortClause[]; groupBy: string[]; /** Plain-English explanation of how the model read the request. */ rationale: string; }; export type AIExportOptions = { /** * Also apply the filter / sort / grouping to the grid (mutating the view) so * it mirrors the export. Default FALSE - the export is self-contained (it * computes its own rows), so the grid is left untouched unless you opt in. */ apply?: boolean; /** Actually download the file. Default true; set false to preview the plan. */ run?: boolean; /** Base filename (no extension). Default 'export'. */ filename?: string; signal?: AbortSignal; }; /** * Turn a natural-language request ("export EU orders from Q2 as a grouped PDF") * into an export: the model returns a `{ format, filters, sort, groupBy }` plan * against the grid's columns; we apply the filter/sort to the grid and hand the * result to the registered export engine (@svgrid/enterprise). Returns the plan * so the UI can show what it did (or preview it first with `run: false`). */ export declare function aiExport(api: SvGridApi, query: string, opts?: AIExportOptions): Promise; export type AIAnomaly = { /** Index into the SCANNED rows (target order), when the model pins one row. */ rowIndex?: number; field?: string; value?: unknown; reason: string; severity: 'low' | 'medium' | 'high'; }; export type AIAnomalyResult = { anomalies: AIAnomaly[]; summary: string; }; export type AIAnomalyOptions = { /** Which rows to scan. Defaults to the whole dataset. */ target?: AISummarizeTarget; /** Optional focus, e.g. "look at pricing and margins". */ question?: string; signal?: AbortSignal; }; /** * Scan a slice of the grid (all / selection / group) for anomalies - outliers, * suspicious values, inconsistencies - and return a structured list plus a * one-line summary. Pairs naturally with an export: "find the odd ones, then * export just those". */ export declare function aiFindAnomalies(api: SvGridApi, opts?: AIAnomalyOptions): Promise; export type AIChartType = 'bar' | 'line' | 'area' | 'pie'; export type AIChartPlan = { type: AIChartType; /** Group-by (category-axis) column field, or null. */ dimension: string | null; /** Split-by column field: one series per distinct value, or null. */ series: string | null; /** Measure (value-axis) column field, or null. */ measure: string | null; reduce: 'sum' | 'avg' | 'count'; stacked: boolean; logScale: boolean; timeAxis: boolean; valueFormat: 'number' | 'currency' | 'percent'; rationale: string; }; export type AIChartOptions = { /** Apply the plan to the grid's chart panel (open + configure). Default false. */ apply?: boolean; signal?: AbortSignal; }; /** * Translate a natural-language request into a chart plan for the grid's built-in * `charting` panel. Validates every field against the real schema, then (with * `apply: true`) pushes it into the panel through `api.configureChart`. */ export declare function aiChart(api: SvGridApi, query: string, opts?: AIChartOptions): Promise; /** * Wire the grid's chart-panel AI button to the model: registers a handler (via * `api.setChartAiHandler`) that runs `aiChart` and returns the plan for the * panel to apply + explain. Call once after `onApiReady`. `installEnterprise` * calls this for you. */ export declare function enableAiCharting(api: SvGridApi): void; export declare function disableAiCharting(api: SvGridApi): void; /** * A deterministic provider that returns canned, schema-shaped responses * for each task. Wire it in via `setAIProvider(mockAIProvider)` to make * the AI demo work end-to-end without a real model key. Not for production. */ export declare const mockAIProvider: AIProvider; export {};