@querypanel/node-sdk 1.0.39 → 1.0.40

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/dist/index.d.cts CHANGED
@@ -179,6 +179,7 @@ interface SdkChart {
179
179
  sql: string;
180
180
  sql_params: Record<string, unknown> | null;
181
181
  vega_lite_spec: Record<string, unknown>;
182
+ spec_type?: 'vega-lite' | 'vizspec';
182
183
  query_id: string | null;
183
184
  organization_id: string | null;
184
185
  tenant_id: string | null;
@@ -194,6 +195,7 @@ interface ChartCreateInput {
194
195
  sql: string;
195
196
  sql_params?: Record<string, unknown>;
196
197
  vega_lite_spec: Record<string, unknown>;
198
+ spec_type?: 'vega-lite' | 'vizspec';
197
199
  query_id?: string;
198
200
  target_db?: string;
199
201
  }
@@ -203,6 +205,7 @@ interface ChartUpdateInput {
203
205
  sql?: string;
204
206
  sql_params?: Record<string, unknown>;
205
207
  vega_lite_spec?: Record<string, unknown>;
208
+ spec_type?: 'vega-lite' | 'vizspec';
206
209
  target_db?: string;
207
210
  }
208
211
  interface PaginationQuery {
@@ -281,6 +284,94 @@ interface SchemaSyncOptions {
281
284
  forceReindex?: boolean;
282
285
  }
283
286
 
287
+ /**
288
+ * VizSpec types for flexible visualization specifications
289
+ * Supports chart, table, and metric visualizations
290
+ */
291
+ type FieldType = 'quantitative' | 'temporal' | 'ordinal' | 'nominal' | 'boolean';
292
+ interface ValueFormat {
293
+ style?: 'number' | 'currency' | 'percent' | 'date' | 'time' | 'datetime';
294
+ currency?: string;
295
+ minimumFractionDigits?: number;
296
+ maximumFractionDigits?: number;
297
+ dateStyle?: 'short' | 'medium' | 'long';
298
+ }
299
+ interface FieldRef {
300
+ field: string;
301
+ label?: string;
302
+ type?: FieldType;
303
+ format?: ValueFormat;
304
+ }
305
+ type AggregateOp = 'sum' | 'avg' | 'min' | 'max' | 'count' | 'distinct';
306
+ type TimeUnit = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute';
307
+ interface AxisField extends FieldRef {
308
+ aggregate?: AggregateOp;
309
+ timeUnit?: TimeUnit;
310
+ }
311
+ interface MetricField extends FieldRef {
312
+ aggregate?: AggregateOp;
313
+ }
314
+ interface SortSpec {
315
+ field: string;
316
+ direction?: 'asc' | 'desc';
317
+ }
318
+ interface VizSpecBase {
319
+ version: '1.0';
320
+ kind: 'chart' | 'table' | 'metric';
321
+ title?: string;
322
+ description?: string;
323
+ data: {
324
+ sourceId: string;
325
+ };
326
+ }
327
+ type ChartType = 'line' | 'bar' | 'area' | 'scatter' | 'pie';
328
+ type StackingMode = 'none' | 'stacked' | 'percent';
329
+ interface ChartEncoding {
330
+ chartType: ChartType;
331
+ x?: AxisField;
332
+ y?: AxisField | AxisField[];
333
+ series?: FieldRef;
334
+ stacking?: StackingMode;
335
+ sort?: SortSpec;
336
+ limit?: number;
337
+ tooltips?: FieldRef[];
338
+ }
339
+ interface ChartSpec extends VizSpecBase {
340
+ kind: 'chart';
341
+ encoding: ChartEncoding;
342
+ }
343
+ type TextAlign = 'left' | 'right' | 'center';
344
+ interface TableColumn extends FieldRef {
345
+ width?: number;
346
+ align?: TextAlign;
347
+ isHidden?: boolean;
348
+ }
349
+ interface TableEncoding {
350
+ columns: TableColumn[];
351
+ sort?: SortSpec;
352
+ limit?: number;
353
+ }
354
+ interface TableSpec extends VizSpecBase {
355
+ kind: 'table';
356
+ encoding: TableEncoding;
357
+ }
358
+ type ComparisonMode = 'delta' | 'deltaPercent' | 'ratio';
359
+ interface MetricTrend {
360
+ timeField: AxisField;
361
+ valueField: MetricField;
362
+ }
363
+ interface MetricEncoding {
364
+ valueField: MetricField;
365
+ comparisonField?: MetricField;
366
+ comparisonMode?: ComparisonMode;
367
+ trend?: MetricTrend;
368
+ }
369
+ interface MetricSpec extends VizSpecBase {
370
+ kind: 'metric';
371
+ encoding: MetricEncoding;
372
+ }
373
+ type VizSpec = ChartSpec | TableSpec | MetricSpec;
374
+
284
375
  interface ContextDocument {
285
376
  source?: string;
286
377
  pageContent: string;
@@ -288,7 +379,9 @@ interface ContextDocument {
288
379
  score?: number;
289
380
  }
290
381
  interface ChartEnvelope {
291
- vegaLiteSpec: Record<string, unknown> | null;
382
+ vegaLiteSpec?: Record<string, unknown> | null;
383
+ vizSpec?: VizSpec | null;
384
+ specType: 'vega-lite' | 'vizspec';
292
385
  notes: string | null;
293
386
  }
294
387
  interface AskOptions {
@@ -300,6 +393,7 @@ interface AskOptions {
300
393
  previousSql?: string;
301
394
  maxRetry?: number;
302
395
  chartMaxRetries?: number;
396
+ chartType?: 'vega-lite' | 'vizspec';
303
397
  }
304
398
  interface AskResponse {
305
399
  sql: string;
@@ -317,6 +411,26 @@ interface AskResponse {
317
411
  }
318
412
  declare function anonymizeResults(rows: Array<Record<string, unknown>>): Array<Record<string, string>>;
319
413
 
414
+ interface VizSpecGenerateInput {
415
+ question: string;
416
+ sql: string;
417
+ rationale?: string;
418
+ fields: string[];
419
+ rows: Array<Record<string, unknown>>;
420
+ max_retries?: number;
421
+ query_id?: string;
422
+ }
423
+ interface VizSpecGenerateOptions {
424
+ tenantId?: string;
425
+ userId?: string;
426
+ scopes?: string[];
427
+ maxRetries?: number;
428
+ }
429
+ interface VizSpecResponse {
430
+ spec: VizSpec;
431
+ notes: string | null;
432
+ }
433
+
320
434
  /**
321
435
  * Main SDK class - Thin orchestrator
322
436
  * Delegates to deep modules (ApiClient, QueryEngine, route modules)
@@ -347,6 +461,7 @@ declare class QueryPanelSdkAPI {
347
461
  introspect(databaseName: string, tables?: string[]): Promise<SchemaIntrospection>;
348
462
  syncSchema(databaseName: string, options: SchemaSyncOptions, signal?: AbortSignal): Promise<IngestResponse>;
349
463
  ask(question: string, options: AskOptions, signal?: AbortSignal): Promise<AskResponse>;
464
+ generateVizSpec(input: VizSpecGenerateInput, options?: VizSpecGenerateOptions, signal?: AbortSignal): Promise<VizSpecResponse>;
350
465
  createChart(body: ChartCreateInput, options?: {
351
466
  tenantId?: string;
352
467
  userId?: string;
@@ -387,4 +502,4 @@ declare class QueryPanelSdkAPI {
387
502
  }, signal?: AbortSignal): Promise<void>;
388
503
  }
389
504
 
390
- export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AskOptions, type AskResponse, type ChartCreateInput, type ChartEnvelope, type ChartListOptions, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type IngestResponse, type PaginatedResponse, type PaginationInfo, type PaginationQuery, type ParamRecord, type ParamValue, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryPanelSdkAPI, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, anonymizeResults };
505
+ export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AskOptions, type AskResponse, type AxisField, type ChartCreateInput, type ChartEncoding, type ChartEnvelope, type ChartListOptions, type ChartSpec, type ChartType, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type FieldRef, type FieldType, type IngestResponse, type MetricEncoding, type MetricField, type MetricSpec, type PaginatedResponse, type PaginationInfo, type PaginationQuery, type ParamRecord, type ParamValue, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryPanelSdkAPI, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, type TableColumn, type TableEncoding, type TableSpec, type VizSpec, type VizSpecGenerateInput, type VizSpecGenerateOptions, type VizSpecResponse, anonymizeResults };
package/dist/index.d.ts CHANGED
@@ -179,6 +179,7 @@ interface SdkChart {
179
179
  sql: string;
180
180
  sql_params: Record<string, unknown> | null;
181
181
  vega_lite_spec: Record<string, unknown>;
182
+ spec_type?: 'vega-lite' | 'vizspec';
182
183
  query_id: string | null;
183
184
  organization_id: string | null;
184
185
  tenant_id: string | null;
@@ -194,6 +195,7 @@ interface ChartCreateInput {
194
195
  sql: string;
195
196
  sql_params?: Record<string, unknown>;
196
197
  vega_lite_spec: Record<string, unknown>;
198
+ spec_type?: 'vega-lite' | 'vizspec';
197
199
  query_id?: string;
198
200
  target_db?: string;
199
201
  }
@@ -203,6 +205,7 @@ interface ChartUpdateInput {
203
205
  sql?: string;
204
206
  sql_params?: Record<string, unknown>;
205
207
  vega_lite_spec?: Record<string, unknown>;
208
+ spec_type?: 'vega-lite' | 'vizspec';
206
209
  target_db?: string;
207
210
  }
208
211
  interface PaginationQuery {
@@ -281,6 +284,94 @@ interface SchemaSyncOptions {
281
284
  forceReindex?: boolean;
282
285
  }
283
286
 
287
+ /**
288
+ * VizSpec types for flexible visualization specifications
289
+ * Supports chart, table, and metric visualizations
290
+ */
291
+ type FieldType = 'quantitative' | 'temporal' | 'ordinal' | 'nominal' | 'boolean';
292
+ interface ValueFormat {
293
+ style?: 'number' | 'currency' | 'percent' | 'date' | 'time' | 'datetime';
294
+ currency?: string;
295
+ minimumFractionDigits?: number;
296
+ maximumFractionDigits?: number;
297
+ dateStyle?: 'short' | 'medium' | 'long';
298
+ }
299
+ interface FieldRef {
300
+ field: string;
301
+ label?: string;
302
+ type?: FieldType;
303
+ format?: ValueFormat;
304
+ }
305
+ type AggregateOp = 'sum' | 'avg' | 'min' | 'max' | 'count' | 'distinct';
306
+ type TimeUnit = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute';
307
+ interface AxisField extends FieldRef {
308
+ aggregate?: AggregateOp;
309
+ timeUnit?: TimeUnit;
310
+ }
311
+ interface MetricField extends FieldRef {
312
+ aggregate?: AggregateOp;
313
+ }
314
+ interface SortSpec {
315
+ field: string;
316
+ direction?: 'asc' | 'desc';
317
+ }
318
+ interface VizSpecBase {
319
+ version: '1.0';
320
+ kind: 'chart' | 'table' | 'metric';
321
+ title?: string;
322
+ description?: string;
323
+ data: {
324
+ sourceId: string;
325
+ };
326
+ }
327
+ type ChartType = 'line' | 'bar' | 'area' | 'scatter' | 'pie';
328
+ type StackingMode = 'none' | 'stacked' | 'percent';
329
+ interface ChartEncoding {
330
+ chartType: ChartType;
331
+ x?: AxisField;
332
+ y?: AxisField | AxisField[];
333
+ series?: FieldRef;
334
+ stacking?: StackingMode;
335
+ sort?: SortSpec;
336
+ limit?: number;
337
+ tooltips?: FieldRef[];
338
+ }
339
+ interface ChartSpec extends VizSpecBase {
340
+ kind: 'chart';
341
+ encoding: ChartEncoding;
342
+ }
343
+ type TextAlign = 'left' | 'right' | 'center';
344
+ interface TableColumn extends FieldRef {
345
+ width?: number;
346
+ align?: TextAlign;
347
+ isHidden?: boolean;
348
+ }
349
+ interface TableEncoding {
350
+ columns: TableColumn[];
351
+ sort?: SortSpec;
352
+ limit?: number;
353
+ }
354
+ interface TableSpec extends VizSpecBase {
355
+ kind: 'table';
356
+ encoding: TableEncoding;
357
+ }
358
+ type ComparisonMode = 'delta' | 'deltaPercent' | 'ratio';
359
+ interface MetricTrend {
360
+ timeField: AxisField;
361
+ valueField: MetricField;
362
+ }
363
+ interface MetricEncoding {
364
+ valueField: MetricField;
365
+ comparisonField?: MetricField;
366
+ comparisonMode?: ComparisonMode;
367
+ trend?: MetricTrend;
368
+ }
369
+ interface MetricSpec extends VizSpecBase {
370
+ kind: 'metric';
371
+ encoding: MetricEncoding;
372
+ }
373
+ type VizSpec = ChartSpec | TableSpec | MetricSpec;
374
+
284
375
  interface ContextDocument {
285
376
  source?: string;
286
377
  pageContent: string;
@@ -288,7 +379,9 @@ interface ContextDocument {
288
379
  score?: number;
289
380
  }
290
381
  interface ChartEnvelope {
291
- vegaLiteSpec: Record<string, unknown> | null;
382
+ vegaLiteSpec?: Record<string, unknown> | null;
383
+ vizSpec?: VizSpec | null;
384
+ specType: 'vega-lite' | 'vizspec';
292
385
  notes: string | null;
293
386
  }
294
387
  interface AskOptions {
@@ -300,6 +393,7 @@ interface AskOptions {
300
393
  previousSql?: string;
301
394
  maxRetry?: number;
302
395
  chartMaxRetries?: number;
396
+ chartType?: 'vega-lite' | 'vizspec';
303
397
  }
304
398
  interface AskResponse {
305
399
  sql: string;
@@ -317,6 +411,26 @@ interface AskResponse {
317
411
  }
318
412
  declare function anonymizeResults(rows: Array<Record<string, unknown>>): Array<Record<string, string>>;
319
413
 
414
+ interface VizSpecGenerateInput {
415
+ question: string;
416
+ sql: string;
417
+ rationale?: string;
418
+ fields: string[];
419
+ rows: Array<Record<string, unknown>>;
420
+ max_retries?: number;
421
+ query_id?: string;
422
+ }
423
+ interface VizSpecGenerateOptions {
424
+ tenantId?: string;
425
+ userId?: string;
426
+ scopes?: string[];
427
+ maxRetries?: number;
428
+ }
429
+ interface VizSpecResponse {
430
+ spec: VizSpec;
431
+ notes: string | null;
432
+ }
433
+
320
434
  /**
321
435
  * Main SDK class - Thin orchestrator
322
436
  * Delegates to deep modules (ApiClient, QueryEngine, route modules)
@@ -347,6 +461,7 @@ declare class QueryPanelSdkAPI {
347
461
  introspect(databaseName: string, tables?: string[]): Promise<SchemaIntrospection>;
348
462
  syncSchema(databaseName: string, options: SchemaSyncOptions, signal?: AbortSignal): Promise<IngestResponse>;
349
463
  ask(question: string, options: AskOptions, signal?: AbortSignal): Promise<AskResponse>;
464
+ generateVizSpec(input: VizSpecGenerateInput, options?: VizSpecGenerateOptions, signal?: AbortSignal): Promise<VizSpecResponse>;
350
465
  createChart(body: ChartCreateInput, options?: {
351
466
  tenantId?: string;
352
467
  userId?: string;
@@ -387,4 +502,4 @@ declare class QueryPanelSdkAPI {
387
502
  }, signal?: AbortSignal): Promise<void>;
388
503
  }
389
504
 
390
- export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AskOptions, type AskResponse, type ChartCreateInput, type ChartEnvelope, type ChartListOptions, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type IngestResponse, type PaginatedResponse, type PaginationInfo, type PaginationQuery, type ParamRecord, type ParamValue, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryPanelSdkAPI, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, anonymizeResults };
505
+ export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AskOptions, type AskResponse, type AxisField, type ChartCreateInput, type ChartEncoding, type ChartEnvelope, type ChartListOptions, type ChartSpec, type ChartType, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type FieldRef, type FieldType, type IngestResponse, type MetricEncoding, type MetricField, type MetricSpec, type PaginatedResponse, type PaginationInfo, type PaginationQuery, type ParamRecord, type ParamValue, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryPanelSdkAPI, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, type TableColumn, type TableEncoding, type TableSpec, type VizSpec, type VizSpecGenerateInput, type VizSpecGenerateOptions, type VizSpecResponse, anonymizeResults };
package/dist/index.js CHANGED
@@ -1162,35 +1162,62 @@ async function ask(client, queryEngine, question, options, signal) {
1162
1162
  tenantId
1163
1163
  );
1164
1164
  const rows = execution.rows ?? [];
1165
+ const chartType = options.chartType ?? "vega-lite";
1165
1166
  let chart = {
1166
- vegaLiteSpec: null,
1167
+ specType: chartType,
1167
1168
  notes: rows.length === 0 ? "Query returned no rows." : null
1168
1169
  };
1169
1170
  if (rows.length > 0) {
1170
- const chartResponse = await client.post(
1171
- "/chart",
1172
- {
1173
- question,
1174
- sql: queryResponse.sql,
1175
- rationale: queryResponse.rationale,
1176
- fields: execution.fields,
1177
- rows: anonymizeResults(rows),
1178
- max_retries: options.chartMaxRetries ?? 3,
1179
- query_id: queryResponse.queryId
1180
- },
1181
- tenantId,
1182
- options.userId,
1183
- options.scopes,
1184
- signal,
1185
- sessionId
1186
- );
1187
- chart = {
1188
- vegaLiteSpec: chartResponse.chart ? {
1189
- ...chartResponse.chart,
1190
- data: { values: rows }
1191
- } : null,
1192
- notes: chartResponse.notes
1193
- };
1171
+ if (chartType === "vizspec") {
1172
+ const vizspecResponse = await client.post(
1173
+ "/vizspec",
1174
+ {
1175
+ question,
1176
+ sql: queryResponse.sql,
1177
+ rationale: queryResponse.rationale,
1178
+ fields: execution.fields,
1179
+ rows: anonymizeResults(rows),
1180
+ max_retries: options.chartMaxRetries ?? 3,
1181
+ query_id: queryResponse.queryId
1182
+ },
1183
+ tenantId,
1184
+ options.userId,
1185
+ options.scopes,
1186
+ signal,
1187
+ sessionId
1188
+ );
1189
+ chart = {
1190
+ vizSpec: vizspecResponse.spec,
1191
+ specType: "vizspec",
1192
+ notes: vizspecResponse.notes
1193
+ };
1194
+ } else {
1195
+ const chartResponse = await client.post(
1196
+ "/chart",
1197
+ {
1198
+ question,
1199
+ sql: queryResponse.sql,
1200
+ rationale: queryResponse.rationale,
1201
+ fields: execution.fields,
1202
+ rows: anonymizeResults(rows),
1203
+ max_retries: options.chartMaxRetries ?? 3,
1204
+ query_id: queryResponse.queryId
1205
+ },
1206
+ tenantId,
1207
+ options.userId,
1208
+ options.scopes,
1209
+ signal,
1210
+ sessionId
1211
+ );
1212
+ chart = {
1213
+ vegaLiteSpec: chartResponse.chart ? {
1214
+ ...chartResponse.chart,
1215
+ data: { values: rows }
1216
+ } : null,
1217
+ specType: "vega-lite",
1218
+ notes: chartResponse.notes
1219
+ };
1220
+ }
1194
1221
  }
1195
1222
  return {
1196
1223
  sql: queryResponse.sql,
@@ -1242,6 +1269,39 @@ function anonymizeResults(rows) {
1242
1269
  });
1243
1270
  }
1244
1271
 
1272
+ // src/routes/vizspec.ts
1273
+ async function generateVizSpec(client, input, options, signal) {
1274
+ const tenantId = resolveTenantId5(client, options?.tenantId);
1275
+ const sessionId = crypto.randomUUID();
1276
+ const response = await client.post(
1277
+ "/vizspec",
1278
+ {
1279
+ question: input.question,
1280
+ sql: input.sql,
1281
+ rationale: input.rationale,
1282
+ fields: input.fields,
1283
+ rows: input.rows,
1284
+ max_retries: options?.maxRetries ?? input.max_retries ?? 3,
1285
+ query_id: input.query_id
1286
+ },
1287
+ tenantId,
1288
+ options?.userId,
1289
+ options?.scopes,
1290
+ signal,
1291
+ sessionId
1292
+ );
1293
+ return response;
1294
+ }
1295
+ function resolveTenantId5(client, tenantId) {
1296
+ const resolved = tenantId ?? client.getDefaultTenantId();
1297
+ if (!resolved) {
1298
+ throw new Error(
1299
+ "tenantId is required. Provide it per request or via defaultTenantId option."
1300
+ );
1301
+ }
1302
+ return resolved;
1303
+ }
1304
+
1245
1305
  // src/index.ts
1246
1306
  var QueryPanelSdkAPI = class {
1247
1307
  client;
@@ -1307,6 +1367,15 @@ var QueryPanelSdkAPI = class {
1307
1367
  signal
1308
1368
  );
1309
1369
  }
1370
+ // VizSpec generation
1371
+ async generateVizSpec(input, options, signal) {
1372
+ return await generateVizSpec(
1373
+ this.client,
1374
+ input,
1375
+ options,
1376
+ signal
1377
+ );
1378
+ }
1310
1379
  // Chart CRUD operations
1311
1380
  async createChart(body, options, signal) {
1312
1381
  return await createChart(this.client, body, options, signal);