@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.
- package/dist/agent-run-engine.d.ts +74 -0
- package/dist/agent-run-engine.d.ts.map +1 -1
- package/dist/agent-run-engine.js +225 -13
- package/dist/agent-run-engine.js.map +1 -1
- package/dist/agent-run-store.d.ts +11 -1
- package/dist/agent-run-store.d.ts.map +1 -1
- package/dist/agent-run-store.js +152 -0
- package/dist/agent-run-store.js.map +1 -1
- package/dist/analytical-compatibility.d.ts +3 -1
- package/dist/analytical-compatibility.d.ts.map +1 -1
- package/dist/analytical-compatibility.js +157 -12
- package/dist/analytical-compatibility.js.map +1 -1
- package/dist/analytical-frame.d.ts +2 -0
- package/dist/analytical-frame.d.ts.map +1 -1
- package/dist/analytical-frame.js +37 -26
- package/dist/analytical-frame.js.map +1 -1
- package/dist/answer-loop.d.ts.map +1 -1
- package/dist/answer-loop.js +95 -9
- package/dist/answer-loop.js.map +1 -1
- package/dist/conversation/session-store.d.ts +2 -0
- package/dist/conversation/session-store.d.ts.map +1 -1
- package/dist/conversation/session-store.js +52 -3
- package/dist/conversation/session-store.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata/analysis-planner.d.ts.map +1 -1
- package/dist/metadata/analysis-planner.js +33 -2
- package/dist/metadata/analysis-planner.js.map +1 -1
- package/dist/resolved-analytical-plan.d.ts.map +1 -1
- package/dist/resolved-analytical-plan.js +9 -2
- package/dist/resolved-analytical-plan.js.map +1 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +108 -4
- package/dist/router.js.map +1 -1
- package/dist/semantic-bridge/compose.d.ts.map +1 -1
- package/dist/semantic-bridge/compose.js +35 -59
- package/dist/semantic-bridge/compose.js.map +1 -1
- package/package.json +4 -4
package/dist/answer-loop.js
CHANGED
|
@@ -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
|
|
1933
|
-
|
|
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
|
-
?
|
|
1936
|
-
: `The governed semantic metric was found, but its semantic runtime could not compile the request: ${compactSemanticRuntimeFailure(
|
|
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:
|
|
2026
|
+
message: runtimeFailure.message,
|
|
1951
2027
|
},
|
|
1952
2028
|
...(semanticExecutionTrace ? { semanticExecutionTrace } : {}),
|
|
1953
|
-
...(
|
|
1954
|
-
|
|
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
|
-
|
|
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
|
});
|