@querypanel/node-sdk 1.3.0-beta.2 → 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 +30 -2
- package/dist/index.cjs +142 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -17
- package/dist/index.d.ts +40 -17
- package/dist/index.js +142 -50
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.cts
CHANGED
|
@@ -360,10 +360,15 @@ interface ChartCreateInput {
|
|
|
360
360
|
title: string;
|
|
361
361
|
prompt?: string;
|
|
362
362
|
description?: string;
|
|
363
|
-
|
|
363
|
+
/**
|
|
364
|
+
* Required when `query_id` is not provided. Ignored (with `sql_params`) when
|
|
365
|
+
* `query_id` is present: the server saves the SQL and params it stored for that query.
|
|
366
|
+
*/
|
|
367
|
+
sql?: string;
|
|
364
368
|
sql_params?: Record<string, unknown>;
|
|
365
369
|
vega_lite_spec: Record<string, unknown>;
|
|
366
370
|
spec_type?: 'vega-lite' | 'vizspec';
|
|
371
|
+
/** Server-issued query id from ask() / modifyChart(). Preferred over `sql`. */
|
|
367
372
|
query_id?: string;
|
|
368
373
|
target_db?: string;
|
|
369
374
|
}
|
|
@@ -373,6 +378,8 @@ interface ChartUpdateInput {
|
|
|
373
378
|
description?: string;
|
|
374
379
|
sql?: string;
|
|
375
380
|
sql_params?: Record<string, unknown>;
|
|
381
|
+
/** When present, the server replaces sql / sql_params with the stored query. */
|
|
382
|
+
query_id?: string;
|
|
376
383
|
vega_lite_spec?: Record<string, unknown>;
|
|
377
384
|
spec_type?: 'vega-lite' | 'vizspec';
|
|
378
385
|
target_db?: string;
|
|
@@ -724,12 +731,11 @@ interface AskOptions {
|
|
|
724
731
|
*/
|
|
725
732
|
querypanelSessionId?: string;
|
|
726
733
|
/**
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
730
|
-
* - `"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.
|
|
731
737
|
*/
|
|
732
|
-
pipeline?: "
|
|
738
|
+
pipeline?: "v2";
|
|
733
739
|
/**
|
|
734
740
|
* Optional model id for SQL generation (e.g. OpenAI or `gemini-*` when the API uses Gemini). Omit for server default.
|
|
735
741
|
*/
|
|
@@ -743,7 +749,7 @@ interface AskOptions {
|
|
|
743
749
|
* Use this for tenant-specific policies (e.g. retention windows) that must
|
|
744
750
|
* be enforced on every query.
|
|
745
751
|
*
|
|
746
|
-
* Sent
|
|
752
|
+
* Sent on every ask (`POST /v2/query`).
|
|
747
753
|
*/
|
|
748
754
|
systemPrompt?: string;
|
|
749
755
|
/**
|
|
@@ -821,9 +827,10 @@ interface AskResponse {
|
|
|
821
827
|
trace?: PipelineTrace;
|
|
822
828
|
}
|
|
823
829
|
/**
|
|
824
|
-
* 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.
|
|
825
832
|
*/
|
|
826
|
-
declare function resolveQueryPipeline(pipeline?: "
|
|
833
|
+
declare function resolveQueryPipeline(pipeline?: "v2"): "v2";
|
|
827
834
|
declare function anonymizeResults(rows: Array<Record<string, unknown>>): Array<Record<string, string>>;
|
|
828
835
|
|
|
829
836
|
/**
|
|
@@ -917,11 +924,22 @@ interface VizModifications {
|
|
|
917
924
|
*/
|
|
918
925
|
interface ChartModifyInput {
|
|
919
926
|
/**
|
|
920
|
-
*
|
|
927
|
+
* Server-issued id of the query to modify or re-execute.
|
|
928
|
+
* From ask() / modifyChart() response: response.queryId
|
|
929
|
+
* From saved chart: chart.query_id
|
|
930
|
+
*
|
|
931
|
+
* Preferred over `sql`: when present the SQL and params are loaded from the server
|
|
932
|
+
* (scoped to the authenticated tenant) and `sql` / `params` are ignored.
|
|
933
|
+
*/
|
|
934
|
+
queryId?: string;
|
|
935
|
+
/**
|
|
936
|
+
* The SQL query to modify or re-execute. Required when `queryId` is not provided.
|
|
921
937
|
* From ask() response: response.sql
|
|
922
938
|
* From saved chart: chart.sql
|
|
939
|
+
*
|
|
940
|
+
* Kept for backward compatibility; prefer `queryId`.
|
|
923
941
|
*/
|
|
924
|
-
sql
|
|
942
|
+
sql?: string;
|
|
925
943
|
/**
|
|
926
944
|
* The original natural language question.
|
|
927
945
|
* Used when regenerating SQL with modifications.
|
|
@@ -967,12 +985,11 @@ interface ChartModifyOptions {
|
|
|
967
985
|
/** Chart generation method: 'vega-lite' or 'vizspec' */
|
|
968
986
|
chartType?: "vega-lite" | "vizspec";
|
|
969
987
|
/**
|
|
970
|
-
*
|
|
971
|
-
*
|
|
972
|
-
*
|
|
973
|
-
* - `"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.
|
|
974
991
|
*/
|
|
975
|
-
pipeline?: "
|
|
992
|
+
pipeline?: "v2";
|
|
976
993
|
/**
|
|
977
994
|
* QueryPanel session ID for context-aware follow-ups.
|
|
978
995
|
* Pass the querypanelSessionId from a previous ask() response
|
|
@@ -1313,7 +1330,13 @@ declare class QueryPanelSdkAPI {
|
|
|
1313
1330
|
* to be attached (e.g. via attachPostgres) and options.tenantId.
|
|
1314
1331
|
*/
|
|
1315
1332
|
runSqlForDashboard(input: {
|
|
1316
|
-
|
|
1333
|
+
/**
|
|
1334
|
+
* Server-issued id from ask() / modifyChart(). Takes priority: the stored SQL
|
|
1335
|
+
* and params are executed and `sql` / `params` are ignored.
|
|
1336
|
+
*/
|
|
1337
|
+
queryId?: string;
|
|
1338
|
+
/** Required when `queryId` is not provided (backward compatible raw SQL). */
|
|
1339
|
+
sql?: string;
|
|
1317
1340
|
params?: Record<string, unknown>;
|
|
1318
1341
|
database?: string;
|
|
1319
1342
|
}, options: {
|
package/dist/index.d.ts
CHANGED
|
@@ -360,10 +360,15 @@ interface ChartCreateInput {
|
|
|
360
360
|
title: string;
|
|
361
361
|
prompt?: string;
|
|
362
362
|
description?: string;
|
|
363
|
-
|
|
363
|
+
/**
|
|
364
|
+
* Required when `query_id` is not provided. Ignored (with `sql_params`) when
|
|
365
|
+
* `query_id` is present: the server saves the SQL and params it stored for that query.
|
|
366
|
+
*/
|
|
367
|
+
sql?: string;
|
|
364
368
|
sql_params?: Record<string, unknown>;
|
|
365
369
|
vega_lite_spec: Record<string, unknown>;
|
|
366
370
|
spec_type?: 'vega-lite' | 'vizspec';
|
|
371
|
+
/** Server-issued query id from ask() / modifyChart(). Preferred over `sql`. */
|
|
367
372
|
query_id?: string;
|
|
368
373
|
target_db?: string;
|
|
369
374
|
}
|
|
@@ -373,6 +378,8 @@ interface ChartUpdateInput {
|
|
|
373
378
|
description?: string;
|
|
374
379
|
sql?: string;
|
|
375
380
|
sql_params?: Record<string, unknown>;
|
|
381
|
+
/** When present, the server replaces sql / sql_params with the stored query. */
|
|
382
|
+
query_id?: string;
|
|
376
383
|
vega_lite_spec?: Record<string, unknown>;
|
|
377
384
|
spec_type?: 'vega-lite' | 'vizspec';
|
|
378
385
|
target_db?: string;
|
|
@@ -724,12 +731,11 @@ interface AskOptions {
|
|
|
724
731
|
*/
|
|
725
732
|
querypanelSessionId?: string;
|
|
726
733
|
/**
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
730
|
-
* - `"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.
|
|
731
737
|
*/
|
|
732
|
-
pipeline?: "
|
|
738
|
+
pipeline?: "v2";
|
|
733
739
|
/**
|
|
734
740
|
* Optional model id for SQL generation (e.g. OpenAI or `gemini-*` when the API uses Gemini). Omit for server default.
|
|
735
741
|
*/
|
|
@@ -743,7 +749,7 @@ interface AskOptions {
|
|
|
743
749
|
* Use this for tenant-specific policies (e.g. retention windows) that must
|
|
744
750
|
* be enforced on every query.
|
|
745
751
|
*
|
|
746
|
-
* Sent
|
|
752
|
+
* Sent on every ask (`POST /v2/query`).
|
|
747
753
|
*/
|
|
748
754
|
systemPrompt?: string;
|
|
749
755
|
/**
|
|
@@ -821,9 +827,10 @@ interface AskResponse {
|
|
|
821
827
|
trace?: PipelineTrace;
|
|
822
828
|
}
|
|
823
829
|
/**
|
|
824
|
-
* 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.
|
|
825
832
|
*/
|
|
826
|
-
declare function resolveQueryPipeline(pipeline?: "
|
|
833
|
+
declare function resolveQueryPipeline(pipeline?: "v2"): "v2";
|
|
827
834
|
declare function anonymizeResults(rows: Array<Record<string, unknown>>): Array<Record<string, string>>;
|
|
828
835
|
|
|
829
836
|
/**
|
|
@@ -917,11 +924,22 @@ interface VizModifications {
|
|
|
917
924
|
*/
|
|
918
925
|
interface ChartModifyInput {
|
|
919
926
|
/**
|
|
920
|
-
*
|
|
927
|
+
* Server-issued id of the query to modify or re-execute.
|
|
928
|
+
* From ask() / modifyChart() response: response.queryId
|
|
929
|
+
* From saved chart: chart.query_id
|
|
930
|
+
*
|
|
931
|
+
* Preferred over `sql`: when present the SQL and params are loaded from the server
|
|
932
|
+
* (scoped to the authenticated tenant) and `sql` / `params` are ignored.
|
|
933
|
+
*/
|
|
934
|
+
queryId?: string;
|
|
935
|
+
/**
|
|
936
|
+
* The SQL query to modify or re-execute. Required when `queryId` is not provided.
|
|
921
937
|
* From ask() response: response.sql
|
|
922
938
|
* From saved chart: chart.sql
|
|
939
|
+
*
|
|
940
|
+
* Kept for backward compatibility; prefer `queryId`.
|
|
923
941
|
*/
|
|
924
|
-
sql
|
|
942
|
+
sql?: string;
|
|
925
943
|
/**
|
|
926
944
|
* The original natural language question.
|
|
927
945
|
* Used when regenerating SQL with modifications.
|
|
@@ -967,12 +985,11 @@ interface ChartModifyOptions {
|
|
|
967
985
|
/** Chart generation method: 'vega-lite' or 'vizspec' */
|
|
968
986
|
chartType?: "vega-lite" | "vizspec";
|
|
969
987
|
/**
|
|
970
|
-
*
|
|
971
|
-
*
|
|
972
|
-
*
|
|
973
|
-
* - `"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.
|
|
974
991
|
*/
|
|
975
|
-
pipeline?: "
|
|
992
|
+
pipeline?: "v2";
|
|
976
993
|
/**
|
|
977
994
|
* QueryPanel session ID for context-aware follow-ups.
|
|
978
995
|
* Pass the querypanelSessionId from a previous ask() response
|
|
@@ -1313,7 +1330,13 @@ declare class QueryPanelSdkAPI {
|
|
|
1313
1330
|
* to be attached (e.g. via attachPostgres) and options.tenantId.
|
|
1314
1331
|
*/
|
|
1315
1332
|
runSqlForDashboard(input: {
|
|
1316
|
-
|
|
1333
|
+
/**
|
|
1334
|
+
* Server-issued id from ask() / modifyChart(). Takes priority: the stored SQL
|
|
1335
|
+
* and params are executed and `sql` / `params` are ignored.
|
|
1336
|
+
*/
|
|
1337
|
+
queryId?: string;
|
|
1338
|
+
/** Required when `queryId` is not provided (backward compatible raw SQL). */
|
|
1339
|
+
sql?: string;
|
|
1317
1340
|
params?: Record<string, unknown>;
|
|
1318
1341
|
database?: string;
|
|
1319
1342
|
}, options: {
|
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(
|
|
@@ -2147,34 +2185,53 @@ function anonymizeResults(rows) {
|
|
|
2147
2185
|
});
|
|
2148
2186
|
}
|
|
2149
2187
|
|
|
2188
|
+
// src/routes/queries.ts
|
|
2189
|
+
async function resolveQuery(client, queryEngine, queryId, options, signal) {
|
|
2190
|
+
const response = await client.get(
|
|
2191
|
+
`/v2/queries/${encodeURIComponent(queryId)}`,
|
|
2192
|
+
options.tenantId,
|
|
2193
|
+
options.userId,
|
|
2194
|
+
options.scopes,
|
|
2195
|
+
signal
|
|
2196
|
+
);
|
|
2197
|
+
const paramMetadata = Array.isArray(response.params) ? response.params : [];
|
|
2198
|
+
return {
|
|
2199
|
+
queryId: response.queryId,
|
|
2200
|
+
sql: response.sql,
|
|
2201
|
+
params: queryEngine.mapGeneratedParams(paramMetadata),
|
|
2202
|
+
paramMetadata,
|
|
2203
|
+
dialect: response.dialect
|
|
2204
|
+
};
|
|
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
|
+
}
|
|
2219
|
+
|
|
2150
2220
|
// src/routes/modify.ts
|
|
2151
|
-
function buildModifiedQuestion(originalQuestion, modifications,
|
|
2221
|
+
function buildModifiedQuestion(originalQuestion, modifications, hasSessionContext = false) {
|
|
2152
2222
|
const hints = [];
|
|
2153
2223
|
if (modifications.timeGranularity) {
|
|
2154
2224
|
hints.push(`group results by ${modifications.timeGranularity}`);
|
|
2155
2225
|
}
|
|
2156
2226
|
if (modifications.dateRange) {
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
hints.push(`change end date to ${to}`);
|
|
2166
|
-
}
|
|
2167
|
-
} else {
|
|
2168
|
-
const parts = [];
|
|
2169
|
-
if (modifications.dateRange.from) {
|
|
2170
|
-
parts.push(`from ${modifications.dateRange.from}`);
|
|
2171
|
-
}
|
|
2172
|
-
if (modifications.dateRange.to) {
|
|
2173
|
-
parts.push(`to ${modifications.dateRange.to}`);
|
|
2174
|
-
}
|
|
2175
|
-
if (parts.length > 0) {
|
|
2176
|
-
hints.push(`filter date range ${parts.join(" ")}`);
|
|
2177
|
-
}
|
|
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}`);
|
|
2178
2235
|
}
|
|
2179
2236
|
}
|
|
2180
2237
|
if (modifications.additionalInstructions) {
|
|
@@ -2183,7 +2240,7 @@ function buildModifiedQuestion(originalQuestion, modifications, pipeline, hasSes
|
|
|
2183
2240
|
if (hints.length === 0) {
|
|
2184
2241
|
return originalQuestion;
|
|
2185
2242
|
}
|
|
2186
|
-
if (
|
|
2243
|
+
if (hasSessionContext) {
|
|
2187
2244
|
return hints.join(", ");
|
|
2188
2245
|
}
|
|
2189
2246
|
return `${originalQuestion} (${hints.join(", ")})`;
|
|
@@ -2299,13 +2356,30 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2299
2356
|
const hasSqlMods = !!input.sqlModifications;
|
|
2300
2357
|
const hasVizMods = !!input.vizModifications;
|
|
2301
2358
|
const hasCustomSql = !!input.sqlModifications?.customSql;
|
|
2302
|
-
|
|
2303
|
-
const queryEndpoint =
|
|
2304
|
-
let
|
|
2359
|
+
resolveQueryPipeline(options?.pipeline);
|
|
2360
|
+
const queryEndpoint = "/v2/query";
|
|
2361
|
+
let currentSql = input.sql;
|
|
2305
2362
|
let finalParams = input.params ?? {};
|
|
2306
2363
|
let paramMetadata = [];
|
|
2307
2364
|
let rationale;
|
|
2308
2365
|
let queryId;
|
|
2366
|
+
if (input.queryId) {
|
|
2367
|
+
const resolved = await resolveQuery(
|
|
2368
|
+
client,
|
|
2369
|
+
queryEngine,
|
|
2370
|
+
input.queryId,
|
|
2371
|
+
{ tenantId, userId: options?.userId, scopes: options?.scopes },
|
|
2372
|
+
signal
|
|
2373
|
+
);
|
|
2374
|
+
currentSql = resolved.sql;
|
|
2375
|
+
finalParams = resolved.params;
|
|
2376
|
+
paramMetadata = resolved.paramMetadata;
|
|
2377
|
+
queryId = resolved.queryId;
|
|
2378
|
+
}
|
|
2379
|
+
if (!currentSql) {
|
|
2380
|
+
throw new Error("modifyChart requires either queryId or sql.");
|
|
2381
|
+
}
|
|
2382
|
+
let finalSql = currentSql;
|
|
2309
2383
|
let sqlChanged = false;
|
|
2310
2384
|
let finalQuestion = input.question;
|
|
2311
2385
|
const databaseName = input.database ?? queryEngine.getDefaultDatabase();
|
|
@@ -2333,23 +2407,21 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2333
2407
|
finalSql = input.sqlModifications.customSql;
|
|
2334
2408
|
finalParams = {};
|
|
2335
2409
|
paramMetadata = [];
|
|
2410
|
+
queryId = void 0;
|
|
2336
2411
|
sqlChanged = true;
|
|
2337
2412
|
} else if (hasSqlMods && !hasCustomSql) {
|
|
2338
2413
|
const modifiedQuestion = buildModifiedQuestion(
|
|
2339
2414
|
input.question,
|
|
2340
2415
|
input.sqlModifications,
|
|
2341
|
-
pipeline,
|
|
2342
2416
|
hasQuerypanelSessionContext
|
|
2343
2417
|
);
|
|
2344
|
-
|
|
2345
|
-
finalQuestion = modifiedQuestion;
|
|
2346
|
-
}
|
|
2418
|
+
finalQuestion = modifiedQuestion;
|
|
2347
2419
|
const queryResponse = await client.post(
|
|
2348
2420
|
queryEndpoint,
|
|
2349
2421
|
{
|
|
2350
2422
|
question: modifiedQuestion,
|
|
2351
2423
|
session_id: querypanelSessionId,
|
|
2352
|
-
previous_sql:
|
|
2424
|
+
previous_sql: currentSql,
|
|
2353
2425
|
...options?.maxRetry ? { max_retry: options.maxRetry } : {},
|
|
2354
2426
|
...tenantSettings ? { tenant_settings: tenantSettings } : {},
|
|
2355
2427
|
...databaseName ? { database: databaseName } : {},
|
|
@@ -2365,16 +2437,14 @@ async function modifyChart(client, queryEngine, input, options, signal) {
|
|
|
2365
2437
|
finalSql = queryResponse.sql;
|
|
2366
2438
|
paramMetadata = Array.isArray(queryResponse.params) ? queryResponse.params : [];
|
|
2367
2439
|
finalParams = queryEngine.mapGeneratedParams(paramMetadata);
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
);
|
|
2374
|
-
}
|
|
2440
|
+
applyDateRangeOverrides(
|
|
2441
|
+
input.sqlModifications?.dateRange,
|
|
2442
|
+
finalParams,
|
|
2443
|
+
paramMetadata
|
|
2444
|
+
);
|
|
2375
2445
|
rationale = queryResponse.rationale;
|
|
2376
2446
|
queryId = queryResponse.queryId;
|
|
2377
|
-
sqlChanged = finalSql !==
|
|
2447
|
+
sqlChanged = finalSql !== currentSql;
|
|
2378
2448
|
}
|
|
2379
2449
|
const execution = await queryEngine.validateAndExecute(
|
|
2380
2450
|
finalSql,
|
|
@@ -2589,6 +2659,9 @@ function resolveAttachEnforceTenantIsolation(tenantFieldName, enforceTenantIsola
|
|
|
2589
2659
|
return tenantFieldName ? true : void 0;
|
|
2590
2660
|
}
|
|
2591
2661
|
var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
2662
|
+
client;
|
|
2663
|
+
queryEngine;
|
|
2664
|
+
supportedChartTypes;
|
|
2592
2665
|
/**
|
|
2593
2666
|
* @param workspaceId - Workspace UUID (same value as your org in the dashboard). Passed to the API as JWT claim `organizationId`.
|
|
2594
2667
|
*/
|
|
@@ -2819,13 +2892,32 @@ var QueryPanelSdkAPI = class _QueryPanelSdkAPI {
|
|
|
2819
2892
|
throw new Error("tenantId is required");
|
|
2820
2893
|
}
|
|
2821
2894
|
const databaseName = input.database ?? "db";
|
|
2822
|
-
|
|
2895
|
+
let sql = input.sql;
|
|
2896
|
+
let params = input.params ?? {};
|
|
2897
|
+
if (input.queryId) {
|
|
2898
|
+
const resolved = await resolveQuery(
|
|
2899
|
+
this.client,
|
|
2900
|
+
this.queryEngine,
|
|
2901
|
+
input.queryId,
|
|
2902
|
+
{ tenantId }
|
|
2903
|
+
);
|
|
2904
|
+
sql = resolved.sql;
|
|
2905
|
+
params = resolved.params;
|
|
2906
|
+
}
|
|
2907
|
+
if (!sql) {
|
|
2908
|
+
throw new Error("Either queryId or sql is required");
|
|
2909
|
+
}
|
|
2823
2910
|
const result = await this.queryEngine.validateAndExecute(
|
|
2824
|
-
|
|
2911
|
+
sql,
|
|
2825
2912
|
params,
|
|
2826
2913
|
databaseName,
|
|
2827
2914
|
tenantId
|
|
2828
2915
|
);
|
|
2916
|
+
if (input.queryId) {
|
|
2917
|
+
await markQueryExecuted(this.client, input.queryId, {
|
|
2918
|
+
tenantId
|
|
2919
|
+
});
|
|
2920
|
+
}
|
|
2829
2921
|
return { rows: result.rows, fields: result.fields };
|
|
2830
2922
|
}
|
|
2831
2923
|
// VizSpec generation
|