@duckcodeailabs/dql-cli 1.6.5 → 1.6.7
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/apps-api.d.ts.map +1 -1
- package/dist/apps-api.js +89 -8
- package/dist/apps-api.js.map +1 -1
- package/dist/args.d.ts +13 -0
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +24 -0
- package/dist/args.js.map +1 -1
- package/dist/assets/dql-notebook/assets/{index-L-zyCapt.js → index-BbGJ8gZk.js} +175 -172
- package/dist/assets/dql-notebook/assets/index-CIMLd3Cb.js +3289 -0
- package/dist/assets/dql-notebook/index.html +1 -1
- package/dist/commands/agent.d.ts +62 -2
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +307 -22
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/app.d.ts.map +1 -1
- package/dist/commands/app.js +3 -2
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/compile.d.ts +3 -0
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +45 -10
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +2 -1
- package/dist/commands/sync.js.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/llm/providers/dql-agent-provider.d.ts.map +1 -1
- package/dist/llm/providers/dql-agent-provider.js +107 -5
- package/dist/llm/providers/dql-agent-provider.js.map +1 -1
- package/dist/llm/types.d.ts +19 -0
- package/dist/llm/types.d.ts.map +1 -1
- package/dist/local-runtime.d.ts +1 -0
- package/dist/local-runtime.d.ts.map +1 -1
- package/dist/local-runtime.js +228 -14
- package/dist/local-runtime.js.map +1 -1
- package/dist/package.json +10 -10
- package/dist/promote-from-draft.d.ts +4 -4
- package/dist/promote-from-draft.js +8 -8
- package/dist/promote-from-draft.js.map +1 -1
- package/package.json +11 -11
package/dist/apps-api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps-api.d.ts","sourceRoot":"","sources":["../src/apps-api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAQL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"apps-api.d.ts","sourceRoot":"","sources":["../src/apps-api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAQL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAQL,KAAK,2BAA2B,EACjC,MAAM,6BAA6B,CAAC;AAErC,UAAU,GAAG;IACX,GAAG,EAAE,eAAe,CAAC;IACrB,GAAG,EAAE,cAAc,CAAC;IACpB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE,iCAAiC,KAAK,OAAO,CAAC,gCAAgC,CAAC,CAAC;IACnH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAylB9D;AAID,KAAK,YAAY,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;IACjD,aAAa,EAAE,WAAW,GAAG,aAAa,CAAC;IAC3C,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACxC,UAAU,EAAE,WAAW,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;IACnD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,YAAY,CAAC;QAAC,UAAU,EAAE,WAAW,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAA;KAAE,CAAC,CAAC;IACnJ,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CACpC,CAAC;AAEF,iBAAS,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,EAAE,CAuC5D;AAED,UAAU,wBAAwB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;IAC/C,SAAS,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AA6ED,UAAU,iCAAiC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,2BAA2B,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,gCAAgC;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,GAAG,cAAc,EAAE,CA6CtG;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CACN;IACE,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/B,GAAG,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACvD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAC/B,CA6CA;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,gBAAgB,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA2HpI;AAsWD,iBAAS,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQ9E;AAkHD,iBAAS,0BAA0B,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiCrH;AAED,iBAAS,uBAAuB,CAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,EAAE,2BAA2B,GAClC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAoChC;AA8BD,iBAAS,kCAAkC,CACzC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE;IACL,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,2BAA2B,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAoE/E;AAgrBD,iBAAS,WAAW,CAClB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,GACT;IACD,GAAG,EAAE,WAAW,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1F,SAAS,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;IACrC,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC/B,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,cAAc,EAAE,OAAO,EAAE,CAAC;CAC3B,GAAG,IAAI,CA2BP;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IACnG,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,YAAY,CAAC;IAC5C,UAAU,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC,CA2BD;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9F;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAyBlH;AAED,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAwD/E;AA0TD,eAAO,MAAM,QAAQ;;;;;CAKpB,CAAC"}
|
package/dist/apps-api.js
CHANGED
|
@@ -48,6 +48,7 @@ export async function handleAppsApi(ctx) {
|
|
|
48
48
|
sendJson(res, 400, { error: result.error });
|
|
49
49
|
return true;
|
|
50
50
|
}
|
|
51
|
+
await refreshGeneratedMetadata(projectRoot);
|
|
51
52
|
sendJson(res, 201, result);
|
|
52
53
|
}
|
|
53
54
|
catch (err) {
|
|
@@ -202,6 +203,7 @@ export async function handleAppsApi(ctx) {
|
|
|
202
203
|
title: body.title,
|
|
203
204
|
dashboardId: body.dashboardId,
|
|
204
205
|
notebookPath: body.notebookPath,
|
|
206
|
+
context: normalizeConversationContext(body.context),
|
|
205
207
|
messages: normalizeConversationMessages(body.messages),
|
|
206
208
|
});
|
|
207
209
|
sendJson(res, 201, { ok: true, conversation });
|
|
@@ -237,6 +239,7 @@ export async function handleAppsApi(ctx) {
|
|
|
237
239
|
title: body.title,
|
|
238
240
|
dashboardId: body.dashboardId,
|
|
239
241
|
notebookPath: body.notebookPath,
|
|
242
|
+
context: body.context === undefined ? undefined : normalizeConversationContext(body.context) ?? null,
|
|
240
243
|
messages: body.messages ? normalizeConversationMessages(body.messages) : undefined,
|
|
241
244
|
});
|
|
242
245
|
sendJson(res, 200, { ok: true, conversation: updated });
|
|
@@ -635,6 +638,29 @@ function collectAppsList(projectRoot) {
|
|
|
635
638
|
}
|
|
636
639
|
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
637
640
|
}
|
|
641
|
+
function normalizeConversationContext(value) {
|
|
642
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
643
|
+
return undefined;
|
|
644
|
+
const record = value;
|
|
645
|
+
return {
|
|
646
|
+
activeSurface: cleanString(record.activeSurface) || undefined,
|
|
647
|
+
sourceCertifiedBlock: cleanString(record.sourceCertifiedBlock) || undefined,
|
|
648
|
+
sourceQuestion: cleanString(record.sourceQuestion) || undefined,
|
|
649
|
+
sourceAnswerSummary: cleanString(record.sourceAnswerSummary) || undefined,
|
|
650
|
+
followupKind: record.followupKind === 'generic' || record.followupKind === 'drilldown' ? record.followupKind : undefined,
|
|
651
|
+
requestedFilters: stringArray(record.requestedFilters),
|
|
652
|
+
requestedDimensions: stringArray(record.requestedDimensions),
|
|
653
|
+
outputColumns: stringArray(record.outputColumns),
|
|
654
|
+
trustLabel: cleanString(record.trustLabel) || undefined,
|
|
655
|
+
reviewStatus: cleanString(record.reviewStatus) || undefined,
|
|
656
|
+
certification: cleanString(record.certification) || undefined,
|
|
657
|
+
route: cleanString(record.route) || undefined,
|
|
658
|
+
contextPackId: cleanString(record.contextPackId) || undefined,
|
|
659
|
+
draftBlockPath: cleanString(record.draftBlockPath) || undefined,
|
|
660
|
+
selectedEvidence: Array.isArray(record.selectedEvidence) ? record.selectedEvidence.slice(0, 16) : undefined,
|
|
661
|
+
updatedAt: cleanString(record.updatedAt) || undefined,
|
|
662
|
+
};
|
|
663
|
+
}
|
|
638
664
|
export function recommendBlocks(projectRoot, input) {
|
|
639
665
|
const domain = cleanString(input.domain).toLowerCase();
|
|
640
666
|
const tags = normalizeTags(input.tags ?? []);
|
|
@@ -689,7 +715,7 @@ export async function generateAppPackage(projectRoot, input) {
|
|
|
689
715
|
if (!prompt)
|
|
690
716
|
return { ok: false, error: 'prompt is required' };
|
|
691
717
|
const selectedBlockIds = unique((input.selectedBlockIds ?? []).map(cleanString).filter(Boolean));
|
|
692
|
-
const { KGStore, defaultKgPath, generateAppFromPlan, planAppFromPrompt, reindexProject, validateAppPlan, } = await import('@duckcodeailabs/dql-agent');
|
|
718
|
+
const { KGStore, defaultKgPath, generateAppFromPlan, ensureMetadataCatalogFresh, planAppFromPrompt, reindexProject, validateAppPlan, } = await import('@duckcodeailabs/dql-agent');
|
|
693
719
|
const kgPath = defaultKgPath(projectRoot);
|
|
694
720
|
await reindexProject(projectRoot, { kgPath });
|
|
695
721
|
const kg = new KGStore(kgPath);
|
|
@@ -705,6 +731,7 @@ export async function generateAppPackage(projectRoot, input) {
|
|
|
705
731
|
const generated = generateAppFromPlan(projectRoot, plan, kg, {
|
|
706
732
|
overwrite: Boolean(input.force),
|
|
707
733
|
});
|
|
734
|
+
await ensureMetadataCatalogFresh(projectRoot, { force: true });
|
|
708
735
|
const app = collectAppsList(projectRoot).find((entry) => entry.id === plan.appId) ?? null;
|
|
709
736
|
return {
|
|
710
737
|
ok: true,
|
|
@@ -1063,9 +1090,10 @@ async function runAppInvestigation(ctx, storage, investigation, input = {}) {
|
|
|
1063
1090
|
const previews = buildContextPreviews(selected);
|
|
1064
1091
|
let metricSnapshot = buildMetricSnapshot(selected);
|
|
1065
1092
|
let driverCards = buildDriverCards(selected, intent);
|
|
1093
|
+
const baselineGap = intent === 'diagnose_change' && hasSelectedRows(selected) && !hasComparableTimeBaseline(selected);
|
|
1066
1094
|
const sourceTileId = investigation.sourceTileId ?? selectedContextString(context, 'tileId');
|
|
1067
1095
|
const sourceBlockId = investigation.sourceBlockId ?? selectedContextString(context, 'blockId');
|
|
1068
|
-
const deterministicGeneration = generatedSql
|
|
1096
|
+
const deterministicGeneration = generatedSql || baselineGap
|
|
1069
1097
|
? undefined
|
|
1070
1098
|
: buildDeterministicInvestigationSql(ctx.projectRoot, {
|
|
1071
1099
|
question,
|
|
@@ -1074,7 +1102,7 @@ async function runAppInvestigation(ctx, storage, investigation, input = {}) {
|
|
|
1074
1102
|
sourceBlockId,
|
|
1075
1103
|
});
|
|
1076
1104
|
generatedSql = generatedSql || deterministicGeneration?.sql;
|
|
1077
|
-
const agentGeneration = generatedSql
|
|
1105
|
+
const agentGeneration = generatedSql || baselineGap
|
|
1078
1106
|
? undefined
|
|
1079
1107
|
: await generateInvestigationSql(ctx, {
|
|
1080
1108
|
appId: investigation.appId,
|
|
@@ -1106,7 +1134,8 @@ async function runAppInvestigation(ctx, storage, investigation, input = {}) {
|
|
|
1106
1134
|
generatedSql: generatedSql || undefined,
|
|
1107
1135
|
sqlExecuted: Boolean(sqlEvidence.preview),
|
|
1108
1136
|
sqlError,
|
|
1109
|
-
generationSource: deterministicGeneration ? 'selected_block_metadata' : agentGeneration?.providerUsed ? 'ai_provider' : generatedSql ? 'provided_sql' : 'context_only',
|
|
1137
|
+
generationSource: baselineGap ? 'missing_baseline' : deterministicGeneration ? 'selected_block_metadata' : agentGeneration?.providerUsed ? 'ai_provider' : generatedSql ? 'provided_sql' : 'context_only',
|
|
1138
|
+
baselineGap,
|
|
1110
1139
|
sourceBlockPath: deterministicGeneration?.sourceBlockPath,
|
|
1111
1140
|
sourceBlockName: deterministicGeneration?.sourceBlockName,
|
|
1112
1141
|
providerUsed: agentGeneration?.providerUsed,
|
|
@@ -1121,14 +1150,21 @@ async function runAppInvestigation(ctx, storage, investigation, input = {}) {
|
|
|
1121
1150
|
sourceBlockPath: deterministicGeneration?.sourceBlockPath ?? selectedString(selected, 'blockPath'),
|
|
1122
1151
|
certificationStatus: selectedString(selected, 'certificationStatus'),
|
|
1123
1152
|
},
|
|
1124
|
-
assumptions:
|
|
1153
|
+
assumptions: [
|
|
1154
|
+
...investigationAssumptions(intent, selected, generatedSql, sqlError),
|
|
1155
|
+
...(baselineGap ? ['The selected tile sample does not include at least two comparable time values, so DQL did not invent a change query from an unrelated table.'] : []),
|
|
1156
|
+
],
|
|
1125
1157
|
context,
|
|
1126
1158
|
agentEvidence: agentGeneration?.evidence,
|
|
1127
1159
|
analysisPlan: agentGeneration?.analysisPlan,
|
|
1128
1160
|
citations: agentGeneration?.citations,
|
|
1129
1161
|
};
|
|
1130
|
-
const summary = cleanString(agentGeneration?.answer) ||
|
|
1131
|
-
|
|
1162
|
+
const summary = cleanString(agentGeneration?.answer) || (baselineGap
|
|
1163
|
+
? buildMissingBaselineSummary(question, selected)
|
|
1164
|
+
: buildInvestigationSummary(intent, question, selected, metricSnapshot, driverCards));
|
|
1165
|
+
const recommendation = baselineGap
|
|
1166
|
+
? buildMissingBaselineRecommendation(selected)
|
|
1167
|
+
: buildInvestigationRecommendation(intent, selected, sqlError);
|
|
1132
1168
|
return storage.updateAppInvestigation(investigation.id, {
|
|
1133
1169
|
title: cleanString(input.question) ? titleFromInvestigation(question, selected) : investigation.title,
|
|
1134
1170
|
question,
|
|
@@ -1248,6 +1284,24 @@ function buildMetricSnapshot(selected) {
|
|
|
1248
1284
|
context: selectedString(selected, 'title') ?? 'Selected dashboard tile',
|
|
1249
1285
|
};
|
|
1250
1286
|
}
|
|
1287
|
+
function hasSelectedRows(selected) {
|
|
1288
|
+
return selectedRows(selected).length > 0;
|
|
1289
|
+
}
|
|
1290
|
+
function hasComparableTimeBaseline(selected) {
|
|
1291
|
+
const rows = selectedRows(selected);
|
|
1292
|
+
if (rows.length < 2)
|
|
1293
|
+
return false;
|
|
1294
|
+
const columns = selectedColumns(selected, rows);
|
|
1295
|
+
const profile = profileResultColumns(columns, rows);
|
|
1296
|
+
const timeDimension = chooseTimeDimension(profile);
|
|
1297
|
+
if (!timeDimension)
|
|
1298
|
+
return false;
|
|
1299
|
+
const values = new Set(rows
|
|
1300
|
+
.map((row) => row[timeDimension.name])
|
|
1301
|
+
.filter((value) => value !== null && value !== undefined && String(value).trim())
|
|
1302
|
+
.map((value) => String(value)));
|
|
1303
|
+
return values.size >= 2;
|
|
1304
|
+
}
|
|
1251
1305
|
function buildDriverCards(selected, intent) {
|
|
1252
1306
|
const rows = selectedRows(selected);
|
|
1253
1307
|
const columns = selectedColumns(selected, rows);
|
|
@@ -1408,7 +1462,7 @@ function buildDeterministicInvestigationSql(projectRoot, input) {
|
|
|
1408
1462
|
sourceBlockName: block.name,
|
|
1409
1463
|
};
|
|
1410
1464
|
}
|
|
1411
|
-
if (input.intent === 'anomaly_investigation') {
|
|
1465
|
+
if (input.intent === 'anomaly_investigation' || input.intent === 'diagnose_change') {
|
|
1412
1466
|
const timeDimension = chooseTimeDimension(profile) ?? dimension;
|
|
1413
1467
|
const rankExpr = `${measureAgg(measure)}(${quoteSqlIdentifier(measure.name)})`;
|
|
1414
1468
|
if (timeDimension) {
|
|
@@ -1747,6 +1801,14 @@ function buildInvestigationSummary(intent, question, selected, metrics, drivers)
|
|
|
1747
1801
|
const driver = drivers[0]?.title ? ` Top visible driver in the current evidence is ${drivers[0].title}.` : '';
|
|
1748
1802
|
return `DQL opened a review-required investigation for ${target}: ${question}.${delta}${driver}`;
|
|
1749
1803
|
}
|
|
1804
|
+
function buildMissingBaselineSummary(question, selected) {
|
|
1805
|
+
const target = selectedString(selected, 'title') ?? 'the selected tile';
|
|
1806
|
+
return `DQL opened a review-required investigation for ${target}: ${question}. The selected tile shows the current certified result, but its sample does not include a comparable prior period or historical snapshot, so DQL cannot calculate what changed without guessing.`;
|
|
1807
|
+
}
|
|
1808
|
+
function buildMissingBaselineRecommendation(selected) {
|
|
1809
|
+
const target = selectedString(selected, 'title') ?? 'this tile';
|
|
1810
|
+
return `Use ${target} as current-state evidence. To explain change, add or select a block with a time grain, snapshot date, or prior-period baseline, then rerun the investigation.`;
|
|
1811
|
+
}
|
|
1750
1812
|
function buildInvestigationRecommendation(intent, selected, sqlError) {
|
|
1751
1813
|
if (sqlError)
|
|
1752
1814
|
return 'Review the generated SQL or add a certified drilldown block before promoting this result.';
|
|
@@ -1818,6 +1880,15 @@ function asRecord(value) {
|
|
|
1818
1880
|
function cleanString(value) {
|
|
1819
1881
|
return typeof value === 'string' ? value.trim() : '';
|
|
1820
1882
|
}
|
|
1883
|
+
function stringArray(value) {
|
|
1884
|
+
if (!Array.isArray(value))
|
|
1885
|
+
return undefined;
|
|
1886
|
+
const items = value
|
|
1887
|
+
.map((item) => cleanString(item))
|
|
1888
|
+
.filter(Boolean)
|
|
1889
|
+
.slice(0, 24);
|
|
1890
|
+
return items.length > 0 ? items : undefined;
|
|
1891
|
+
}
|
|
1821
1892
|
function normalizeTags(values) {
|
|
1822
1893
|
return Array.from(new Set(values.map((value) => cleanString(value)).filter(Boolean)));
|
|
1823
1894
|
}
|
|
@@ -2451,6 +2522,16 @@ function activatePersona(projectRoot, userId, appId) {
|
|
|
2451
2522
|
return null;
|
|
2452
2523
|
}
|
|
2453
2524
|
// ---- IO utilities ----
|
|
2525
|
+
async function refreshGeneratedMetadata(projectRoot) {
|
|
2526
|
+
try {
|
|
2527
|
+
const { ensureMetadataCatalogFresh } = await import('@duckcodeailabs/dql-agent');
|
|
2528
|
+
await ensureMetadataCatalogFresh(projectRoot, { force: true });
|
|
2529
|
+
}
|
|
2530
|
+
catch {
|
|
2531
|
+
// App files remain the source of truth; the local catalog refreshes again
|
|
2532
|
+
// on the next agent/MCP call if this best-effort update fails.
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2454
2535
|
function sendJson(res, status, body) {
|
|
2455
2536
|
res.writeHead(status, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
2456
2537
|
res.end(JSON.stringify(body));
|