@querypanel/node-sdk 1.3.0 → 1.3.1
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 +1 -1
- package/dist/index.cjs +86 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -13
- package/dist/index.d.ts +12 -13
- package/dist/index.js +86 -45
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.cts
CHANGED
|
@@ -731,12 +731,11 @@ interface AskOptions {
|
|
|
731
731
|
*/
|
|
732
732
|
querypanelSessionId?: string;
|
|
733
733
|
/**
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
*
|
|
737
|
-
* - `"v1"` (**deprecated**): legacy `POST /query` pipeline — prefer omitting or `"v2"`
|
|
734
|
+
* Query pipeline. Only `"v2"` is accepted (`POST /v2/query`).
|
|
735
|
+
* `"v1"` was removed: passing it fails typecheck and throws at runtime.
|
|
736
|
+
* Omit this field; asks always use v2.
|
|
738
737
|
*/
|
|
739
|
-
pipeline?: "
|
|
738
|
+
pipeline?: "v2";
|
|
740
739
|
/**
|
|
741
740
|
* Optional model id for SQL generation (e.g. OpenAI or `gemini-*` when the API uses Gemini). Omit for server default.
|
|
742
741
|
*/
|
|
@@ -750,7 +749,7 @@ interface AskOptions {
|
|
|
750
749
|
* Use this for tenant-specific policies (e.g. retention windows) that must
|
|
751
750
|
* be enforced on every query.
|
|
752
751
|
*
|
|
753
|
-
* Sent
|
|
752
|
+
* Sent on every ask (`POST /v2/query`).
|
|
754
753
|
*/
|
|
755
754
|
systemPrompt?: string;
|
|
756
755
|
/**
|
|
@@ -828,9 +827,10 @@ interface AskResponse {
|
|
|
828
827
|
trace?: PipelineTrace;
|
|
829
828
|
}
|
|
830
829
|
/**
|
|
831
|
-
* Resolve ask/modify pipeline.
|
|
830
|
+
* Resolve ask/modify pipeline. Always `"v2"` (`POST /v2/query`).
|
|
831
|
+
* Throws if a removed pipeline such as `"v1"` is passed.
|
|
832
832
|
*/
|
|
833
|
-
declare function resolveQueryPipeline(pipeline?: "
|
|
833
|
+
declare function resolveQueryPipeline(pipeline?: "v2"): "v2";
|
|
834
834
|
declare function anonymizeResults(rows: Array<Record<string, unknown>>): Array<Record<string, string>>;
|
|
835
835
|
|
|
836
836
|
/**
|
|
@@ -985,12 +985,11 @@ interface ChartModifyOptions {
|
|
|
985
985
|
/** Chart generation method: 'vega-lite' or 'vizspec' */
|
|
986
986
|
chartType?: "vega-lite" | "vizspec";
|
|
987
987
|
/**
|
|
988
|
-
*
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
* - `"v1"` (**deprecated**): legacy `POST /query` pipeline — prefer omitting or `"v2"`
|
|
988
|
+
* Query pipeline. Only `"v2"` is accepted (`POST /v2/query`).
|
|
989
|
+
* `"v1"` was removed: passing it fails typecheck and throws at runtime.
|
|
990
|
+
* Omit this field; chart modifications always use v2.
|
|
992
991
|
*/
|
|
993
|
-
pipeline?: "
|
|
992
|
+
pipeline?: "v2";
|
|
994
993
|
/**
|
|
995
994
|
* QueryPanel session ID for context-aware follow-ups.
|
|
996
995
|
* Pass the querypanelSessionId from a previous ask() response
|
package/dist/index.d.ts
CHANGED
|
@@ -731,12 +731,11 @@ interface AskOptions {
|
|
|
731
731
|
*/
|
|
732
732
|
querypanelSessionId?: string;
|
|
733
733
|
/**
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
*
|
|
737
|
-
* - `"v1"` (**deprecated**): legacy `POST /query` pipeline — prefer omitting or `"v2"`
|
|
734
|
+
* Query pipeline. Only `"v2"` is accepted (`POST /v2/query`).
|
|
735
|
+
* `"v1"` was removed: passing it fails typecheck and throws at runtime.
|
|
736
|
+
* Omit this field; asks always use v2.
|
|
738
737
|
*/
|
|
739
|
-
pipeline?: "
|
|
738
|
+
pipeline?: "v2";
|
|
740
739
|
/**
|
|
741
740
|
* Optional model id for SQL generation (e.g. OpenAI or `gemini-*` when the API uses Gemini). Omit for server default.
|
|
742
741
|
*/
|
|
@@ -750,7 +749,7 @@ interface AskOptions {
|
|
|
750
749
|
* Use this for tenant-specific policies (e.g. retention windows) that must
|
|
751
750
|
* be enforced on every query.
|
|
752
751
|
*
|
|
753
|
-
* Sent
|
|
752
|
+
* Sent on every ask (`POST /v2/query`).
|
|
754
753
|
*/
|
|
755
754
|
systemPrompt?: string;
|
|
756
755
|
/**
|
|
@@ -828,9 +827,10 @@ interface AskResponse {
|
|
|
828
827
|
trace?: PipelineTrace;
|
|
829
828
|
}
|
|
830
829
|
/**
|
|
831
|
-
* Resolve ask/modify pipeline.
|
|
830
|
+
* Resolve ask/modify pipeline. Always `"v2"` (`POST /v2/query`).
|
|
831
|
+
* Throws if a removed pipeline such as `"v1"` is passed.
|
|
832
832
|
*/
|
|
833
|
-
declare function resolveQueryPipeline(pipeline?: "
|
|
833
|
+
declare function resolveQueryPipeline(pipeline?: "v2"): "v2";
|
|
834
834
|
declare function anonymizeResults(rows: Array<Record<string, unknown>>): Array<Record<string, string>>;
|
|
835
835
|
|
|
836
836
|
/**
|
|
@@ -985,12 +985,11 @@ interface ChartModifyOptions {
|
|
|
985
985
|
/** Chart generation method: 'vega-lite' or 'vizspec' */
|
|
986
986
|
chartType?: "vega-lite" | "vizspec";
|
|
987
987
|
/**
|
|
988
|
-
*
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
* - `"v1"` (**deprecated**): legacy `POST /query` pipeline — prefer omitting or `"v2"`
|
|
988
|
+
* Query pipeline. Only `"v2"` is accepted (`POST /v2/query`).
|
|
989
|
+
* `"v1"` was removed: passing it fails typecheck and throws at runtime.
|
|
990
|
+
* Omit this field; chart modifications always use v2.
|
|
992
991
|
*/
|
|
993
|
-
pipeline?: "
|
|
992
|
+
pipeline?: "v2";
|
|
994
993
|
/**
|
|
995
994
|
* QueryPanel session ID for context-aware follow-ups.
|
|
996
995
|
* Pass the querypanelSessionId from a previous ask() response
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,13 @@ var BigQueryAdapter = class {
|
|
|
14
14
|
);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
clientFn;
|
|
18
|
+
projectId;
|
|
19
|
+
datasetProjectId;
|
|
20
|
+
defaultDataset;
|
|
21
|
+
databaseName;
|
|
22
|
+
kind;
|
|
23
|
+
allowedTables;
|
|
17
24
|
async execute(sql, params) {
|
|
18
25
|
if (this.allowedTables) {
|
|
19
26
|
this.validateQueryTables(sql);
|
|
@@ -244,6 +251,11 @@ var ClickHouseAdapter = class {
|
|
|
244
251
|
this.allowedTables = normalizeTableFilter2(options.allowedTables);
|
|
245
252
|
}
|
|
246
253
|
}
|
|
254
|
+
clientFn;
|
|
255
|
+
databaseName;
|
|
256
|
+
defaultFormat;
|
|
257
|
+
kind;
|
|
258
|
+
allowedTables;
|
|
247
259
|
async execute(sql, params) {
|
|
248
260
|
if (this.allowedTables) {
|
|
249
261
|
this.validateQueryTables(sql);
|
|
@@ -497,6 +509,11 @@ var PostgresAdapter = class {
|
|
|
497
509
|
);
|
|
498
510
|
}
|
|
499
511
|
}
|
|
512
|
+
clientFn;
|
|
513
|
+
databaseName;
|
|
514
|
+
defaultSchema;
|
|
515
|
+
kind;
|
|
516
|
+
allowedTables;
|
|
500
517
|
async execute(sql, params) {
|
|
501
518
|
if (this.allowedTables) {
|
|
502
519
|
this.validateQueryTables(sql);
|
|
@@ -805,6 +822,9 @@ var QueryPipelineError = class extends Error {
|
|
|
805
822
|
this.status = status;
|
|
806
823
|
this.name = "QueryPipelineError";
|
|
807
824
|
}
|
|
825
|
+
code;
|
|
826
|
+
details;
|
|
827
|
+
status;
|
|
808
828
|
/**
|
|
809
829
|
* Check if this is a moderation error
|
|
810
830
|
*/
|
|
@@ -857,8 +877,14 @@ var QueryPipelineError = class extends Error {
|
|
|
857
877
|
|
|
858
878
|
// src/core/client.ts
|
|
859
879
|
var ApiClient = class {
|
|
880
|
+
baseUrl;
|
|
881
|
+
privateKey;
|
|
882
|
+
organizationId;
|
|
883
|
+
defaultTenantId;
|
|
884
|
+
additionalHeaders;
|
|
885
|
+
fetchImpl;
|
|
886
|
+
cryptoKey = null;
|
|
860
887
|
constructor(baseUrl, privateKey, organizationId, options) {
|
|
861
|
-
this.cryptoKey = null;
|
|
862
888
|
if (!baseUrl) {
|
|
863
889
|
throw new Error("Base URL is required");
|
|
864
890
|
}
|
|
@@ -1112,6 +1138,8 @@ var ApiClient = class {
|
|
|
1112
1138
|
|
|
1113
1139
|
// src/core/callback-client.ts
|
|
1114
1140
|
var CallbackApiClient = class {
|
|
1141
|
+
requestHandler;
|
|
1142
|
+
defaultTenantId;
|
|
1115
1143
|
constructor(requestHandler, options) {
|
|
1116
1144
|
this.requestHandler = requestHandler;
|
|
1117
1145
|
this.defaultTenantId = options?.defaultTenantId;
|
|
@@ -1254,10 +1282,9 @@ function normalizeSqlParamsInput(params) {
|
|
|
1254
1282
|
|
|
1255
1283
|
// src/core/query-engine.ts
|
|
1256
1284
|
var QueryEngine = class {
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
}
|
|
1285
|
+
databases = /* @__PURE__ */ new Map();
|
|
1286
|
+
databaseMetadata = /* @__PURE__ */ new Map();
|
|
1287
|
+
defaultDatabase;
|
|
1261
1288
|
attachDatabase(name, adapter, metadata) {
|
|
1262
1289
|
this.databases.set(name, adapter);
|
|
1263
1290
|
this.databaseMetadata.set(name, metadata);
|
|
@@ -1943,7 +1970,13 @@ import crypto4 from "crypto";
|
|
|
1943
1970
|
// src/routes/query.ts
|
|
1944
1971
|
import crypto3 from "crypto";
|
|
1945
1972
|
function resolveQueryPipeline(pipeline) {
|
|
1946
|
-
|
|
1973
|
+
const requested = pipeline;
|
|
1974
|
+
if (requested != null && requested !== "v2") {
|
|
1975
|
+
throw new Error(
|
|
1976
|
+
`Query pipeline "${requested}" was removed. ask() and modifyChart() always use POST /v2/query.`
|
|
1977
|
+
);
|
|
1978
|
+
}
|
|
1979
|
+
return "v2";
|
|
1947
1980
|
}
|
|
1948
1981
|
async function ask(client, queryEngine, question, options, signal) {
|
|
1949
1982
|
const tenantId = resolveTenantId5(client, options.tenantId);
|
|
@@ -1953,8 +1986,9 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1953
1986
|
let attempt = 0;
|
|
1954
1987
|
let lastError = options.lastError;
|
|
1955
1988
|
let previousSql = options.previousSql;
|
|
1956
|
-
|
|
1957
|
-
|
|
1989
|
+
let parentQueryId;
|
|
1990
|
+
resolveQueryPipeline(options.pipeline);
|
|
1991
|
+
const queryEndpoint = "/v2/query";
|
|
1958
1992
|
while (attempt <= maxRetry) {
|
|
1959
1993
|
const databaseName = options.database ?? queryEngine.getDefaultDatabase();
|
|
1960
1994
|
const metadata = databaseName ? queryEngine.getDatabaseMetadata(databaseName) : void 0;
|
|
@@ -1984,7 +2018,8 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
1984
2018
|
...databaseName ? { database: databaseName } : {},
|
|
1985
2019
|
...metadata?.dialect ? { dialect: metadata.dialect } : {},
|
|
1986
2020
|
...options.model?.trim() ? { model: options.model.trim() } : {},
|
|
1987
|
-
...
|
|
2021
|
+
...options.systemPrompt?.trim() ? { system_prompt: options.systemPrompt.trim() } : {},
|
|
2022
|
+
...parentQueryId ? { parent_query_id: parentQueryId } : {},
|
|
1988
2023
|
debug: options.debug ?? false
|
|
1989
2024
|
},
|
|
1990
2025
|
tenantId,
|
|
@@ -2006,6 +2041,9 @@ async function ask(client, queryEngine, question, options, signal) {
|
|
|
2006
2041
|
if (!sql || !dialect) {
|
|
2007
2042
|
throw new Error("Query response missing required SQL or dialect");
|
|
2008
2043
|
}
|
|
2044
|
+
if (queryResponse.data.queryId) {
|
|
2045
|
+
parentQueryId = queryResponse.data.queryId;
|
|
2046
|
+
}
|
|
2009
2047
|
const dbName = queryResponse.data.database ?? options.database ?? queryEngine.getDefaultDatabase();
|
|
2010
2048
|
if (!dbName) {
|
|
2011
2049
|
throw new Error(
|
|
@@ -2165,35 +2203,35 @@ async function resolveQuery(client, queryEngine, queryId, options, signal) {
|
|
|
2165
2203
|
dialect: response.dialect
|
|
2166
2204
|
};
|
|
2167
2205
|
}
|
|
2206
|
+
async function markQueryExecuted(client, queryId, options, signal) {
|
|
2207
|
+
try {
|
|
2208
|
+
await client.post(
|
|
2209
|
+
`/v2/queries/${encodeURIComponent(queryId)}/executed`,
|
|
2210
|
+
{},
|
|
2211
|
+
options.tenantId,
|
|
2212
|
+
options.userId,
|
|
2213
|
+
options.scopes,
|
|
2214
|
+
signal
|
|
2215
|
+
);
|
|
2216
|
+
} catch {
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2168
2219
|
|
|
2169
2220
|
// src/routes/modify.ts
|
|
2170
|
-
function buildModifiedQuestion(originalQuestion, modifications,
|
|
2221
|
+
function buildModifiedQuestion(originalQuestion, modifications, hasSessionContext = false) {
|
|
2171
2222
|
const hints = [];
|
|
2172
2223
|
if (modifications.timeGranularity) {
|
|
2173
2224
|
hints.push(`group results by ${modifications.timeGranularity}`);
|
|
2174
2225
|
}
|
|
2175
2226
|
if (modifications.dateRange) {
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
hints.push(`change end date to ${to}`);
|
|
2185
|
-
}
|
|
2186
|
-
} else {
|
|
2187
|
-
const parts = [];
|
|
2188
|
-
if (modifications.dateRange.from) {
|
|
2189
|
-
parts.push(`from ${modifications.dateRange.from}`);
|
|
2190
|
-
}
|
|
2191
|
-
if (modifications.dateRange.to) {
|
|
2192
|
-
parts.push(`to ${modifications.dateRange.to}`);
|
|
2193
|
-
}
|
|
2194
|
-
if (parts.length > 0) {
|
|
2195
|
-
hints.push(`filter date range ${parts.join(" ")}`);
|
|
2196
|
-
}
|
|
2227
|
+
const from = normalizeDateInput(modifications.dateRange.from);
|
|
2228
|
+
const to = normalizeDateInput(modifications.dateRange.to);
|
|
2229
|
+
if (from && to) {
|
|
2230
|
+
hints.push(`change date range to ${from} through ${to}`);
|
|
2231
|
+
} else if (from) {
|
|
2232
|
+
hints.push(`change start date to ${from}`);
|
|
2233
|
+
} else if (to) {
|
|
2234
|
+
hints.push(`change end date to ${to}`);
|
|
2197
2235
|
}
|
|
2198
2236
|
}
|
|
2199
2237
|
if (modifications.additionalInstructions) {
|
|
@@ -2202,7 +2240,7 @@ function buildModifiedQuestion(originalQuestion, modifications, pipeline, hasSes
|
|
|
2202
2240
|
if (hints.length === 0) {
|
|
2203
2241
|
return originalQuestion;
|
|
2204
2242
|
}
|
|
2205
|
-
if (
|
|
2243
|
+
if (hasSessionContext) {
|
|
2206
2244
|
return hints.join(", ");
|
|
2207
2245
|
}
|
|
2208
2246
|
return `${originalQuestion} (${hints.join(", ")})`;
|
|
@@ -2318,8 +2356,8 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2318
2356
|
const hasSqlMods = !!input.sqlModifications;
|
|
2319
2357
|
const hasVizMods = !!input.vizModifications;
|
|
2320
2358
|
const hasCustomSql = !!input.sqlModifications?.customSql;
|
|
2321
|
-
|
|
2322
|
-
const queryEndpoint =
|
|
2359
|
+
resolveQueryPipeline(options?.pipeline);
|
|
2360
|
+
const queryEndpoint = "/v2/query";
|
|
2323
2361
|
let currentSql = input.sql;
|
|
2324
2362
|
let finalParams = input.params ?? {};
|
|
2325
2363
|
let paramMetadata = [];
|
|
@@ -2375,12 +2413,9 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2375
2413
|
const modifiedQuestion = buildModifiedQuestion(
|
|
2376
2414
|
input.question,
|
|
2377
2415
|
input.sqlModifications,
|
|
2378
|
-
pipeline,
|
|
2379
2416
|
hasQuerypanelSessionContext
|
|
2380
2417
|
);
|
|
2381
|
-
|
|
2382
|
-
finalQuestion = modifiedQuestion;
|
|
2383
|
-
}
|
|
2418
|
+
finalQuestion = modifiedQuestion;
|
|
2384
2419
|
const queryResponse = await client.post(
|
|
2385
2420
|
queryEndpoint,
|
|
2386
2421
|
{
|
|
@@ -2402,13 +2437,11 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2402
2437
|
finalSql = queryResponse.sql;
|
|
2403
2438
|
paramMetadata = Array.isArray(queryResponse.params) ? queryResponse.params : [];
|
|
2404
2439
|
finalParams = queryEngine.mapGeneratedParams(paramMetadata);
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
);
|
|
2411
|
-
}
|
|
2440
|
+
applyDateRangeOverrides(
|
|
2441
|
+
input.sqlModifications?.dateRange,
|
|
2442
|
+
finalParams,
|
|
2443
|
+
paramMetadata
|
|
2444
|
+
);
|
|
2412
2445
|
rationale = queryResponse.rationale;
|
|
2413
2446
|
queryId = queryResponse.queryId;
|
|
2414
2447
|
sqlChanged = finalSql !== currentSql;
|
|
@@ -2626,6 +2659,9 @@ function resolveAttachEnforceTenantIsolation(tenantFieldName, enforceTenantIsola
|
|
|
2626
2659
|
return tenantFieldName ? true : void 0;
|
|
2627
2660
|
}
|
|
2628
2661
|
var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
2662
|
+
client;
|
|
2663
|
+
queryEngine;
|
|
2664
|
+
supportedChartTypes;
|
|
2629
2665
|
/**
|
|
2630
2666
|
* @param workspaceId - Workspace UUID (same value as your org in the dashboard). Passed to the API as JWT claim `organizationId`.
|
|
2631
2667
|
*/
|
|
@@ -2877,6 +2913,11 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
2877
2913
|
databaseName,
|
|
2878
2914
|
tenantId
|
|
2879
2915
|
);
|
|
2916
|
+
if (input.queryId) {
|
|
2917
|
+
await markQueryExecuted(this.client, input.queryId, {
|
|
2918
|
+
tenantId
|
|
2919
|
+
});
|
|
2920
|
+
}
|
|
2880
2921
|
return { rows: result.rows, fields: result.fields };
|
|
2881
2922
|
}
|
|
2882
2923
|
// VizSpec generation
|