@querypanel/node-sdk 1.3.6 → 1.3.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/README.md +14 -0
- package/dist/index.cjs +21 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -7
- package/dist/index.d.ts +32 -7
- package/dist/index.js +21 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -621,6 +621,20 @@ The SDK will:
|
|
|
621
621
|
|
|
622
622
|
Without `maxRetry`, execution errors throw immediately (default behavior).
|
|
623
623
|
|
|
624
|
+
#### Retry when the query returns nothing
|
|
625
|
+
|
|
626
|
+
A query can run fine and still return nothing because a filter value does not match how the data stores it (`state = 'approved'` when the column holds `APPROVE`). With `retryOnEmptyResult`, the SDK treats an empty result, or a single row of only zeros/NULLs such as `COUNT(*) = 0`, like an execution error and asks for a repaired query within the same `maxRetry` budget:
|
|
627
|
+
|
|
628
|
+
```ts
|
|
629
|
+
const response = await qp.ask("How many transactions were declined?", {
|
|
630
|
+
tenantId: "tenant_123",
|
|
631
|
+
maxRetry: 1,
|
|
632
|
+
retryOnEmptyResult: true,
|
|
633
|
+
});
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
Only the fact that the result was empty and the previous SQL are sent back; no rows or values leave your backend. If the last attempt is still empty, it is returned as is (no error). Off by default; each retry is one more generation round, so expect a few extra seconds on those questions.
|
|
637
|
+
|
|
624
638
|
## Need more?
|
|
625
639
|
|
|
626
640
|
Open an issue or extend the SDK: the public class is in `src/index.ts` and each API route has a module under `src/routes/`. Pull requests are welcome for additional adapters, richer param coercion, or convenience helpers around charts/annotations.
|
package/dist/index.cjs
CHANGED
|
@@ -2492,6 +2492,15 @@ function resolveQueryPipeline(pipeline) {
|
|
|
2492
2492
|
}
|
|
2493
2493
|
return "v2";
|
|
2494
2494
|
}
|
|
2495
|
+
var EMPTY_RESULT_ERROR = "The query ran but returned no rows (or only zero/NULL values). A filter value probably does not match how the data stores it (case, spelling, codes such as 'APPROVE' vs 'approved'), or a filter is narrower than the question. Check each filter value against the column's documented values and fix it; keep every filter the question asks for.";
|
|
2496
|
+
function isEmptyLikeResult(rows) {
|
|
2497
|
+
if (rows.length === 0) return true;
|
|
2498
|
+
if (rows.length > 1) return false;
|
|
2499
|
+
const row = rows[0];
|
|
2500
|
+
if (!row || typeof row !== "object") return false;
|
|
2501
|
+
const values = Object.values(row);
|
|
2502
|
+
return values.length > 0 && values.every((v) => v === null || v === 0 || v === "0" || v === 0n);
|
|
2503
|
+
}
|
|
2495
2504
|
async function ask(client, queryEngine, question, options, signal) {
|
|
2496
2505
|
const tenantId = resolveTenantId5(client, options.tenantId);
|
|
2497
2506
|
const sessionId = import_node_crypto3.default.randomUUID();
|
|
@@ -2574,6 +2583,17 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
2574
2583
|
tenantId
|
|
2575
2584
|
);
|
|
2576
2585
|
const rows = execution.rows ?? [];
|
|
2586
|
+
if (options.retryOnEmptyResult && attempt < maxRetry && isEmptyLikeResult(rows)) {
|
|
2587
|
+
attempt++;
|
|
2588
|
+
lastError = EMPTY_RESULT_ERROR;
|
|
2589
|
+
previousSql = sql;
|
|
2590
|
+
console.warn("Query returned no data, retrying query generation", {
|
|
2591
|
+
attempt,
|
|
2592
|
+
maxAttempts: maxRetry + 1,
|
|
2593
|
+
sql
|
|
2594
|
+
});
|
|
2595
|
+
continue;
|
|
2596
|
+
}
|
|
2577
2597
|
const chartType = options.chartType ?? "vega-lite";
|
|
2578
2598
|
let chart = {
|
|
2579
2599
|
specType: chartType,
|
|
@@ -3660,7 +3680,7 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
3660
3680
|
* @param input - VizSpec generation input with question, SQL, and result data
|
|
3661
3681
|
* @param options - Optional settings for tenant and retries
|
|
3662
3682
|
* @param signal - Optional AbortSignal for cancellation
|
|
3663
|
-
* @returns VizSpec specification for chart, table, or
|
|
3683
|
+
* @returns VizSpec specification for chart, table, metric, or map visualization
|
|
3664
3684
|
*
|
|
3665
3685
|
* @example
|
|
3666
3686
|
* ```typescript
|