reveal-sdk-node-ai 1.2.1-rc.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +164 -8
- package/index.js +50 -5
- package/native/AIPlugin.dll +0 -0
- package/native/Reveal.Sdk.AI.Abstractions.Debug.dll +0 -0
- package/native/Reveal.Sdk.AI.Anthropic.dll +0 -0
- package/native/Reveal.Sdk.AI.AspNetCore.dll +0 -0
- package/native/Reveal.Sdk.AI.AzureOpenAI.dll +0 -0
- package/native/Reveal.Sdk.AI.Google.dll +0 -0
- package/native/Reveal.Sdk.AI.OpenAI.dll +0 -0
- package/native/Reveal.Sdk.AI.dll +0 -0
- package/native/Reveal.Sdk.Dom.dll +0 -0
- package/package.json +2 -2
package/index.d.ts
CHANGED
|
@@ -80,6 +80,14 @@ export interface AIRequestJson {
|
|
|
80
80
|
/** The stable engine intent that produced this call (e.g. 'generation-build-report'). */
|
|
81
81
|
intent: string;
|
|
82
82
|
userContext: AIUserContextJson | null;
|
|
83
|
+
/**
|
|
84
|
+
* Present only when a message has a stable prefix: one entry per message (same order as `messages`), the number of
|
|
85
|
+
* leading characters of its `content` (UTF-16 code units, as JavaScript's `length` counts) that stay the same from one
|
|
86
|
+
* request to the next (a prompt's instructions and schema), or null. A hint for services with explicit prompt caching,
|
|
87
|
+
* which can mark that prefix as a cache point; ignore it otherwise. Kept out of the messages, which can be passed to an
|
|
88
|
+
* LLM client as they are.
|
|
89
|
+
*/
|
|
90
|
+
stablePrefixLengths?: (number | null)[];
|
|
83
91
|
}
|
|
84
92
|
|
|
85
93
|
/** What a custom AI provider callback returns (v2 contract). */
|
|
@@ -113,11 +121,21 @@ export interface AIUsageRecordJson {
|
|
|
113
121
|
inputTokens?: number | null;
|
|
114
122
|
outputTokens?: number | null;
|
|
115
123
|
totalTokens?: number | null;
|
|
124
|
+
/** Tokens spent on internal reasoning; null when the provider reported none. */
|
|
125
|
+
reasoningTokens?: number | null;
|
|
126
|
+
/** Input tokens served from the provider's prompt cache; null when the provider reported none. */
|
|
127
|
+
cachedInputTokens?: number | null;
|
|
116
128
|
durationMs: number;
|
|
117
129
|
finishReason?: 'Stop' | 'Length' | 'ContentFilter' | 'Other' | null;
|
|
118
130
|
succeeded: boolean;
|
|
119
131
|
/** 'provider_error' | 'timeout' | 'cancelled' | 'denied' when succeeded is false. */
|
|
120
132
|
errorCode?: string | null;
|
|
133
|
+
/** The stage of a multi-step feature (e.g. 'DefineWidgets' in dashboard generation); null outside one. */
|
|
134
|
+
stage?: string | null;
|
|
135
|
+
/** Within `stage`: 1 for its first call, 2 and up for repair calls. */
|
|
136
|
+
attempt?: number | null;
|
|
137
|
+
/** The top-level operation this call ran under, when it differs from `operationId` (e.g. datasource ranking during a generation). */
|
|
138
|
+
parentOperationId?: string | null;
|
|
121
139
|
}
|
|
122
140
|
|
|
123
141
|
/** What `quotaGate` receives before every gated AI call. The user's identity and any
|
|
@@ -192,7 +210,8 @@ export interface MetadataManagerCallbacks {
|
|
|
192
210
|
getDatasourceList?: (userContext: any) => Promise<any[]>;
|
|
193
211
|
getMetadata?: (userContext: any, datasourceId: string, datasourceItemId: string | null, database: string, tables: string[], currentModel?: string | null) => Promise<any>;
|
|
194
212
|
getMetadataIndex?: (userContext: any, datasourceId: string, datasourceItemId?: string | null) => Promise<any>;
|
|
195
|
-
|
|
213
|
+
/** `alias` (optional) is the friendly table name the AI is shown instead of `name`. */
|
|
214
|
+
getTableSummaries?: (userContext: any, datasourceId: string, datasourceItemId: string | null, database: string, currentModel?: string | null) => Promise<Array<{ name: string; alias?: string | null; description?: string | null }>>;
|
|
196
215
|
deleteMetadata?: (userContext: any, datasourceId: string, datasourceItemId?: string | null) => Promise<void>;
|
|
197
216
|
getProgress?: (userContext: any, datasourceId: string, datasourceItemId?: string | null) => Promise<any>;
|
|
198
217
|
hasMetadata?: (userContext: any, datasourceId: string, datasourceItemId?: string | null) => Promise<boolean>;
|
|
@@ -202,21 +221,88 @@ export interface MetadataManagerCallbacks {
|
|
|
202
221
|
upsertFieldOverride?: (userContext: any, datasourceId: string, datasourceItemId: string | null, database: string, table: string, fieldName: string, fieldOverride: any) => Promise<void>;
|
|
203
222
|
deleteFieldOverride?: (userContext: any, datasourceId: string, datasourceItemId: string | null, database: string, table: string, fieldName: string) => Promise<boolean>;
|
|
204
223
|
upsertTableDescription?: (userContext: any, datasourceId: string, datasourceItemId: string | null, database: string, table: string, description: string | null, appliesTo?: string[] | null) => Promise<void>;
|
|
205
|
-
|
|
224
|
+
/** The plugin passes the user context again as the first argument after `userContext` (`userContextArg`). */
|
|
225
|
+
getRuntimeOverrides?: (userContext: any, userContextArg: any, datasourceId?: string | null, datasourceItemId?: string | null) => Promise<any | null>;
|
|
206
226
|
getFullMetadata?: (userContext: any, datasourceId: string, datasourceItemId?: string | null) => Promise<any | null>;
|
|
207
|
-
|
|
227
|
+
/**
|
|
228
|
+
* Ranks the catalog datasources against a prompt. The dashboard generator uses it to shortlist the
|
|
229
|
+
* datasources a chat request without `datasourceId` is built from (see `RevealAIPluginOptions` for which
|
|
230
|
+
* datasources the AI may then see). Optional: when it is missing, the
|
|
231
|
+
* plugin ranks with the same built-in ranker as the C# SDK, reading this manager's
|
|
232
|
+
* `getDatasourceList`, `getMetadataIndex` and `getMetadata`. It calls `getMetadata` with no
|
|
233
|
+
* `currentModel`, so it ranks on what that handler returns for the request's user context
|
|
234
|
+
* (overrides and any model filtering included), and leaves out a datasource whose index is
|
|
235
|
+
* missing or fails to load. Implement it only to rank with your own logic; when it fails, the AI
|
|
236
|
+
* is shown every datasource instead. A stub that returns no candidates also leaves the AI with
|
|
237
|
+
* every datasource: delete it to get the built-in ranker. The plugin passes the user context
|
|
238
|
+
* again after `userPrompt` (`userContextArg`).
|
|
239
|
+
*
|
|
240
|
+
* Resolve to `{ candidates: [{ datasourceId, datasourceItemId?, score, rationale?, relevantTables? }] }`,
|
|
241
|
+
* or `{ candidates: [], error }` on failure:
|
|
242
|
+
* - `datasourceId` / `datasourceItemId`: the catalog entry's `Id` / `ItemId` exactly (omit the
|
|
243
|
+
* item id when the entry has none); a candidate that matches no entry is ignored.
|
|
244
|
+
* - `score`: 0..1; the shortlist is ordered by it.
|
|
245
|
+
* - `relevantTables`: "database.table", with the real names as the metadata index lists them,
|
|
246
|
+
* not their aliases (e.g. `'NorthwindCloud.dbo.Orders'`). The AI is shown each table's alias;
|
|
247
|
+
* an entry without its database is shown as is.
|
|
248
|
+
*/
|
|
249
|
+
rankDatasourcesForPrompt?: (userContext: any, userPrompt: string, userContextArg: any, maxResults: number) => Promise<any>;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* One field (column) definition in the metadata catalog. Mirrors the C# `FieldSchema`.
|
|
254
|
+
* `Alias` is shown to the AI INSTEAD of `Name`; `expression` / `expressionType` / `dataType`
|
|
255
|
+
* define a virtual (calculated) field.
|
|
256
|
+
*/
|
|
257
|
+
export interface FieldSchemaJson {
|
|
258
|
+
Name: string;
|
|
259
|
+
Alias?: string | null;
|
|
260
|
+
Description?: string | null;
|
|
261
|
+
expression?: string | null;
|
|
262
|
+
expressionType?: 'CalculatedField' | 'PostCalculatedField';
|
|
263
|
+
dataType?: string | null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* One table (or cube) definition in the metadata catalog. Mirrors the C# `TableSchema`.
|
|
268
|
+
* `Alias` is the friendly name the AI is shown instead of `Name` (the SDK maps the AI's
|
|
269
|
+
* answer back to the real name).
|
|
270
|
+
*/
|
|
271
|
+
export interface TableSchemaJson {
|
|
272
|
+
Name: string;
|
|
273
|
+
Alias?: string | null;
|
|
274
|
+
Description?: string | null;
|
|
275
|
+
Fields?: FieldSchemaJson[] | null;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* One database (or XMLA catalog) definition in the metadata catalog. Mirrors the C#
|
|
280
|
+
* `DatabaseSchema`. `Name` accepts a single name or an array of names sharing the same
|
|
281
|
+
* configuration; `Alias` / `Description` then apply to each of them. `DiscoveryMode`
|
|
282
|
+
* 'Restricted' exposes only the listed tables.
|
|
283
|
+
*/
|
|
284
|
+
export interface DatabaseSchemaJson {
|
|
285
|
+
Name: string | string[];
|
|
286
|
+
Alias?: string | null;
|
|
287
|
+
Description?: string | null;
|
|
288
|
+
DiscoveryMode?: 'Default' | 'Restricted';
|
|
289
|
+
Tables?: TableSchemaJson[] | null;
|
|
208
290
|
}
|
|
209
291
|
|
|
210
292
|
/**
|
|
211
293
|
* One datasource definition in the metadata catalog. Property names match the C#
|
|
212
294
|
* `DatasourceSchema` (PascalCase); `Provider` is a Reveal provider enum name (e.g.
|
|
213
|
-
* 'SQLServer', 'PostgreSQL', 'MySQL', 'REST').
|
|
295
|
+
* 'SQLServer', 'PostgreSQL', 'MySQL', 'REST'). `Alias` is the friendly name the AI is
|
|
296
|
+
* shown instead of `Id` in ranking / selection prompts (useful when ids are opaque);
|
|
297
|
+
* `Description` is printed next to it.
|
|
214
298
|
*/
|
|
215
299
|
export interface DatasourceSchemaJson {
|
|
216
300
|
Id: string;
|
|
217
301
|
ItemId?: string | null;
|
|
218
302
|
Provider: string;
|
|
219
|
-
|
|
303
|
+
Alias?: string | null;
|
|
304
|
+
Description?: string | null;
|
|
305
|
+
Databases?: DatabaseSchemaJson[] | null;
|
|
220
306
|
}
|
|
221
307
|
|
|
222
308
|
/**
|
|
@@ -239,6 +325,46 @@ export type MetadataCatalogProviderCallback = (
|
|
|
239
325
|
userContext?: any
|
|
240
326
|
) => MetadataCatalogJson | Promise<MetadataCatalogJson>;
|
|
241
327
|
|
|
328
|
+
/**
|
|
329
|
+
* A single custom date filter rule declared by the host — a relative window such as "Next 7 Days"
|
|
330
|
+
* or "Last 90 Days". Mirrors the C# `AIDateFilterRule`. Only `Last` and `Next` relations are
|
|
331
|
+
* honored (other relations overlap the built-in options and are ignored).
|
|
332
|
+
*/
|
|
333
|
+
export interface AIDateFilterRuleJson {
|
|
334
|
+
/** The window's relation to today. Only `'Last'` and `'Next'` are honored. */
|
|
335
|
+
Relation: 'Last' | 'Next';
|
|
336
|
+
/** How many `Period`s the window spans (e.g. 7 for "Next 7 Days"). Must be positive. */
|
|
337
|
+
Count: number;
|
|
338
|
+
/** The unit of the window. */
|
|
339
|
+
Period: 'Day' | 'Week' | 'Month' | 'Quarter' | 'Semester' | 'Year';
|
|
340
|
+
/**
|
|
341
|
+
* Whether today is included in the window, or omitted for the default. Honored for `Last` rules,
|
|
342
|
+
* which include today by default, and for `Next` rules over `'Day'`, which start tomorrow by default
|
|
343
|
+
* (with true, "Next 7 Days" starts today instead). Ignored for other periods.
|
|
344
|
+
*/
|
|
345
|
+
IncludeToday?: boolean | null;
|
|
346
|
+
/**
|
|
347
|
+
* Optional canonical name the AI uses to select this rule. When omitted, a stable name is
|
|
348
|
+
* derived from the relation, count and period (e.g. "Next7Days"). Names that collide with a
|
|
349
|
+
* built-in date option are ignored in favor of the built-in.
|
|
350
|
+
*/
|
|
351
|
+
Name?: string | null;
|
|
352
|
+
/**
|
|
353
|
+
* Optional human-readable description surfaced to the AI (falls back to a generated phrase).
|
|
354
|
+
*/
|
|
355
|
+
Description?: string | null;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Node.js-side implementation of IAIDateFilterProvider. Returns the host's custom date menu
|
|
360
|
+
* options so the AI can offer them alongside the built-ins when generating or editing dashboards.
|
|
361
|
+
* Invoked once per generation/edit with no arguments other than the request's user context (so the
|
|
362
|
+
* rules can vary per user/tenant). Return an empty array when there are none.
|
|
363
|
+
*/
|
|
364
|
+
export type DateFilterProviderCallback = (
|
|
365
|
+
userContext?: any
|
|
366
|
+
) => AIDateFilterRuleJson[] | Promise<AIDateFilterRuleJson[]>;
|
|
367
|
+
|
|
242
368
|
/**
|
|
243
369
|
* Node.js-side implementation of IMetadataStorageProvider — the persistence layer the built-in
|
|
244
370
|
* file-based MetadataManager reads and writes through. Implement the operations your host supports
|
|
@@ -247,6 +373,16 @@ export type MetadataCatalogProviderCallback = (
|
|
|
247
373
|
* unchanged from `getById` (deserialized back into the requesting C# type). The first argument of
|
|
248
374
|
* every handler is the request's user context, for multi-tenant scoping.
|
|
249
375
|
*
|
|
376
|
+
* A handler may filter what that user sees, but the answer of `getById` and `list` must depend only
|
|
377
|
+
* on the id (or pattern) and the user context: within one dashboard generation or edit, each item
|
|
378
|
+
* and listing is fetched once for the request's user and the request's later reads reuse a copy of
|
|
379
|
+
* that answer. Nothing is reused across requests or users; a metadata write Reveal makes, from any
|
|
380
|
+
* request, makes running requests fetch again, and a change your application makes to the storage
|
|
381
|
+
* directly is seen from the next request. Writes are made under the system
|
|
382
|
+
* user context (`reveal-ai-metadata-user` by default), and some write back a document just read, so
|
|
383
|
+
* return unfiltered documents to it. The index document carries every table's alias and
|
|
384
|
+
* description; filter it like the per-table documents.
|
|
385
|
+
*
|
|
250
386
|
* When this object is provided, the C# plugin replaces its default JSONMetadataStorageProvider with
|
|
251
387
|
* MetadataStorageProvider, which proxies every call to these handlers. Independent of
|
|
252
388
|
* `metadataManager` (which replaces the whole IMetadataManager and so bypasses storage entirely).
|
|
@@ -285,7 +421,8 @@ export interface Callbacks {
|
|
|
285
421
|
* Observability export: receives one {@link AIUsageRecordJson} per AI call (success or
|
|
286
422
|
* failure, foreground or background) — "save the usage log anywhere". One-way — the return
|
|
287
423
|
* value is ignored and failures never affect AI calls. Not a billing seam: plan checks,
|
|
288
|
-
* budgets, and debiting tokens belong on `quotaGate`/`quotaSettle`.
|
|
424
|
+
* budgets, and debiting tokens belong on `quotaGate`/`quotaSettle`. The sink is not called
|
|
425
|
+
* within a request, so `userContext` is always null; the record's `userId` identifies the user.
|
|
289
426
|
*/
|
|
290
427
|
usageSink?: (record: AIUsageRecordJson, userContext?: any) => void | Promise<void>;
|
|
291
428
|
/**
|
|
@@ -301,8 +438,10 @@ export interface Callbacks {
|
|
|
301
438
|
*/
|
|
302
439
|
quotaSettle?: (settlement: { context: AICallContextJson; usage: AIUsageRecordJson }, userContext?: any) => void | Promise<void>;
|
|
303
440
|
/**
|
|
304
|
-
* Plan gating: return the subset of `candidateProfiles` this user may use.
|
|
305
|
-
*
|
|
441
|
+
* Plan gating: return the subset of `candidateProfiles` this user may use. Called with every
|
|
442
|
+
* profile for the profile listing, and with just the requested profile to validate a request
|
|
443
|
+
* (leaving it out returns 403). Malformed results or exceptions deny all profiles (fail
|
|
444
|
+
* closed); names outside the candidate set are ignored.
|
|
306
445
|
*/
|
|
307
446
|
profileAuthorizer?: (request: { user: AIUserContextJson | null; candidateProfiles: string[] }, userContext?: any) => string[] | Promise<string[]>;
|
|
308
447
|
/**
|
|
@@ -323,6 +462,12 @@ export interface Callbacks {
|
|
|
323
462
|
* — configure exactly one catalog source (the plugin throws at startup if both are set).
|
|
324
463
|
*/
|
|
325
464
|
metadataCatalogProvider?: MetadataCatalogProviderCallback;
|
|
465
|
+
/**
|
|
466
|
+
* Node.js-side IAIDateFilterProvider implementation. Declares the host's custom date menu
|
|
467
|
+
* options ("Next 7 Days", "Last 90 Days") server-side so the AI recognizes them when generating
|
|
468
|
+
* or editing dashboards. Mirror the same rules into the client's `onDateFilterMenuOpening`.
|
|
469
|
+
*/
|
|
470
|
+
dateFilterProvider?: DateFilterProviderCallback;
|
|
326
471
|
/**
|
|
327
472
|
* Node.js-side IMetadataStorageProvider implementation. Swaps the built-in file-based metadata
|
|
328
473
|
* persistence for a custom backend (database, cloud storage, ...) while leaving the rest of the
|
|
@@ -331,6 +476,17 @@ export interface Callbacks {
|
|
|
331
476
|
metadataStorageProvider?: MetadataStorageProviderCallbacks;
|
|
332
477
|
}
|
|
333
478
|
|
|
479
|
+
/**
|
|
480
|
+
* Options for the Reveal AI plugin.
|
|
481
|
+
*
|
|
482
|
+
* A chat request may omit `datasourceId`: the AI then picks one or more datasources from the catalog
|
|
483
|
+
* (`metadataCatalogFile`, or `getDatasourceList` of a `metadataManager` callback) and may mix and join them in
|
|
484
|
+
* one dashboard. The request comes from the browser client, so the server can't rely on it naming a datasource.
|
|
485
|
+
* The AI only considers the datasources whose metadata index the request's user can read: every metadata read
|
|
486
|
+
* gets the user context. A host that restricts datasources per user must therefore also filter its metadata
|
|
487
|
+
* per user (or tenant) in its metadata storage or manager callbacks, returning no index for the datasources a
|
|
488
|
+
* user can't use; then nothing about them reaches the AI.
|
|
489
|
+
*/
|
|
334
490
|
export interface RevealAIPluginOptions {
|
|
335
491
|
/** Absolute path to AIPlugin.dll (defaults to the bundled native binaries). */
|
|
336
492
|
assemblyPath?: string;
|
package/index.js
CHANGED
|
@@ -17,6 +17,27 @@ function wrapJsonCallback(handler) {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* The engine only receives the user's id from the SDK, so the hook payloads it sends carry
|
|
22
|
+
* `user.properties: null`. Fill them in from the user context the SDK resolved for the request
|
|
23
|
+
* (passed to every callback), so per-request claims are on `user.properties` as documented.
|
|
24
|
+
* Only done when that context is the payload's user: system calls carry the plugin's own user.
|
|
25
|
+
*/
|
|
26
|
+
function withUserProperties(payload, userContext) {
|
|
27
|
+
const user = payload?.user ?? payload?.context?.user;
|
|
28
|
+
const properties = userContext?.properties;
|
|
29
|
+
if (!user || user.properties != null || properties == null || user.userId !== userContext.userId) {
|
|
30
|
+
return payload;
|
|
31
|
+
}
|
|
32
|
+
user.properties = properties instanceof Map ? Object.fromEntries(properties) : properties;
|
|
33
|
+
return payload;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** wrapJsonCallback for the hooks whose payload carries the user (gate, authorizer, resolver). */
|
|
37
|
+
function wrapUserJsonCallback(handler) {
|
|
38
|
+
return wrapJsonCallback((payload, userContext) => handler(withUserProperties(payload, userContext), userContext));
|
|
39
|
+
}
|
|
40
|
+
|
|
20
41
|
/**
|
|
21
42
|
* Same as wrapJsonCallback for one-way callbacks: the return value is ignored by the plugin.
|
|
22
43
|
*/
|
|
@@ -93,6 +114,7 @@ function withOptions(options = {}) {
|
|
|
93
114
|
aiProvider,
|
|
94
115
|
metadataManager: metadataManagerCallbacks,
|
|
95
116
|
metadataCatalogProvider,
|
|
117
|
+
dateFilterProvider,
|
|
96
118
|
metadataStorageProvider: metadataStorageProviderCallbacks,
|
|
97
119
|
usageSink, quotaGate, quotaSettle, profileAuthorizer, connectionResolver,
|
|
98
120
|
...otherCallbacks
|
|
@@ -130,10 +152,12 @@ function withOptions(options = {}) {
|
|
|
130
152
|
// v2 hook callbacks: always object-friendly (parsed payload in, plain value out). Their
|
|
131
153
|
// presence is signaled to the plugin via has* flags.
|
|
132
154
|
if (typeof usageSink === 'function') callbacks.usageSink = wrapOneWayJsonCallback(usageSink);
|
|
133
|
-
if (typeof quotaGate === 'function') callbacks.quotaGate =
|
|
134
|
-
if (typeof quotaSettle === 'function')
|
|
135
|
-
|
|
136
|
-
|
|
155
|
+
if (typeof quotaGate === 'function') callbacks.quotaGate = wrapUserJsonCallback(quotaGate);
|
|
156
|
+
if (typeof quotaSettle === 'function') {
|
|
157
|
+
callbacks.quotaSettle = wrapOneWayJsonCallback((payload, userContext) => quotaSettle(withUserProperties(payload, userContext), userContext));
|
|
158
|
+
}
|
|
159
|
+
if (typeof profileAuthorizer === 'function') callbacks.profileAuthorizer = wrapUserJsonCallback(profileAuthorizer);
|
|
160
|
+
if (typeof connectionResolver === 'function') callbacks.connectionResolver = wrapUserJsonCallback(connectionResolver);
|
|
137
161
|
parameters.hasUsageSink = typeof usageSink === 'function';
|
|
138
162
|
parameters.hasQuotaGate = typeof quotaGate === 'function';
|
|
139
163
|
parameters.hasQuotaSettle = typeof quotaSettle === 'function';
|
|
@@ -159,6 +183,22 @@ function withOptions(options = {}) {
|
|
|
159
183
|
parameters.hasMetadataCatalogProvider = true;
|
|
160
184
|
}
|
|
161
185
|
|
|
186
|
+
// IAIDateFilterProvider bridge — a single getFilterRules() method. When
|
|
187
|
+
// provided, the C# plugin registers DateFilterProvider, which proxies
|
|
188
|
+
// IAIDateFilterProvider.GetFilterRulesAsync() to this handler so the AI can
|
|
189
|
+
// offer the host's custom date menu options ("Next 7 Days", "Last 90 Days"). The payload
|
|
190
|
+
// carries no arguments, so only the userContext is forwarded; return the array of rules.
|
|
191
|
+
if (dateFilterProvider) {
|
|
192
|
+
if (typeof dateFilterProvider !== 'function') {
|
|
193
|
+
throw new Error('callbacks.dateFilterProvider must be a function returning the custom date filter rules (it may be sync or async)');
|
|
194
|
+
}
|
|
195
|
+
callbacks.dateFilterProvider = async (userContext, _message) => {
|
|
196
|
+
const rules = await dateFilterProvider(userContext);
|
|
197
|
+
return JSON.stringify(rules ?? []);
|
|
198
|
+
};
|
|
199
|
+
parameters.hasDateFilterProvider = true;
|
|
200
|
+
}
|
|
201
|
+
|
|
162
202
|
// IMetadataManager bridge — dispatches by methodName from EndpointMethodCallModel.
|
|
163
203
|
if (metadataManagerCallbacks) {
|
|
164
204
|
if (typeof metadataManagerCallbacks !== 'object' || typeof metadataManagerCallbacks === 'function') {
|
|
@@ -166,7 +206,12 @@ function withOptions(options = {}) {
|
|
|
166
206
|
}
|
|
167
207
|
|
|
168
208
|
// Tell the C# side to use MetadataManagerProvider instead of the file-based MetadataManager.
|
|
169
|
-
|
|
209
|
+
// Without a rankDatasourcesForPrompt handler, the C# side ranks datasources with the
|
|
210
|
+
// built-in ranker over this manager's getDatasourceList / getMetadataIndex / getMetadata.
|
|
211
|
+
parameters.metadataManager = Object.assign({}, parameters.metadataManager, {
|
|
212
|
+
useNodeProvider: true,
|
|
213
|
+
hostRanksDatasources: typeof metadataManagerCallbacks.rankDatasourcesForPrompt === 'function',
|
|
214
|
+
});
|
|
170
215
|
|
|
171
216
|
callbacks.metadataManager = async (userContext, message) => {
|
|
172
217
|
let methodName, args;
|
package/native/AIPlugin.dll
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/native/Reveal.Sdk.AI.dll
CHANGED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reveal-sdk-node-ai",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Reveal SDK AI plugin for Node.js — adds AI capabilities to Reveal BI dashboards",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -23,6 +23,6 @@
|
|
|
23
23
|
"node": ">=16.0.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"reveal-sdk-node": ">=2.
|
|
26
|
+
"reveal-sdk-node": ">=2.3.0"
|
|
27
27
|
}
|
|
28
28
|
}
|