@querypanel/node-sdk 1.3.1 → 1.3.3
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 +144 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +144 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2292,6 +2292,7 @@ function buildModifiedQuestion(originalQuestion, modifications, hasSessionContex
|
|
|
2292
2292
|
}
|
|
2293
2293
|
return `${originalQuestion} (${hints.join(", ")})`;
|
|
2294
2294
|
}
|
|
2295
|
+
var REWRITE_DATEFILTER_ENDPOINT = "/v2/rewrite-datefilter";
|
|
2295
2296
|
var START_PARAM_KEY_REGEX = /(^|_)(start|from)(_|$)/i;
|
|
2296
2297
|
var END_PARAM_KEY_REGEX = /(^|_)(end|to)(_|$)/i;
|
|
2297
2298
|
var ISO_DATETIME_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z?$/;
|
|
@@ -2328,31 +2329,118 @@ function normalizeGeneratedParamKey(param, index) {
|
|
|
2328
2329
|
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);
|
|
2329
2330
|
return nameCandidate.replace(/[{}]/g, "").replace(/(.+):.*$/, "$1").replace(/^[:$]/, "").trim();
|
|
2330
2331
|
}
|
|
2331
|
-
function
|
|
2332
|
+
function collectParamKeys(params, paramMetadata) {
|
|
2333
|
+
const keys = new Set(Object.keys(params));
|
|
2334
|
+
for (let i = 0; i < paramMetadata.length; i++) {
|
|
2335
|
+
const param = paramMetadata[i];
|
|
2336
|
+
if (!param) continue;
|
|
2337
|
+
keys.add(normalizeGeneratedParamKey(param, i));
|
|
2338
|
+
}
|
|
2339
|
+
return [...keys];
|
|
2340
|
+
}
|
|
2341
|
+
function placeholderKey(token) {
|
|
2342
|
+
if (token.startsWith("$") || token.startsWith("@")) return token.slice(1);
|
|
2343
|
+
return token.slice(1, -1).replace(/:.+$/, "").trim();
|
|
2344
|
+
}
|
|
2345
|
+
function isDateLike(value) {
|
|
2346
|
+
return typeof value === "string" && /^\d{4}-\d{2}-\d{2}/.test(value.trim());
|
|
2347
|
+
}
|
|
2348
|
+
function dateBoundKeysFromSql(sql) {
|
|
2349
|
+
const start = /* @__PURE__ */ new Set();
|
|
2350
|
+
const end = /* @__PURE__ */ new Set();
|
|
2351
|
+
const comparison = /(>=|<=|>|<)\s*(\$\d+|\{[^}]+\}|@[A-Za-z_][\w]*)/g;
|
|
2352
|
+
const between = /BETWEEN\s+(\$\d+|\{[^}]+\}|@[A-Za-z_][\w]*)\s+AND\s+(\$\d+|\{[^}]+\}|@[A-Za-z_][\w]*)/gi;
|
|
2353
|
+
for (const match of sql.matchAll(comparison)) {
|
|
2354
|
+
const key = placeholderKey(match[2] ?? "");
|
|
2355
|
+
if (!key) continue;
|
|
2356
|
+
if (match[1] === ">=" || match[1] === ">") start.add(key);
|
|
2357
|
+
else end.add(key);
|
|
2358
|
+
}
|
|
2359
|
+
for (const match of sql.matchAll(between)) {
|
|
2360
|
+
const startKey = placeholderKey(match[1] ?? "");
|
|
2361
|
+
const endKey = placeholderKey(match[2] ?? "");
|
|
2362
|
+
if (startKey) start.add(startKey);
|
|
2363
|
+
if (endKey) end.add(endKey);
|
|
2364
|
+
}
|
|
2365
|
+
return { start, end };
|
|
2366
|
+
}
|
|
2367
|
+
function paramValueForKey(key, params, paramMetadata) {
|
|
2368
|
+
if (key in params) return params[key];
|
|
2369
|
+
for (let i = 0; i < paramMetadata.length; i++) {
|
|
2370
|
+
const param = paramMetadata[i];
|
|
2371
|
+
if (!param) continue;
|
|
2372
|
+
if (normalizeGeneratedParamKey(param, i) === key) return param.value;
|
|
2373
|
+
}
|
|
2374
|
+
return void 0;
|
|
2375
|
+
}
|
|
2376
|
+
function dateBoundKeys(sql, params, paramMetadata, boundary) {
|
|
2377
|
+
const fromSql = dateBoundKeysFromSql(sql)[boundary];
|
|
2378
|
+
const keys = [];
|
|
2379
|
+
for (const key of collectParamKeys(params, paramMetadata)) {
|
|
2380
|
+
const named = keyLooksLikeDateBoundary(key, boundary);
|
|
2381
|
+
if (!named && !fromSql.has(key)) continue;
|
|
2382
|
+
if (!isDateLike(paramValueForKey(key, params, paramMetadata))) continue;
|
|
2383
|
+
keys.push(key);
|
|
2384
|
+
}
|
|
2385
|
+
return keys;
|
|
2386
|
+
}
|
|
2387
|
+
function canSubstituteDateRangeParams(dateRange, sql, params, paramMetadata = []) {
|
|
2388
|
+
if (!dateRange) return false;
|
|
2389
|
+
const from = normalizeDateInput(dateRange.from);
|
|
2390
|
+
const to = normalizeDateInput(dateRange.to);
|
|
2391
|
+
if (!from && !to) return false;
|
|
2392
|
+
if (from && dateBoundKeys(sql, params, paramMetadata, "start").length === 0) {
|
|
2393
|
+
return false;
|
|
2394
|
+
}
|
|
2395
|
+
if (to && dateBoundKeys(sql, params, paramMetadata, "end").length === 0) {
|
|
2396
|
+
return false;
|
|
2397
|
+
}
|
|
2398
|
+
return true;
|
|
2399
|
+
}
|
|
2400
|
+
function isDateRangeOnlySqlModification(modifications) {
|
|
2401
|
+
if (!modifications?.dateRange) return false;
|
|
2402
|
+
if (modifications.customSql) return false;
|
|
2403
|
+
if (modifications.timeGranularity) return false;
|
|
2404
|
+
if (typeof modifications.additionalInstructions === "string" && modifications.additionalInstructions.trim().length > 0) {
|
|
2405
|
+
return false;
|
|
2406
|
+
}
|
|
2407
|
+
return true;
|
|
2408
|
+
}
|
|
2409
|
+
function applyDateRangeOverrides(dateRange, sql, params, paramMetadata) {
|
|
2332
2410
|
if (!dateRange) return;
|
|
2333
2411
|
const from = normalizeDateInput(dateRange.from);
|
|
2334
2412
|
const to = normalizeDateInput(dateRange.to);
|
|
2335
2413
|
if (!from && !to) return;
|
|
2414
|
+
const startKeys = new Set(
|
|
2415
|
+
from ? dateBoundKeys(sql, params, paramMetadata, "start") : []
|
|
2416
|
+
);
|
|
2417
|
+
const endKeys = new Set(
|
|
2418
|
+
to ? dateBoundKeys(sql, params, paramMetadata, "end") : []
|
|
2419
|
+
);
|
|
2336
2420
|
for (const [key, value] of Object.entries(params)) {
|
|
2337
|
-
if (
|
|
2338
|
-
params[key] = formatDateOverride(from, "start", value);
|
|
2421
|
+
if (startKeys.has(key)) {
|
|
2422
|
+
params[key] = formatDateOverride(from ?? "", "start", value);
|
|
2339
2423
|
}
|
|
2340
|
-
if (
|
|
2341
|
-
params[key] = formatDateOverride(to, "end", value);
|
|
2424
|
+
if (endKeys.has(key)) {
|
|
2425
|
+
params[key] = formatDateOverride(to ?? "", "end", value);
|
|
2342
2426
|
}
|
|
2343
2427
|
}
|
|
2344
2428
|
for (let i = 0; i < paramMetadata.length; i++) {
|
|
2345
2429
|
const param = paramMetadata[i];
|
|
2346
2430
|
if (!param) continue;
|
|
2347
2431
|
const key = normalizeGeneratedParamKey(param, i);
|
|
2348
|
-
if (
|
|
2349
|
-
param.value = formatDateOverride(from, "start", param.value);
|
|
2432
|
+
if (startKeys.has(key)) {
|
|
2433
|
+
param.value = formatDateOverride(from ?? "", "start", param.value);
|
|
2350
2434
|
}
|
|
2351
|
-
if (
|
|
2352
|
-
param.value = formatDateOverride(to, "end", param.value);
|
|
2435
|
+
if (endKeys.has(key)) {
|
|
2436
|
+
param.value = formatDateOverride(to ?? "", "end", param.value);
|
|
2353
2437
|
}
|
|
2354
2438
|
}
|
|
2355
2439
|
}
|
|
2440
|
+
function buildPreviousParams(params, paramMetadata) {
|
|
2441
|
+
if (paramMetadata.length > 0) return paramMetadata;
|
|
2442
|
+
return Object.entries(params).map(([name, value]) => ({ name, value }));
|
|
2443
|
+
}
|
|
2356
2444
|
function buildVizHints(modifications) {
|
|
2357
2445
|
const hints = {};
|
|
2358
2446
|
if (modifications.kind) {
|
|
@@ -2403,6 +2491,9 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2403
2491
|
const hasSqlMods = !!input.sqlModifications;
|
|
2404
2492
|
const hasVizMods = !!input.vizModifications;
|
|
2405
2493
|
const hasCustomSql = !!input.sqlModifications?.customSql;
|
|
2494
|
+
const lightweight = options?.lightweight === true;
|
|
2495
|
+
const dateOnly = lightweight && isDateRangeOnlySqlModification(input.sqlModifications);
|
|
2496
|
+
const skipChartLlm = lightweight && !hasCustomSql && (dateOnly || hasVizMods && !hasSqlMods);
|
|
2406
2497
|
resolveQueryPipeline(options?.pipeline);
|
|
2407
2498
|
const queryEndpoint = "/v2/query";
|
|
2408
2499
|
let currentSql = input.sql;
|
|
@@ -2456,6 +2547,20 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2456
2547
|
paramMetadata = [];
|
|
2457
2548
|
queryId = void 0;
|
|
2458
2549
|
sqlChanged = true;
|
|
2550
|
+
} else if (dateOnly && canSubstituteDateRangeParams(
|
|
2551
|
+
input.sqlModifications?.dateRange,
|
|
2552
|
+
finalSql,
|
|
2553
|
+
finalParams,
|
|
2554
|
+
paramMetadata
|
|
2555
|
+
)) {
|
|
2556
|
+
finalParams = { ...finalParams };
|
|
2557
|
+
applyDateRangeOverrides(
|
|
2558
|
+
input.sqlModifications?.dateRange,
|
|
2559
|
+
finalSql,
|
|
2560
|
+
finalParams,
|
|
2561
|
+
paramMetadata
|
|
2562
|
+
);
|
|
2563
|
+
sqlChanged = false;
|
|
2459
2564
|
} else if (hasSqlMods && !hasCustomSql) {
|
|
2460
2565
|
const modifiedQuestion = buildModifiedQuestion(
|
|
2461
2566
|
input.question,
|
|
@@ -2463,18 +2568,36 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2463
2568
|
hasQuerypanelSessionContext
|
|
2464
2569
|
);
|
|
2465
2570
|
finalQuestion = modifiedQuestion;
|
|
2466
|
-
const
|
|
2571
|
+
const sharedBody = {
|
|
2572
|
+
session_id: querypanelSessionId,
|
|
2573
|
+
previous_sql: currentSql,
|
|
2574
|
+
...tenantSettings ? { tenant_settings: tenantSettings } : {},
|
|
2575
|
+
...databaseName ? { database: databaseName } : {},
|
|
2576
|
+
...metadata?.dialect ? { dialect: metadata.dialect } : {},
|
|
2577
|
+
debug: options?.debug ?? false
|
|
2578
|
+
};
|
|
2579
|
+
const [endpoint, body] = dateOnly ? [
|
|
2580
|
+
REWRITE_DATEFILTER_ENDPOINT,
|
|
2581
|
+
{
|
|
2582
|
+
...sharedBody,
|
|
2583
|
+
question: input.question,
|
|
2584
|
+
previous_params: buildPreviousParams(finalParams, paramMetadata),
|
|
2585
|
+
date_range: {
|
|
2586
|
+
from: normalizeDateInput(input.sqlModifications?.dateRange?.from),
|
|
2587
|
+
to: normalizeDateInput(input.sqlModifications?.dateRange?.to)
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
] : [
|
|
2467
2591
|
queryEndpoint,
|
|
2468
2592
|
{
|
|
2593
|
+
...sharedBody,
|
|
2469
2594
|
question: modifiedQuestion,
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
debug: options?.debug ?? false
|
|
2477
|
-
},
|
|
2595
|
+
...options?.maxRetry ? { max_retry: options.maxRetry } : {}
|
|
2596
|
+
}
|
|
2597
|
+
];
|
|
2598
|
+
const queryResponse = await client.post(
|
|
2599
|
+
endpoint,
|
|
2600
|
+
body,
|
|
2478
2601
|
tenantId,
|
|
2479
2602
|
options?.userId,
|
|
2480
2603
|
options?.scopes,
|
|
@@ -2486,6 +2609,7 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2486
2609
|
finalParams = queryEngine.mapGeneratedParams(paramMetadata);
|
|
2487
2610
|
applyDateRangeOverrides(
|
|
2488
2611
|
input.sqlModifications?.dateRange,
|
|
2612
|
+
finalSql,
|
|
2489
2613
|
finalParams,
|
|
2490
2614
|
paramMetadata
|
|
2491
2615
|
);
|
|
@@ -2506,7 +2630,7 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2506
2630
|
};
|
|
2507
2631
|
const vizHints = hasVizMods ? buildVizHints(input.vizModifications) : {};
|
|
2508
2632
|
const vizHintsForChart = chartType === "vizspec" ? vizHints : stripVizSpecOnlyHints(vizHints);
|
|
2509
|
-
if (chartType === "vizspec") {
|
|
2633
|
+
if (!skipChartLlm && chartType === "vizspec") {
|
|
2510
2634
|
const vizspecResponse = await client.post(
|
|
2511
2635
|
"/vizspec",
|
|
2512
2636
|
{
|
|
@@ -2533,7 +2657,7 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2533
2657
|
specType: "vizspec",
|
|
2534
2658
|
notes: rows.length === 0 ? vizspecResponse.notes ?? "Query returned no rows." : vizspecResponse.notes
|
|
2535
2659
|
};
|
|
2536
|
-
} else {
|
|
2660
|
+
} else if (!skipChartLlm) {
|
|
2537
2661
|
const chartResponse = await client.post(
|
|
2538
2662
|
"/chart",
|
|
2539
2663
|
{
|