@duckcodeailabs/dql-agent 1.10.2 → 1.10.4
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 +4 -0
- package/dist/agent-run-engine.d.ts.map +1 -1
- package/dist/agent-run-engine.js +6 -3
- package/dist/agent-run-engine.js.map +1 -1
- package/dist/answer-loop.d.ts +89 -1
- package/dist/answer-loop.d.ts.map +1 -1
- package/dist/answer-loop.js +146 -8
- package/dist/answer-loop.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/answer-loop.js
CHANGED
|
@@ -50,6 +50,74 @@ import { buildAnalyticalResultFacts, renderDeterministicAnalyticalNarrative, val
|
|
|
50
50
|
import { resolveAnalyticalPeriods, } from './analytical-period-resolution.js';
|
|
51
51
|
import { classifyAnalyticalFailure, createAnalyticalFailure, } from './analytical-failure-repair.js';
|
|
52
52
|
import { QUICK_PROMPT_CONTEXT_BUDGET, canUseLaneRepair, cascadeBudgetTrace, createCascadeBudgetState, deepAlternativeCountForQuestion, promptContextBudgetForQuestion, proposalToolBudgetForQuestion, recordLaneRepair, } from './cascade/budgets.js';
|
|
53
|
+
function semanticCompilerFailure(error) {
|
|
54
|
+
const record = error && typeof error === 'object' ? error : undefined;
|
|
55
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
56
|
+
const details = record?.details && typeof record.details === 'object'
|
|
57
|
+
? record.details
|
|
58
|
+
: undefined;
|
|
59
|
+
const trace = record?.semanticTrace && typeof record.semanticTrace === 'object'
|
|
60
|
+
? record.semanticTrace
|
|
61
|
+
: details?.semanticTrace && typeof details.semanticTrace === 'object'
|
|
62
|
+
? details.semanticTrace
|
|
63
|
+
: undefined;
|
|
64
|
+
const rawCandidates = Array.isArray(details?.candidates)
|
|
65
|
+
? details.candidates
|
|
66
|
+
: Array.isArray(trace?.failure?.candidates)
|
|
67
|
+
? trace.failure.candidates
|
|
68
|
+
: [];
|
|
69
|
+
const candidates = rawCandidates.flatMap((candidate) => {
|
|
70
|
+
if (!candidate || typeof candidate !== 'object')
|
|
71
|
+
return [];
|
|
72
|
+
const value = candidate;
|
|
73
|
+
if (typeof value.id !== 'string' || typeof value.label !== 'string')
|
|
74
|
+
return [];
|
|
75
|
+
return [{
|
|
76
|
+
id: value.id,
|
|
77
|
+
label: value.label,
|
|
78
|
+
...(typeof value.description === 'string' ? { description: value.description } : {}),
|
|
79
|
+
kind: 'semantic_entity_path',
|
|
80
|
+
}];
|
|
81
|
+
});
|
|
82
|
+
return {
|
|
83
|
+
message,
|
|
84
|
+
...(typeof record?.code === 'string' ? { code: record.code } : {}),
|
|
85
|
+
...(trace ? { trace } : {}),
|
|
86
|
+
...(candidates.length > 0 ? { candidates } : {}),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function semanticTraceAfterExecution(trace, input) {
|
|
90
|
+
if (!trace)
|
|
91
|
+
return undefined;
|
|
92
|
+
const executionStatus = input.error ? 'failed' : input.executed ? 'completed' : 'not_started';
|
|
93
|
+
const executionDetail = input.error
|
|
94
|
+
? `Warehouse execution failed: ${input.error}`
|
|
95
|
+
: input.executed
|
|
96
|
+
? 'The authorized warehouse query executed and returned a result.'
|
|
97
|
+
: 'The compiler produced SQL, but execution was not requested.';
|
|
98
|
+
return {
|
|
99
|
+
...trace,
|
|
100
|
+
...(input.result?.semanticTargetBinding
|
|
101
|
+
? { targetBinding: input.result.semanticTargetBinding }
|
|
102
|
+
: {}),
|
|
103
|
+
...(input.result?.semanticExecutionReceipt
|
|
104
|
+
? { executionReceipt: input.result.semanticExecutionReceipt }
|
|
105
|
+
: {}),
|
|
106
|
+
status: input.error ? 'failed' : trace.status,
|
|
107
|
+
steps: trace.steps.map((step) => step.id === 'execute_query'
|
|
108
|
+
? { ...step, status: executionStatus, detail: executionDetail }
|
|
109
|
+
: step),
|
|
110
|
+
...(input.error
|
|
111
|
+
? {
|
|
112
|
+
failure: {
|
|
113
|
+
code: 'EXECUTION_FAILED',
|
|
114
|
+
phase: 'execution',
|
|
115
|
+
message: input.error,
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
: {}),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
53
121
|
/**
|
|
54
122
|
* Physical column names whose sampled runtime values include `value`. Used by the
|
|
55
123
|
* semantic bridge to bind a filter literal to the dimension that actually carries
|
|
@@ -1623,6 +1691,7 @@ async function runAnswerLoop(input) {
|
|
|
1623
1691
|
const semanticBridgeToolCalls = [];
|
|
1624
1692
|
let semanticBridgeAnswer;
|
|
1625
1693
|
let semanticRuntimeFailure;
|
|
1694
|
+
let semanticExecutionTrace;
|
|
1626
1695
|
let semanticRuntimeCompiledAnswer = false;
|
|
1627
1696
|
if (authoritativeSemanticBinding && input.semanticLayer) {
|
|
1628
1697
|
const selection = authoritativeSemanticBinding.selection;
|
|
@@ -1636,6 +1705,7 @@ async function runAnswerLoop(input) {
|
|
|
1636
1705
|
if (!semanticBridgeAnswer && input.semanticQueryCompiler) {
|
|
1637
1706
|
try {
|
|
1638
1707
|
const compiled = await input.semanticQueryCompiler(selection);
|
|
1708
|
+
semanticExecutionTrace = compiled.trace;
|
|
1639
1709
|
semanticBridgeAnswer = composeSemanticQueryFromCompiledMembers({
|
|
1640
1710
|
semanticLayer: input.semanticLayer,
|
|
1641
1711
|
question,
|
|
@@ -1645,7 +1715,8 @@ async function runAnswerLoop(input) {
|
|
|
1645
1715
|
semanticRuntimeCompiledAnswer = Boolean(semanticBridgeAnswer && compiled.engine !== 'native');
|
|
1646
1716
|
}
|
|
1647
1717
|
catch (error) {
|
|
1648
|
-
semanticRuntimeFailure =
|
|
1718
|
+
semanticRuntimeFailure = semanticCompilerFailure(error);
|
|
1719
|
+
semanticExecutionTrace = semanticRuntimeFailure.trace;
|
|
1649
1720
|
}
|
|
1650
1721
|
}
|
|
1651
1722
|
if (semanticBridgeAnswer) {
|
|
@@ -1658,7 +1729,9 @@ async function runAnswerLoop(input) {
|
|
|
1658
1729
|
});
|
|
1659
1730
|
}
|
|
1660
1731
|
else if (!semanticRuntimeFailure) {
|
|
1661
|
-
semanticRuntimeFailure =
|
|
1732
|
+
semanticRuntimeFailure = {
|
|
1733
|
+
message: `The exact plan ${authoritativeSemanticBinding.planId} is not composable by the pinned semantic runtime.`,
|
|
1734
|
+
};
|
|
1662
1735
|
}
|
|
1663
1736
|
}
|
|
1664
1737
|
if (!authoritativeSemanticBinding && input.semanticLayer && semanticMetricMatch) {
|
|
@@ -1688,6 +1761,7 @@ async function runAnswerLoop(input) {
|
|
|
1688
1761
|
const selection = { metrics: [matchedName], dimensions: [] };
|
|
1689
1762
|
try {
|
|
1690
1763
|
const compiled = await input.semanticQueryCompiler(selection);
|
|
1764
|
+
semanticExecutionTrace = compiled.trace;
|
|
1691
1765
|
semanticBridgeAnswer = composeSemanticQueryFromCompiledMembers({
|
|
1692
1766
|
semanticLayer: input.semanticLayer,
|
|
1693
1767
|
question,
|
|
@@ -1706,7 +1780,8 @@ async function runAnswerLoop(input) {
|
|
|
1706
1780
|
}
|
|
1707
1781
|
}
|
|
1708
1782
|
catch (error) {
|
|
1709
|
-
semanticRuntimeFailure =
|
|
1783
|
+
semanticRuntimeFailure = semanticCompilerFailure(error);
|
|
1784
|
+
semanticExecutionTrace = semanticRuntimeFailure.trace;
|
|
1710
1785
|
}
|
|
1711
1786
|
}
|
|
1712
1787
|
}
|
|
@@ -1740,6 +1815,7 @@ async function runAnswerLoop(input) {
|
|
|
1740
1815
|
if (!composed && input.semanticQueryCompiler) {
|
|
1741
1816
|
try {
|
|
1742
1817
|
const compiled = await input.semanticQueryCompiler(selection);
|
|
1818
|
+
semanticExecutionTrace = compiled.trace;
|
|
1743
1819
|
composed = composeSemanticQueryFromCompiledMembers({
|
|
1744
1820
|
semanticLayer: bridgeLayer,
|
|
1745
1821
|
question,
|
|
@@ -1758,7 +1834,8 @@ async function runAnswerLoop(input) {
|
|
|
1758
1834
|
}
|
|
1759
1835
|
}
|
|
1760
1836
|
catch (error) {
|
|
1761
|
-
semanticRuntimeFailure =
|
|
1837
|
+
semanticRuntimeFailure = semanticCompilerFailure(error);
|
|
1838
|
+
semanticExecutionTrace = semanticRuntimeFailure.trace;
|
|
1762
1839
|
}
|
|
1763
1840
|
}
|
|
1764
1841
|
return composed;
|
|
@@ -1812,7 +1889,11 @@ async function runAnswerLoop(input) {
|
|
|
1812
1889
|
}
|
|
1813
1890
|
}
|
|
1814
1891
|
if (!semanticBridgeAnswer && semanticRuntimeFailure) {
|
|
1815
|
-
const
|
|
1892
|
+
const isPathAmbiguity = semanticRuntimeFailure.code === 'SEMANTIC_PATH_AMBIGUOUS'
|
|
1893
|
+
|| semanticRuntimeFailure.trace?.failure?.code === 'SEMANTIC_PATH_AMBIGUOUS';
|
|
1894
|
+
const text = isPathAmbiguity
|
|
1895
|
+
? semanticRuntimeFailure.message
|
|
1896
|
+
: `The governed semantic metric was found, but its semantic runtime could not compile the request: ${compactSemanticRuntimeFailure(semanticRuntimeFailure.message)}`;
|
|
1816
1897
|
return {
|
|
1817
1898
|
kind: 'no_answer',
|
|
1818
1899
|
sourceTier: 'no_answer',
|
|
@@ -1821,10 +1902,17 @@ async function runAnswerLoop(input) {
|
|
|
1821
1902
|
confidence: 0,
|
|
1822
1903
|
text,
|
|
1823
1904
|
answer: text,
|
|
1824
|
-
refusalCode: 'modeling_gap',
|
|
1905
|
+
refusalCode: isPathAmbiguity ? 'ambiguous' : 'modeling_gap',
|
|
1825
1906
|
// The answer shows the compact business-readable failure; the FULL compiler
|
|
1826
1907
|
// output stays here for Inspect/debugging.
|
|
1827
|
-
refusalDetails: {
|
|
1908
|
+
refusalDetails: {
|
|
1909
|
+
code: isPathAmbiguity ? 'semantic_path_ambiguous' : 'semantic_runtime_required',
|
|
1910
|
+
message: semanticRuntimeFailure.message,
|
|
1911
|
+
},
|
|
1912
|
+
...(semanticExecutionTrace ? { semanticExecutionTrace } : {}),
|
|
1913
|
+
...(semanticRuntimeFailure.candidates?.length
|
|
1914
|
+
? { clarificationOptions: semanticRuntimeFailure.candidates.map((candidate) => ({ ...candidate, question })) }
|
|
1915
|
+
: {}),
|
|
1828
1916
|
citations: [],
|
|
1829
1917
|
memoryContext: input.memoryContext,
|
|
1830
1918
|
evidence: buildNoAnswerEvidence({
|
|
@@ -2935,6 +3023,11 @@ async function runAnswerLoop(input) {
|
|
|
2935
3023
|
: undefined;
|
|
2936
3024
|
const certifiedMetricAnswer = semanticMetricCertification === 'certified' || semanticMetricCertification === 'reviewed';
|
|
2937
3025
|
const governedMetricExecutionFailure = governedMetricAnswer && Boolean(executionError);
|
|
3026
|
+
const finalSemanticExecutionTrace = semanticTraceAfterExecution(semanticExecutionTrace, {
|
|
3027
|
+
executed: Boolean(result),
|
|
3028
|
+
...(executionError ? { error: executionError } : {}),
|
|
3029
|
+
...(result ? { result } : {}),
|
|
3030
|
+
});
|
|
2938
3031
|
return {
|
|
2939
3032
|
kind: governedMetricExecutionFailure ? 'no_answer' : 'uncertified',
|
|
2940
3033
|
sourceTier: governedMetricExecutionFailure ? 'no_answer' : governedMetricAnswer ? 'semantic_layer' : activeTier,
|
|
@@ -2948,6 +3041,7 @@ async function runAnswerLoop(input) {
|
|
|
2948
3041
|
sql: parsed.sql,
|
|
2949
3042
|
result,
|
|
2950
3043
|
executionError,
|
|
3044
|
+
...(finalSemanticExecutionTrace ? { semanticExecutionTrace: finalSemanticExecutionTrace } : {}),
|
|
2951
3045
|
...(governedMetricExecutionFailure ? { refusalCode: 'grounding_gap' } : {}),
|
|
2952
3046
|
suggestedViz: parsed.viz ?? 'table',
|
|
2953
3047
|
dqlArtifact: answerDqlArtifact,
|
|
@@ -3138,6 +3232,7 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3138
3232
|
const sourceResults = {};
|
|
3139
3233
|
const compiledSql = [];
|
|
3140
3234
|
const artifacts = [];
|
|
3235
|
+
let semanticExecutionTrace;
|
|
3141
3236
|
for (const invocation of input.binding.invocations) {
|
|
3142
3237
|
let composed = composeSemanticQueryFromMembers({
|
|
3143
3238
|
semanticLayer: layer,
|
|
@@ -3149,6 +3244,7 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3149
3244
|
if (!composed && input.input.semanticQueryCompiler) {
|
|
3150
3245
|
try {
|
|
3151
3246
|
const compiled = await input.input.semanticQueryCompiler(invocation.selection);
|
|
3247
|
+
semanticExecutionTrace = compiled.trace;
|
|
3152
3248
|
composed = composeSemanticQueryFromCompiledMembers({
|
|
3153
3249
|
semanticLayer: layer,
|
|
3154
3250
|
question: input.input.question,
|
|
@@ -3157,9 +3253,34 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3157
3253
|
});
|
|
3158
3254
|
}
|
|
3159
3255
|
catch (error) {
|
|
3256
|
+
const failure = semanticCompilerFailure(error);
|
|
3257
|
+
if (failure.candidates?.length) {
|
|
3258
|
+
return {
|
|
3259
|
+
kind: 'no_answer',
|
|
3260
|
+
sourceTier: 'no_answer',
|
|
3261
|
+
certification: 'analyst_review_required',
|
|
3262
|
+
reviewStatus: 'none',
|
|
3263
|
+
confidence: 0,
|
|
3264
|
+
text: failure.message,
|
|
3265
|
+
answer: failure.message,
|
|
3266
|
+
refusalCode: 'ambiguous',
|
|
3267
|
+
refusalDetails: { code: 'semantic_path_ambiguous', message: failure.message },
|
|
3268
|
+
...(failure.trace ? { semanticExecutionTrace: failure.trace } : {}),
|
|
3269
|
+
clarificationOptions: failure.candidates.map((candidate) => ({
|
|
3270
|
+
...candidate,
|
|
3271
|
+
question: input.input.question,
|
|
3272
|
+
})),
|
|
3273
|
+
analyticalExecutionGraph: input.graph,
|
|
3274
|
+
citations: contextPackCitations(input.input.contextPack, 8),
|
|
3275
|
+
considered: input.considered,
|
|
3276
|
+
contextPack: input.input.contextPack,
|
|
3277
|
+
providerUsed: input.providerName,
|
|
3278
|
+
};
|
|
3279
|
+
}
|
|
3160
3280
|
return analyticalGraphFailureAnswer(input, 'COMPILATION_FAILED', error instanceof Error ? error.message : String(error), {
|
|
3161
3281
|
phase: 'compilation',
|
|
3162
3282
|
...(compiledSql.length ? { compiledSql: renderAnalyticalStatements(compiledSql) } : {}),
|
|
3283
|
+
...(failure.trace ? { semanticExecutionTrace: failure.trace } : {}),
|
|
3163
3284
|
});
|
|
3164
3285
|
}
|
|
3165
3286
|
}
|
|
@@ -3182,9 +3303,19 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3182
3303
|
let result;
|
|
3183
3304
|
try {
|
|
3184
3305
|
result = await executor();
|
|
3306
|
+
semanticExecutionTrace = semanticTraceAfterExecution(semanticExecutionTrace, {
|
|
3307
|
+
executed: true,
|
|
3308
|
+
result,
|
|
3309
|
+
});
|
|
3185
3310
|
}
|
|
3186
3311
|
catch (error) {
|
|
3187
|
-
|
|
3312
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3313
|
+
return analyticalGraphFailureAnswer(input, 'EXECUTION_FAILED', message, {
|
|
3314
|
+
phase: 'execution',
|
|
3315
|
+
dqlArtifact: composed.dqlArtifact,
|
|
3316
|
+
compiledSql: composed.sql,
|
|
3317
|
+
semanticExecutionTrace: semanticTraceAfterExecution(semanticExecutionTrace, { executed: false, error: message }),
|
|
3318
|
+
});
|
|
3188
3319
|
}
|
|
3189
3320
|
const normalized = normalizeAnalyticalSourceResult({
|
|
3190
3321
|
result,
|
|
@@ -3219,6 +3350,9 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3219
3350
|
sql,
|
|
3220
3351
|
...(artifacts.length === 1 ? { dqlArtifact: artifacts[0] } : {}),
|
|
3221
3352
|
analyticalExecutionGraph: input.graph,
|
|
3353
|
+
...(semanticExecutionTrace
|
|
3354
|
+
? { semanticExecutionTrace: semanticTraceAfterExecution(semanticExecutionTrace, { executed: false }) }
|
|
3355
|
+
: {}),
|
|
3222
3356
|
citations: contextPackCitations(input.input.contextPack, 8),
|
|
3223
3357
|
considered: input.considered,
|
|
3224
3358
|
contextPack: input.input.contextPack,
|
|
@@ -3263,6 +3397,9 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3263
3397
|
analyticalExecutionReceipt: executed.receipt,
|
|
3264
3398
|
analyticalFacts: story.factSet,
|
|
3265
3399
|
analyticalNarrative: story.narrative,
|
|
3400
|
+
...(semanticExecutionTrace
|
|
3401
|
+
? { semanticExecutionTrace: semanticTraceAfterExecution(semanticExecutionTrace, { executed: true }) }
|
|
3402
|
+
: {}),
|
|
3266
3403
|
citations: contextPackCitations(input.input.contextPack, 8),
|
|
3267
3404
|
considered: input.considered,
|
|
3268
3405
|
contextPack: input.input.contextPack,
|
|
@@ -3472,6 +3609,7 @@ function analyticalGraphFailureAnswer(input, code, reason, artifacts = {}) {
|
|
|
3472
3609
|
analyticalExecutionGraph: input.graph,
|
|
3473
3610
|
...(artifacts.compiledSql ? { proposedSql: artifacts.compiledSql, sql: artifacts.compiledSql } : {}),
|
|
3474
3611
|
...(artifacts.dqlArtifact ? { dqlArtifact: artifacts.dqlArtifact } : {}),
|
|
3612
|
+
...(artifacts.semanticExecutionTrace ? { semanticExecutionTrace: artifacts.semanticExecutionTrace } : {}),
|
|
3475
3613
|
citations: contextPackCitations(input.input.contextPack, 8),
|
|
3476
3614
|
considered: input.considered,
|
|
3477
3615
|
contextPack: input.input.contextPack,
|