@querypanel/node-sdk 1.0.51 → 1.0.53
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.cjs +194 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -1
- package/dist/index.d.ts +50 -1
- package/dist/index.js +194 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -180,6 +180,7 @@ declare const QueryErrorCode: {
|
|
|
180
180
|
readonly SQL_GENERATION_FAILED: "SQL_GENERATION_FAILED";
|
|
181
181
|
readonly SQL_VALIDATION_FAILED: "SQL_VALIDATION_FAILED";
|
|
182
182
|
readonly CONTEXT_RETRIEVAL_FAILED: "CONTEXT_RETRIEVAL_FAILED";
|
|
183
|
+
readonly CLARIFICATION_NEEDED: "CLARIFICATION_NEEDED";
|
|
183
184
|
readonly INTERNAL_ERROR: "INTERNAL_ERROR";
|
|
184
185
|
readonly AUTHENTICATION_REQUIRED: "AUTHENTICATION_REQUIRED";
|
|
185
186
|
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
@@ -208,6 +209,10 @@ declare class QueryPipelineError extends Error {
|
|
|
208
209
|
* Check if this is any guardrail error (relevance or security)
|
|
209
210
|
*/
|
|
210
211
|
isGuardrailError(): boolean;
|
|
212
|
+
/**
|
|
213
|
+
* Check if this is a clarification needed error (v2 pipeline)
|
|
214
|
+
*/
|
|
215
|
+
isClarificationNeeded(): boolean;
|
|
211
216
|
}
|
|
212
217
|
|
|
213
218
|
type ParamValue = string | number | boolean | string[] | number[];
|
|
@@ -514,6 +519,40 @@ interface AskOptions {
|
|
|
514
519
|
* Use this to reuse a previously returned session for follow-up prompts.
|
|
515
520
|
*/
|
|
516
521
|
querypanelSessionId?: string;
|
|
522
|
+
/**
|
|
523
|
+
* Pipeline version to use for query generation.
|
|
524
|
+
* - "v1" (default): Original query pipeline
|
|
525
|
+
* - "v2": Improved pipeline with intent planning, hybrid retrieval, schema linking, and SQL reflection
|
|
526
|
+
*/
|
|
527
|
+
pipeline?: "v1" | "v2";
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Intent analysis result from the v2 pipeline.
|
|
531
|
+
*/
|
|
532
|
+
interface IntentResult {
|
|
533
|
+
intent: string;
|
|
534
|
+
confidence: number;
|
|
535
|
+
plan: {
|
|
536
|
+
tables: string[];
|
|
537
|
+
operations: string[];
|
|
538
|
+
filters: string[];
|
|
539
|
+
orderBy?: string;
|
|
540
|
+
limit?: number;
|
|
541
|
+
};
|
|
542
|
+
ambiguities: Array<{
|
|
543
|
+
issue: string;
|
|
544
|
+
suggestion: string;
|
|
545
|
+
}>;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Pipeline execution trace with step-level timing.
|
|
549
|
+
*/
|
|
550
|
+
interface PipelineTrace {
|
|
551
|
+
totalDurationMs: number;
|
|
552
|
+
steps: Array<{
|
|
553
|
+
step: string;
|
|
554
|
+
durationMs: number;
|
|
555
|
+
}>;
|
|
517
556
|
}
|
|
518
557
|
/**
|
|
519
558
|
* Response returned after executing a query.
|
|
@@ -545,6 +584,10 @@ interface AskResponse {
|
|
|
545
584
|
target_db?: string;
|
|
546
585
|
/** QueryPanel session ID for follow-up queries. */
|
|
547
586
|
querypanelSessionId?: string;
|
|
587
|
+
/** Intent analysis from v2 pipeline. */
|
|
588
|
+
intent?: IntentResult;
|
|
589
|
+
/** Pipeline execution trace from v2 pipeline. */
|
|
590
|
+
trace?: PipelineTrace;
|
|
548
591
|
}
|
|
549
592
|
declare function anonymizeResults(rows: Array<Record<string, unknown>>): Array<Record<string, string>>;
|
|
550
593
|
|
|
@@ -688,6 +731,12 @@ interface ChartModifyOptions {
|
|
|
688
731
|
chartMaxRetries?: number;
|
|
689
732
|
/** Chart generation method: 'vega-lite' or 'vizspec' */
|
|
690
733
|
chartType?: "vega-lite" | "vizspec";
|
|
734
|
+
/**
|
|
735
|
+
* Pipeline version to use for SQL regeneration.
|
|
736
|
+
* - "v1" (default): Original query pipeline
|
|
737
|
+
* - "v2": Improved pipeline with intent planning, hybrid retrieval, schema linking, and SQL reflection
|
|
738
|
+
*/
|
|
739
|
+
pipeline?: "v1" | "v2";
|
|
691
740
|
}
|
|
692
741
|
/**
|
|
693
742
|
* Response from modifyChart(), extending AskResponse with modification metadata.
|
|
@@ -1283,4 +1332,4 @@ declare class QueryPanelSdkAPI {
|
|
|
1283
1332
|
}, signal?: AbortSignal): Promise<void>;
|
|
1284
1333
|
}
|
|
1285
1334
|
|
|
1286
|
-
export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AggregateOp, type AskOptions, type AskResponse, type AxisField, type AxisFieldInput, type ChartCreateInput, type ChartEncoding, type ChartEnvelope, type ChartListOptions, type ChartModifyInput, type ChartModifyOptions, type ChartModifyResponse, type ChartSpec, type ChartType, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type DateRangeInput, type EncodingHints, type FieldRef, type FieldRefInput, type FieldType, type IngestResponse, type MetricEncoding, type MetricField, type MetricSpec, type PaginatedResponse$1 as PaginatedResponse, type PaginationInfo$1 as PaginationInfo, type PaginationQuery$1 as PaginationQuery, type ParamRecord, type ParamValue, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryErrorCode, QueryErrorCode as QueryErrorCodeType, QueryPanelSdkAPI, QueryPipelineError, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, type SdkSession, type SdkSessionTurn, type SessionGetOptions, type SessionListOptions, type SessionUpdateInput, type SqlModifications, type StackingMode, type TableColumn, type TableEncoding, type TableSpec, type TimeUnit, type ValueFormat, type VizModifications, type VizSpec, type VizSpecGenerateInput, type VizSpecGenerateOptions, type VizSpecGeneratorInput, type VizSpecKind, type VizSpecResponse, type VizSpecResult, anonymizeResults };
|
|
1335
|
+
export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AggregateOp, type AskOptions, type AskResponse, type AxisField, type AxisFieldInput, type ChartCreateInput, type ChartEncoding, type ChartEnvelope, type ChartListOptions, type ChartModifyInput, type ChartModifyOptions, type ChartModifyResponse, type ChartSpec, type ChartType, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type DateRangeInput, type EncodingHints, type FieldRef, type FieldRefInput, type FieldType, type IngestResponse, type IntentResult, type MetricEncoding, type MetricField, type MetricSpec, type PaginatedResponse$1 as PaginatedResponse, type PaginationInfo$1 as PaginationInfo, type PaginationQuery$1 as PaginationQuery, type ParamRecord, type ParamValue, type PipelineTrace, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryErrorCode, QueryErrorCode as QueryErrorCodeType, QueryPanelSdkAPI, QueryPipelineError, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, type SdkSession, type SdkSessionTurn, type SessionGetOptions, type SessionListOptions, type SessionUpdateInput, type SqlModifications, type StackingMode, type TableColumn, type TableEncoding, type TableSpec, type TimeUnit, type ValueFormat, type VizModifications, type VizSpec, type VizSpecGenerateInput, type VizSpecGenerateOptions, type VizSpecGeneratorInput, type VizSpecKind, type VizSpecResponse, type VizSpecResult, anonymizeResults };
|
package/dist/index.d.ts
CHANGED
|
@@ -180,6 +180,7 @@ declare const QueryErrorCode: {
|
|
|
180
180
|
readonly SQL_GENERATION_FAILED: "SQL_GENERATION_FAILED";
|
|
181
181
|
readonly SQL_VALIDATION_FAILED: "SQL_VALIDATION_FAILED";
|
|
182
182
|
readonly CONTEXT_RETRIEVAL_FAILED: "CONTEXT_RETRIEVAL_FAILED";
|
|
183
|
+
readonly CLARIFICATION_NEEDED: "CLARIFICATION_NEEDED";
|
|
183
184
|
readonly INTERNAL_ERROR: "INTERNAL_ERROR";
|
|
184
185
|
readonly AUTHENTICATION_REQUIRED: "AUTHENTICATION_REQUIRED";
|
|
185
186
|
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
@@ -208,6 +209,10 @@ declare class QueryPipelineError extends Error {
|
|
|
208
209
|
* Check if this is any guardrail error (relevance or security)
|
|
209
210
|
*/
|
|
210
211
|
isGuardrailError(): boolean;
|
|
212
|
+
/**
|
|
213
|
+
* Check if this is a clarification needed error (v2 pipeline)
|
|
214
|
+
*/
|
|
215
|
+
isClarificationNeeded(): boolean;
|
|
211
216
|
}
|
|
212
217
|
|
|
213
218
|
type ParamValue = string | number | boolean | string[] | number[];
|
|
@@ -514,6 +519,40 @@ interface AskOptions {
|
|
|
514
519
|
* Use this to reuse a previously returned session for follow-up prompts.
|
|
515
520
|
*/
|
|
516
521
|
querypanelSessionId?: string;
|
|
522
|
+
/**
|
|
523
|
+
* Pipeline version to use for query generation.
|
|
524
|
+
* - "v1" (default): Original query pipeline
|
|
525
|
+
* - "v2": Improved pipeline with intent planning, hybrid retrieval, schema linking, and SQL reflection
|
|
526
|
+
*/
|
|
527
|
+
pipeline?: "v1" | "v2";
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Intent analysis result from the v2 pipeline.
|
|
531
|
+
*/
|
|
532
|
+
interface IntentResult {
|
|
533
|
+
intent: string;
|
|
534
|
+
confidence: number;
|
|
535
|
+
plan: {
|
|
536
|
+
tables: string[];
|
|
537
|
+
operations: string[];
|
|
538
|
+
filters: string[];
|
|
539
|
+
orderBy?: string;
|
|
540
|
+
limit?: number;
|
|
541
|
+
};
|
|
542
|
+
ambiguities: Array<{
|
|
543
|
+
issue: string;
|
|
544
|
+
suggestion: string;
|
|
545
|
+
}>;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Pipeline execution trace with step-level timing.
|
|
549
|
+
*/
|
|
550
|
+
interface PipelineTrace {
|
|
551
|
+
totalDurationMs: number;
|
|
552
|
+
steps: Array<{
|
|
553
|
+
step: string;
|
|
554
|
+
durationMs: number;
|
|
555
|
+
}>;
|
|
517
556
|
}
|
|
518
557
|
/**
|
|
519
558
|
* Response returned after executing a query.
|
|
@@ -545,6 +584,10 @@ interface AskResponse {
|
|
|
545
584
|
target_db?: string;
|
|
546
585
|
/** QueryPanel session ID for follow-up queries. */
|
|
547
586
|
querypanelSessionId?: string;
|
|
587
|
+
/** Intent analysis from v2 pipeline. */
|
|
588
|
+
intent?: IntentResult;
|
|
589
|
+
/** Pipeline execution trace from v2 pipeline. */
|
|
590
|
+
trace?: PipelineTrace;
|
|
548
591
|
}
|
|
549
592
|
declare function anonymizeResults(rows: Array<Record<string, unknown>>): Array<Record<string, string>>;
|
|
550
593
|
|
|
@@ -688,6 +731,12 @@ interface ChartModifyOptions {
|
|
|
688
731
|
chartMaxRetries?: number;
|
|
689
732
|
/** Chart generation method: 'vega-lite' or 'vizspec' */
|
|
690
733
|
chartType?: "vega-lite" | "vizspec";
|
|
734
|
+
/**
|
|
735
|
+
* Pipeline version to use for SQL regeneration.
|
|
736
|
+
* - "v1" (default): Original query pipeline
|
|
737
|
+
* - "v2": Improved pipeline with intent planning, hybrid retrieval, schema linking, and SQL reflection
|
|
738
|
+
*/
|
|
739
|
+
pipeline?: "v1" | "v2";
|
|
691
740
|
}
|
|
692
741
|
/**
|
|
693
742
|
* Response from modifyChart(), extending AskResponse with modification metadata.
|
|
@@ -1283,4 +1332,4 @@ declare class QueryPanelSdkAPI {
|
|
|
1283
1332
|
}, signal?: AbortSignal): Promise<void>;
|
|
1284
1333
|
}
|
|
1285
1334
|
|
|
1286
|
-
export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AggregateOp, type AskOptions, type AskResponse, type AxisField, type AxisFieldInput, type ChartCreateInput, type ChartEncoding, type ChartEnvelope, type ChartListOptions, type ChartModifyInput, type ChartModifyOptions, type ChartModifyResponse, type ChartSpec, type ChartType, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type DateRangeInput, type EncodingHints, type FieldRef, type FieldRefInput, type FieldType, type IngestResponse, type MetricEncoding, type MetricField, type MetricSpec, type PaginatedResponse$1 as PaginatedResponse, type PaginationInfo$1 as PaginationInfo, type PaginationQuery$1 as PaginationQuery, type ParamRecord, type ParamValue, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryErrorCode, QueryErrorCode as QueryErrorCodeType, QueryPanelSdkAPI, QueryPipelineError, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, type SdkSession, type SdkSessionTurn, type SessionGetOptions, type SessionListOptions, type SessionUpdateInput, type SqlModifications, type StackingMode, type TableColumn, type TableEncoding, type TableSpec, type TimeUnit, type ValueFormat, type VizModifications, type VizSpec, type VizSpecGenerateInput, type VizSpecGenerateOptions, type VizSpecGeneratorInput, type VizSpecKind, type VizSpecResponse, type VizSpecResult, anonymizeResults };
|
|
1335
|
+
export { type ActiveChartCreateInput, type ActiveChartListOptions, type ActiveChartUpdateInput, type AggregateOp, type AskOptions, type AskResponse, type AxisField, type AxisFieldInput, type ChartCreateInput, type ChartEncoding, type ChartEnvelope, type ChartListOptions, type ChartModifyInput, type ChartModifyOptions, type ChartModifyResponse, type ChartSpec, type ChartType, type ChartUpdateInput, ClickHouseAdapter, type ClickHouseAdapterOptions, type ClickHouseClientFn, type ContextDocument, type DatabaseAdapter, type DatabaseDialect, type DateRangeInput, type EncodingHints, type FieldRef, type FieldRefInput, type FieldType, type IngestResponse, type IntentResult, type MetricEncoding, type MetricField, type MetricSpec, type PaginatedResponse$1 as PaginatedResponse, type PaginationInfo$1 as PaginationInfo, type PaginationQuery$1 as PaginationQuery, type ParamRecord, type ParamValue, type PipelineTrace, PostgresAdapter, type PostgresAdapterOptions, type PostgresClientFn, QueryErrorCode, QueryErrorCode as QueryErrorCodeType, QueryPanelSdkAPI, QueryPipelineError, type SchemaIntrospection, type SchemaSyncOptions, type SdkActiveChart, type SdkChart, type SdkSession, type SdkSessionTurn, type SessionGetOptions, type SessionListOptions, type SessionUpdateInput, type SqlModifications, type StackingMode, type TableColumn, type TableEncoding, type TableSpec, type TimeUnit, type ValueFormat, type VizModifications, type VizSpec, type VizSpecGenerateInput, type VizSpecGenerateOptions, type VizSpecGeneratorInput, type VizSpecKind, type VizSpecResponse, type VizSpecResult, anonymizeResults };
|
package/dist/index.js
CHANGED
|
@@ -888,6 +888,8 @@ var QueryErrorCode = {
|
|
|
888
888
|
SQL_VALIDATION_FAILED: "SQL_VALIDATION_FAILED",
|
|
889
889
|
// Context retrieval errors
|
|
890
890
|
CONTEXT_RETRIEVAL_FAILED: "CONTEXT_RETRIEVAL_FAILED",
|
|
891
|
+
// Clarification errors (v2)
|
|
892
|
+
CLARIFICATION_NEEDED: "CLARIFICATION_NEEDED",
|
|
891
893
|
// General errors
|
|
892
894
|
INTERNAL_ERROR: "INTERNAL_ERROR",
|
|
893
895
|
AUTHENTICATION_REQUIRED: "AUTHENTICATION_REQUIRED",
|
|
@@ -924,6 +926,12 @@ var QueryPipelineError = class extends Error {
|
|
|
924
926
|
isGuardrailError() {
|
|
925
927
|
return this.isRelevanceError() || this.isSecurityError();
|
|
926
928
|
}
|
|
929
|
+
/**
|
|
930
|
+
* Check if this is a clarification needed error (v2 pipeline)
|
|
931
|
+
*/
|
|
932
|
+
isClarificationNeeded() {
|
|
933
|
+
return this.code === QueryErrorCode.CLARIFICATION_NEEDED;
|
|
934
|
+
}
|
|
927
935
|
};
|
|
928
936
|
|
|
929
937
|
// src/routes/charts.ts
|
|
@@ -1235,6 +1243,7 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1235
1243
|
let attempt = 0;
|
|
1236
1244
|
let lastError = options.lastError;
|
|
1237
1245
|
let previousSql = options.previousSql;
|
|
1246
|
+
const queryEndpoint = options.pipeline === "v2" ? "/v2/query" : "/query";
|
|
1238
1247
|
while (attempt <= maxRetry) {
|
|
1239
1248
|
console.log({ lastError, previousSql });
|
|
1240
1249
|
const databaseName = options.database ?? queryEngine.getDefaultDatabase();
|
|
@@ -1248,7 +1257,7 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1248
1257
|
};
|
|
1249
1258
|
}
|
|
1250
1259
|
const queryResponse = await client.postWithHeaders(
|
|
1251
|
-
|
|
1260
|
+
queryEndpoint,
|
|
1252
1261
|
{
|
|
1253
1262
|
question,
|
|
1254
1263
|
...querypanelSessionId ? { session_id: querypanelSessionId } : {},
|
|
@@ -1364,7 +1373,9 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1364
1373
|
context: queryResponse.data.context,
|
|
1365
1374
|
attempts: attempt + 1,
|
|
1366
1375
|
target_db: dbName,
|
|
1367
|
-
querypanelSessionId: responseSessionId ?? void 0
|
|
1376
|
+
querypanelSessionId: responseSessionId ?? void 0,
|
|
1377
|
+
intent: queryResponse.data.intent,
|
|
1378
|
+
trace: queryResponse.data.trace
|
|
1368
1379
|
};
|
|
1369
1380
|
} catch (error) {
|
|
1370
1381
|
attempt++;
|
|
@@ -1403,21 +1414,39 @@ function anonymizeResults(rows) {
|
|
|
1403
1414
|
}
|
|
1404
1415
|
|
|
1405
1416
|
// src/routes/modify.ts
|
|
1406
|
-
function buildModifiedQuestion(originalQuestion, modifications) {
|
|
1417
|
+
function buildModifiedQuestion(originalQuestion, modifications, pipeline) {
|
|
1407
1418
|
const hints = [];
|
|
1408
1419
|
if (modifications.timeGranularity) {
|
|
1409
1420
|
hints.push(`group results by ${modifications.timeGranularity}`);
|
|
1410
1421
|
}
|
|
1411
1422
|
if (modifications.dateRange) {
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1423
|
+
if (pipeline === "v2") {
|
|
1424
|
+
const from = normalizeDateInput(modifications.dateRange.from);
|
|
1425
|
+
const to = normalizeDateInput(modifications.dateRange.to);
|
|
1426
|
+
if (from && to) {
|
|
1427
|
+
hints.push(
|
|
1428
|
+
`replace any existing date filters with exact date range from ${from} to ${to} (inclusive, do not add extra days)`
|
|
1429
|
+
);
|
|
1430
|
+
} else if (from) {
|
|
1431
|
+
hints.push(
|
|
1432
|
+
`replace any existing date filters with exact start date ${from} (do not shift this date)`
|
|
1433
|
+
);
|
|
1434
|
+
} else if (to) {
|
|
1435
|
+
hints.push(
|
|
1436
|
+
`replace any existing date filters with exact end date ${to} (inclusive, do not add extra days)`
|
|
1437
|
+
);
|
|
1438
|
+
}
|
|
1439
|
+
} else {
|
|
1440
|
+
const parts = [];
|
|
1441
|
+
if (modifications.dateRange.from) {
|
|
1442
|
+
parts.push(`from ${modifications.dateRange.from}`);
|
|
1443
|
+
}
|
|
1444
|
+
if (modifications.dateRange.to) {
|
|
1445
|
+
parts.push(`to ${modifications.dateRange.to}`);
|
|
1446
|
+
}
|
|
1447
|
+
if (parts.length > 0) {
|
|
1448
|
+
hints.push(`filter date range ${parts.join(" ")}`);
|
|
1449
|
+
}
|
|
1421
1450
|
}
|
|
1422
1451
|
}
|
|
1423
1452
|
if (modifications.additionalInstructions) {
|
|
@@ -1428,6 +1457,67 @@ function buildModifiedQuestion(originalQuestion, modifications) {
|
|
|
1428
1457
|
}
|
|
1429
1458
|
return `${originalQuestion} (${hints.join(", ")})`;
|
|
1430
1459
|
}
|
|
1460
|
+
var START_PARAM_KEY_REGEX = /(^|_)(start|from)(_|$)/i;
|
|
1461
|
+
var END_PARAM_KEY_REGEX = /(^|_)(end|to)(_|$)/i;
|
|
1462
|
+
var ISO_DATETIME_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z?$/;
|
|
1463
|
+
var SQL_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
1464
|
+
var SQL_DATETIME_RE = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
|
|
1465
|
+
function normalizeDateInput(value) {
|
|
1466
|
+
if (!value) return void 0;
|
|
1467
|
+
const trimmed = value.trim();
|
|
1468
|
+
if (!trimmed) return void 0;
|
|
1469
|
+
if (ISO_DATETIME_RE.test(trimmed)) {
|
|
1470
|
+
return trimmed.replace("T", " ").replace(/\.\d+Z?$/, "").replace(/Z$/, "");
|
|
1471
|
+
}
|
|
1472
|
+
return trimmed;
|
|
1473
|
+
}
|
|
1474
|
+
function keyLooksLikeDateBoundary(key, boundary) {
|
|
1475
|
+
return boundary === "start" ? START_PARAM_KEY_REGEX.test(key) : END_PARAM_KEY_REGEX.test(key);
|
|
1476
|
+
}
|
|
1477
|
+
function hasTimeComponent(value) {
|
|
1478
|
+
return typeof value === "string" && /\d{2}:\d{2}:\d{2}/.test(value);
|
|
1479
|
+
}
|
|
1480
|
+
function formatDateOverride(dateValue, boundary, existingValue) {
|
|
1481
|
+
if (SQL_DATE_RE.test(dateValue) && !hasTimeComponent(existingValue)) {
|
|
1482
|
+
return dateValue;
|
|
1483
|
+
}
|
|
1484
|
+
if (SQL_DATE_RE.test(dateValue)) {
|
|
1485
|
+
return `${dateValue} ${boundary === "start" ? "00:00:00" : "23:59:59"}`;
|
|
1486
|
+
}
|
|
1487
|
+
if (SQL_DATETIME_RE.test(dateValue)) {
|
|
1488
|
+
return dateValue;
|
|
1489
|
+
}
|
|
1490
|
+
return dateValue;
|
|
1491
|
+
}
|
|
1492
|
+
function normalizeGeneratedParamKey(param, index) {
|
|
1493
|
+
const nameCandidate = typeof param.name === "string" && param.name.trim() || typeof param.placeholder === "string" && param.placeholder.trim() || typeof param.position === "number" && String(param.position) || String(index + 1);
|
|
1494
|
+
return nameCandidate.replace(/[{}]/g, "").replace(/(.+):.*$/, "$1").replace(/^[:$]/, "").trim();
|
|
1495
|
+
}
|
|
1496
|
+
function applyDateRangeOverrides(dateRange, params, paramMetadata) {
|
|
1497
|
+
if (!dateRange) return;
|
|
1498
|
+
const from = normalizeDateInput(dateRange.from);
|
|
1499
|
+
const to = normalizeDateInput(dateRange.to);
|
|
1500
|
+
if (!from && !to) return;
|
|
1501
|
+
for (const [key, value] of Object.entries(params)) {
|
|
1502
|
+
if (from && keyLooksLikeDateBoundary(key, "start")) {
|
|
1503
|
+
params[key] = formatDateOverride(from, "start", value);
|
|
1504
|
+
}
|
|
1505
|
+
if (to && keyLooksLikeDateBoundary(key, "end")) {
|
|
1506
|
+
params[key] = formatDateOverride(to, "end", value);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
for (let i = 0; i < paramMetadata.length; i++) {
|
|
1510
|
+
const param = paramMetadata[i];
|
|
1511
|
+
if (!param) continue;
|
|
1512
|
+
const key = normalizeGeneratedParamKey(param, i);
|
|
1513
|
+
if (from && keyLooksLikeDateBoundary(key, "start")) {
|
|
1514
|
+
param.value = formatDateOverride(from, "start", param.value);
|
|
1515
|
+
}
|
|
1516
|
+
if (to && keyLooksLikeDateBoundary(key, "end")) {
|
|
1517
|
+
param.value = formatDateOverride(to, "end", param.value);
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1431
1521
|
function buildVizHints(modifications) {
|
|
1432
1522
|
const hints = {};
|
|
1433
1523
|
if (modifications.kind) {
|
|
@@ -1460,6 +1550,9 @@ function stripVizSpecOnlyHints(hints) {
|
|
|
1460
1550
|
const { kind: _kind, ...rest } = hints;
|
|
1461
1551
|
return rest;
|
|
1462
1552
|
}
|
|
1553
|
+
function isDateRangeOnly(mods) {
|
|
1554
|
+
return !!mods.dateRange && !mods.timeGranularity && !mods.additionalInstructions && !mods.customSql;
|
|
1555
|
+
}
|
|
1463
1556
|
function resolveTenantId5(client, tenantId) {
|
|
1464
1557
|
const resolved = tenantId ?? client.getDefaultTenantId();
|
|
1465
1558
|
if (!resolved) {
|
|
@@ -1476,12 +1569,14 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
1476
1569
|
const hasSqlMods = !!input.sqlModifications;
|
|
1477
1570
|
const hasVizMods = !!input.vizModifications;
|
|
1478
1571
|
const hasCustomSql = !!input.sqlModifications?.customSql;
|
|
1572
|
+
const queryEndpoint = options?.pipeline === "v2" ? "/v2/query" : "/query";
|
|
1479
1573
|
let finalSql = input.sql;
|
|
1480
1574
|
let finalParams = input.params ?? {};
|
|
1481
1575
|
let paramMetadata = [];
|
|
1482
1576
|
let rationale;
|
|
1483
1577
|
let queryId;
|
|
1484
1578
|
let sqlChanged = false;
|
|
1579
|
+
let finalQuestion = input.question;
|
|
1485
1580
|
const databaseName = input.database ?? queryEngine.getDefaultDatabase();
|
|
1486
1581
|
if (!databaseName) {
|
|
1487
1582
|
throw new Error(
|
|
@@ -1502,13 +1597,89 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
1502
1597
|
finalParams = {};
|
|
1503
1598
|
paramMetadata = [];
|
|
1504
1599
|
sqlChanged = true;
|
|
1600
|
+
} else if (hasSqlMods && options?.pipeline === "v2" && isDateRangeOnly(input.sqlModifications)) {
|
|
1601
|
+
let usedFastPath = false;
|
|
1602
|
+
try {
|
|
1603
|
+
const rewriteResponse = await client.post(
|
|
1604
|
+
"/v2/rewrite-datefilter",
|
|
1605
|
+
{
|
|
1606
|
+
previous_sql: input.sql,
|
|
1607
|
+
previous_params: input.params ? Object.entries(input.params).map(([name, value]) => ({
|
|
1608
|
+
name,
|
|
1609
|
+
value
|
|
1610
|
+
})) : [],
|
|
1611
|
+
date_range: input.sqlModifications.dateRange,
|
|
1612
|
+
question: input.question,
|
|
1613
|
+
...tenantSettings ? { tenant_settings: tenantSettings } : {},
|
|
1614
|
+
...databaseName ? { database: databaseName } : {},
|
|
1615
|
+
...metadata?.dialect ? { dialect: metadata.dialect } : {}
|
|
1616
|
+
},
|
|
1617
|
+
tenantId,
|
|
1618
|
+
options?.userId,
|
|
1619
|
+
options?.scopes,
|
|
1620
|
+
signal,
|
|
1621
|
+
sessionId
|
|
1622
|
+
);
|
|
1623
|
+
finalSql = rewriteResponse.sql;
|
|
1624
|
+
paramMetadata = Array.isArray(rewriteResponse.params) ? rewriteResponse.params : [];
|
|
1625
|
+
finalParams = queryEngine.mapGeneratedParams(paramMetadata);
|
|
1626
|
+
applyDateRangeOverrides(
|
|
1627
|
+
input.sqlModifications?.dateRange,
|
|
1628
|
+
finalParams,
|
|
1629
|
+
paramMetadata
|
|
1630
|
+
);
|
|
1631
|
+
rationale = rewriteResponse.rationale;
|
|
1632
|
+
queryId = rewriteResponse.queryId;
|
|
1633
|
+
sqlChanged = finalSql !== input.sql;
|
|
1634
|
+
usedFastPath = true;
|
|
1635
|
+
} catch {
|
|
1636
|
+
}
|
|
1637
|
+
if (!usedFastPath) {
|
|
1638
|
+
const modifiedQuestion = buildModifiedQuestion(
|
|
1639
|
+
input.question,
|
|
1640
|
+
input.sqlModifications,
|
|
1641
|
+
"v2"
|
|
1642
|
+
);
|
|
1643
|
+
finalQuestion = modifiedQuestion;
|
|
1644
|
+
const queryResponse = await client.post(
|
|
1645
|
+
queryEndpoint,
|
|
1646
|
+
{
|
|
1647
|
+
question: modifiedQuestion,
|
|
1648
|
+
previous_sql: input.sql,
|
|
1649
|
+
...options?.maxRetry ? { max_retry: options.maxRetry } : {},
|
|
1650
|
+
...tenantSettings ? { tenant_settings: tenantSettings } : {},
|
|
1651
|
+
...databaseName ? { database: databaseName } : {},
|
|
1652
|
+
...metadata?.dialect ? { dialect: metadata.dialect } : {}
|
|
1653
|
+
},
|
|
1654
|
+
tenantId,
|
|
1655
|
+
options?.userId,
|
|
1656
|
+
options?.scopes,
|
|
1657
|
+
signal,
|
|
1658
|
+
sessionId
|
|
1659
|
+
);
|
|
1660
|
+
finalSql = queryResponse.sql;
|
|
1661
|
+
paramMetadata = Array.isArray(queryResponse.params) ? queryResponse.params : [];
|
|
1662
|
+
finalParams = queryEngine.mapGeneratedParams(paramMetadata);
|
|
1663
|
+
applyDateRangeOverrides(
|
|
1664
|
+
input.sqlModifications?.dateRange,
|
|
1665
|
+
finalParams,
|
|
1666
|
+
paramMetadata
|
|
1667
|
+
);
|
|
1668
|
+
rationale = queryResponse.rationale;
|
|
1669
|
+
queryId = queryResponse.queryId;
|
|
1670
|
+
sqlChanged = finalSql !== input.sql;
|
|
1671
|
+
}
|
|
1505
1672
|
} else if (hasSqlMods && !hasCustomSql) {
|
|
1506
1673
|
const modifiedQuestion = buildModifiedQuestion(
|
|
1507
1674
|
input.question,
|
|
1508
|
-
input.sqlModifications
|
|
1675
|
+
input.sqlModifications,
|
|
1676
|
+
options?.pipeline
|
|
1509
1677
|
);
|
|
1678
|
+
if (options?.pipeline === "v2") {
|
|
1679
|
+
finalQuestion = modifiedQuestion;
|
|
1680
|
+
}
|
|
1510
1681
|
const queryResponse = await client.post(
|
|
1511
|
-
|
|
1682
|
+
queryEndpoint,
|
|
1512
1683
|
{
|
|
1513
1684
|
question: modifiedQuestion,
|
|
1514
1685
|
previous_sql: input.sql,
|
|
@@ -1526,6 +1697,13 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
1526
1697
|
finalSql = queryResponse.sql;
|
|
1527
1698
|
paramMetadata = Array.isArray(queryResponse.params) ? queryResponse.params : [];
|
|
1528
1699
|
finalParams = queryEngine.mapGeneratedParams(paramMetadata);
|
|
1700
|
+
if (options?.pipeline === "v2") {
|
|
1701
|
+
applyDateRangeOverrides(
|
|
1702
|
+
input.sqlModifications?.dateRange,
|
|
1703
|
+
finalParams,
|
|
1704
|
+
paramMetadata
|
|
1705
|
+
);
|
|
1706
|
+
}
|
|
1529
1707
|
rationale = queryResponse.rationale;
|
|
1530
1708
|
queryId = queryResponse.queryId;
|
|
1531
1709
|
sqlChanged = finalSql !== input.sql;
|
|
@@ -1548,7 +1726,7 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
1548
1726
|
const vizspecResponse = await client.post(
|
|
1549
1727
|
"/vizspec",
|
|
1550
1728
|
{
|
|
1551
|
-
question:
|
|
1729
|
+
question: finalQuestion,
|
|
1552
1730
|
sql: finalSql,
|
|
1553
1731
|
rationale,
|
|
1554
1732
|
fields: execution.fields,
|
|
@@ -1573,7 +1751,7 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
1573
1751
|
const chartResponse = await client.post(
|
|
1574
1752
|
"/chart",
|
|
1575
1753
|
{
|
|
1576
|
-
question:
|
|
1754
|
+
question: finalQuestion,
|
|
1577
1755
|
sql: finalSql,
|
|
1578
1756
|
rationale,
|
|
1579
1757
|
fields: execution.fields,
|