@duckcodeailabs/dql-cli 1.14.0 → 1.14.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/args.d.ts +15 -0
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +25 -0
- package/dist/args.js.map +1 -1
- package/dist/assets/dql-notebook/assets/{AgentLogPage-Ch7VK20X.js → AgentLogPage-BPz-UWFh.js} +1 -1
- package/dist/assets/dql-notebook/assets/{AiBuildDialog-DBr5TmyM.js → AiBuildDialog-BEl53WA_.js} +1 -1
- package/dist/assets/dql-notebook/assets/{AiBuildResult-jLPzQO7O.js → AiBuildResult-B4yfGTTZ.js} +1 -1
- package/dist/assets/dql-notebook/assets/{AiSidePanel-CdlGsiVC.js → AiSidePanel-CSZAAvuD.js} +1 -1
- package/dist/assets/dql-notebook/assets/{AnalyticsHome-C0DXbOwY.js → AnalyticsHome-D5P6Ujwi.js} +1 -1
- package/dist/assets/dql-notebook/assets/{AppsView-CcpwjApv.js → AppsView-DQOwU9Cg.js} +4 -4
- package/dist/assets/dql-notebook/assets/{BlockStudio-CFYxafw-.js → BlockStudio-B4ap0GdY.js} +1 -1
- package/dist/assets/dql-notebook/assets/{BusinessArtifactView-C0kLYg2p.js → BusinessArtifactView-BIfNI-0S.js} +1 -1
- package/dist/assets/dql-notebook/assets/{DbtFirstModelingPage-CMwElXD_.js → DbtFirstModelingPage-D72byb2g.js} +1 -1
- package/dist/assets/dql-notebook/assets/{GitPage-JjhRDeWY.js → GitPage-lQb1uXH2.js} +1 -1
- package/dist/assets/dql-notebook/assets/{GlobalAiRail-DakE4NdR.js → GlobalAiRail-CVECf6Xj.js} +1 -1
- package/dist/assets/dql-notebook/assets/{GovernedContextPage-BokDqG6a.js → GovernedContextPage-trOyMCY6.js} +1 -1
- package/dist/assets/dql-notebook/assets/{HelpDocsPage-CjOv6_gz.js → HelpDocsPage-D8hLS5lE.js} +1 -1
- package/dist/assets/dql-notebook/assets/{HomePage-nGaNcwdw.js → HomePage-eIkfBIep.js} +1 -1
- package/dist/assets/dql-notebook/assets/{LineageDAG-CO6CFJRg.js → LineageDAG-CSqcbDrE.js} +1 -1
- package/dist/assets/dql-notebook/assets/{LineageDetailView-BnGb7OF7.js → LineageDetailView-DJZZjZu-.js} +1 -1
- package/dist/assets/dql-notebook/assets/{LineageDrawer-C5Y0Ht0b.js → LineageDrawer-BcIipIc3.js} +1 -1
- package/dist/assets/dql-notebook/assets/{LineagePathBreadcrumb-Cgh3GR3F.js → LineagePathBreadcrumb-CviIf8PN.js} +1 -1
- package/dist/assets/dql-notebook/assets/{MiniLineageGraph-Kla9PYuj.js → MiniLineageGraph-vH_MY_Ju.js} +1 -1
- package/dist/assets/dql-notebook/assets/{NewBlockModal-BR2SnmPT.js → NewBlockModal-DbCQg-pj.js} +1 -1
- package/dist/assets/dql-notebook/assets/{NewNotebookModal-BaCHMYeB.js → NewNotebookModal-5Vp6XiuK.js} +1 -1
- package/dist/assets/dql-notebook/assets/{NotebookEditor-CBLqY8cE.js → NotebookEditor-DjqJS44s.js} +1 -1
- package/dist/assets/dql-notebook/assets/{ReadinessPage-CiN0IWSS.js → ReadinessPage-BHGrC5ho.js} +1 -1
- package/dist/assets/dql-notebook/assets/{SetupOnboarding-BhiCsYF-.js → SetupOnboarding-BfS9Tdx-.js} +1 -1
- package/dist/assets/dql-notebook/assets/{SkillsPage-CCSf8VMm.js → SkillsPage-BFH21wSj.js} +1 -1
- package/dist/assets/dql-notebook/assets/{TrustBadge-BgQmFe_x.js → TrustBadge-zm6g_SxZ.js} +1 -1
- package/dist/assets/dql-notebook/assets/{UnifiedAgentRunPanel-Bw5AXNDB.js → UnifiedAgentRunPanel--oxmjlgr.js} +21 -21
- package/dist/assets/dql-notebook/assets/{answer-to-notebook-AeDYUDla.js → answer-to-notebook-DPhxIEzF.js} +1 -1
- package/dist/assets/dql-notebook/assets/{arrow-left-C55x2hq_.js → arrow-left-DNEb86Xc.js} +1 -1
- package/dist/assets/dql-notebook/assets/{arrow-right-C1cJrhOm.js → arrow-right-DpPWbwaD.js} +1 -1
- package/dist/assets/dql-notebook/assets/{book-open-text-CQf_sdv2.js → book-open-text-D7s5jo4X.js} +1 -1
- package/dist/assets/dql-notebook/assets/{circle-x-X8-Z2yLY.js → circle-x-Db3dXKg7.js} +1 -1
- package/dist/assets/dql-notebook/assets/{dagre.esm-BjjNYKyY.js → dagre.esm-C7pppQ1a.js} +1 -1
- package/dist/assets/dql-notebook/assets/{external-link-C2zrz5DH.js → external-link-BxwXitO_.js} +1 -1
- package/dist/assets/dql-notebook/assets/{grip-vertical-qGV_PYGU.js → grip-vertical-Dt4lkWRi.js} +1 -1
- package/dist/assets/dql-notebook/assets/{index-ByTDPDaH.js → index-DKo-bwNw.js} +2 -2
- package/dist/assets/dql-notebook/assets/{link-2-VpyOxQXG.js → link-2-Dfo2P6wi.js} +1 -1
- package/dist/assets/dql-notebook/assets/{list-tree-CH2Jhwms.js → list-tree-DiTmIWAL.js} +1 -1
- package/dist/assets/dql-notebook/assets/{minimize-2-B2TZJ8BT.js → minimize-2-CMTAkPzL.js} +1 -1
- package/dist/assets/dql-notebook/assets/{panel-right-open-BunF88lt.js → panel-right-open-DwYr7FW4.js} +1 -1
- package/dist/assets/dql-notebook/assets/{play-DAFVF4_G.js → play-BXhHYQ4x.js} +1 -1
- package/dist/assets/dql-notebook/assets/{rotate-ccw-DGCrrqtY.js → rotate-ccw-BNi6F8pl.js} +1 -1
- package/dist/assets/dql-notebook/assets/{semantic-fields-Ci-9QL9F.js → semantic-fields-CNOGysAy.js} +1 -1
- package/dist/assets/dql-notebook/assets/{sliders-horizontal-BOAlXXbn.js → sliders-horizontal-Ec5MUMUW.js} +1 -1
- package/dist/assets/dql-notebook/assets/{star-CkksZXHt.js → star-B9leDkp_.js} +1 -1
- package/dist/assets/dql-notebook/assets/{triangle-alert-D3mjyJZE.js → triangle-alert-BefTYCzx.js} +1 -1
- package/dist/assets/dql-notebook/assets/{upload-CTNOAVEO.js → upload-SPiOM2tQ.js} +1 -1
- package/dist/assets/dql-notebook/assets/{usePersistedAgentThreadId-DiQjc7x-.js → usePersistedAgentThreadId-C4foXeiQ.js} +1 -1
- package/dist/assets/dql-notebook/assets/{user-round-BWd5tQRg.js → user-round-comGmyw-.js} +1 -1
- package/dist/assets/dql-notebook/assets/{wand-sparkles-CqsAv8P-.js → wand-sparkles-BffR4dF8.js} +1 -1
- package/dist/assets/dql-notebook/assets/{workflow-CSqsj-sC.js → workflow-ChmPTEzH.js} +1 -1
- package/dist/assets/dql-notebook/assets/{wrench-DWqzqlX8.js → wrench-DovaG_ze.js} +1 -1
- package/dist/assets/dql-notebook/assets/{x-65M5rLCE.js → x-nRx91AgW.js} +1 -1
- package/dist/assets/dql-notebook/index.html +1 -1
- package/dist/commands/agent-eval-cassette.d.ts +73 -0
- package/dist/commands/agent-eval-cassette.d.ts.map +1 -0
- package/dist/commands/agent-eval-cassette.js +170 -0
- package/dist/commands/agent-eval-cassette.js.map +1 -0
- package/dist/commands/agent-eval-runtime.d.ts +97 -0
- package/dist/commands/agent-eval-runtime.d.ts.map +1 -0
- package/dist/commands/agent-eval-runtime.js +155 -0
- package/dist/commands/agent-eval-runtime.js.map +1 -0
- package/dist/commands/agent.d.ts +115 -1
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +289 -62
- package/dist/commands/agent.js.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/analyst-loop-tools.d.ts +19 -0
- package/dist/llm/analyst-loop-tools.d.ts.map +1 -0
- package/dist/llm/analyst-loop-tools.js +56 -0
- package/dist/llm/analyst-loop-tools.js.map +1 -0
- package/dist/llm/providers/dql-agent-provider.d.ts +24 -1
- package/dist/llm/providers/dql-agent-provider.d.ts.map +1 -1
- package/dist/llm/providers/dql-agent-provider.js +306 -7
- package/dist/llm/providers/dql-agent-provider.js.map +1 -1
- package/dist/llm/types.d.ts +19 -1
- package/dist/llm/types.d.ts.map +1 -1
- package/dist/local-runtime.d.ts +108 -1
- package/dist/local-runtime.d.ts.map +1 -1
- package/dist/local-runtime.js +626 -110
- package/dist/local-runtime.js.map +1 -1
- package/dist/package.json +10 -10
- package/package.json +10 -10
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider cassettes — record a suite once against a real model, replay it
|
|
3
|
+
* offline forever.
|
|
4
|
+
*
|
|
5
|
+
* A provider-backed eval is the only kind that measures the product users get:
|
|
6
|
+
* without one, `mayAssumeInterpretation` is false and every ambiguous question
|
|
7
|
+
* clarifies by design (AGT-017), which makes a clarification rate an artifact.
|
|
8
|
+
* But calling a real model on every PR is slow, costly, and non-deterministic —
|
|
9
|
+
* so the suite could never gate anything.
|
|
10
|
+
*
|
|
11
|
+
* Recording once and replaying fixes all three. Model drift then shows up as a
|
|
12
|
+
* reviewable diff when cassettes are re-recorded, instead of as a mystery
|
|
13
|
+
* regression on an unrelated pull request.
|
|
14
|
+
*/
|
|
15
|
+
import { createHash } from 'node:crypto';
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { dirname, join } from 'node:path';
|
|
18
|
+
/**
|
|
19
|
+
* Stable key for one provider dispatch.
|
|
20
|
+
*
|
|
21
|
+
* Deliberately includes the full message list: the prompt IS the input, and two
|
|
22
|
+
* turns that differ only in retrieved context are genuinely different calls.
|
|
23
|
+
* Tool NAMES are included but not their schemas — a description edit should not
|
|
24
|
+
* invalidate every cassette in the suite.
|
|
25
|
+
*/
|
|
26
|
+
export function cassetteKey(input) {
|
|
27
|
+
const canonical = JSON.stringify({
|
|
28
|
+
p: input.providerName,
|
|
29
|
+
o: input.operation,
|
|
30
|
+
m: input.messages.map((message) => ({ r: message.role, c: message.content })),
|
|
31
|
+
t: [...(input.toolNames ?? [])].sort(),
|
|
32
|
+
e: input.options?.reasoningEffort ?? null,
|
|
33
|
+
x: input.options?.maxTokens ?? null,
|
|
34
|
+
z: input.options?.temperature ?? null,
|
|
35
|
+
});
|
|
36
|
+
return createHash('sha256').update(canonical).digest('hex').slice(0, 32);
|
|
37
|
+
}
|
|
38
|
+
export class CassetteStore {
|
|
39
|
+
dir;
|
|
40
|
+
loaded = new Map();
|
|
41
|
+
constructor(dir) {
|
|
42
|
+
this.dir = dir;
|
|
43
|
+
if (!existsSync(dir))
|
|
44
|
+
return;
|
|
45
|
+
for (const file of readdirSync(dir)) {
|
|
46
|
+
if (!file.endsWith('.json'))
|
|
47
|
+
continue;
|
|
48
|
+
try {
|
|
49
|
+
const entry = JSON.parse(readFileSync(join(dir, file), 'utf-8'));
|
|
50
|
+
if (entry?.key)
|
|
51
|
+
this.loaded.set(entry.key, entry);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// A corrupt cassette is skipped, not fatal: it re-records on the next
|
|
55
|
+
// --record run, and a replay miss reports the key that is missing.
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
get(key) {
|
|
60
|
+
return this.loaded.get(key);
|
|
61
|
+
}
|
|
62
|
+
put(entry) {
|
|
63
|
+
this.loaded.set(entry.key, entry);
|
|
64
|
+
mkdirSync(this.dir, { recursive: true });
|
|
65
|
+
writeFileSync(join(this.dir, `${entry.key}.json`), `${JSON.stringify(entry, null, 2)}\n`, 'utf-8');
|
|
66
|
+
}
|
|
67
|
+
size() {
|
|
68
|
+
return this.loaded.size;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export class CassetteMissError extends Error {
|
|
72
|
+
key;
|
|
73
|
+
constructor(key, operation) {
|
|
74
|
+
super(`No cassette for ${operation} (${key}). CI replays recorded provider responses and never calls a live model; `
|
|
75
|
+
+ 're-record with --record against a real provider and commit the new cassettes.');
|
|
76
|
+
this.name = 'CassetteMissError';
|
|
77
|
+
this.key = key;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Wrap a provider so its dispatches are recorded or replayed.
|
|
82
|
+
*
|
|
83
|
+
* On replay of a tool loop the recorded tool calls are RE-INVOKED against the
|
|
84
|
+
* live tools rather than stubbed. The model's choices stay frozen (that is the
|
|
85
|
+
* point), but compilation, validation, and execution still really happen — so
|
|
86
|
+
* the suite keeps catching a broken compiler or a wrong number, which a fully
|
|
87
|
+
* stubbed replay would sail straight past.
|
|
88
|
+
*/
|
|
89
|
+
export function withCassette(provider, store, mode) {
|
|
90
|
+
if (mode === 'live')
|
|
91
|
+
return provider;
|
|
92
|
+
const wrapped = {
|
|
93
|
+
name: provider.name,
|
|
94
|
+
available: () => (mode === 'replay' ? Promise.resolve(true) : provider.available()),
|
|
95
|
+
async generate(messages, options) {
|
|
96
|
+
const key = cassetteKey({ providerName: provider.name, operation: 'generate', messages, options });
|
|
97
|
+
const hit = store.get(key);
|
|
98
|
+
if (hit)
|
|
99
|
+
return hit.text;
|
|
100
|
+
if (mode === 'replay')
|
|
101
|
+
throw new CassetteMissError(key, 'generate');
|
|
102
|
+
const text = await provider.generate(messages, options);
|
|
103
|
+
store.put({
|
|
104
|
+
key, operation: 'generate', text,
|
|
105
|
+
providerName: provider.name, recordedAt: new Date().toISOString(),
|
|
106
|
+
});
|
|
107
|
+
return text;
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
if (provider.generateWithTools) {
|
|
111
|
+
wrapped.generateWithTools = async (messages, tools, options) => {
|
|
112
|
+
const key = cassetteKey({
|
|
113
|
+
providerName: provider.name,
|
|
114
|
+
operation: 'generate_with_tools',
|
|
115
|
+
messages,
|
|
116
|
+
toolNames: tools.map((tool) => tool.name),
|
|
117
|
+
options: options,
|
|
118
|
+
});
|
|
119
|
+
const hit = store.get(key);
|
|
120
|
+
if (hit) {
|
|
121
|
+
const byName = new Map(tools.map((tool) => [tool.name, tool]));
|
|
122
|
+
for (const call of hit.toolCalls ?? []) {
|
|
123
|
+
const tool = byName.get(call.name);
|
|
124
|
+
// A cassette recorded against a tool set that no longer has this tool
|
|
125
|
+
// is stale in a way the run should surface, not paper over.
|
|
126
|
+
if (!tool)
|
|
127
|
+
continue;
|
|
128
|
+
await tool.run(call.args).catch(() => undefined);
|
|
129
|
+
}
|
|
130
|
+
return hit.text;
|
|
131
|
+
}
|
|
132
|
+
if (mode === 'replay')
|
|
133
|
+
throw new CassetteMissError(key, 'generate_with_tools');
|
|
134
|
+
const observed = [];
|
|
135
|
+
const recordingTools = tools.map((tool) => ({
|
|
136
|
+
...tool,
|
|
137
|
+
run: async (args) => {
|
|
138
|
+
observed.push({ name: tool.name, args });
|
|
139
|
+
return tool.run(args);
|
|
140
|
+
},
|
|
141
|
+
}));
|
|
142
|
+
const text = await provider.generateWithTools(messages, recordingTools, options);
|
|
143
|
+
store.put({
|
|
144
|
+
key, operation: 'generate_with_tools', text, toolCalls: observed,
|
|
145
|
+
providerName: provider.name, recordedAt: new Date().toISOString(),
|
|
146
|
+
});
|
|
147
|
+
return text;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return wrapped;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Pick the cassette mode from the environment.
|
|
154
|
+
*
|
|
155
|
+
* Defaults to `replay` for ANY value that is not explicitly `record` or `live`,
|
|
156
|
+
* including a missing or misspelled one. If someone sets the cassette directory
|
|
157
|
+
* in CI and forgets the mode, the safe outcome is "never call a live model",
|
|
158
|
+
* not a surprise bill and a non-deterministic suite.
|
|
159
|
+
*/
|
|
160
|
+
export function resolveCassetteModeFromEnv(env) {
|
|
161
|
+
const raw = env.DQL_EVAL_CASSETTE_MODE;
|
|
162
|
+
return raw === 'record' || raw === 'live' ? raw : 'replay';
|
|
163
|
+
}
|
|
164
|
+
/** Where a project's eval cassettes live. */
|
|
165
|
+
export function cassetteDirFor(projectRoot, suiteName) {
|
|
166
|
+
const safe = suiteName.replace(/[^a-z0-9._-]+/gi, '-').replace(/\.(ya?ml)$/i, '');
|
|
167
|
+
return join(projectRoot, 'test-cassettes', safe);
|
|
168
|
+
}
|
|
169
|
+
export { dirname as _dirname };
|
|
170
|
+
//# sourceMappingURL=agent-eval-cassette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-eval-cassette.js","sourceRoot":"","sources":["../../src/commands/agent-eval-cassette.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA6B1C;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,KAM3B;IACC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAC/B,CAAC,EAAE,KAAK,CAAC,YAAY;QACrB,CAAC,EAAE,KAAK,CAAC,SAAS;QAClB,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7E,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;QACtC,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,eAAe,IAAI,IAAI;QACzC,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,IAAI,IAAI;QACnC,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,WAAW,IAAI,IAAI;KACtC,CAAC,CAAC;IACH,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,OAAO,aAAa;IACP,GAAG,CAAS;IACZ,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE3D,YAAY,GAAW;QACrB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO;QAC7B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAkB,CAAC;gBAClF,IAAI,KAAK,EAAE,GAAG;oBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACpD,CAAC;YAAC,MAAM,CAAC;gBACP,sEAAsE;gBACtE,mEAAmE;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,GAAG,CAAC,KAAoB;QACtB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrG,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,GAAG,CAAS;IACrB,YAAY,GAAW,EAAE,SAAiB;QACxC,KAAK,CACH,mBAAmB,SAAS,KAAK,GAAG,0EAA0E;cAC5G,+EAA+E,CAClF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAuB,EACvB,KAAoB,EACpB,IAAkB;IAElB,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,QAAQ,CAAC;IAErC,MAAM,OAAO,GAAkB;QAC7B,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAEnF,KAAK,CAAC,QAAQ,CAAC,QAAwB,EAAE,OAA4B;YACnE,MAAM,GAAG,GAAG,WAAW,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YACnG,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,GAAG;gBAAE,OAAO,GAAG,CAAC,IAAI,CAAC;YACzB,IAAI,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YACpE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACxD,KAAK,CAAC,GAAG,CAAC;gBACR,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI;gBAChC,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aAClE,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;IAEF,IAAI,QAAQ,CAAC,iBAAiB,EAAE,CAAC;QAC/B,OAAO,CAAC,iBAAiB,GAAG,KAAK,EAC/B,QAAwB,EACxB,KAA4B,EAC5B,OAAiC,EAChB,EAAE;YACnB,MAAM,GAAG,GAAG,WAAW,CAAC;gBACtB,YAAY,EAAE,QAAQ,CAAC,IAAI;gBAC3B,SAAS,EAAE,qBAAqB;gBAChC,QAAQ;gBACR,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;gBACzC,OAAO,EAAE,OAAoD;aAC9D,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC/D,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;oBACvC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACnC,sEAAsE;oBACtE,4DAA4D;oBAC5D,IAAI,CAAC,IAAI;wBAAE,SAAS;oBACpB,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBACnD,CAAC;gBACD,OAAO,GAAG,CAAC,IAAI,CAAC;YAClB,CAAC;YACD,IAAI,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,iBAAiB,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;YAC/E,MAAM,QAAQ,GAAuB,EAAE,CAAC;YACxC,MAAM,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC1C,GAAG,IAAI;gBACP,GAAG,EAAE,KAAK,EAAE,IAAa,EAAE,EAAE;oBAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;oBACzC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACxB,CAAC;aACF,CAAC,CAAC,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,iBAAkB,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;YAClF,KAAK,CAAC,GAAG,CAAC;gBACR,GAAG,EAAE,SAAS,EAAE,qBAAqB,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ;gBAChE,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aAClE,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B,CAAC,GAAuC;IAChF,MAAM,GAAG,GAAG,GAAG,CAAC,sBAAsB,CAAC;IACvC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC7D,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,SAAiB;IACnE,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAClF,OAAO,IAAI,CAAC,WAAW,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime driver for `dql agent eval`.
|
|
3
|
+
*
|
|
4
|
+
* The in-process driver calls `answer()` directly, which skips
|
|
5
|
+
* `createHybridRouter`, `AgentRunEngine`, `enforceOrdinaryAnalyticalPlanBoundary`
|
|
6
|
+
* and `defaultAgentRunGates`. Every dead-end this harness exists to measure lives
|
|
7
|
+
* in that skipped half — the router can block before the cascade runs, the engine
|
|
8
|
+
* synthesizes its own modeling-gap block, and the gates declare refusal codes
|
|
9
|
+
* terminal. Measuring the answer loop alone reports a cleaner picture than users
|
|
10
|
+
* experience.
|
|
11
|
+
*
|
|
12
|
+
* This driver posts the same body the Ask panel posts and scores the persisted
|
|
13
|
+
* `AgentRun`, so the suite exercises routing, gates, and the transport projection
|
|
14
|
+
* as a real end-to-end contract.
|
|
15
|
+
*/
|
|
16
|
+
import type { AgentAnswer, AgentRun, AgentRunRoute, AgentRunStatus, AgentRunTrustState } from '@duckcodeailabs/dql-agent';
|
|
17
|
+
/** Eval-facing view of a run, shaped like the fields the scorer already reads. */
|
|
18
|
+
export interface RuntimeDrivenRun {
|
|
19
|
+
kind: 'certified' | 'uncertified' | 'no_answer';
|
|
20
|
+
route?: 'certified' | 'generated_sql' | 'research' | 'clarify';
|
|
21
|
+
runRoute: AgentRunRoute;
|
|
22
|
+
status: AgentRunStatus;
|
|
23
|
+
trustState: AgentRunTrustState;
|
|
24
|
+
answer?: string;
|
|
25
|
+
proposedSql?: string;
|
|
26
|
+
rows?: unknown[];
|
|
27
|
+
clarificationOptionCount: number;
|
|
28
|
+
refusalCode?: string;
|
|
29
|
+
runId: string;
|
|
30
|
+
/**
|
|
31
|
+
* A conversational reply (greeting, capability, polite redirect). It asserts
|
|
32
|
+
* nothing about the data, so it is neither an answer nor a refusal — scoring it
|
|
33
|
+
* as either misreads the correct outcome for an out-of-scope question.
|
|
34
|
+
*/
|
|
35
|
+
conversational: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Did the meaning resolver actually run for this turn?
|
|
38
|
+
*
|
|
39
|
+
* With no provider configured it cannot, and `mayAssumeInterpretation` goes
|
|
40
|
+
* false (AGT-017) — DQL deliberately refuses to settle `booked_revenue` vs
|
|
41
|
+
* `billed_revenue` by lexical rank with semantic judgment switched off. Every
|
|
42
|
+
* ambiguous question then clarifies. That is correct behaviour, but it makes a
|
|
43
|
+
* clarification rate measured without a provider meaningless, so the harness
|
|
44
|
+
* has to be able to say so.
|
|
45
|
+
*/
|
|
46
|
+
meaningResolved: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Did this run decline to produce a usable answer?
|
|
50
|
+
*
|
|
51
|
+
* `needs_review` is deliberately NOT a refusal: a review-required generated
|
|
52
|
+
* answer is the intended outcome when no governed plan froze, and counting it as
|
|
53
|
+
* a refusal would make the false-refusal metric punish the very behaviour the
|
|
54
|
+
* cascade is supposed to produce.
|
|
55
|
+
*/
|
|
56
|
+
export declare function runtimeRunRefused(run: Pick<AgentRun, 'route' | 'status'>): boolean;
|
|
57
|
+
/** Map an engine route onto the vocabulary the eval cases already use. */
|
|
58
|
+
export declare function evalRouteForRun(route: AgentRunRoute): RuntimeDrivenRun['route'];
|
|
59
|
+
/**
|
|
60
|
+
* Collapse a run into the coarse `kind` the existing expectations assert.
|
|
61
|
+
* Certification follows TRUST, not route: a certified route that degraded to a
|
|
62
|
+
* review-required answer must not be scored as certified.
|
|
63
|
+
*/
|
|
64
|
+
export declare function evalKindForRun(run: Pick<AgentRun, 'route' | 'status' | 'trustState'>): RuntimeDrivenRun['kind'];
|
|
65
|
+
/** Pull SQL and result rows out of the run's artifacts, when it produced any. */
|
|
66
|
+
export declare function runtimeRunOutputs(run: AgentRun): {
|
|
67
|
+
proposedSql?: string;
|
|
68
|
+
rows?: unknown[];
|
|
69
|
+
};
|
|
70
|
+
export declare function projectRuntimeRun(run: AgentRun): RuntimeDrivenRun;
|
|
71
|
+
export interface RuntimeDriverOptions {
|
|
72
|
+
runtimeBase: string;
|
|
73
|
+
question: string;
|
|
74
|
+
requestedMode?: 'ask' | 'auto' | 'research';
|
|
75
|
+
threadId?: string;
|
|
76
|
+
timeoutMs?: number;
|
|
77
|
+
fetchImpl?: typeof fetch;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Post one question to a running `dql serve` and return the persisted run.
|
|
81
|
+
*
|
|
82
|
+
* Failures are surfaced rather than swallowed: a harness that silently scores a
|
|
83
|
+
* transport error as a refusal would report a false-refusal spike that no code
|
|
84
|
+
* change caused.
|
|
85
|
+
*/
|
|
86
|
+
export declare function driveViaRuntime(options: RuntimeDriverOptions): Promise<AgentRun>;
|
|
87
|
+
/**
|
|
88
|
+
* Adapt a persisted run into the `AgentAnswer` shape the existing scorer reads,
|
|
89
|
+
* so both drivers share one set of assertions.
|
|
90
|
+
*
|
|
91
|
+
* Fields the run genuinely does not carry are left UNDEFINED rather than
|
|
92
|
+
* defaulted. An expectation that references one then fails loudly instead of
|
|
93
|
+
* passing against a fabricated value — a harness that quietly invents
|
|
94
|
+
* `sourceTier` would report agreement it never observed.
|
|
95
|
+
*/
|
|
96
|
+
export declare function answerFromRuntimeRun(run: AgentRun): AgentAnswer;
|
|
97
|
+
//# sourceMappingURL=agent-eval-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-eval-runtime.d.ts","sourceRoot":"","sources":["../../src/commands/agent-eval-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE1H,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,GAAG,aAAa,GAAG,WAAW,CAAC;IAChD,KAAK,CAAC,EAAE,WAAW,GAAG,eAAe,GAAG,UAAU,GAAG,SAAS,CAAC;IAC/D,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,cAAc,CAAC;IACvB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,wBAAwB,EAAE,MAAM,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;;;;;;;;OASG;IACH,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAC,GAAG,OAAO,CAKlF;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAU/E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,YAAY,CAAC,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAI/G;AAYD,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,CAe3F;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CAgBjE;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8BtF;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,CAuB/D"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Did this run decline to produce a usable answer?
|
|
3
|
+
*
|
|
4
|
+
* `needs_review` is deliberately NOT a refusal: a review-required generated
|
|
5
|
+
* answer is the intended outcome when no governed plan froze, and counting it as
|
|
6
|
+
* a refusal would make the false-refusal metric punish the very behaviour the
|
|
7
|
+
* cascade is supposed to produce.
|
|
8
|
+
*/
|
|
9
|
+
export function runtimeRunRefused(run) {
|
|
10
|
+
return run.route === 'blocked'
|
|
11
|
+
|| run.route === 'clarify'
|
|
12
|
+
|| run.status === 'blocked'
|
|
13
|
+
|| run.status === 'needs_clarification';
|
|
14
|
+
}
|
|
15
|
+
/** Map an engine route onto the vocabulary the eval cases already use. */
|
|
16
|
+
export function evalRouteForRun(route) {
|
|
17
|
+
switch (route) {
|
|
18
|
+
case 'certified_answer': return 'certified';
|
|
19
|
+
case 'semantic_answer': return 'certified';
|
|
20
|
+
case 'generated_answer': return 'generated_sql';
|
|
21
|
+
case 'research': return 'research';
|
|
22
|
+
case 'clarify':
|
|
23
|
+
case 'blocked': return 'clarify';
|
|
24
|
+
default: return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Collapse a run into the coarse `kind` the existing expectations assert.
|
|
29
|
+
* Certification follows TRUST, not route: a certified route that degraded to a
|
|
30
|
+
* review-required answer must not be scored as certified.
|
|
31
|
+
*/
|
|
32
|
+
export function evalKindForRun(run) {
|
|
33
|
+
if (runtimeRunRefused(run))
|
|
34
|
+
return 'no_answer';
|
|
35
|
+
if (run.trustState === 'certified')
|
|
36
|
+
return 'certified';
|
|
37
|
+
return 'uncertified';
|
|
38
|
+
}
|
|
39
|
+
function firstArtifactPayload(run, kinds) {
|
|
40
|
+
for (const artifact of run.artifacts ?? []) {
|
|
41
|
+
if (!kinds.includes(String(artifact.kind)))
|
|
42
|
+
continue;
|
|
43
|
+
if (artifact.payload && typeof artifact.payload === 'object') {
|
|
44
|
+
return artifact.payload;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
/** Pull SQL and result rows out of the run's artifacts, when it produced any. */
|
|
50
|
+
export function runtimeRunOutputs(run) {
|
|
51
|
+
const payload = firstArtifactPayload(run, ['sql_cell', 'dql_block', 'generated_answer', 'answer', 'result']);
|
|
52
|
+
const sql = typeof payload?.sql === 'string'
|
|
53
|
+
? payload.sql
|
|
54
|
+
: typeof payload?.compiledSql === 'string' ? payload.compiledSql : undefined;
|
|
55
|
+
const resultRecord = payload?.result && typeof payload.result === 'object'
|
|
56
|
+
? payload.result
|
|
57
|
+
: undefined;
|
|
58
|
+
const rows = Array.isArray(resultRecord?.rows)
|
|
59
|
+
? resultRecord.rows
|
|
60
|
+
: Array.isArray(payload?.rows) ? payload.rows : undefined;
|
|
61
|
+
return {
|
|
62
|
+
...(sql ? { proposedSql: sql } : {}),
|
|
63
|
+
...(rows ? { rows } : {}),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function projectRuntimeRun(run) {
|
|
67
|
+
const refusalEvaluation = (run.evaluations ?? []).find((evaluation) => !evaluation.passed);
|
|
68
|
+
return {
|
|
69
|
+
kind: evalKindForRun(run),
|
|
70
|
+
route: evalRouteForRun(run.route),
|
|
71
|
+
runRoute: run.route,
|
|
72
|
+
status: run.status,
|
|
73
|
+
trustState: run.trustState,
|
|
74
|
+
clarificationOptionCount: run.clarificationOptions?.length ?? 0,
|
|
75
|
+
runId: run.id,
|
|
76
|
+
conversational: run.route === 'conversation' || run.answerKind === 'conversational',
|
|
77
|
+
meaningResolved: Boolean(run.routeDecision?.meaningResolution),
|
|
78
|
+
...(run.answer ? { answer: run.answer } : {}),
|
|
79
|
+
...(refusalEvaluation?.id ? { refusalCode: refusalEvaluation.id } : {}),
|
|
80
|
+
...runtimeRunOutputs(run),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Post one question to a running `dql serve` and return the persisted run.
|
|
85
|
+
*
|
|
86
|
+
* Failures are surfaced rather than swallowed: a harness that silently scores a
|
|
87
|
+
* transport error as a refusal would report a false-refusal spike that no code
|
|
88
|
+
* change caused.
|
|
89
|
+
*/
|
|
90
|
+
export async function driveViaRuntime(options) {
|
|
91
|
+
const base = options.runtimeBase.replace(/\/$/, '');
|
|
92
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
93
|
+
const controller = new AbortController();
|
|
94
|
+
const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 120_000);
|
|
95
|
+
try {
|
|
96
|
+
const response = await fetchImpl(`${base}/api/agent-runs`, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
headers: { 'Content-Type': 'application/json' },
|
|
99
|
+
body: JSON.stringify({
|
|
100
|
+
question: options.question,
|
|
101
|
+
requestedMode: options.requestedMode ?? 'ask',
|
|
102
|
+
...(options.threadId ? { threadId: options.threadId } : {}),
|
|
103
|
+
}),
|
|
104
|
+
signal: controller.signal,
|
|
105
|
+
});
|
|
106
|
+
if (!response.ok) {
|
|
107
|
+
throw new Error(`Runtime returned ${response.status}: ${(await response.text()).slice(0, 400)}`);
|
|
108
|
+
}
|
|
109
|
+
// The endpoint wraps the record (`{ run }`); older/streamed paths return it
|
|
110
|
+
// bare. Accept both rather than guessing one and failing the whole suite.
|
|
111
|
+
const body = await response.json();
|
|
112
|
+
const run = body.run ?? body;
|
|
113
|
+
if (!run || typeof run.id !== 'string') {
|
|
114
|
+
throw new Error(`Runtime response was not an agent run: ${JSON.stringify(body).slice(0, 200)}`);
|
|
115
|
+
}
|
|
116
|
+
return run;
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
clearTimeout(timer);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Adapt a persisted run into the `AgentAnswer` shape the existing scorer reads,
|
|
124
|
+
* so both drivers share one set of assertions.
|
|
125
|
+
*
|
|
126
|
+
* Fields the run genuinely does not carry are left UNDEFINED rather than
|
|
127
|
+
* defaulted. An expectation that references one then fails loudly instead of
|
|
128
|
+
* passing against a fabricated value — a harness that quietly invents
|
|
129
|
+
* `sourceTier` would report agreement it never observed.
|
|
130
|
+
*/
|
|
131
|
+
export function answerFromRuntimeRun(run) {
|
|
132
|
+
const projected = projectRuntimeRun(run);
|
|
133
|
+
const certification = projected.kind === 'no_answer'
|
|
134
|
+
? 'analyst_review_required'
|
|
135
|
+
: run.trustState === 'certified'
|
|
136
|
+
? 'certified'
|
|
137
|
+
: run.trustState === 'review_required'
|
|
138
|
+
? 'analyst_review_required'
|
|
139
|
+
: 'ai_generated';
|
|
140
|
+
return {
|
|
141
|
+
kind: projected.kind,
|
|
142
|
+
certification,
|
|
143
|
+
reviewStatus: run.trustState === 'review_required' ? 'analyst_review_required' : 'none',
|
|
144
|
+
text: run.answer ?? run.summary,
|
|
145
|
+
citations: [],
|
|
146
|
+
considered: [],
|
|
147
|
+
...(projected.proposedSql ? { proposedSql: projected.proposedSql } : {}),
|
|
148
|
+
...(projected.rows ? { result: { columns: [], rows: projected.rows, rowCount: projected.rows.length } } : {}),
|
|
149
|
+
...(projected.refusalCode ? { refusalCode: projected.refusalCode } : {}),
|
|
150
|
+
// Carried so the scorer can tell an answerable clarification from a dead end.
|
|
151
|
+
...(run.clarificationOptions?.length ? { clarificationOptions: run.clarificationOptions } : {}),
|
|
152
|
+
...(projected.conversational ? { answerKind: 'conversational' } : {}),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=agent-eval-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-eval-runtime.js","sourceRoot":"","sources":["../../src/commands/agent-eval-runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/agent.d.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* dql agent feedback <up|down> --block <id> --question "..."
|
|
22
22
|
* Records feedback into the KG. Used by clients without MCP access.
|
|
23
23
|
*/
|
|
24
|
-
import { answer, type AgentAnswer, type AgentFollowUpContext, type AnalysisDepth, type ReasoningEffort } from '@duckcodeailabs/dql-agent';
|
|
24
|
+
import { answer, type AgentAnswer, type AgentFollowUpContext, type AnalysisDepth, type NarrationIntegrityReceiptV1, type ReasoningEffort } from '@duckcodeailabs/dql-agent';
|
|
25
25
|
import type { CLIFlags } from '../args.js';
|
|
26
26
|
declare function cliReasoningEffort(flags: CLIFlags): ReasoningEffort | undefined;
|
|
27
27
|
declare function cliAnalysisDepth(flags: CLIFlags): AnalysisDepth | undefined;
|
|
@@ -49,6 +49,18 @@ interface AgentEvalCase {
|
|
|
49
49
|
draftSaved?: boolean;
|
|
50
50
|
minToolCalls?: number;
|
|
51
51
|
rows?: unknown[];
|
|
52
|
+
/**
|
|
53
|
+
* Is this question answerable at all?
|
|
54
|
+
*
|
|
55
|
+
* When true, ANY refusal (`no_answer` / `clarify`) is a FALSE REFUSAL — the
|
|
56
|
+
* single number that makes "Ask AI refuses too much" measurable instead of
|
|
57
|
+
* anecdotal. When false, the case belongs to the genuine-refusal class and a
|
|
58
|
+
* refusal is the correct outcome; answering it would be a hallucination.
|
|
59
|
+
*
|
|
60
|
+
* Omitted, it is inferred from the other expectations, so existing case files
|
|
61
|
+
* contribute to the metric without being rewritten.
|
|
62
|
+
*/
|
|
63
|
+
answerable?: boolean;
|
|
52
64
|
};
|
|
53
65
|
}
|
|
54
66
|
interface AgentEvalResult {
|
|
@@ -56,6 +68,20 @@ interface AgentEvalResult {
|
|
|
56
68
|
passed: boolean;
|
|
57
69
|
failures: string[];
|
|
58
70
|
durationMs: number;
|
|
71
|
+
/**
|
|
72
|
+
* True when verified narration failed its fact check and the deterministic
|
|
73
|
+
* record was shown instead. A silent rise here is exactly the truncation
|
|
74
|
+
* defect that shipped unnoticed, so it is measured.
|
|
75
|
+
*/
|
|
76
|
+
narrationFallback?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Was verified-fact narration ATTEMPTED at all? Undefined on cases that never
|
|
79
|
+
* reach the narrator (refusals, conversational replies). Without this the
|
|
80
|
+
* grounded-narration denominator counted every case, diluting real failures
|
|
81
|
+
* with runs that were never at risk — a metric that masks the defect it was
|
|
82
|
+
* added to catch.
|
|
83
|
+
*/
|
|
84
|
+
narrationAttempted?: boolean;
|
|
59
85
|
executionMs?: number;
|
|
60
86
|
executionMatched?: boolean;
|
|
61
87
|
kind: AgentAnswer['kind'];
|
|
@@ -71,6 +97,18 @@ interface AgentEvalResult {
|
|
|
71
97
|
toolCalls: number;
|
|
72
98
|
judgeScore?: number;
|
|
73
99
|
judgePass?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Selectable options offered with a clarification. A clarification that offers
|
|
102
|
+
* real choices is answerable in one more turn; one that offers none is the
|
|
103
|
+
* dead end this suite exists to catch.
|
|
104
|
+
*/
|
|
105
|
+
clarificationOptionCount?: number;
|
|
106
|
+
/** True when the run replied conversationally instead of asserting data. */
|
|
107
|
+
conversational?: boolean;
|
|
108
|
+
/** True when that conversational reply actually carried content. */
|
|
109
|
+
conversationalAnswer?: boolean;
|
|
110
|
+
/** True when the meaning resolver ran (a provider was reachable). */
|
|
111
|
+
meaningResolved?: boolean;
|
|
74
112
|
}
|
|
75
113
|
type AgentEvalTraceStageName = 'context' | 'rewrite' | 'lane' | 'tools' | 'answer' | 'validation' | 'execution' | 'draft' | 'scoring';
|
|
76
114
|
interface AgentEvalTraceStage {
|
|
@@ -84,6 +122,32 @@ declare function evaluateCase(testCase: AgentEvalCase, result: Awaited<ReturnTyp
|
|
|
84
122
|
validationCode?: string;
|
|
85
123
|
executionMatched?: boolean;
|
|
86
124
|
};
|
|
125
|
+
/**
|
|
126
|
+
* Is the case answerable? Explicit `expected.answerable` wins; otherwise infer
|
|
127
|
+
* from the expectations already present, so the metric covers legacy case files.
|
|
128
|
+
* A case with no expectations at all is excluded — it asserts nothing, so it can
|
|
129
|
+
* neither prove nor disprove a false refusal.
|
|
130
|
+
*/
|
|
131
|
+
export declare function evalCaseIsAnswerable(expected: AgentEvalCase['expected']): boolean | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* Did the run leave the user with NO way forward?
|
|
134
|
+
*
|
|
135
|
+
* Deliberately narrower than "did not answer". A clarification that offers
|
|
136
|
+
* selectable options is answerable on the next turn — worth minimising, tracked
|
|
137
|
+
* separately as `clarification_rate`, but not the defect. A clarification with
|
|
138
|
+
* ZERO options is a true dead end: the reported production loop was exactly
|
|
139
|
+
* this, and a free-text reply to it reproduced the same question forever.
|
|
140
|
+
*/
|
|
141
|
+
export declare function evalResultRefused(result: Pick<AgentEvalResult, 'kind' | 'route' | 'clarificationOptionCount' | 'conversationalAnswer'>): boolean;
|
|
142
|
+
/** Did the run ask an answerable clarification rather than answering outright? */
|
|
143
|
+
export declare function evalResultClarified(result: Pick<AgentEvalResult, 'route' | 'clarificationOptionCount'>): boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Translate only the durable narration receipt into evaluation fields.
|
|
146
|
+
*
|
|
147
|
+
* Reader prose, row count, and result shape are deliberately absent: a skipped
|
|
148
|
+
* narration can have rows, and a deterministic fallback can use any wording.
|
|
149
|
+
*/
|
|
150
|
+
export declare function narrationOutcomeForEval(receipt: NarrationIntegrityReceiptV1 | undefined): Pick<AgentEvalResult, 'narrationAttempted' | 'narrationFallback'>;
|
|
87
151
|
declare function computeEvalMetrics(results: AgentEvalResult[]): {
|
|
88
152
|
certified_hit_rate: number | null;
|
|
89
153
|
judge_mean_score: number | null;
|
|
@@ -94,6 +158,52 @@ declare function computeEvalMetrics(results: AgentEvalResult[]): {
|
|
|
94
158
|
tool_requirement_pass_rate: number | null;
|
|
95
159
|
wrong_certified_count: number;
|
|
96
160
|
outside_context_rejection_count: number;
|
|
161
|
+
/**
|
|
162
|
+
* THE headline number: how often an answerable question was refused.
|
|
163
|
+
* Bounds every other quality metric — a run that refuses cannot be wrong,
|
|
164
|
+
* so a falling false-refusal rate must be read together with
|
|
165
|
+
* `execution_match_rate` to be sure refusals were replaced by CORRECT answers.
|
|
166
|
+
*/
|
|
167
|
+
false_refusal_rate: number | null;
|
|
168
|
+
false_refusal_count: number;
|
|
169
|
+
answerable_case_count: number;
|
|
170
|
+
/**
|
|
171
|
+
* Answerable cases that asked an option-bearing clarification instead of
|
|
172
|
+
* answering. Not a defect, but a direct cost in turns — read it next to
|
|
173
|
+
* false_refusal_rate so a fall in refusals is not just a rise in questions.
|
|
174
|
+
*/
|
|
175
|
+
clarification_rate: number | null;
|
|
176
|
+
/**
|
|
177
|
+
* Cases where semantic judgment ran. Without a provider `mayAssumeInterpretation`
|
|
178
|
+
* is false (AGT-017), so every ambiguous question clarifies by design and
|
|
179
|
+
* `clarification_rate` says nothing about product quality.
|
|
180
|
+
*/
|
|
181
|
+
meaning_resolved_rate: number | null;
|
|
182
|
+
/**
|
|
183
|
+
* Latency, which the acceptance matrix asked for and nothing measured. A
|
|
184
|
+
* quality gain paid for entirely in wall clock is not a gain: the plan's
|
|
185
|
+
* two-tier target is certified/semantic under 5s while research takes
|
|
186
|
+
* minutes, and only a per-class p95 can tell those apart from a regression.
|
|
187
|
+
*/
|
|
188
|
+
latency_p50_ms: number | null;
|
|
189
|
+
latency_p95_ms: number | null;
|
|
190
|
+
latency_p95_answerable_ms: number | null;
|
|
191
|
+
/**
|
|
192
|
+
* How often verified narration survived. When the drafted narration fails
|
|
193
|
+
* its fact check the reader gets the deterministic record under a
|
|
194
|
+
* disclaimer — correct, but visibly worse. A silent fall here is exactly
|
|
195
|
+
* the truncation defect that shipped unnoticed, so it is measured.
|
|
196
|
+
*/
|
|
197
|
+
grounded_narration_rate: number | null;
|
|
198
|
+
grounded_narration_attempted: number;
|
|
199
|
+
/**
|
|
200
|
+
* The guard on the above: cases that must NOT produce a data answer.
|
|
201
|
+
* Scored on "did not answer" rather than "dead-ended", because declining via
|
|
202
|
+
* a clarification is still declining — what would be wrong is asserting
|
|
203
|
+
* something about data the project does not have.
|
|
204
|
+
*/
|
|
205
|
+
refusal_recall: number | null;
|
|
206
|
+
refusal_required_case_count: number;
|
|
97
207
|
draft_saved_count: number;
|
|
98
208
|
tool_observed_case_count: number;
|
|
99
209
|
avg_tool_calls: number;
|
|
@@ -105,6 +215,9 @@ declare function agentEvalThresholdsPass(metrics: ReturnType<typeof computeEvalM
|
|
|
105
215
|
minExecutionMatch?: number | null;
|
|
106
216
|
minJudgePass?: number | null;
|
|
107
217
|
maxWrongCertified?: number | null;
|
|
218
|
+
maxFalseRefusal?: number | null;
|
|
219
|
+
minRefusalRecall?: number | null;
|
|
220
|
+
minGroundedNarration?: number | null;
|
|
108
221
|
}): boolean;
|
|
109
222
|
declare function buildEvalTrace(input: {
|
|
110
223
|
testCase: AgentEvalCase;
|
|
@@ -119,6 +232,7 @@ export declare const __test__: {
|
|
|
119
232
|
cliAnalysisDepth: typeof cliAnalysisDepth;
|
|
120
233
|
cliReasoningEffort: typeof cliReasoningEffort;
|
|
121
234
|
computeEvalMetrics: typeof computeEvalMetrics;
|
|
235
|
+
narrationOutcomeForEval: typeof narrationOutcomeForEval;
|
|
122
236
|
evaluateCase: typeof evaluateCase;
|
|
123
237
|
};
|
|
124
238
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"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"}
|