@duckcodeailabs/dql-agent 1.10.9 → 1.11.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.
Files changed (39) hide show
  1. package/dist/agent-run-engine.d.ts +74 -0
  2. package/dist/agent-run-engine.d.ts.map +1 -1
  3. package/dist/agent-run-engine.js +225 -13
  4. package/dist/agent-run-engine.js.map +1 -1
  5. package/dist/agent-run-store.d.ts +11 -1
  6. package/dist/agent-run-store.d.ts.map +1 -1
  7. package/dist/agent-run-store.js +152 -0
  8. package/dist/agent-run-store.js.map +1 -1
  9. package/dist/analytical-compatibility.d.ts +3 -1
  10. package/dist/analytical-compatibility.d.ts.map +1 -1
  11. package/dist/analytical-compatibility.js +157 -12
  12. package/dist/analytical-compatibility.js.map +1 -1
  13. package/dist/analytical-frame.d.ts +2 -0
  14. package/dist/analytical-frame.d.ts.map +1 -1
  15. package/dist/analytical-frame.js +37 -26
  16. package/dist/analytical-frame.js.map +1 -1
  17. package/dist/answer-loop.d.ts.map +1 -1
  18. package/dist/answer-loop.js +95 -9
  19. package/dist/answer-loop.js.map +1 -1
  20. package/dist/conversation/session-store.d.ts +2 -0
  21. package/dist/conversation/session-store.d.ts.map +1 -1
  22. package/dist/conversation/session-store.js +52 -3
  23. package/dist/conversation/session-store.js.map +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/metadata/analysis-planner.d.ts.map +1 -1
  28. package/dist/metadata/analysis-planner.js +33 -2
  29. package/dist/metadata/analysis-planner.js.map +1 -1
  30. package/dist/resolved-analytical-plan.d.ts.map +1 -1
  31. package/dist/resolved-analytical-plan.js +9 -2
  32. package/dist/resolved-analytical-plan.js.map +1 -1
  33. package/dist/router.d.ts.map +1 -1
  34. package/dist/router.js +108 -4
  35. package/dist/router.js.map +1 -1
  36. package/dist/semantic-bridge/compose.d.ts.map +1 -1
  37. package/dist/semantic-bridge/compose.js +35 -59
  38. package/dist/semantic-bridge/compose.js.map +1 -1
  39. 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;
@@ -750,8 +795,10 @@ export async function answer(input) {
750
795
  const analyticalAdapterId = analyticalCapability && analyticalRoute
751
796
  ? analyticalCapability.executionCapabilities.find((candidate) => candidate.route === analyticalRoute)?.adapterId
752
797
  : undefined;
798
+ const multiMetricPlan = (normalizedInput.resolvedAnalyticalPlan?.analyticalFrame?.metricConceptIds.length ?? 0) > 1;
753
799
  const analyticalGraphBuild = normalizedInput.resolvedAnalyticalPlan?.schemaVersion === 2
754
800
  && normalizedInput.resolvedAnalyticalPlan.analyticalFrame
801
+ && !multiMetricPlan
755
802
  && !normalizedInput.analyticalPeriodResolutionFailure
756
803
  && analyticalCapability
757
804
  && analyticalRoute
@@ -766,6 +813,7 @@ export async function answer(input) {
766
813
  ? analyticalGraphBuild.graph
767
814
  : undefined;
768
815
  const analyticalExecutionGraphFailure = normalizedInput.resolvedAnalyticalPlan?.schemaVersion === 2
816
+ && !multiMetricPlan
769
817
  ? analyticalGraphBuild?.status === 'blocked'
770
818
  ? {
771
819
  code: analyticalGraphBuild.code,
@@ -1732,9 +1780,11 @@ async function runAnswerLoop(input) {
1732
1780
  let semanticBridgeAnswer;
1733
1781
  let semanticRuntimeFailure;
1734
1782
  let semanticExecutionTrace;
1783
+ let semanticAttemptedArtifact;
1735
1784
  let semanticRuntimeCompiledAnswer = false;
1736
1785
  if (authoritativeSemanticBinding && input.semanticLayer) {
1737
1786
  const selection = authoritativeSemanticBinding.selection;
1787
+ semanticAttemptedArtifact = semanticAttemptArtifact(input.semanticLayer, question, selection);
1738
1788
  semanticBridgeAnswer = composeSemanticQueryFromMembers({
1739
1789
  semanticLayer: input.semanticLayer,
1740
1790
  question,
@@ -1799,6 +1849,7 @@ async function runAnswerLoop(input) {
1799
1849
  || semanticMetricMatch.metric.name.endsWith(`.${metric.name}`))?.name;
1800
1850
  if (matchedName) {
1801
1851
  const selection = { metrics: [matchedName], dimensions: [] };
1852
+ semanticAttemptedArtifact = semanticAttemptArtifact(input.semanticLayer, question, selection);
1802
1853
  try {
1803
1854
  const compiled = await input.semanticQueryCompiler(selection);
1804
1855
  semanticExecutionTrace = compiled.trace;
@@ -1845,6 +1896,7 @@ async function runAnswerLoop(input) {
1845
1896
  // metrics native can't express. Side effects (runtime flags, tool calls)
1846
1897
  // are recorded here so a retry reruns them cleanly.
1847
1898
  const composeSelection = async (selection) => {
1899
+ semanticAttemptedArtifact = semanticAttemptArtifact(bridgeLayer, question, selection);
1848
1900
  let composed = composeSemanticQueryFromMembers({
1849
1901
  semanticLayer: bridgeLayer,
1850
1902
  question,
@@ -1929,11 +1981,34 @@ async function runAnswerLoop(input) {
1929
1981
  }
1930
1982
  }
1931
1983
  if (!semanticBridgeAnswer && semanticRuntimeFailure) {
1932
- const isPathAmbiguity = semanticRuntimeFailure.code === 'SEMANTIC_PATH_AMBIGUOUS'
1933
- || 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';
1934
1987
  const text = isPathAmbiguity
1935
- ? semanticRuntimeFailure.message
1936
- : `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
+ });
1937
2012
  return {
1938
2013
  kind: 'no_answer',
1939
2014
  sourceTier: 'no_answer',
@@ -1942,16 +2017,22 @@ async function runAnswerLoop(input) {
1942
2017
  confidence: 0,
1943
2018
  text,
1944
2019
  answer: text,
2020
+ ...(analyticalFailure ? { executionError: analyticalFailure.message } : {}),
1945
2021
  refusalCode: isPathAmbiguity ? 'ambiguous' : 'modeling_gap',
1946
2022
  // The answer shows the compact business-readable failure; the FULL compiler
1947
2023
  // output stays here for Inspect/debugging.
1948
2024
  refusalDetails: {
1949
2025
  code: isPathAmbiguity ? 'semantic_path_ambiguous' : 'semantic_runtime_required',
1950
- message: semanticRuntimeFailure.message,
2026
+ message: runtimeFailure.message,
1951
2027
  },
1952
2028
  ...(semanticExecutionTrace ? { semanticExecutionTrace } : {}),
1953
- ...(semanticRuntimeFailure.candidates?.length
1954
- ? { 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 })) }
1955
2036
  : {}),
1956
2037
  citations: [],
1957
2038
  memoryContext: input.memoryContext,
@@ -3276,6 +3357,7 @@ async function executeSemanticAnalyticalGraph(input) {
3276
3357
  const artifacts = [];
3277
3358
  let semanticExecutionTrace;
3278
3359
  for (const invocation of input.binding.invocations) {
3360
+ const attemptedArtifact = semanticAttemptArtifact(layer, input.input.question, invocation.selection);
3279
3361
  let composed = composeSemanticQueryFromMembers({
3280
3362
  semanticLayer: layer,
3281
3363
  question: input.input.question,
@@ -3321,7 +3403,10 @@ async function executeSemanticAnalyticalGraph(input) {
3321
3403
  }
3322
3404
  return analyticalGraphFailureAnswer(input, 'COMPILATION_FAILED', error instanceof Error ? error.message : String(error), {
3323
3405
  phase: 'compilation',
3324
- ...(compiledSql.length ? { compiledSql: renderAnalyticalStatements(compiledSql) } : {}),
3406
+ dqlArtifact: attemptedArtifact,
3407
+ ...([...compiledSql, ...(failure.attemptedSql ? [failure.attemptedSql] : [])].length
3408
+ ? { compiledSql: renderAnalyticalStatements([...compiledSql, ...(failure.attemptedSql ? [failure.attemptedSql] : [])]) }
3409
+ : {}),
3325
3410
  ...(failure.trace ? { semanticExecutionTrace: failure.trace } : {}),
3326
3411
  });
3327
3412
  }
@@ -3329,6 +3414,7 @@ async function executeSemanticAnalyticalGraph(input) {
3329
3414
  if (!composed) {
3330
3415
  return analyticalGraphFailureAnswer(input, 'COMPILATION_FAILED', `The pinned semantic adapter could not compile ${invocation.nodeId}.`, {
3331
3416
  phase: 'compilation',
3417
+ dqlArtifact: attemptedArtifact,
3332
3418
  ...(compiledSql.length ? { compiledSql: renderAnalyticalStatements(compiledSql) } : {}),
3333
3419
  failedBindings: [{ role: 'source_invocation', reasonCode: 'SEMANTIC_COMPILE_FAILED' }],
3334
3420
  });