@querypanel/node-sdk 1.2.6 → 1.2.8
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 +25 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +25 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -382,10 +382,15 @@ var ClickHouseAdapter = class {
|
|
|
382
382
|
return;
|
|
383
383
|
}
|
|
384
384
|
const allowedSet = new Set(this.allowedTables);
|
|
385
|
-
const tablePattern =
|
|
385
|
+
const tablePattern = /\b(FROM|JOIN)\s+(?:FINAL\s+)?(?:(?:[a-zA-Z_][a-zA-Z0-9_]*)\.)?(["'`]?[a-zA-Z_][a-zA-Z0-9_]*["'`]?)/gi;
|
|
386
386
|
const matches = sql.matchAll(tablePattern);
|
|
387
387
|
for (const match of matches) {
|
|
388
|
-
const
|
|
388
|
+
const clause = match[1]?.toUpperCase();
|
|
389
|
+
const matchIndex = match.index ?? -1;
|
|
390
|
+
if (clause === "JOIN" && matchIndex >= 0 && isArrayJoinClause(sql, matchIndex)) {
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
const table = match[2]?.replace(/["'`]/g, "");
|
|
389
394
|
if (table) {
|
|
390
395
|
if (!allowedSet.has(table)) {
|
|
391
396
|
throw new Error(
|
|
@@ -453,6 +458,11 @@ function normalizeTableFilter2(tables) {
|
|
|
453
458
|
}
|
|
454
459
|
return normalized;
|
|
455
460
|
}
|
|
461
|
+
function isArrayJoinClause(sql, joinIndex) {
|
|
462
|
+
const beforeJoin = sql.slice(0, joinIndex);
|
|
463
|
+
const previousToken = beforeJoin.trim().split(/\s+/).pop()?.toUpperCase();
|
|
464
|
+
return previousToken === "ARRAY";
|
|
465
|
+
}
|
|
456
466
|
function transformColumnRow(row) {
|
|
457
467
|
const unwrappedType = unwrapTypeModifiers(row.type);
|
|
458
468
|
const column = {
|
|
@@ -1832,7 +1842,6 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1832
1842
|
let previousSql = options.previousSql;
|
|
1833
1843
|
const queryEndpoint = options.pipeline === "v2" ? "/v2/query" : "/query";
|
|
1834
1844
|
while (attempt <= maxRetry) {
|
|
1835
|
-
console.log({ lastError, previousSql });
|
|
1836
1845
|
const databaseName = options.database ?? queryEngine.getDefaultDatabase();
|
|
1837
1846
|
const metadata = databaseName ? queryEngine.getDatabaseMetadata(databaseName) : void 0;
|
|
1838
1847
|
let tenantSettings;
|
|
@@ -1855,7 +1864,8 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1855
1864
|
...databaseName ? { database: databaseName } : {},
|
|
1856
1865
|
...metadata?.dialect ? { dialect: metadata.dialect } : {},
|
|
1857
1866
|
...options.model?.trim() ? { model: options.model.trim() } : {},
|
|
1858
|
-
...options.pipeline === "v2" && options.systemPrompt?.trim() ? { system_prompt: options.systemPrompt.trim() } : {}
|
|
1867
|
+
...options.pipeline === "v2" && options.systemPrompt?.trim() ? { system_prompt: options.systemPrompt.trim() } : {},
|
|
1868
|
+
debug: options.debug ?? false
|
|
1859
1869
|
},
|
|
1860
1870
|
tenantId,
|
|
1861
1871
|
options.userId,
|
|
@@ -1976,9 +1986,14 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1976
1986
|
}
|
|
1977
1987
|
lastError = error instanceof Error ? error.message : String(error);
|
|
1978
1988
|
previousSql = queryResponse.data.sql ?? previousSql;
|
|
1979
|
-
console.warn(
|
|
1980
|
-
|
|
1981
|
-
|
|
1989
|
+
console.warn("SQL execution failed, retrying query generation", {
|
|
1990
|
+
attempt,
|
|
1991
|
+
maxAttempts: maxRetry + 1,
|
|
1992
|
+
error: lastError,
|
|
1993
|
+
sql: queryResponse.data.sql ?? null,
|
|
1994
|
+
paramMetadata,
|
|
1995
|
+
params: paramValues
|
|
1996
|
+
});
|
|
1982
1997
|
}
|
|
1983
1998
|
}
|
|
1984
1999
|
throw new Error("Unexpected error in ask retry loop");
|
|
@@ -2204,7 +2219,8 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2204
2219
|
...options?.maxRetry ? { max_retry: options.maxRetry } : {},
|
|
2205
2220
|
...tenantSettings ? { tenant_settings: tenantSettings } : {},
|
|
2206
2221
|
...databaseName ? { database: databaseName } : {},
|
|
2207
|
-
...metadata?.dialect ? { dialect: metadata.dialect } : {}
|
|
2222
|
+
...metadata?.dialect ? { dialect: metadata.dialect } : {},
|
|
2223
|
+
debug: options?.debug ?? false
|
|
2208
2224
|
},
|
|
2209
2225
|
tenantId,
|
|
2210
2226
|
options?.userId,
|
|
@@ -2585,7 +2601,7 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
2585
2601
|
* It handles the complete flow: SQL generation → validation → execution → chart generation.
|
|
2586
2602
|
*
|
|
2587
2603
|
* @param question - Natural language question (e.g., "Show revenue by country")
|
|
2588
|
-
* @param options - Query options including tenantId, database, and
|
|
2604
|
+
* @param options - Query options including tenantId, database, retry settings, and optional `debug` for engineer-style rationale
|
|
2589
2605
|
* @param signal - Optional AbortSignal for cancellation
|
|
2590
2606
|
* @returns Response with SQL, executed data rows, and generated chart
|
|
2591
2607
|
* @throws {Error} When SQL generation or execution fails after all retries
|