@duckcodeailabs/dql-agent 1.13.5 → 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.
Files changed (158) hide show
  1. package/dist/agent-run-engine.d.ts +79 -4
  2. package/dist/agent-run-engine.d.ts.map +1 -1
  3. package/dist/agent-run-engine.js +457 -39
  4. package/dist/agent-run-engine.js.map +1 -1
  5. package/dist/agent-run-gates.d.ts.map +1 -1
  6. package/dist/agent-run-gates.js +13 -0
  7. package/dist/agent-run-gates.js.map +1 -1
  8. package/dist/agent-run-store.d.ts.map +1 -1
  9. package/dist/agent-run-store.js +42 -25
  10. package/dist/agent-run-store.js.map +1 -1
  11. package/dist/agentic/analyst-loop.d.ts +91 -0
  12. package/dist/agentic/analyst-loop.d.ts.map +1 -0
  13. package/dist/agentic/analyst-loop.js +311 -0
  14. package/dist/agentic/analyst-loop.js.map +1 -0
  15. package/dist/agentic/assumptions.d.ts +62 -0
  16. package/dist/agentic/assumptions.d.ts.map +1 -0
  17. package/dist/agentic/assumptions.js +73 -0
  18. package/dist/agentic/assumptions.js.map +1 -0
  19. package/dist/agentic/business-explanation.d.ts +56 -0
  20. package/dist/agentic/business-explanation.d.ts.map +1 -0
  21. package/dist/agentic/business-explanation.js +130 -0
  22. package/dist/agentic/business-explanation.js.map +1 -0
  23. package/dist/agentic/identifier-ledger.d.ts +74 -0
  24. package/dist/agentic/identifier-ledger.d.ts.map +1 -0
  25. package/dist/agentic/identifier-ledger.js +151 -0
  26. package/dist/agentic/identifier-ledger.js.map +1 -0
  27. package/dist/agentic/ledger-tools.d.ts +68 -0
  28. package/dist/agentic/ledger-tools.d.ts.map +1 -0
  29. package/dist/agentic/ledger-tools.js +198 -0
  30. package/dist/agentic/ledger-tools.js.map +1 -0
  31. package/dist/agentic/orchestrator-policy.d.ts +60 -0
  32. package/dist/agentic/orchestrator-policy.d.ts.map +1 -0
  33. package/dist/agentic/orchestrator-policy.js +73 -0
  34. package/dist/agentic/orchestrator-policy.js.map +1 -0
  35. package/dist/agentic/orchestrator.d.ts +54 -0
  36. package/dist/agentic/orchestrator.d.ts.map +1 -0
  37. package/dist/agentic/orchestrator.js +67 -0
  38. package/dist/agentic/orchestrator.js.map +1 -0
  39. package/dist/agentic/preview-tool.d.ts +36 -0
  40. package/dist/agentic/preview-tool.d.ts.map +1 -0
  41. package/dist/agentic/preview-tool.js +71 -0
  42. package/dist/agentic/preview-tool.js.map +1 -0
  43. package/dist/agentic/rerank.d.ts +50 -0
  44. package/dist/agentic/rerank.d.ts.map +1 -0
  45. package/dist/agentic/rerank.js +140 -0
  46. package/dist/agentic/rerank.js.map +1 -0
  47. package/dist/agentic/research/hypothesis.d.ts +110 -0
  48. package/dist/agentic/research/hypothesis.d.ts.map +1 -0
  49. package/dist/agentic/research/hypothesis.js +125 -0
  50. package/dist/agentic/research/hypothesis.js.map +1 -0
  51. package/dist/agentic/research/synthesis.d.ts +32 -0
  52. package/dist/agentic/research/synthesis.d.ts.map +1 -0
  53. package/dist/agentic/research/synthesis.js +94 -0
  54. package/dist/agentic/research/synthesis.js.map +1 -0
  55. package/dist/agentic/research-agent.d.ts +54 -0
  56. package/dist/agentic/research-agent.d.ts.map +1 -0
  57. package/dist/agentic/research-agent.js +176 -0
  58. package/dist/agentic/research-agent.js.map +1 -0
  59. package/dist/agentic/sql-authorization.d.ts +131 -0
  60. package/dist/agentic/sql-authorization.d.ts.map +1 -0
  61. package/dist/agentic/sql-authorization.js +232 -0
  62. package/dist/agentic/sql-authorization.js.map +1 -0
  63. package/dist/agentic/tool-loop.d.ts +29 -0
  64. package/dist/agentic/tool-loop.d.ts.map +1 -1
  65. package/dist/agentic/tool-loop.js +129 -52
  66. package/dist/agentic/tool-loop.js.map +1 -1
  67. package/dist/agentic/toolset.d.ts.map +1 -1
  68. package/dist/agentic/toolset.js +155 -0
  69. package/dist/agentic/toolset.js.map +1 -1
  70. package/dist/agentic/turn-plan.d.ts +35 -0
  71. package/dist/agentic/turn-plan.d.ts.map +1 -0
  72. package/dist/agentic/turn-plan.js +108 -0
  73. package/dist/agentic/turn-plan.js.map +1 -0
  74. package/dist/agentic/value-probe.d.ts +89 -0
  75. package/dist/agentic/value-probe.d.ts.map +1 -0
  76. package/dist/agentic/value-probe.js +304 -0
  77. package/dist/agentic/value-probe.js.map +1 -0
  78. package/dist/analytical-orchestration.d.ts +336 -0
  79. package/dist/analytical-orchestration.d.ts.map +1 -0
  80. package/dist/analytical-orchestration.js +631 -0
  81. package/dist/analytical-orchestration.js.map +1 -0
  82. package/dist/analytical-request-policy.d.ts +26 -0
  83. package/dist/analytical-request-policy.d.ts.map +1 -0
  84. package/dist/analytical-request-policy.js +82 -0
  85. package/dist/analytical-request-policy.js.map +1 -0
  86. package/dist/analytical-result-facts.d.ts +14 -1
  87. package/dist/analytical-result-facts.d.ts.map +1 -1
  88. package/dist/analytical-result-facts.js +76 -1
  89. package/dist/analytical-result-facts.js.map +1 -1
  90. package/dist/answer-loop.d.ts +61 -16
  91. package/dist/answer-loop.d.ts.map +1 -1
  92. package/dist/answer-loop.js +256 -36
  93. package/dist/answer-loop.js.map +1 -1
  94. package/dist/cascade/budgets.d.ts.map +1 -1
  95. package/dist/cascade/budgets.js +8 -1
  96. package/dist/cascade/budgets.js.map +1 -1
  97. package/dist/cascade/packer.d.ts +88 -0
  98. package/dist/cascade/packer.d.ts.map +1 -0
  99. package/dist/cascade/packer.js +106 -0
  100. package/dist/cascade/packer.js.map +1 -0
  101. package/dist/conversation/result-ops.d.ts +18 -3
  102. package/dist/conversation/result-ops.d.ts.map +1 -1
  103. package/dist/conversation/result-ops.js +77 -5
  104. package/dist/conversation/result-ops.js.map +1 -1
  105. package/dist/conversation/rolling-summary.d.ts.map +1 -1
  106. package/dist/conversation/rolling-summary.js +7 -2
  107. package/dist/conversation/rolling-summary.js.map +1 -1
  108. package/dist/conversation/session-store.d.ts +3 -0
  109. package/dist/conversation/session-store.d.ts.map +1 -1
  110. package/dist/conversation/session-store.js +8 -4
  111. package/dist/conversation/session-store.js.map +1 -1
  112. package/dist/conversation/snapshot.d.ts.map +1 -1
  113. package/dist/conversation/snapshot.js +13 -1
  114. package/dist/conversation/snapshot.js.map +1 -1
  115. package/dist/conversation/turn-trust.d.ts.map +1 -1
  116. package/dist/conversation/turn-trust.js +6 -0
  117. package/dist/conversation/turn-trust.js.map +1 -1
  118. package/dist/hints/store.d.ts.map +1 -1
  119. package/dist/hints/store.js +15 -5
  120. package/dist/hints/store.js.map +1 -1
  121. package/dist/index.d.ts +27 -5
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +28 -4
  124. package/dist/index.js.map +1 -1
  125. package/dist/intent-controller.d.ts +8 -0
  126. package/dist/intent-controller.d.ts.map +1 -1
  127. package/dist/intent-controller.js +65 -0
  128. package/dist/intent-controller.js.map +1 -1
  129. package/dist/meaning-resolution.d.ts +7 -0
  130. package/dist/meaning-resolution.d.ts.map +1 -1
  131. package/dist/meaning-resolution.js.map +1 -1
  132. package/dist/metadata/block-fit.d.ts +18 -0
  133. package/dist/metadata/block-fit.d.ts.map +1 -1
  134. package/dist/metadata/block-fit.js +41 -1
  135. package/dist/metadata/block-fit.js.map +1 -1
  136. package/dist/metadata/catalog.d.ts +44 -23
  137. package/dist/metadata/catalog.d.ts.map +1 -1
  138. package/dist/metadata/catalog.js +363 -53
  139. package/dist/metadata/catalog.js.map +1 -1
  140. package/dist/metadata/meaning-evidence.d.ts.map +1 -1
  141. package/dist/metadata/meaning-evidence.js +101 -8
  142. package/dist/metadata/meaning-evidence.js.map +1 -1
  143. package/dist/metadata/metric-match.d.ts +32 -0
  144. package/dist/metadata/metric-match.d.ts.map +1 -1
  145. package/dist/metadata/metric-match.js +120 -9
  146. package/dist/metadata/metric-match.js.map +1 -1
  147. package/dist/research-loop.d.ts +33 -2
  148. package/dist/research-loop.d.ts.map +1 -1
  149. package/dist/research-loop.js +44 -4
  150. package/dist/research-loop.js.map +1 -1
  151. package/dist/resolved-analytical-plan.d.ts.map +1 -1
  152. package/dist/resolved-analytical-plan.js +92 -5
  153. package/dist/resolved-analytical-plan.js.map +1 -1
  154. package/dist/router.d.ts +36 -16
  155. package/dist/router.d.ts.map +1 -1
  156. package/dist/router.js +604 -25
  157. package/dist/router.js.map +1 -1
  158. package/package.json +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytical-orchestration.d.ts","sourceRoot":"","sources":["../src/analytical-orchestration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,631 @@
1
+ /**
2
+ * Shared contracts for the conversational analytical orchestrator.
3
+ *
4
+ * The existing DQL engine remains the authority for compilation, execution,
5
+ * trust, and the immutable resolved analytical plan. This module is the thin
6
+ * outer contract used by the conversational layer to describe what it
7
+ * understood, what it searched, and why it could or could not continue.
8
+ *
9
+ * The contract is intentionally content-only: it never carries model
10
+ * chain-of-thought, credentials, raw provider payloads, or authorization.
11
+ *
12
+ * Acceptance: AGT-027..033, CTX-007, PERF-003, E2E-022.
13
+ */
14
+ import { createHash } from 'node:crypto';
15
+ export const ANALYTICAL_ORCHESTRATION_CONTRACT_VERSION = 1;
16
+ /**
17
+ * Small, explainable intent vocabulary used before the physical plan exists.
18
+ * It is deliberately not a second semantic matcher: candidate identity still
19
+ * comes from retrieval plus the bounded meaning call. These helpers only turn
20
+ * a request into a task graph and output contract, so a compound question can
21
+ * report partial success instead of collapsing the whole turn to one error.
22
+ */
23
+ export function inferAnalyticalTurnKind(question) {
24
+ const text = question.toLowerCase();
25
+ if (/\b(hello|hi|hey|thanks|thank you|good morning|good afternoon)\b/.test(text))
26
+ return 'conversation';
27
+ if (/\b(why|root cause|driver|diagnos|anomal|changed)\b/.test(text))
28
+ return 'diagnosis';
29
+ if (/\b(research|investigate|deep dive|tell a story|surrounding context)\b/.test(text))
30
+ return 'research';
31
+ if (/\b(compare|versus|vs\.?|difference)\b/.test(text))
32
+ return 'comparison';
33
+ if (/\b(top|bottom|highest|lowest|rank)\b/.test(text))
34
+ return 'ranking';
35
+ if (/\b(by|per|over time|trend|monthly|daily|weekly)\b/.test(text))
36
+ return 'breakdown';
37
+ if (/\b(what is|what are|define|definition|meaning)\b/.test(text) && !/\b(total|revenue|count|sales|amount)\b/.test(text))
38
+ return 'definition';
39
+ if (/\b(region|country|state|city|name|label|email|category|product|customer)\b/.test(text)
40
+ && /\b(where|which|what|who)\b/.test(text))
41
+ return 'lookup';
42
+ return 'aggregation';
43
+ }
44
+ /**
45
+ * `Regarding: "Mr. Matthew Meyer"` and friends — a short label, a colon, and a
46
+ * quoted value, with nothing else in the clause. Deliberately narrow: it must
47
+ * be the WHOLE clause and the value must be quoted, so an ordinary question
48
+ * that happens to contain a colon is untouched.
49
+ */
50
+ const ANNOTATION_CLAUSE = /^\s*[A-Za-z][A-Za-z ]{0,24}:\s*["“'‘][^"”'’]*["”'’]\s*$/;
51
+ export function splitAnalyticalTasks(question) {
52
+ // The separator belongs to the SPLIT, not to the clause. Carrying it through
53
+ // produced a child task whose question was literally
54
+ // `" then "What customer type is Wesley Jenkins` — quote, connector and all —
55
+ // which then failed to resolve and surfaced that punctuation to the reader as
56
+ // the task title.
57
+ const leadingJunk = /^(?:[\s"'“”‘’,:;.\-]+|\b(?:then|and|also)\b)+/i;
58
+ const trailingJunk = /[\s"'“”‘’,:;.\-]+$/;
59
+ const raw = question
60
+ .split(/\s*(?:\?|;|\band then\b|\balso\b)\s*/i)
61
+ .flatMap((part) => part.split(/\s+\band\s+(?=(?:what|who|which|show|list|tell|give|how|why)\b)/i));
62
+ // A `Label: "value"` clause is an ANNOTATION, not a question. The composer
63
+ // appends `Regarding: "<selected row>"` when the reader follows up on
64
+ // something they clicked, and splitting on the `?` before it turned that
65
+ // referent into a task of its own — titled `Regarding: "Mr. Matthew Meyer`,
66
+ // which then "answered" by computing an unrelated maximum over the rows still
67
+ // on screen. Context says WHO the real task is about; it is never a task.
68
+ // Filtered before the junk strip, which would unbalance the quotes.
69
+ const asked = raw.filter((part) => !ANNOTATION_CLAUSE.test(part));
70
+ const parts = (asked.length > 0 ? asked : raw)
71
+ .map((part) => part.replace(leadingJunk, '').replace(trailingJunk, '').trim())
72
+ .filter(Boolean);
73
+ return parts.length > 0 ? parts : [question.trim()];
74
+ }
75
+ export function buildAnalyticalTaskGraph(input) {
76
+ const rootKind = input.mode === 'research' ? 'research' : inferAnalyticalTurnKind(input.question);
77
+ // A research turn may later create bounded evidence branches, but that is a
78
+ // research planner's job. Splitting at ingress loses the surrounding story
79
+ // before it has an opportunity to reason about it.
80
+ const clauses = (rootKind === 'research' ? [input.question.trim()] : splitAnalyticalTasks(input.question))
81
+ .slice(0, Math.max(1, Math.min(6, input.maxTasks ?? 6)));
82
+ const candidateIds = [...new Set((input.candidateIds ?? []).filter((id) => id.trim()))];
83
+ const metrics = [...new Set((input.metrics ?? []).filter((metric) => metric.trim()))];
84
+ const dimensions = [...new Set((input.dimensions ?? []).filter((dimension) => dimension.trim()))];
85
+ const filters = input.filters ?? [];
86
+ const inheritedBindings = input.inheritedBindings ?? [];
87
+ const unboundTasks = clauses.map((clause, index) => {
88
+ const kind = rootKind === 'research' ? 'research' : inferAnalyticalTurnKind(clause);
89
+ const research = kind === 'research' || kind === 'diagnosis';
90
+ const taskKind = research
91
+ ? 'research_branch'
92
+ : kind === 'lookup'
93
+ ? 'attribute_lookup'
94
+ : kind === 'breakdown'
95
+ ? 'breakdown'
96
+ : kind === 'comparison'
97
+ ? 'comparison'
98
+ : kind === 'ranking'
99
+ ? 'ranking'
100
+ : kind === 'definition'
101
+ ? 'definition'
102
+ : 'aggregation';
103
+ return {
104
+ version: 1,
105
+ id: `task-${index + 1}`,
106
+ kind: taskKind,
107
+ question: clause,
108
+ dependencies: index === 0 ? [] : [],
109
+ output: {
110
+ metrics,
111
+ dimensions,
112
+ filters,
113
+ ...(kind === 'ranking' ? { order: 'desc' } : {}),
114
+ },
115
+ status: 'planned',
116
+ candidateIds,
117
+ inheritedBindings,
118
+ };
119
+ });
120
+ const tasks = bindTopRankedRegionDependencies(unboundTasks);
121
+ return {
122
+ kind: rootKind === 'research' ? 'research' : tasks.length > 1 ? 'compound' : rootKind,
123
+ tasks,
124
+ partial: false,
125
+ };
126
+ }
127
+ const TOP_RANKED_REGION_RE = /(?:\b(?:top|highest|most)\b[^?.!]{0,72}\bregions?\b|\bregions?\b[^?.!]{0,72}\b(?:top|highest|most)\b)/i;
128
+ const DEPENDENT_REGION_CUSTOMERS_RE = /\b(?:that|this|same)\s+region\b/i;
129
+ /**
130
+ * Recognise only the demonstrated two-step dependency. Broader pronoun
131
+ * resolution belongs to the normal conversation layer; turning every compound
132
+ * question into a dependency would serialise unrelated work and invent filters.
133
+ */
134
+ function bindTopRankedRegionDependencies(tasks) {
135
+ return tasks.map((task, index) => {
136
+ if (!DEPENDENT_REGION_CUSTOMERS_RE.test(task.question) || !/\bcustomers?\b/i.test(task.question))
137
+ return task;
138
+ const parent = tasks.slice(0, index).reverse().find((candidate) => TOP_RANKED_REGION_RE.test(candidate.question));
139
+ if (!parent)
140
+ return task;
141
+ const dependency = {
142
+ version: 1,
143
+ kind: 'top_ranked_region',
144
+ sourceTaskId: parent.id,
145
+ targetDimension: 'region',
146
+ };
147
+ return { ...task, dependencies: [parent.id], dependency };
148
+ });
149
+ }
150
+ export function buildAnalyticalTurnPlan(input) {
151
+ const graph = buildAnalyticalTaskGraph(input);
152
+ const zeroCall = input.zeroCallReason === 'explicit_binding'
153
+ || input.zeroCallReason === 'conversation_only'
154
+ || input.zeroCallReason === 'frozen_research_child';
155
+ return {
156
+ version: 1,
157
+ ...(input.turnId ? { turnId: input.turnId } : {}),
158
+ question: input.question,
159
+ kind: graph.kind,
160
+ meaningCallBudget: zeroCall ? 0 : 1,
161
+ meaningCallReason: input.zeroCallReason ?? 'candidate_interpretation',
162
+ ...(input.snapshotId ? { snapshotId: input.snapshotId } : {}),
163
+ ...(input.sourceFingerprint ? { sourceFingerprint: input.sourceFingerprint } : {}),
164
+ taskIds: graph.tasks.map((task) => task.id),
165
+ tasks: graph.tasks,
166
+ authorityOrder: ['certified', 'semantic', 'governed_relational', 'generated'],
167
+ frozen: input.frozen === true,
168
+ };
169
+ }
170
+ export function summarizeTaskOutcomes(tasks) {
171
+ const completed = tasks.filter((task) => task.status === 'completed').map((task) => task.id);
172
+ const gaps = tasks.filter((task) => task.status === 'gap' || task.status === 'blocked').map((task) => task.id);
173
+ const status = completed.length === tasks.length && tasks.length > 0
174
+ ? 'completed'
175
+ : completed.length > 0
176
+ ? 'partial'
177
+ : gaps.some((id) => tasks.find((task) => task.id === id)?.status === 'blocked')
178
+ ? 'blocked'
179
+ : 'gap';
180
+ return { status, completed, gaps };
181
+ }
182
+ /** Stable scalar transport for a selected canonical result cell. */
183
+ export function canonicalResultBindingValue(value) {
184
+ if (typeof value === 'string')
185
+ return value;
186
+ if (typeof value === 'number' && Number.isFinite(value))
187
+ return String(value);
188
+ if (typeof value === 'boolean')
189
+ return String(value);
190
+ return undefined;
191
+ }
192
+ /** A row proof includes all canonical columns, not just the selected cell. */
193
+ export function canonicalResultRowFingerprint(result, row) {
194
+ return stableFingerprint({
195
+ columns: result.columns,
196
+ row: Object.fromEntries(result.columns.map((column) => [column, row[column]])),
197
+ });
198
+ }
199
+ /**
200
+ * Validate an untrusted selected-result reference against a persisted
201
+ * canonical result. The source run/artifact identities are checked by the
202
+ * host before calling this pure result-level validator.
203
+ */
204
+ export function validateSelectedResultBinding(binding, result) {
205
+ if (!binding
206
+ || binding.version !== 1
207
+ || !binding.sourceRunId.trim()
208
+ || !binding.sourceArtifactId.trim()
209
+ || !binding.canonicalColumn.trim()
210
+ || !binding.value.trim()
211
+ || !normalizeAnalyticalExecutionFingerprint(binding.rowFingerprint)
212
+ || !normalizeAnalyticalExecutionFingerprint(binding.resultFingerprint)) {
213
+ return {
214
+ ok: false,
215
+ code: 'RESULT_BINDING_INVALID',
216
+ message: 'The selected result reference is incomplete or malformed.',
217
+ };
218
+ }
219
+ if (!result || binding.resultFingerprint !== result.resultFingerprint) {
220
+ return {
221
+ ok: false,
222
+ code: 'RESULT_BINDING_RESULT_MISMATCH',
223
+ message: 'The selected result is no longer the persisted result for this run.',
224
+ };
225
+ }
226
+ if (!result.columns.includes(binding.canonicalColumn)) {
227
+ return {
228
+ ok: false,
229
+ code: 'RESULT_BINDING_ROW_MISMATCH',
230
+ message: `The selected column ${binding.canonicalColumn} is not present in the persisted result.`,
231
+ };
232
+ }
233
+ const matched = result.rows.some((row) => canonicalResultRowFingerprint(result, row) === binding.rowFingerprint
234
+ && canonicalResultBindingValue(row[binding.canonicalColumn]) === binding.value);
235
+ if (!matched) {
236
+ return {
237
+ ok: false,
238
+ code: 'RESULT_BINDING_ROW_MISMATCH',
239
+ message: 'The selected row/value does not match the persisted result.',
240
+ };
241
+ }
242
+ return { ok: true, binding: { ...binding, resultFingerprint: result.resultFingerprint } };
243
+ }
244
+ /**
245
+ * Derive the one value a `top region -> customers in that region` child may
246
+ * consume. A first row alone is never proof. The parent must either return an
247
+ * explicit rank, or be the server-computed descending ranking task and return
248
+ * at least two rows with one strictly-leading numeric measure. `rowCount` is
249
+ * the returned-row contract, not proof that a singleton is the complete group
250
+ * set. Ties and ambiguous result shapes remain a typed child gap.
251
+ */
252
+ export function resolveTopRankedRegionDependency(sourceTaskId, result, parentTask) {
253
+ if (!result || result.rows.length === 0) {
254
+ return {
255
+ ok: false,
256
+ code: 'RESULT_CONTRACT_MISMATCH',
257
+ message: 'The top-region task did not produce a canonical result that can bind the dependent customer task.',
258
+ };
259
+ }
260
+ const canonicalResultFingerprint = normalizeAnalyticalExecutionFingerprint(result.resultFingerprint);
261
+ const executionReceipt = normalizeAnalyticalExecutionReceipt(result.executionReceipt);
262
+ if (!executionReceipt) {
263
+ return {
264
+ ok: false,
265
+ code: 'RESULT_CONTRACT_MISMATCH',
266
+ message: 'The top-region result did not retain a complete normalized execution receipt, so the dependent customer task was not run.',
267
+ };
268
+ }
269
+ if (!canonicalResultFingerprint
270
+ || result.resultFingerprint !== canonicalResultFingerprint
271
+ || executionReceipt.resultFingerprint !== canonicalResultFingerprint) {
272
+ return {
273
+ ok: false,
274
+ code: 'RESULT_CONTRACT_MISMATCH',
275
+ message: 'The top-region execution receipt does not match the canonical result, so the dependent customer task was not run.',
276
+ };
277
+ }
278
+ const regionColumns = result.columns.filter((column) => /(?:^|_)region(?:_name)?$/i.test(column));
279
+ if (regionColumns.length !== 1) {
280
+ return {
281
+ ok: false,
282
+ code: 'RESULT_CONTRACT_MISMATCH',
283
+ message: 'The top-region result did not contain exactly one canonical region column.',
284
+ };
285
+ }
286
+ const canonicalColumn = regionColumns[0];
287
+ const first = result.rows[0];
288
+ const value = canonicalResultBindingValue(first[canonicalColumn]);
289
+ if (!value) {
290
+ return {
291
+ ok: false,
292
+ code: 'RESULT_CONTRACT_MISMATCH',
293
+ message: 'The leading top-region row did not contain a usable region value.',
294
+ };
295
+ }
296
+ if (!hasUnambiguousTopRow(result, parentTask)) {
297
+ return {
298
+ ok: false,
299
+ code: 'RESULT_CONTRACT_MISMATCH',
300
+ message: 'The top-region result did not prove a single leading region, so the dependent customer task was not run.',
301
+ };
302
+ }
303
+ return {
304
+ ok: true,
305
+ binding: {
306
+ version: 1,
307
+ sourceTaskId,
308
+ sourceResultFingerprint: canonicalResultFingerprint,
309
+ canonicalColumn,
310
+ value,
311
+ rowFingerprint: canonicalResultRowFingerprint(result, first),
312
+ },
313
+ };
314
+ }
315
+ function hasUnambiguousTopRow(result, parentTask) {
316
+ const rankColumn = result.columns.find((column) => /(?:^|_)(?:rank|row_number)$/i.test(column));
317
+ if (rankColumn) {
318
+ const ranks = result.rows.map((row) => numericCell(row[rankColumn]));
319
+ if (ranks[0] === 1 && ranks.slice(1).every((rank) => rank === undefined || rank > 1))
320
+ return true;
321
+ }
322
+ // A plain numerical result column does not say that its first row was ranked.
323
+ // It becomes a ranking proof only when the server's own parent task explicitly
324
+ // asked for a descending ranking AND the returned rows demonstrate a strictly
325
+ // leading value. A singleton needs an explicit rank = 1: it cannot establish
326
+ // that unreturned groups are lower.
327
+ if (parentTask?.kind !== 'ranking' || parentTask.output.order !== 'desc')
328
+ return false;
329
+ if (result.rows.length < 2)
330
+ return false;
331
+ const measures = result.columns.filter((column) => {
332
+ if (column === rankColumn)
333
+ return false;
334
+ const values = result.rows.map((row) => numericCell(row[column]));
335
+ return values.every((value) => value !== undefined);
336
+ });
337
+ if (measures.length !== 1)
338
+ return false;
339
+ const values = result.rows.map((row) => numericCell(row[measures[0]]));
340
+ return values.slice(1).every((value) => values[0] > value);
341
+ }
342
+ function numericCell(value) {
343
+ if (typeof value === 'number' && Number.isFinite(value))
344
+ return value;
345
+ if (typeof value === 'string' && value.trim() && Number.isFinite(Number(value)))
346
+ return Number(value);
347
+ return undefined;
348
+ }
349
+ /**
350
+ * Normalize connector, MetricFlow, and provider result shapes at one boundary.
351
+ * Connectors may return `ColumnMeta[]` and rows as arrays; UI surfaces should
352
+ * never need to guess how to index those rows.
353
+ */
354
+ export function normalizeCanonicalQueryResult(input) {
355
+ const columns = Array.isArray(input.columns)
356
+ ? input.columns.map(columnName)
357
+ : [];
358
+ const rawRows = Array.isArray(input.rows) ? input.rows : [];
359
+ const inferredColumns = columns.length > 0
360
+ ? columns
361
+ : objectRowColumns(rawRows).length > 0
362
+ ? objectRowColumns(rawRows)
363
+ : firstArrayRow(rawRows)
364
+ ? firstArrayRow(rawRows).map((_, index) => `column_${index + 1}`)
365
+ : [];
366
+ const rows = rawRows.map((row) => normalizeRow(row, inferredColumns));
367
+ const rowCount = typeof input.rowCount === 'number' && Number.isFinite(input.rowCount)
368
+ ? Math.max(0, Math.trunc(input.rowCount))
369
+ : rows.length;
370
+ const executionTime = typeof input.executionTimeMs === 'number'
371
+ ? input.executionTimeMs
372
+ : typeof input.executionTime === 'number'
373
+ ? input.executionTime
374
+ : undefined;
375
+ const canonical = {
376
+ version: 1,
377
+ columns: inferredColumns,
378
+ rows,
379
+ rowCount,
380
+ ...(executionTime !== undefined ? { executionTime } : {}),
381
+ ...(input.truncated === true ? { truncated: true } : {}),
382
+ };
383
+ const receipt = input.executionReceipt && typeof input.executionReceipt === 'object'
384
+ ? input.executionReceipt
385
+ : undefined;
386
+ const receiptFingerprint = typeof receipt?.resultFingerprint === 'string' ? receipt.resultFingerprint : undefined;
387
+ const suppliedFingerprint = typeof input.resultFingerprint === 'string' && input.resultFingerprint.trim()
388
+ ? input.resultFingerprint.trim()
389
+ : receiptFingerprint;
390
+ const trustState = input.trustState === 'certified'
391
+ || input.trustState === 'governed'
392
+ || input.trustState === 'review_required'
393
+ || input.trustState === 'not_applicable'
394
+ || input.trustState === 'blocked'
395
+ ? input.trustState
396
+ : undefined;
397
+ return {
398
+ ...canonical,
399
+ ...(receipt ? { executionReceipt: receipt } : {}),
400
+ ...(trustState ? { trustState } : {}),
401
+ ...(typeof input.answerTier === 'string' && input.answerTier.trim()
402
+ ? { answerTier: input.answerTier.trim() }
403
+ : {}),
404
+ // A connector/execution receipt is authoritative. The local digest is only
405
+ // a backwards-compatible fallback for legacy unreceipted rows.
406
+ resultFingerprint: suppliedFingerprint ?? stableFingerprint(canonical),
407
+ };
408
+ }
409
+ export function canonicalResultRows(result) {
410
+ return result.rows.map((row) => result.columns.map((column) => row[column]));
411
+ }
412
+ export function assertCanonicalResult(result) {
413
+ if (result.version !== 1)
414
+ throw new Error('Unsupported analytical result contract version.');
415
+ if (result.rowCount < result.rows.length)
416
+ throw new Error('Result rowCount cannot be smaller than the returned rows.');
417
+ if (new Set(result.columns).size !== result.columns.length)
418
+ throw new Error('Result columns must be unique.');
419
+ for (const row of result.rows) {
420
+ for (const column of result.columns) {
421
+ if (!Object.prototype.hasOwnProperty.call(row, column)) {
422
+ throw new Error(`Result row is missing the declared column ${column}.`);
423
+ }
424
+ }
425
+ }
426
+ }
427
+ /** Reciprocal-rank fusion keeps recall across lexical, vector, and graph lanes. */
428
+ export function fuseContextCandidates(lanes, limit = 32) {
429
+ const safeLimit = Math.max(1, Math.min(100, Math.trunc(limit)));
430
+ const byId = new Map();
431
+ const diagnostics = { lanes: {}, selectedIds: [], truncated: false };
432
+ for (const [lane, cards] of Object.entries(lanes)) {
433
+ diagnostics.lanes[lane] = { returned: cards.length };
434
+ cards.forEach((card, index) => {
435
+ if (!card.id.trim())
436
+ return;
437
+ const score = 1 / (60 + index + 1) + Math.max(0, Math.min(1, card.relevance)) * 0.25;
438
+ const existing = byId.get(card.id);
439
+ if (existing) {
440
+ existing.score += score;
441
+ existing.lanes.add(lane);
442
+ if ((card.relevance ?? 0) > existing.relevance)
443
+ existing.relevance = card.relevance;
444
+ if (card.compatible === true)
445
+ existing.compatible = true;
446
+ if (!existing.summary && card.summary)
447
+ existing.summary = card.summary;
448
+ }
449
+ else {
450
+ byId.set(card.id, { ...card, score, lanes: new Set([lane]) });
451
+ }
452
+ });
453
+ }
454
+ const selected = [...byId.values()]
455
+ .sort((left, right) => right.score - left.score || right.relevance - left.relevance || left.id.localeCompare(right.id))
456
+ .slice(0, safeLimit)
457
+ .map(({ score: _score, lanes: _lanes, ...card }) => card);
458
+ diagnostics.selectedIds = selected.map((card) => card.id);
459
+ diagnostics.truncated = byId.size > selected.length;
460
+ return { candidates: selected, diagnostics };
461
+ }
462
+ export async function retrieveContextLanes(lanes, limit = 32, maxConcurrent = 4) {
463
+ const entries = Object.entries(lanes);
464
+ const concurrency = Math.max(1, Math.min(8, Math.trunc(maxConcurrent) || 1));
465
+ const settled = [];
466
+ let nextIndex = 0;
467
+ const worker = async () => {
468
+ for (;;) {
469
+ const index = nextIndex;
470
+ nextIndex += 1;
471
+ const entry = entries[index];
472
+ if (!entry)
473
+ return;
474
+ const [name, retrieve] = entry;
475
+ const startedAt = Date.now();
476
+ try {
477
+ const cards = await retrieve();
478
+ settled[index] = [name, cards, Date.now() - startedAt];
479
+ }
480
+ catch (error) {
481
+ settled[index] = [name, { error: error instanceof Error ? error.message : String(error) }, Date.now() - startedAt];
482
+ }
483
+ }
484
+ };
485
+ await Promise.all(Array.from({ length: Math.min(concurrency, entries.length) }, () => worker()));
486
+ const successful = {};
487
+ const errors = {};
488
+ const durations = {};
489
+ for (const [name, result, durationMs] of settled) {
490
+ durations[name] = durationMs;
491
+ if (Array.isArray(result))
492
+ successful[name] = result;
493
+ else
494
+ errors[name] = result.error;
495
+ }
496
+ const fused = fuseContextCandidates(successful, limit);
497
+ for (const [name, cards] of Object.entries(successful)) {
498
+ fused.diagnostics.lanes[name] = {
499
+ returned: cards.length,
500
+ durationMs: durations[name],
501
+ status: cards.length > 0 ? 'ok' : 'empty',
502
+ };
503
+ }
504
+ for (const [name, error] of Object.entries(errors)) {
505
+ fused.diagnostics.lanes[name] = {
506
+ returned: 0,
507
+ durationMs: durations[name],
508
+ status: 'error',
509
+ error,
510
+ };
511
+ }
512
+ return fused;
513
+ }
514
+ export function capResearchBranches(branches, max = 6) {
515
+ return branches.slice(0, Math.max(1, Math.min(6, Math.trunc(max))));
516
+ }
517
+ export function buildResearchEvidenceLedger(input) {
518
+ const entries = input.entries.slice(0, 6).map((entry) => {
519
+ const resultFingerprint = normalizeAnalyticalExecutionFingerprint(entry.resultFingerprint);
520
+ const executionReceipt = normalizeAnalyticalExecutionReceipt(entry.executionReceipt);
521
+ const receiptFingerprint = executionReceipt?.resultFingerprint;
522
+ const listedFingerprint = entry.receipts
523
+ .map((receipt) => normalizeAnalyticalExecutionFingerprint(receipt))
524
+ .find((receipt) => Boolean(receipt));
525
+ const executionProof = resultFingerprint ?? receiptFingerprint ?? listedFingerprint;
526
+ // A receipt/result proof is meaningful only for an observed branch. Never
527
+ // carry a preloaded receipt, child ID, context-pack ID, or malformed
528
+ // fingerprint through a failed/cancelled/skipped entry.
529
+ if (entry.status !== 'observed') {
530
+ const { executionReceipt: _receipt, resultFingerprint: _fingerprint, ...withoutProof } = entry;
531
+ return { ...withoutProof, receipts: [] };
532
+ }
533
+ // A ready/observed branch without a complete receipt or canonical result
534
+ // fingerprint is not an observation. Downgrade it and retain no invented
535
+ // proof; callers can still inspect the branch and retry it explicitly.
536
+ if (!executionProof) {
537
+ const { executionReceipt: _receipt, resultFingerprint: _fingerprint, ...withoutProof } = entry;
538
+ return {
539
+ ...withoutProof,
540
+ status: 'failed',
541
+ receipts: [],
542
+ error: entry.error ?? 'Research branch had no valid execution receipt or canonical result fingerprint.',
543
+ };
544
+ }
545
+ return {
546
+ ...entry,
547
+ status: 'observed',
548
+ resultFingerprint: executionProof,
549
+ ...(executionReceipt ? { executionReceipt } : {}),
550
+ receipts: [executionProof],
551
+ };
552
+ });
553
+ return {
554
+ version: 1,
555
+ rootQuestion: input.rootQuestion,
556
+ ...(input.planId ? { planId: input.planId } : {}),
557
+ ...(input.snapshotId ? { snapshotId: input.snapshotId } : {}),
558
+ entries,
559
+ factIds: [...new Set(entries.flatMap((entry) => entry.facts))],
560
+ stoppingReason: input.stoppingReason ?? (entries.length > 0 ? 'completed' : 'not_started'),
561
+ };
562
+ }
563
+ /** The only accepted host-side execution identity is a SHA-256 fingerprint. */
564
+ export function normalizeAnalyticalExecutionFingerprint(value) {
565
+ return typeof value === 'string' && /^[a-f0-9]{64}$/i.test(value.trim())
566
+ ? value.trim().toLowerCase()
567
+ : undefined;
568
+ }
569
+ /**
570
+ * Normalize a complete DQL execution receipt. A partial object or arbitrary
571
+ * identifier is deliberately not execution evidence.
572
+ */
573
+ export function normalizeAnalyticalExecutionReceipt(value) {
574
+ if (!value || typeof value !== 'object' || Array.isArray(value))
575
+ return undefined;
576
+ const record = value;
577
+ const sourceFingerprint = normalizeAnalyticalExecutionFingerprint(record.sourceFingerprint);
578
+ const compiledSqlFingerprint = normalizeAnalyticalExecutionFingerprint(record.compiledSqlFingerprint);
579
+ const parameterFingerprint = normalizeAnalyticalExecutionFingerprint(record.parameterFingerprint);
580
+ const resultFingerprint = normalizeAnalyticalExecutionFingerprint(record.resultFingerprint);
581
+ return sourceFingerprint && compiledSqlFingerprint && parameterFingerprint && resultFingerprint
582
+ ? { sourceFingerprint, compiledSqlFingerprint, parameterFingerprint, resultFingerprint }
583
+ : undefined;
584
+ }
585
+ export function buildCoverageGap(input) {
586
+ return { version: 1, ...input };
587
+ }
588
+ function columnName(value) {
589
+ if (typeof value === 'string')
590
+ return value;
591
+ if (value && typeof value === 'object' && typeof value.name === 'string') {
592
+ return String(value.name);
593
+ }
594
+ return String(value ?? 'column');
595
+ }
596
+ function objectRowColumns(rows) {
597
+ const columns = new Set();
598
+ for (const row of rows) {
599
+ if (!row || typeof row !== 'object' || Array.isArray(row))
600
+ continue;
601
+ for (const column of Object.keys(row))
602
+ columns.add(column);
603
+ }
604
+ return [...columns];
605
+ }
606
+ function firstArrayRow(rows) {
607
+ const row = rows.find((candidate) => Array.isArray(candidate));
608
+ return row;
609
+ }
610
+ function normalizeRow(row, columns) {
611
+ if (Array.isArray(row))
612
+ return Object.fromEntries(columns.map((column, index) => [column, row[index]]));
613
+ if (row && typeof row === 'object') {
614
+ const record = row;
615
+ return Object.fromEntries(columns.map((column) => [column, record[column]]));
616
+ }
617
+ return Object.fromEntries(columns.map((column) => [column, undefined]));
618
+ }
619
+ function stableFingerprint(value) {
620
+ const text = stableStringify(value);
621
+ return createHash('sha256').update(text).digest('hex');
622
+ }
623
+ function stableStringify(value) {
624
+ if (value === null || typeof value !== 'object')
625
+ return JSON.stringify(value);
626
+ if (Array.isArray(value))
627
+ return `[${value.map(stableStringify).join(',')}]`;
628
+ const record = value;
629
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`).join(',')}}`;
630
+ }
631
+ //# sourceMappingURL=analytical-orchestration.js.map