@duckcodeailabs/dql-agent 1.11.0 → 1.11.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 (33) hide show
  1. package/dist/agent-run-engine.d.ts +2 -0
  2. package/dist/agent-run-engine.d.ts.map +1 -1
  3. package/dist/agent-run-engine.js +24 -5
  4. package/dist/agent-run-engine.js.map +1 -1
  5. package/dist/answer-loop.d.ts.map +1 -1
  6. package/dist/answer-loop.js +92 -9
  7. package/dist/answer-loop.js.map +1 -1
  8. package/dist/conversation/session-store.d.ts.map +1 -1
  9. package/dist/conversation/session-store.js +46 -0
  10. package/dist/conversation/session-store.js.map +1 -1
  11. package/dist/metadata/analysis-planner.d.ts.map +1 -1
  12. package/dist/metadata/analysis-planner.js +33 -2
  13. package/dist/metadata/analysis-planner.js.map +1 -1
  14. package/dist/propose/build-from-prompt.d.ts.map +1 -1
  15. package/dist/propose/build-from-prompt.js +1 -0
  16. package/dist/propose/build-from-prompt.js.map +1 -1
  17. package/dist/propose/generate-sql.d.ts +5 -7
  18. package/dist/propose/generate-sql.d.ts.map +1 -1
  19. package/dist/propose/generate-sql.js +3 -5
  20. package/dist/propose/generate-sql.js.map +1 -1
  21. package/dist/propose/propose.js +4 -4
  22. package/dist/propose/propose.js.map +1 -1
  23. package/dist/propose/write-draft.d.ts +4 -3
  24. package/dist/propose/write-draft.d.ts.map +1 -1
  25. package/dist/propose/write-draft.js +19 -7
  26. package/dist/propose/write-draft.js.map +1 -1
  27. package/dist/semantic-bridge/compose.d.ts.map +1 -1
  28. package/dist/semantic-bridge/compose.js +35 -59
  29. package/dist/semantic-bridge/compose.js.map +1 -1
  30. package/dist/semantic-bridge/member-select.d.ts.map +1 -1
  31. package/dist/semantic-bridge/member-select.js +52 -3
  32. package/dist/semantic-bridge/member-select.js.map +1 -1
  33. package/package.json +4 -4
@@ -32,7 +32,7 @@ import { evaluateDbtFirstGeneratedSql } from './metadata/dbt-first-safety.js';
32
32
  import { planAnalyticalPath, humanizeAnalyticalEntityId, analyticalPolicyUserFacingReason, } from './metadata/analytical-policy.js';
33
33
  import { planCertifiedAdaptation } from './metadata/block-adapt.js';
34
34
  import { compactSqlSnippet, extractSimpleSelectShape, selectExpressionOutputName, } from './metadata/sql-shape.js';
35
- import { composeSemanticQueryForQuestion, composeSemanticQueryFromCompiledMembers, composeSemanticQueryFromMembers, } from './semantic-bridge/compose.js';
35
+ import { composeSemanticQueryForQuestion, composeSemanticQueryFromCompiledMembers, composeSemanticQueryFromMembers, renderSemanticDqlArtifact, semanticDqlArtifactName, } from './semantic-bridge/compose.js';
36
36
  import { runAgenticToolLoop } from './agentic/tool-loop.js';
37
37
  import { buildSemanticStageTools } from './agentic/toolset.js';
38
38
  import { deriveAgenticTrust } from './agentic/answer-contract.js';
@@ -61,6 +61,14 @@ function semanticCompilerFailure(error) {
61
61
  : details?.semanticTrace && typeof details.semanticTrace === 'object'
62
62
  ? details.semanticTrace
63
63
  : undefined;
64
+ const attemptedSql = [
65
+ record?.compiledSql,
66
+ record?.attemptedSql,
67
+ record?.sql,
68
+ details?.compiledSql,
69
+ details?.attemptedSql,
70
+ details?.sql,
71
+ ].find((value) => typeof value === 'string' && value.trim().length > 0)?.trim();
64
72
  const rawCandidates = Array.isArray(details?.candidates)
65
73
  ? details.candidates
66
74
  : Array.isArray(trace?.failure?.candidates)
@@ -82,10 +90,47 @@ function semanticCompilerFailure(error) {
82
90
  return {
83
91
  message,
84
92
  ...(typeof record?.code === 'string' ? { code: record.code } : {}),
93
+ ...(attemptedSql ? { attemptedSql } : {}),
85
94
  ...(trace ? { trace } : {}),
86
95
  ...(candidates.length > 0 ? { candidates } : {}),
87
96
  };
88
97
  }
98
+ /**
99
+ * Preserve the authoring contract before calling an external semantic compiler.
100
+ * A compiler failure is still a researchable DQL attempt, not an empty answer.
101
+ * Acceptance: AGT-017, API-007, UI-012, UI-013, E2E-015.
102
+ */
103
+ function semanticAttemptArtifact(semanticLayer, question, selection) {
104
+ const metrics = [...new Set(selection.metrics.map((value) => value.trim()).filter(Boolean))];
105
+ const dimensions = [...new Set((selection.dimensions ?? []).map((value) => value.trim()).filter(Boolean))];
106
+ const filters = selection.filters ?? [];
107
+ const domains = [...new Set(metrics
108
+ .map((name) => semanticLayer.listMetrics().find((metric) => metric.name.toLowerCase() === name.toLowerCase())?.domain)
109
+ .filter((domain) => Boolean(domain?.trim())))];
110
+ const sourceInput = {
111
+ question,
112
+ metrics,
113
+ dimensions,
114
+ filters,
115
+ ...(domains.length === 1 ? { domain: domains[0] } : {}),
116
+ ...(selection.timeDimension ? { timeDimension: selection.timeDimension } : {}),
117
+ ...(selection.orderBy ? { orderBy: selection.orderBy } : {}),
118
+ ...(selection.limit ? { limit: selection.limit } : {}),
119
+ };
120
+ return {
121
+ kind: 'semantic_block',
122
+ name: semanticDqlArtifactName(sourceInput),
123
+ source: renderSemanticDqlArtifact(sourceInput),
124
+ metrics,
125
+ dimensions,
126
+ filters,
127
+ ...(selection.timeDimension ? { timeDimension: selection.timeDimension } : {}),
128
+ ...(selection.orderBy ? { orderBy: selection.orderBy } : {}),
129
+ ...(selection.limit ? { limit: selection.limit } : {}),
130
+ persistence: 'transient',
131
+ trustState: 'governed',
132
+ };
133
+ }
89
134
  export function semanticTraceAfterExecution(trace, input) {
90
135
  if (!trace)
91
136
  return undefined;
@@ -1735,9 +1780,11 @@ async function runAnswerLoop(input) {
1735
1780
  let semanticBridgeAnswer;
1736
1781
  let semanticRuntimeFailure;
1737
1782
  let semanticExecutionTrace;
1783
+ let semanticAttemptedArtifact;
1738
1784
  let semanticRuntimeCompiledAnswer = false;
1739
1785
  if (authoritativeSemanticBinding && input.semanticLayer) {
1740
1786
  const selection = authoritativeSemanticBinding.selection;
1787
+ semanticAttemptedArtifact = semanticAttemptArtifact(input.semanticLayer, question, selection);
1741
1788
  semanticBridgeAnswer = composeSemanticQueryFromMembers({
1742
1789
  semanticLayer: input.semanticLayer,
1743
1790
  question,
@@ -1802,6 +1849,7 @@ async function runAnswerLoop(input) {
1802
1849
  || semanticMetricMatch.metric.name.endsWith(`.${metric.name}`))?.name;
1803
1850
  if (matchedName) {
1804
1851
  const selection = { metrics: [matchedName], dimensions: [] };
1852
+ semanticAttemptedArtifact = semanticAttemptArtifact(input.semanticLayer, question, selection);
1805
1853
  try {
1806
1854
  const compiled = await input.semanticQueryCompiler(selection);
1807
1855
  semanticExecutionTrace = compiled.trace;
@@ -1848,6 +1896,7 @@ async function runAnswerLoop(input) {
1848
1896
  // metrics native can't express. Side effects (runtime flags, tool calls)
1849
1897
  // are recorded here so a retry reruns them cleanly.
1850
1898
  const composeSelection = async (selection) => {
1899
+ semanticAttemptedArtifact = semanticAttemptArtifact(bridgeLayer, question, selection);
1851
1900
  let composed = composeSemanticQueryFromMembers({
1852
1901
  semanticLayer: bridgeLayer,
1853
1902
  question,
@@ -1932,11 +1981,34 @@ async function runAnswerLoop(input) {
1932
1981
  }
1933
1982
  }
1934
1983
  if (!semanticBridgeAnswer && semanticRuntimeFailure) {
1935
- const isPathAmbiguity = semanticRuntimeFailure.code === 'SEMANTIC_PATH_AMBIGUOUS'
1936
- || semanticRuntimeFailure.trace?.failure?.code === 'SEMANTIC_PATH_AMBIGUOUS';
1984
+ const runtimeFailure = semanticRuntimeFailure;
1985
+ const isPathAmbiguity = runtimeFailure.code === 'SEMANTIC_PATH_AMBIGUOUS'
1986
+ || runtimeFailure.trace?.failure?.code === 'SEMANTIC_PATH_AMBIGUOUS';
1937
1987
  const text = isPathAmbiguity
1938
- ? semanticRuntimeFailure.message
1939
- : `The governed semantic metric was found, but its semantic runtime could not compile the request: ${compactSemanticRuntimeFailure(semanticRuntimeFailure.message)}`;
1988
+ ? runtimeFailure.message
1989
+ : `The governed semantic metric was found, but its semantic runtime could not compile the request: ${compactSemanticRuntimeFailure(runtimeFailure.message)}`;
1990
+ const failedArtifact = semanticAttemptedArtifact
1991
+ ? {
1992
+ ...semanticAttemptedArtifact,
1993
+ ...(runtimeFailure.attemptedSql ? { compiledSql: runtimeFailure.attemptedSql } : {}),
1994
+ }
1995
+ : undefined;
1996
+ const analyticalFailure = isPathAmbiguity
1997
+ ? undefined
1998
+ : analyticalFailureForInput(input, {
1999
+ error: {
2000
+ code: runtimeFailure.code ?? 'COMPILATION_FAILED',
2001
+ message: runtimeFailure.message,
2002
+ },
2003
+ phase: 'compilation',
2004
+ dqlArtifact: failedArtifact,
2005
+ compiledSql: runtimeFailure.attemptedSql,
2006
+ failedBindings: failedArtifact?.metrics?.map((metric) => ({
2007
+ qualifiedId: metric,
2008
+ role: 'metric',
2009
+ reasonCode: runtimeFailure.code ?? 'SEMANTIC_COMPILATION_FAILED',
2010
+ })),
2011
+ });
1940
2012
  return {
1941
2013
  kind: 'no_answer',
1942
2014
  sourceTier: 'no_answer',
@@ -1945,16 +2017,22 @@ async function runAnswerLoop(input) {
1945
2017
  confidence: 0,
1946
2018
  text,
1947
2019
  answer: text,
2020
+ ...(analyticalFailure ? { executionError: analyticalFailure.message } : {}),
1948
2021
  refusalCode: isPathAmbiguity ? 'ambiguous' : 'modeling_gap',
1949
2022
  // The answer shows the compact business-readable failure; the FULL compiler
1950
2023
  // output stays here for Inspect/debugging.
1951
2024
  refusalDetails: {
1952
2025
  code: isPathAmbiguity ? 'semantic_path_ambiguous' : 'semantic_runtime_required',
1953
- message: semanticRuntimeFailure.message,
2026
+ message: runtimeFailure.message,
1954
2027
  },
1955
2028
  ...(semanticExecutionTrace ? { semanticExecutionTrace } : {}),
1956
- ...(semanticRuntimeFailure.candidates?.length
1957
- ? { clarificationOptions: semanticRuntimeFailure.candidates.map((candidate) => ({ ...candidate, question })) }
2029
+ ...(analyticalFailure ? { analyticalFailure } : {}),
2030
+ ...(failedArtifact ? { dqlArtifact: failedArtifact } : {}),
2031
+ ...(runtimeFailure.attemptedSql
2032
+ ? { proposedSql: runtimeFailure.attemptedSql, sql: runtimeFailure.attemptedSql }
2033
+ : {}),
2034
+ ...(runtimeFailure.candidates?.length
2035
+ ? { clarificationOptions: runtimeFailure.candidates.map((candidate) => ({ ...candidate, question })) }
1958
2036
  : {}),
1959
2037
  citations: [],
1960
2038
  memoryContext: input.memoryContext,
@@ -3279,6 +3357,7 @@ async function executeSemanticAnalyticalGraph(input) {
3279
3357
  const artifacts = [];
3280
3358
  let semanticExecutionTrace;
3281
3359
  for (const invocation of input.binding.invocations) {
3360
+ const attemptedArtifact = semanticAttemptArtifact(layer, input.input.question, invocation.selection);
3282
3361
  let composed = composeSemanticQueryFromMembers({
3283
3362
  semanticLayer: layer,
3284
3363
  question: input.input.question,
@@ -3324,7 +3403,10 @@ async function executeSemanticAnalyticalGraph(input) {
3324
3403
  }
3325
3404
  return analyticalGraphFailureAnswer(input, 'COMPILATION_FAILED', error instanceof Error ? error.message : String(error), {
3326
3405
  phase: 'compilation',
3327
- ...(compiledSql.length ? { compiledSql: renderAnalyticalStatements(compiledSql) } : {}),
3406
+ dqlArtifact: attemptedArtifact,
3407
+ ...([...compiledSql, ...(failure.attemptedSql ? [failure.attemptedSql] : [])].length
3408
+ ? { compiledSql: renderAnalyticalStatements([...compiledSql, ...(failure.attemptedSql ? [failure.attemptedSql] : [])]) }
3409
+ : {}),
3328
3410
  ...(failure.trace ? { semanticExecutionTrace: failure.trace } : {}),
3329
3411
  });
3330
3412
  }
@@ -3332,6 +3414,7 @@ async function executeSemanticAnalyticalGraph(input) {
3332
3414
  if (!composed) {
3333
3415
  return analyticalGraphFailureAnswer(input, 'COMPILATION_FAILED', `The pinned semantic adapter could not compile ${invocation.nodeId}.`, {
3334
3416
  phase: 'compilation',
3417
+ dqlArtifact: attemptedArtifact,
3335
3418
  ...(compiledSql.length ? { compiledSql: renderAnalyticalStatements(compiledSql) } : {}),
3336
3419
  failedBindings: [{ role: 'source_invocation', reasonCode: 'SEMANTIC_COMPILE_FAILED' }],
3337
3420
  });