@duckcodeailabs/dql-agent 1.10.2 → 1.10.3
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 +83 -1
- package/dist/answer-loop.d.ts.map +1 -1
- package/dist/answer-loop.js +135 -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,68 @@ 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
|
+
status: input.error ? 'failed' : trace.status,
|
|
101
|
+
steps: trace.steps.map((step) => step.id === 'execute_query'
|
|
102
|
+
? { ...step, status: executionStatus, detail: executionDetail }
|
|
103
|
+
: step),
|
|
104
|
+
...(input.error
|
|
105
|
+
? {
|
|
106
|
+
failure: {
|
|
107
|
+
code: 'EXECUTION_FAILED',
|
|
108
|
+
phase: 'execution',
|
|
109
|
+
message: input.error,
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
: {}),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
53
115
|
/**
|
|
54
116
|
* Physical column names whose sampled runtime values include `value`. Used by the
|
|
55
117
|
* semantic bridge to bind a filter literal to the dimension that actually carries
|
|
@@ -1623,6 +1685,7 @@ async function runAnswerLoop(input) {
|
|
|
1623
1685
|
const semanticBridgeToolCalls = [];
|
|
1624
1686
|
let semanticBridgeAnswer;
|
|
1625
1687
|
let semanticRuntimeFailure;
|
|
1688
|
+
let semanticExecutionTrace;
|
|
1626
1689
|
let semanticRuntimeCompiledAnswer = false;
|
|
1627
1690
|
if (authoritativeSemanticBinding && input.semanticLayer) {
|
|
1628
1691
|
const selection = authoritativeSemanticBinding.selection;
|
|
@@ -1636,6 +1699,7 @@ async function runAnswerLoop(input) {
|
|
|
1636
1699
|
if (!semanticBridgeAnswer && input.semanticQueryCompiler) {
|
|
1637
1700
|
try {
|
|
1638
1701
|
const compiled = await input.semanticQueryCompiler(selection);
|
|
1702
|
+
semanticExecutionTrace = compiled.trace;
|
|
1639
1703
|
semanticBridgeAnswer = composeSemanticQueryFromCompiledMembers({
|
|
1640
1704
|
semanticLayer: input.semanticLayer,
|
|
1641
1705
|
question,
|
|
@@ -1645,7 +1709,8 @@ async function runAnswerLoop(input) {
|
|
|
1645
1709
|
semanticRuntimeCompiledAnswer = Boolean(semanticBridgeAnswer && compiled.engine !== 'native');
|
|
1646
1710
|
}
|
|
1647
1711
|
catch (error) {
|
|
1648
|
-
semanticRuntimeFailure =
|
|
1712
|
+
semanticRuntimeFailure = semanticCompilerFailure(error);
|
|
1713
|
+
semanticExecutionTrace = semanticRuntimeFailure.trace;
|
|
1649
1714
|
}
|
|
1650
1715
|
}
|
|
1651
1716
|
if (semanticBridgeAnswer) {
|
|
@@ -1658,7 +1723,9 @@ async function runAnswerLoop(input) {
|
|
|
1658
1723
|
});
|
|
1659
1724
|
}
|
|
1660
1725
|
else if (!semanticRuntimeFailure) {
|
|
1661
|
-
semanticRuntimeFailure =
|
|
1726
|
+
semanticRuntimeFailure = {
|
|
1727
|
+
message: `The exact plan ${authoritativeSemanticBinding.planId} is not composable by the pinned semantic runtime.`,
|
|
1728
|
+
};
|
|
1662
1729
|
}
|
|
1663
1730
|
}
|
|
1664
1731
|
if (!authoritativeSemanticBinding && input.semanticLayer && semanticMetricMatch) {
|
|
@@ -1688,6 +1755,7 @@ async function runAnswerLoop(input) {
|
|
|
1688
1755
|
const selection = { metrics: [matchedName], dimensions: [] };
|
|
1689
1756
|
try {
|
|
1690
1757
|
const compiled = await input.semanticQueryCompiler(selection);
|
|
1758
|
+
semanticExecutionTrace = compiled.trace;
|
|
1691
1759
|
semanticBridgeAnswer = composeSemanticQueryFromCompiledMembers({
|
|
1692
1760
|
semanticLayer: input.semanticLayer,
|
|
1693
1761
|
question,
|
|
@@ -1706,7 +1774,8 @@ async function runAnswerLoop(input) {
|
|
|
1706
1774
|
}
|
|
1707
1775
|
}
|
|
1708
1776
|
catch (error) {
|
|
1709
|
-
semanticRuntimeFailure =
|
|
1777
|
+
semanticRuntimeFailure = semanticCompilerFailure(error);
|
|
1778
|
+
semanticExecutionTrace = semanticRuntimeFailure.trace;
|
|
1710
1779
|
}
|
|
1711
1780
|
}
|
|
1712
1781
|
}
|
|
@@ -1740,6 +1809,7 @@ async function runAnswerLoop(input) {
|
|
|
1740
1809
|
if (!composed && input.semanticQueryCompiler) {
|
|
1741
1810
|
try {
|
|
1742
1811
|
const compiled = await input.semanticQueryCompiler(selection);
|
|
1812
|
+
semanticExecutionTrace = compiled.trace;
|
|
1743
1813
|
composed = composeSemanticQueryFromCompiledMembers({
|
|
1744
1814
|
semanticLayer: bridgeLayer,
|
|
1745
1815
|
question,
|
|
@@ -1758,7 +1828,8 @@ async function runAnswerLoop(input) {
|
|
|
1758
1828
|
}
|
|
1759
1829
|
}
|
|
1760
1830
|
catch (error) {
|
|
1761
|
-
semanticRuntimeFailure =
|
|
1831
|
+
semanticRuntimeFailure = semanticCompilerFailure(error);
|
|
1832
|
+
semanticExecutionTrace = semanticRuntimeFailure.trace;
|
|
1762
1833
|
}
|
|
1763
1834
|
}
|
|
1764
1835
|
return composed;
|
|
@@ -1812,7 +1883,11 @@ async function runAnswerLoop(input) {
|
|
|
1812
1883
|
}
|
|
1813
1884
|
}
|
|
1814
1885
|
if (!semanticBridgeAnswer && semanticRuntimeFailure) {
|
|
1815
|
-
const
|
|
1886
|
+
const isPathAmbiguity = semanticRuntimeFailure.code === 'SEMANTIC_PATH_AMBIGUOUS'
|
|
1887
|
+
|| semanticRuntimeFailure.trace?.failure?.code === 'SEMANTIC_PATH_AMBIGUOUS';
|
|
1888
|
+
const text = isPathAmbiguity
|
|
1889
|
+
? semanticRuntimeFailure.message
|
|
1890
|
+
: `The governed semantic metric was found, but its semantic runtime could not compile the request: ${compactSemanticRuntimeFailure(semanticRuntimeFailure.message)}`;
|
|
1816
1891
|
return {
|
|
1817
1892
|
kind: 'no_answer',
|
|
1818
1893
|
sourceTier: 'no_answer',
|
|
@@ -1821,10 +1896,17 @@ async function runAnswerLoop(input) {
|
|
|
1821
1896
|
confidence: 0,
|
|
1822
1897
|
text,
|
|
1823
1898
|
answer: text,
|
|
1824
|
-
refusalCode: 'modeling_gap',
|
|
1899
|
+
refusalCode: isPathAmbiguity ? 'ambiguous' : 'modeling_gap',
|
|
1825
1900
|
// The answer shows the compact business-readable failure; the FULL compiler
|
|
1826
1901
|
// output stays here for Inspect/debugging.
|
|
1827
|
-
refusalDetails: {
|
|
1902
|
+
refusalDetails: {
|
|
1903
|
+
code: isPathAmbiguity ? 'semantic_path_ambiguous' : 'semantic_runtime_required',
|
|
1904
|
+
message: semanticRuntimeFailure.message,
|
|
1905
|
+
},
|
|
1906
|
+
...(semanticExecutionTrace ? { semanticExecutionTrace } : {}),
|
|
1907
|
+
...(semanticRuntimeFailure.candidates?.length
|
|
1908
|
+
? { clarificationOptions: semanticRuntimeFailure.candidates.map((candidate) => ({ ...candidate, question })) }
|
|
1909
|
+
: {}),
|
|
1828
1910
|
citations: [],
|
|
1829
1911
|
memoryContext: input.memoryContext,
|
|
1830
1912
|
evidence: buildNoAnswerEvidence({
|
|
@@ -2935,6 +3017,10 @@ async function runAnswerLoop(input) {
|
|
|
2935
3017
|
: undefined;
|
|
2936
3018
|
const certifiedMetricAnswer = semanticMetricCertification === 'certified' || semanticMetricCertification === 'reviewed';
|
|
2937
3019
|
const governedMetricExecutionFailure = governedMetricAnswer && Boolean(executionError);
|
|
3020
|
+
const finalSemanticExecutionTrace = semanticTraceAfterExecution(semanticExecutionTrace, {
|
|
3021
|
+
executed: Boolean(result),
|
|
3022
|
+
...(executionError ? { error: executionError } : {}),
|
|
3023
|
+
});
|
|
2938
3024
|
return {
|
|
2939
3025
|
kind: governedMetricExecutionFailure ? 'no_answer' : 'uncertified',
|
|
2940
3026
|
sourceTier: governedMetricExecutionFailure ? 'no_answer' : governedMetricAnswer ? 'semantic_layer' : activeTier,
|
|
@@ -2948,6 +3034,7 @@ async function runAnswerLoop(input) {
|
|
|
2948
3034
|
sql: parsed.sql,
|
|
2949
3035
|
result,
|
|
2950
3036
|
executionError,
|
|
3037
|
+
...(finalSemanticExecutionTrace ? { semanticExecutionTrace: finalSemanticExecutionTrace } : {}),
|
|
2951
3038
|
...(governedMetricExecutionFailure ? { refusalCode: 'grounding_gap' } : {}),
|
|
2952
3039
|
suggestedViz: parsed.viz ?? 'table',
|
|
2953
3040
|
dqlArtifact: answerDqlArtifact,
|
|
@@ -3138,6 +3225,7 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3138
3225
|
const sourceResults = {};
|
|
3139
3226
|
const compiledSql = [];
|
|
3140
3227
|
const artifacts = [];
|
|
3228
|
+
let semanticExecutionTrace;
|
|
3141
3229
|
for (const invocation of input.binding.invocations) {
|
|
3142
3230
|
let composed = composeSemanticQueryFromMembers({
|
|
3143
3231
|
semanticLayer: layer,
|
|
@@ -3149,6 +3237,7 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3149
3237
|
if (!composed && input.input.semanticQueryCompiler) {
|
|
3150
3238
|
try {
|
|
3151
3239
|
const compiled = await input.input.semanticQueryCompiler(invocation.selection);
|
|
3240
|
+
semanticExecutionTrace = compiled.trace;
|
|
3152
3241
|
composed = composeSemanticQueryFromCompiledMembers({
|
|
3153
3242
|
semanticLayer: layer,
|
|
3154
3243
|
question: input.input.question,
|
|
@@ -3157,9 +3246,34 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3157
3246
|
});
|
|
3158
3247
|
}
|
|
3159
3248
|
catch (error) {
|
|
3249
|
+
const failure = semanticCompilerFailure(error);
|
|
3250
|
+
if (failure.candidates?.length) {
|
|
3251
|
+
return {
|
|
3252
|
+
kind: 'no_answer',
|
|
3253
|
+
sourceTier: 'no_answer',
|
|
3254
|
+
certification: 'analyst_review_required',
|
|
3255
|
+
reviewStatus: 'none',
|
|
3256
|
+
confidence: 0,
|
|
3257
|
+
text: failure.message,
|
|
3258
|
+
answer: failure.message,
|
|
3259
|
+
refusalCode: 'ambiguous',
|
|
3260
|
+
refusalDetails: { code: 'semantic_path_ambiguous', message: failure.message },
|
|
3261
|
+
...(failure.trace ? { semanticExecutionTrace: failure.trace } : {}),
|
|
3262
|
+
clarificationOptions: failure.candidates.map((candidate) => ({
|
|
3263
|
+
...candidate,
|
|
3264
|
+
question: input.input.question,
|
|
3265
|
+
})),
|
|
3266
|
+
analyticalExecutionGraph: input.graph,
|
|
3267
|
+
citations: contextPackCitations(input.input.contextPack, 8),
|
|
3268
|
+
considered: input.considered,
|
|
3269
|
+
contextPack: input.input.contextPack,
|
|
3270
|
+
providerUsed: input.providerName,
|
|
3271
|
+
};
|
|
3272
|
+
}
|
|
3160
3273
|
return analyticalGraphFailureAnswer(input, 'COMPILATION_FAILED', error instanceof Error ? error.message : String(error), {
|
|
3161
3274
|
phase: 'compilation',
|
|
3162
3275
|
...(compiledSql.length ? { compiledSql: renderAnalyticalStatements(compiledSql) } : {}),
|
|
3276
|
+
...(failure.trace ? { semanticExecutionTrace: failure.trace } : {}),
|
|
3163
3277
|
});
|
|
3164
3278
|
}
|
|
3165
3279
|
}
|
|
@@ -3184,7 +3298,13 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3184
3298
|
result = await executor();
|
|
3185
3299
|
}
|
|
3186
3300
|
catch (error) {
|
|
3187
|
-
|
|
3301
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3302
|
+
return analyticalGraphFailureAnswer(input, 'EXECUTION_FAILED', message, {
|
|
3303
|
+
phase: 'execution',
|
|
3304
|
+
dqlArtifact: composed.dqlArtifact,
|
|
3305
|
+
compiledSql: composed.sql,
|
|
3306
|
+
semanticExecutionTrace: semanticTraceAfterExecution(semanticExecutionTrace, { executed: false, error: message }),
|
|
3307
|
+
});
|
|
3188
3308
|
}
|
|
3189
3309
|
const normalized = normalizeAnalyticalSourceResult({
|
|
3190
3310
|
result,
|
|
@@ -3219,6 +3339,9 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3219
3339
|
sql,
|
|
3220
3340
|
...(artifacts.length === 1 ? { dqlArtifact: artifacts[0] } : {}),
|
|
3221
3341
|
analyticalExecutionGraph: input.graph,
|
|
3342
|
+
...(semanticExecutionTrace
|
|
3343
|
+
? { semanticExecutionTrace: semanticTraceAfterExecution(semanticExecutionTrace, { executed: false }) }
|
|
3344
|
+
: {}),
|
|
3222
3345
|
citations: contextPackCitations(input.input.contextPack, 8),
|
|
3223
3346
|
considered: input.considered,
|
|
3224
3347
|
contextPack: input.input.contextPack,
|
|
@@ -3263,6 +3386,9 @@ async function executeSemanticAnalyticalGraph(input) {
|
|
|
3263
3386
|
analyticalExecutionReceipt: executed.receipt,
|
|
3264
3387
|
analyticalFacts: story.factSet,
|
|
3265
3388
|
analyticalNarrative: story.narrative,
|
|
3389
|
+
...(semanticExecutionTrace
|
|
3390
|
+
? { semanticExecutionTrace: semanticTraceAfterExecution(semanticExecutionTrace, { executed: true }) }
|
|
3391
|
+
: {}),
|
|
3266
3392
|
citations: contextPackCitations(input.input.contextPack, 8),
|
|
3267
3393
|
considered: input.considered,
|
|
3268
3394
|
contextPack: input.input.contextPack,
|
|
@@ -3472,6 +3598,7 @@ function analyticalGraphFailureAnswer(input, code, reason, artifacts = {}) {
|
|
|
3472
3598
|
analyticalExecutionGraph: input.graph,
|
|
3473
3599
|
...(artifacts.compiledSql ? { proposedSql: artifacts.compiledSql, sql: artifacts.compiledSql } : {}),
|
|
3474
3600
|
...(artifacts.dqlArtifact ? { dqlArtifact: artifacts.dqlArtifact } : {}),
|
|
3601
|
+
...(artifacts.semanticExecutionTrace ? { semanticExecutionTrace: artifacts.semanticExecutionTrace } : {}),
|
|
3475
3602
|
citations: contextPackCitations(input.input.contextPack, 8),
|
|
3476
3603
|
considered: input.considered,
|
|
3477
3604
|
contextPack: input.input.contextPack,
|