@duckcodeailabs/dql-cli 1.6.0 → 1.6.2

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.
Files changed (91) hide show
  1. package/README.md +9 -9
  2. package/dist/apps-api.d.ts +20 -0
  3. package/dist/apps-api.d.ts.map +1 -1
  4. package/dist/apps-api.js +82 -4
  5. package/dist/apps-api.js.map +1 -1
  6. package/dist/apps-api.test.js +43 -1
  7. package/dist/apps-api.test.js.map +1 -1
  8. package/dist/args.d.ts +2 -0
  9. package/dist/args.d.ts.map +1 -1
  10. package/dist/args.js +3 -0
  11. package/dist/args.js.map +1 -1
  12. package/dist/assets/dql-notebook/assets/index-60sOoPrg.js +3599 -0
  13. package/dist/assets/dql-notebook/assets/index-RaDW1A5g.css +1 -0
  14. package/dist/assets/dql-notebook/index.html +3 -3
  15. package/dist/commands/app.d.ts +4 -3
  16. package/dist/commands/app.d.ts.map +1 -1
  17. package/dist/commands/app.js +161 -75
  18. package/dist/commands/app.js.map +1 -1
  19. package/dist/commands/build.d.ts.map +1 -1
  20. package/dist/commands/build.js +7 -1
  21. package/dist/commands/build.js.map +1 -1
  22. package/dist/commands/certify.d.ts.map +1 -1
  23. package/dist/commands/certify.js +35 -5
  24. package/dist/commands/certify.js.map +1 -1
  25. package/dist/commands/compile.d.ts +1 -1
  26. package/dist/commands/compile.d.ts.map +1 -1
  27. package/dist/commands/compile.js +42 -3
  28. package/dist/commands/compile.js.map +1 -1
  29. package/dist/commands/doctor.d.ts.map +1 -1
  30. package/dist/commands/doctor.js +91 -4
  31. package/dist/commands/doctor.js.map +1 -1
  32. package/dist/commands/doctor.test.js +1 -0
  33. package/dist/commands/doctor.test.js.map +1 -1
  34. package/dist/commands/info.d.ts.map +1 -1
  35. package/dist/commands/info.js +21 -6
  36. package/dist/commands/info.js.map +1 -1
  37. package/dist/commands/init.d.ts.map +1 -1
  38. package/dist/commands/init.js +3 -1
  39. package/dist/commands/init.js.map +1 -1
  40. package/dist/commands/init.test.js +4 -0
  41. package/dist/commands/init.test.js.map +1 -1
  42. package/dist/commands/lineage.d.ts +3 -0
  43. package/dist/commands/lineage.d.ts.map +1 -1
  44. package/dist/commands/lineage.js +230 -2
  45. package/dist/commands/lineage.js.map +1 -1
  46. package/dist/commands/migrate.d.ts.map +1 -1
  47. package/dist/commands/migrate.js +2 -1
  48. package/dist/commands/migrate.js.map +1 -1
  49. package/dist/commands/new.js +61 -2
  50. package/dist/commands/new.js.map +1 -1
  51. package/dist/commands/new.test.js +106 -0
  52. package/dist/commands/new.test.js.map +1 -1
  53. package/dist/commands/parse.d.ts.map +1 -1
  54. package/dist/commands/parse.js +13 -3
  55. package/dist/commands/parse.js.map +1 -1
  56. package/dist/commands/preview.d.ts.map +1 -1
  57. package/dist/commands/preview.js +7 -1
  58. package/dist/commands/preview.js.map +1 -1
  59. package/dist/commands/validate.d.ts.map +1 -1
  60. package/dist/commands/validate.js +55 -8
  61. package/dist/commands/validate.js.map +1 -1
  62. package/dist/commands/validate.test.js +85 -0
  63. package/dist/commands/validate.test.js.map +1 -1
  64. package/dist/commands/verify.d.ts +1 -1
  65. package/dist/commands/verify.d.ts.map +1 -1
  66. package/dist/commands/verify.js +40 -6
  67. package/dist/commands/verify.js.map +1 -1
  68. package/dist/index.js +136 -64
  69. package/dist/index.js.map +1 -1
  70. package/dist/llm/providers/dql-agent-provider.d.ts.map +1 -1
  71. package/dist/llm/providers/dql-agent-provider.js +95 -19
  72. package/dist/llm/providers/dql-agent-provider.js.map +1 -1
  73. package/dist/llm/tools.d.ts.map +1 -1
  74. package/dist/llm/tools.js +29 -1
  75. package/dist/llm/tools.js.map +1 -1
  76. package/dist/llm/types.d.ts +3 -1
  77. package/dist/llm/types.d.ts.map +1 -1
  78. package/dist/local-runtime.d.ts +14 -0
  79. package/dist/local-runtime.d.ts.map +1 -1
  80. package/dist/local-runtime.js +763 -58
  81. package/dist/local-runtime.js.map +1 -1
  82. package/dist/local-runtime.test.js +64 -1
  83. package/dist/local-runtime.test.js.map +1 -1
  84. package/dist/template-adoption.test.d.ts +2 -0
  85. package/dist/template-adoption.test.d.ts.map +1 -0
  86. package/dist/template-adoption.test.js +105 -0
  87. package/dist/template-adoption.test.js.map +1 -0
  88. package/package.json +13 -13
  89. package/dist/assets/dql-notebook/assets/index-B5jI3I8Q.js +0 -869
  90. package/dist/assets/dql-notebook/assets/index-cv-O4BEj.css +0 -1
  91. package/dist/package.json +0 -44
@@ -7,17 +7,51 @@
7
7
  * schedules) stay in lock-step with their source files.
8
8
  */
9
9
  import { existsSync, readFileSync } from 'node:fs';
10
- import { join } from 'node:path';
11
- import { buildManifest } from '@duckcodeailabs/dql-core';
12
- import { findProjectRoot } from '../local-runtime.js';
13
- export async function runVerify(_rest, flags) {
14
- const projectRoot = findProjectRoot(process.cwd());
10
+ import { join, resolve } from 'node:path';
11
+ import { buildManifest, resolveDataLexManifestPath, resolveDbtManifestPath } from '@duckcodeailabs/dql-core';
12
+ export async function runVerify(pathArg, rest, flags) {
13
+ const allArgs = [...(pathArg ? [pathArg] : []), ...rest];
14
+ let dbtManifestPath;
15
+ const dbtIdx = allArgs.indexOf('--dbt-manifest');
16
+ if (dbtIdx >= 0 && allArgs[dbtIdx + 1]) {
17
+ dbtManifestPath = resolve(allArgs[dbtIdx + 1]);
18
+ if (!existsSync(dbtManifestPath)) {
19
+ throw new Error(`dbt manifest not found: ${dbtManifestPath}`);
20
+ }
21
+ }
22
+ let maxDbtHops;
23
+ const hopsIdx = allArgs.indexOf('--dbt-hops');
24
+ if (hopsIdx >= 0 && allArgs[hopsIdx + 1]) {
25
+ const parsed = Number.parseInt(allArgs[hopsIdx + 1], 10);
26
+ if (Number.isFinite(parsed) && parsed > 0)
27
+ maxDbtHops = parsed;
28
+ }
29
+ const pathCandidates = allArgs.filter((a) => !a.startsWith('-'));
30
+ const filteredCandidates = pathCandidates
31
+ .filter((c) => dbtIdx < 0 || c !== allArgs[dbtIdx + 1])
32
+ .filter((c) => hopsIdx < 0 || c !== allArgs[hopsIdx + 1]);
33
+ const projectRoot = resolve(filteredCandidates[0] ?? '.');
15
34
  const manifestPath = join(projectRoot, 'dql-manifest.json');
16
35
  if (!existsSync(manifestPath)) {
17
36
  throw new Error(`dql-manifest.json not found at ${manifestPath}. Run \`dql compile\` first.`);
18
37
  }
38
+ let dqlVersion = '0.6.0';
39
+ try {
40
+ const pkgPath = join(import.meta.dirname ?? __dirname, '..', '..', 'package.json');
41
+ if (existsSync(pkgPath)) {
42
+ dqlVersion = JSON.parse(readFileSync(pkgPath, 'utf-8')).version ?? dqlVersion;
43
+ }
44
+ }
45
+ catch { /* use default */ }
46
+ const resolvedDbt = resolveDbtManifestPath(projectRoot, dbtManifestPath);
47
+ if (resolvedDbt)
48
+ dbtManifestPath = resolvedDbt;
49
+ const datalexManifestPath = resolveDataLexManifestPath(projectRoot, flags.datalexManifestPath || undefined) ?? undefined;
50
+ if (flags.datalexManifestPath && (!datalexManifestPath || !existsSync(datalexManifestPath))) {
51
+ throw new Error(`DataLex manifest not found: ${flags.datalexManifestPath}`);
52
+ }
19
53
  const onDisk = JSON.parse(readFileSync(manifestPath, 'utf-8'));
20
- const fresh = buildManifest({ projectRoot });
54
+ const fresh = buildManifest({ projectRoot, dqlVersion, dbtManifestPath, maxDbtHops, datalexManifestPath });
21
55
  const drift = diffManifest(onDisk, fresh);
22
56
  const json = flags.format === 'json';
23
57
  if (drift.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,34 +1,34 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync } from 'node:fs';
3
- import { dirname, join } from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import { parseArgs } from './args.js';
6
- import { runInit } from './commands/init.js';
7
- import { runNew } from './commands/new.js';
8
- import { runBuild } from './commands/build.js';
9
- import { runDoctor } from './commands/doctor.js';
10
- import { runPreview } from './commands/preview.js';
11
- import { runServe } from './commands/serve.js';
12
- import { runParse } from './commands/parse.js';
13
- import { runTest } from './commands/test.js';
14
- import { runCertify } from './commands/certify.js';
15
- import { runInfo } from './commands/info.js';
16
- import { runMigrate } from './commands/migrate.js';
17
- import { runFmt } from './commands/fmt.js';
18
- import { runNotebook } from './commands/notebook.js';
19
- import { runValidate } from './commands/validate.js';
20
- import { runSemantic } from './commands/semantic.js';
21
- import { runLineage } from './commands/lineage.js';
22
- import { runCompile } from './commands/compile.js';
23
- import { runSync } from './commands/sync.js';
24
- import { runDiff } from './commands/diff.js';
25
- import { runMcp } from './commands/mcp.js';
26
- import { runApp } from './commands/app.js';
27
- import { runSchedule } from './commands/schedule.js';
28
- import { runAgent } from './commands/agent.js';
29
- import { runSlack } from './commands/slack.js';
30
- import { runVerify } from './commands/verify.js';
31
- import { runImport } from './commands/import.js';
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { parseArgs } from "./args.js";
6
+ import { runInit } from "./commands/init.js";
7
+ import { runNew } from "./commands/new.js";
8
+ import { runBuild } from "./commands/build.js";
9
+ import { runDoctor } from "./commands/doctor.js";
10
+ import { runPreview } from "./commands/preview.js";
11
+ import { runServe } from "./commands/serve.js";
12
+ import { runParse } from "./commands/parse.js";
13
+ import { runTest } from "./commands/test.js";
14
+ import { runCertify } from "./commands/certify.js";
15
+ import { runInfo } from "./commands/info.js";
16
+ import { runMigrate } from "./commands/migrate.js";
17
+ import { runFmt } from "./commands/fmt.js";
18
+ import { runNotebook } from "./commands/notebook.js";
19
+ import { runValidate } from "./commands/validate.js";
20
+ import { runSemantic } from "./commands/semantic.js";
21
+ import { runLineage } from "./commands/lineage.js";
22
+ import { runCompile } from "./commands/compile.js";
23
+ import { runSync } from "./commands/sync.js";
24
+ import { runDiff } from "./commands/diff.js";
25
+ import { runMcp } from "./commands/mcp.js";
26
+ import { runApp } from "./commands/app.js";
27
+ import { runSchedule } from "./commands/schedule.js";
28
+ import { runAgent } from "./commands/agent.js";
29
+ import { runSlack } from "./commands/slack.js";
30
+ import { runVerify } from "./commands/verify.js";
31
+ import { runImport } from "./commands/import.js";
32
32
  const HELP = `
33
33
  dql — DQL CLI
34
34
 
@@ -59,7 +59,7 @@ const HELP = `
59
59
  dql sync dbt [path] Detect dbt manifest changes; report DQL cache status
60
60
  dql lineage [block] [path] Answer-layer lineage analysis
61
61
  dql mcp [--http] Run the DQL MCP server (stdio by default; --http = loopback)
62
- dql app new|ls|show|build|reindex <name>
62
+ dql app new|generate|ls|show|build|reindex <name>
63
63
  Manage App artifacts (metadata, policies, dashboards, schedules)
64
64
  dql schedule list|run|start|status Local scheduler for @schedule'd blocks (alerts + notifications)
65
65
  dql agent ask "<question>" Block-first agent loop (certified blocks → fallback LLM SQL)
@@ -86,17 +86,75 @@ const HELP = `
86
86
  --connection <driver|path> Database connection for certify/test (e.g. duckdb, path/to/db)
87
87
  --from-draft <path> For "certify": promote a Tier-2 draft block to certified
88
88
  --contract <id@version> For "certify --from-draft": DataLex contract id (e.g. commerce.Customer.foo@1)
89
+ --datalex-manifest <path> Optional DataLex manifest for datalex_contract validation
89
90
  --open-pr For "certify --from-draft": push branch + open GitHub PR with the diff
90
91
  --force For "certify --from-draft": overwrite an existing certified block
91
92
  `;
93
+ const COMMAND_HELP = {
94
+ certify: `
95
+ dql certify — Evaluate local certification rules
96
+
97
+ Usage:
98
+ dql certify <file.dql> [--connection <driver|path>] [--skip-tests]
99
+ dql certify --from-draft <path> [--contract <id@version>] [--force]
100
+
101
+ Notes:
102
+ Certification is a local OSS trust label. Use status = "certified" for
103
+ blocks that pass metadata, lineage, and test checks.
104
+ `,
105
+ app: `
106
+ dql app — Manage local App artifacts
107
+
108
+ Usage:
109
+ dql app new <name>
110
+ dql app generate "<prompt>" [--domain <domain>] [--owner <user>]
111
+ dql app ls
112
+ dql app show <name>
113
+ dql app build <name>
114
+ dql app reindex
115
+ `,
116
+ compile: `
117
+ dql compile — Generate dql-manifest.json
118
+
119
+ Usage:
120
+ dql compile [path] [--dbt-manifest <path>] [--dbt-hops <n>] [--datalex-manifest <path>] [--no-cache]
121
+
122
+ dql-manifest.json is the dbt-like compiled artifact for blocks, notebooks,
123
+ Apps, dashboards, semantic objects, sources, dbt imports, and lineage.
124
+ `,
125
+ doctor: `
126
+ dql doctor — Check a local DQL project
127
+
128
+ Usage:
129
+ dql doctor [path] [--format json]
130
+
131
+ Prints setup checks and the next local-first commands to run.
132
+ `,
133
+ semantic: `
134
+ dql semantic — Work with the local semantic layer
135
+
136
+ Usage:
137
+ dql semantic list [path]
138
+ dql semantic validate [path]
139
+ dql semantic query <metrics> [dimensions]
140
+ `,
141
+ verify: `
142
+ dql verify — Verify dql-manifest.json is reproducible
143
+
144
+ Usage:
145
+ dql verify [path] [--dbt-manifest <path>] [--dbt-hops <n>] [--datalex-manifest <path>] [--format json]
146
+
147
+ Run after dql compile in CI or before release commits.
148
+ `,
149
+ };
92
150
  function getVersion() {
93
151
  try {
94
152
  const cliDir = dirname(fileURLToPath(import.meta.url));
95
- const pkg = JSON.parse(readFileSync(join(cliDir, '../package.json'), 'utf-8'));
96
- return pkg.version ?? 'unknown';
153
+ const pkg = JSON.parse(readFileSync(join(cliDir, "../package.json"), "utf-8"));
154
+ return pkg.version ?? "unknown";
97
155
  }
98
156
  catch {
99
- return 'unknown';
157
+ return "unknown";
100
158
  }
101
159
  }
102
160
  async function main() {
@@ -106,92 +164,106 @@ async function main() {
106
164
  process.exit(0);
107
165
  }
108
166
  if (flags.help || !command) {
109
- console.log(HELP.trim());
167
+ console.log((command && COMMAND_HELP[command] ? COMMAND_HELP[command] : HELP).trim());
110
168
  process.exit(0);
111
169
  }
112
- if (!file && command !== 'init' && command !== 'serve' && command !== 'doctor' && command !== 'notebook' && command !== 'validate' && command !== 'semantic' && command !== 'lineage' && command !== 'compile' && command !== 'sync' && command !== 'mcp' && command !== 'app' && command !== 'schedule') {
170
+ const commandAllowsNoFile = command === "init" ||
171
+ command === "serve" ||
172
+ command === "doctor" ||
173
+ command === "notebook" ||
174
+ command === "validate" ||
175
+ command === "semantic" ||
176
+ command === "lineage" ||
177
+ command === "compile" ||
178
+ command === "sync" ||
179
+ command === "mcp" ||
180
+ command === "app" ||
181
+ command === "schedule" ||
182
+ command === "verify" ||
183
+ (command === "certify" && Boolean(flags.fromDraft));
184
+ if (!file && !commandAllowsNoFile) {
113
185
  console.error('Error: No file/argument specified. Run "dql --help" for usage.');
114
186
  process.exit(1);
115
187
  }
116
188
  try {
117
189
  switch (command) {
118
- case 'init':
190
+ case "init":
119
191
  await runInit(file, flags);
120
192
  break;
121
- case 'new':
193
+ case "new":
122
194
  await runNew(file, rest, flags);
123
195
  break;
124
- case 'build':
196
+ case "build":
125
197
  await runBuild(file, flags);
126
198
  break;
127
- case 'doctor':
199
+ case "doctor":
128
200
  await runDoctor(file, flags);
129
201
  break;
130
- case 'parse':
202
+ case "parse":
131
203
  await runParse(file, flags);
132
204
  break;
133
- case 'preview':
205
+ case "preview":
134
206
  await runPreview(file, flags);
135
207
  break;
136
- case 'serve':
208
+ case "serve":
137
209
  await runServe(file, flags);
138
210
  break;
139
- case 'test':
211
+ case "test":
140
212
  await runTest(file, flags);
141
213
  break;
142
- case 'certify':
143
- await runCertify(file, flags);
214
+ case "certify":
215
+ await runCertify(file ?? "", flags);
144
216
  break;
145
- case 'info':
217
+ case "info":
146
218
  await runInfo(file, flags);
147
219
  break;
148
- case 'migrate':
220
+ case "migrate":
149
221
  await runMigrate(file, flags);
150
222
  break;
151
- case 'import':
223
+ case "import":
152
224
  await runImport(file, rest, flags);
153
225
  break;
154
- case 'fmt':
226
+ case "fmt":
155
227
  await runFmt(file, flags);
156
228
  break;
157
- case 'notebook':
229
+ case "notebook":
158
230
  await runNotebook(file, flags);
159
231
  break;
160
- case 'validate':
232
+ case "validate":
161
233
  await runValidate(file, flags);
162
234
  break;
163
- case 'semantic':
235
+ case "semantic":
164
236
  await runSemantic(file, rest, flags);
165
237
  break;
166
- case 'compile':
238
+ case "compile":
167
239
  await runCompile(file, rest, flags);
168
240
  break;
169
- case 'sync':
241
+ case "sync":
170
242
  await runSync(file, rest, flags);
171
243
  break;
172
- case 'lineage':
244
+ case "lineage":
173
245
  await runLineage(file, rest, flags);
174
246
  break;
175
- case 'diff':
247
+ case "diff":
176
248
  await runDiff(file, rest, flags);
177
249
  break;
178
- case 'mcp':
250
+ case "mcp":
179
251
  await runMcp(file, flags);
180
252
  break;
181
- case 'app':
253
+ case "app":
182
254
  await runApp(file, rest, flags);
183
255
  break;
184
- case 'schedule':
256
+ case "schedule":
185
257
  await runSchedule(file, rest, flags);
186
258
  break;
187
- case 'agent':
259
+ case "agent":
188
260
  await runAgent(file, rest, flags);
189
261
  break;
190
- case 'slack':
262
+ case "slack":
191
263
  await runSlack(file, rest, flags);
192
264
  break;
193
- case 'verify':
194
- await runVerify(rest, flags);
265
+ case "verify":
266
+ await runVerify(file, rest, flags);
195
267
  break;
196
268
  default:
197
269
  console.error(`Unknown command: ${command}. Run "dql --help" for usage.`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dql-agent-provider.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/dql-agent-provider.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAmB,WAAW,EAA4B,UAAU,EAAE,MAAM,aAAa,CAAC;AAGtG,KAAK,gBAAgB,GAAG,OAAO,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,eAAe,CAAC,CAAC;AAmE9F,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,gBAAgB,GAAG,WAAW,CAmE9E"}
1
+ {"version":3,"file":"dql-agent-provider.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/dql-agent-provider.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAmB,WAAW,EAA4B,UAAU,EAAE,MAAM,aAAa,CAAC;AAGtG,KAAK,gBAAgB,GAAG,OAAO,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,eAAe,CAAC,CAAC;AAmE9F,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,gBAAgB,GAAG,WAAW,CA0E9E"}
@@ -75,7 +75,7 @@ export function createDqlAgentProviderRunner(id) {
75
75
  emit({ kind: 'thinking', text: `Using ${spec.label} through the governed DQL agent.` });
76
76
  const kgPath = defaultKgPath(req.projectRoot);
77
77
  if (!existsSync(kgPath)) {
78
- emit({ kind: 'thinking', text: 'Building the local agent knowledge graph from blocks, apps, dashboards, dbt, and semantic metadata.' });
78
+ emit({ kind: 'thinking', text: 'Building the local agent knowledge graph from terms, business views, blocks, apps, dashboards, dbt, and semantic metadata.' });
79
79
  await reindexProject(req.projectRoot, { kgPath });
80
80
  }
81
81
  const question = lastUserMessage(req);
@@ -92,18 +92,25 @@ export function createDqlAgentProviderRunner(id) {
92
92
  scopeId: req.upstream?.cellId,
93
93
  limit: 6,
94
94
  });
95
+ const schemaContext = req.getSchemaContext
96
+ ? await req.getSchemaContext(question).catch(() => [])
97
+ : [];
95
98
  const skills = loadSkills(req.projectRoot).skills;
96
- const blockHints = inferFollowUpBlockHints(req, question);
99
+ const followUp = inferFollowUpContext(req, question);
100
+ const blockHints = followUp?.kind === 'generic' && followUp.sourceBlockName ? [followUp.sourceBlockName] : [];
97
101
  const result = await answer({
98
102
  question,
99
- extraContext: renderExtraContext(req, blockHints),
103
+ extraContext: renderExtraContext(req, followUp),
100
104
  provider,
101
105
  kg,
102
106
  skills,
103
107
  blockHints,
108
+ followUp,
104
109
  memoryContext,
110
+ schemaContext,
105
111
  signal,
106
112
  executeCertifiedBlock: req.executeCertifiedBlock,
113
+ executeGeneratedSql: req.executeGeneratedSql,
107
114
  });
108
115
  emit({ kind: 'tool_result', id: 'governed_answer', output: result });
109
116
  emit({ kind: 'text', text: formatAgentAnswer(result) });
@@ -141,29 +148,54 @@ function lastUserMessage(req) {
141
148
  }
142
149
  return '';
143
150
  }
144
- function renderExtraContext(req, blockHints) {
151
+ function renderExtraContext(req, followUp) {
145
152
  const parts = [];
146
- if (req.upstream?.sql)
147
- parts.push(`Current upstream SQL:\n${req.upstream.sql}`);
148
- if (blockHints.length > 0) {
149
- parts.push(`Follow-up context: the user is referring to certified block "${blockHints[0]}".`);
153
+ const upstream = req.upstream?.sql?.trim();
154
+ if (upstream) {
155
+ const label = upstream.startsWith('{') || upstream.startsWith('[')
156
+ ? 'Current app/drill context'
157
+ : 'Current upstream SQL';
158
+ parts.push(`${label}:\n${upstream}`);
159
+ }
160
+ if (followUp?.sourceBlockName) {
161
+ const suffix = followUp.kind === 'drilldown'
162
+ ? 'Use it as source context, but prefer a distinct certified drilldown block or a review-required draft.'
163
+ : 'Reuse it for this generic follow-up.';
164
+ parts.push(`Follow-up context: the user is referring to certified block "${followUp.sourceBlockName}". ${suffix}`);
165
+ }
166
+ if (followUp?.filters?.length) {
167
+ parts.push(`Requested follow-up filters: ${followUp.filters.join(', ')}`);
168
+ }
169
+ if (followUp?.dimensions?.length) {
170
+ parts.push(`Requested follow-up dimensions: ${followUp.dimensions.join(', ')}`);
150
171
  }
151
172
  return parts.length > 0 ? parts.join('\n\n') : undefined;
152
173
  }
153
- function inferFollowUpBlockHints(req, question) {
154
- if (!isGenericFollowUp(question))
155
- return [];
174
+ function inferFollowUpContext(req, question) {
175
+ const kind = isGenericFollowUp(question) ? 'generic' : isDrilldownFollowUp(question) ? 'drilldown' : null;
176
+ if (!kind)
177
+ return undefined;
156
178
  for (let i = req.messages.length - 1; i >= 0; i--) {
157
179
  const msg = req.messages[i];
158
180
  if (msg.role !== 'assistant')
159
181
  continue;
160
- const fromAnswer = msg.content.match(/Answered by certified block \*\*([^*]+)\*\*/i)?.[1];
161
- const fromCitation = msg.content.match(/^- block:\s*([A-Za-z0-9_.-]+)/im)?.[1];
162
- const block = fromAnswer ?? fromCitation;
163
- if (block)
164
- return [block.trim()];
182
+ const sourceBlockName = extractCertifiedBlockName(msg.content);
183
+ if (!sourceBlockName)
184
+ continue;
185
+ return {
186
+ kind,
187
+ sourceBlockName,
188
+ sourceAnswer: msg.content.slice(0, 1200),
189
+ filters: kind === 'drilldown' ? extractDrilldownFilters(question) : undefined,
190
+ dimensions: kind === 'drilldown' ? extractDrilldownDimensions(question) : undefined,
191
+ };
165
192
  }
166
- return [];
193
+ return undefined;
194
+ }
195
+ function extractCertifiedBlockName(content) {
196
+ const fromAnswer = content.match(/Answered by certified block \*\*([^*]+)\*\*/i)?.[1];
197
+ const fromCitation = content.match(/^- block:\s*([A-Za-z0-9_.-]+)/im)?.[1];
198
+ return (fromAnswer ?? fromCitation)?.trim();
167
199
  }
168
200
  const GENERIC_FOLLOW_UP_WORDS = new Set([
169
201
  'a', 'about', 'again', 'all', 'also', 'and', 'as', 'be', 'block', 'can', 'could', 'data', 'do',
@@ -179,6 +211,45 @@ function isGenericFollowUp(question) {
179
211
  const meaningful = tokens.filter((token) => token.length > 1 && !GENERIC_FOLLOW_UP_WORDS.has(token));
180
212
  return meaningful.length === 0;
181
213
  }
214
+ function isDrilldownFollowUp(question) {
215
+ const lower = question.toLowerCase();
216
+ return /\b(drill|break\s*down|slice|segment|filter|compare|split|by|for|only|where|last week|this week|last month|this month|enterprise|region|customer|channel|product)\b/.test(lower)
217
+ && !/\b(what is|what are|define|definition|meaning of)\b/.test(lower);
218
+ }
219
+ function extractDrilldownFilters(question) {
220
+ const filters = [];
221
+ const quoted = [...question.matchAll(/["']([^"']+)["']/g)].map((match) => match[1].trim()).filter(Boolean);
222
+ filters.push(...quoted);
223
+ for (const pattern of [
224
+ /\benterprise\b/i,
225
+ /\bsmall business\b/i,
226
+ /\bmid[- ]market\b/i,
227
+ /\blast week\b/i,
228
+ /\bthis week\b/i,
229
+ /\blast month\b/i,
230
+ /\bthis month\b/i,
231
+ /\blast quarter\b/i,
232
+ /\bthis quarter\b/i,
233
+ ]) {
234
+ const match = question.match(pattern);
235
+ if (match)
236
+ filters.push(match[0]);
237
+ }
238
+ return Array.from(new Set(filters));
239
+ }
240
+ function extractDrilldownDimensions(question) {
241
+ const dims = [];
242
+ for (const match of question.matchAll(/\bby\s+([a-z][a-z0-9_ -]{1,40})/gi)) {
243
+ const value = match[1].replace(/\b(last|this|where|for|only|and|with)\b.*$/i, '').trim();
244
+ if (value)
245
+ dims.push(value);
246
+ }
247
+ for (const dim of ['segment', 'region', 'customer', 'channel', 'product', 'week', 'month']) {
248
+ if (new RegExp(`\\b${dim}\\b`, 'i').test(question))
249
+ dims.push(dim);
250
+ }
251
+ return Array.from(new Set(dims));
252
+ }
182
253
  function formatAgentAnswer(result) {
183
254
  const badge = result.certification === 'certified'
184
255
  ? 'Certified'
@@ -238,13 +309,14 @@ function escapeMarkdownTable(value) {
238
309
  return value.replace(/\|/g, '\\|').replace(/\r?\n/g, ' ');
239
310
  }
240
311
  function emitDraftProposal(result, question, emit) {
312
+ const isDrilldown = result.evidence?.route.some((step) => step.tool === 'propose_drilldown' && step.status === 'checked') ?? false;
241
313
  const proposal = {
242
314
  name: slugify(question).slice(0, 56) || 'ai_generated_analysis',
243
315
  domain: '',
244
316
  owner: `${process.env.USER ?? 'analyst'}@local`,
245
317
  description: result.text.slice(0, 240),
246
318
  sql: result.proposedSql,
247
- tags: ['ai-generated', 'needs-review', result.sourceTier ?? 'dbt_manifest'],
319
+ tags: ['ai-generated', 'needs-review', result.sourceTier ?? 'dbt_manifest', ...(isDrilldown ? ['drilldown'] : [])],
248
320
  chartType: result.suggestedViz,
249
321
  };
250
322
  emit({
@@ -253,7 +325,11 @@ function emitDraftProposal(result, question, emit) {
253
325
  governance: {
254
326
  certified: false,
255
327
  errors: [],
256
- warnings: ['AI generated. Analyst review and certification are required before reuse as governed content.'],
328
+ warnings: [
329
+ isDrilldown
330
+ ? 'AI generated drilldown. Validate filters, joins, and grain before certifying.'
331
+ : 'AI generated. Analyst review and certification are required before reuse as governed content.',
332
+ ],
257
333
  },
258
334
  });
259
335
  }