@adonis-agora/agent 0.35.0 → 0.37.0

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 (74) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/NOTICE +31 -0
  3. package/README.md +5 -5
  4. package/dist/configure.d.ts.map +1 -1
  5. package/dist/configure.js +1 -0
  6. package/dist/configure.js.map +1 -1
  7. package/dist/src/index.d.ts +1 -1
  8. package/dist/src/index.js +1 -1
  9. package/dist/src/rag/index.d.ts +3 -1
  10. package/dist/src/rag/index.d.ts.map +1 -1
  11. package/dist/src/rag/index.js +3 -1
  12. package/dist/src/rag/index.js.map +1 -1
  13. package/dist/src/rag/lexical-query.d.ts +28 -0
  14. package/dist/src/rag/lexical-query.d.ts.map +1 -0
  15. package/dist/src/rag/lexical-query.js +90 -0
  16. package/dist/src/rag/lexical-query.js.map +1 -0
  17. package/dist/src/rag/openai-embeddings.d.ts +20 -2
  18. package/dist/src/rag/openai-embeddings.d.ts.map +1 -1
  19. package/dist/src/rag/openai-embeddings.js +107 -42
  20. package/dist/src/rag/openai-embeddings.js.map +1 -1
  21. package/dist/src/rag/pg-vector-store.d.ts +56 -7
  22. package/dist/src/rag/pg-vector-store.d.ts.map +1 -1
  23. package/dist/src/rag/pg-vector-store.js +65 -17
  24. package/dist/src/rag/pg-vector-store.js.map +1 -1
  25. package/dist/src/rag/tree/build.d.ts +96 -0
  26. package/dist/src/rag/tree/build.d.ts.map +1 -0
  27. package/dist/src/rag/tree/build.js +659 -0
  28. package/dist/src/rag/tree/build.js.map +1 -0
  29. package/dist/src/rag/tree/headings.d.ts +29 -0
  30. package/dist/src/rag/tree/headings.d.ts.map +1 -0
  31. package/dist/src/rag/tree/headings.js +227 -0
  32. package/dist/src/rag/tree/headings.js.map +1 -0
  33. package/dist/src/rag/tree/index-document.d.ts +33 -0
  34. package/dist/src/rag/tree/index-document.d.ts.map +1 -0
  35. package/dist/src/rag/tree/index-document.js +36 -0
  36. package/dist/src/rag/tree/index-document.js.map +1 -0
  37. package/dist/src/rag/tree/index.d.ts +13 -0
  38. package/dist/src/rag/tree/index.d.ts.map +1 -0
  39. package/dist/src/rag/tree/index.js +12 -0
  40. package/dist/src/rag/tree/index.js.map +1 -0
  41. package/dist/src/rag/tree/keyword-tree-llm.d.ts +15 -0
  42. package/dist/src/rag/tree/keyword-tree-llm.d.ts.map +1 -0
  43. package/dist/src/rag/tree/keyword-tree-llm.js +105 -0
  44. package/dist/src/rag/tree/keyword-tree-llm.js.map +1 -0
  45. package/dist/src/rag/tree/llm.d.ts +179 -0
  46. package/dist/src/rag/tree/llm.d.ts.map +1 -0
  47. package/dist/src/rag/tree/llm.js +264 -0
  48. package/dist/src/rag/tree/llm.js.map +1 -0
  49. package/dist/src/rag/tree/navigate-tool.d.ts +58 -0
  50. package/dist/src/rag/tree/navigate-tool.d.ts.map +1 -0
  51. package/dist/src/rag/tree/navigate-tool.js +95 -0
  52. package/dist/src/rag/tree/navigate-tool.js.map +1 -0
  53. package/dist/src/rag/tree/navigate.d.ts +137 -0
  54. package/dist/src/rag/tree/navigate.d.ts.map +1 -0
  55. package/dist/src/rag/tree/navigate.js +404 -0
  56. package/dist/src/rag/tree/navigate.js.map +1 -0
  57. package/dist/src/rag/tree/pg-tree-store.d.ts +45 -0
  58. package/dist/src/rag/tree/pg-tree-store.d.ts.map +1 -0
  59. package/dist/src/rag/tree/pg-tree-store.js +205 -0
  60. package/dist/src/rag/tree/pg-tree-store.js.map +1 -0
  61. package/dist/src/rag/tree/store.d.ts +57 -0
  62. package/dist/src/rag/tree/store.d.ts.map +1 -0
  63. package/dist/src/rag/tree/store.js +66 -0
  64. package/dist/src/rag/tree/store.js.map +1 -0
  65. package/dist/src/rag/tree/two-stage.d.ts +54 -0
  66. package/dist/src/rag/tree/two-stage.d.ts.map +1 -0
  67. package/dist/src/rag/tree/two-stage.js +92 -0
  68. package/dist/src/rag/tree/two-stage.js.map +1 -0
  69. package/dist/src/rag/tree/types.d.ts +135 -0
  70. package/dist/src/rag/tree/types.d.ts.map +1 -0
  71. package/dist/src/rag/tree/types.js +21 -0
  72. package/dist/src/rag/tree/types.js.map +1 -0
  73. package/dist/stubs/database/migrations/create_agent_rag_trees.stub +40 -0
  74. package/package.json +3 -2
@@ -0,0 +1,137 @@
1
+ import type { Passage, RetrieveOptions, Retriever } from '../../spi/retriever.js';
2
+ import { type TreeBudget, type TreeLlm } from './llm.js';
3
+ import type { DocumentTreeStore } from './store.js';
4
+ export interface TreeNavigationRetrieverOptions {
5
+ store: DocumentTreeStore;
6
+ llm: TreeLlm;
7
+ /**
8
+ * A tree whose outline (titles, pages, summaries) fits in this many characters is navigated in
9
+ * **one** call that sees the whole outline — PageIndex's tree search, the variant measured in the
10
+ * benchmark. Bigger trees are walked level by level (a beam). Default 40 000 (~10k tokens).
11
+ */
12
+ singlePassMaxChars?: number;
13
+ /** Nodes the navigator may expand or read per beam step. Default 4. */
14
+ beamWidth?: number;
15
+ /** Beam levels, at most. Nodes still marked "expand" at the last level are read whole. Default 4. */
16
+ maxSteps?: number;
17
+ /** Nodes returned per document, at most. Default 5. */
18
+ maxNodes?: number;
19
+ /**
20
+ * Hard per-document limits for one navigation. Defaults: 6 calls, 60k input tokens, 4k output
21
+ * tokens, 60 s. Running out mid-walk returns what was chosen so far (the nodes last marked for
22
+ * expansion are read whole) and records `stoppedBy: 'budget'`.
23
+ */
24
+ budget?: TreeBudget;
25
+ /** Characters of text per returned node. Default 12 000. */
26
+ maxPassageChars?: number;
27
+ /** Units (pages/sections) read per returned node, at most. Default 25. */
28
+ maxUnitsPerNode?: number;
29
+ /** Characters across all passages of one navigation (every document). Default 48 000 (~12k tokens). */
30
+ maxContextChars?: number;
31
+ /**
32
+ * {@link TreeNavigationRetriever.retrieve} with no first stage: documents navigated per query. When
33
+ * more trees pass the filter, the LLM picks this many from their titles and descriptions
34
+ * (PageIndex's document selection). Default 3.
35
+ */
36
+ maxDocuments?: number;
37
+ /** Trees shown to document selection, at most. Default 200. */
38
+ maxSelectionCandidates?: number;
39
+ /** Documents navigated in parallel. Default 3. */
40
+ concurrency?: number;
41
+ }
42
+ /** One step of a navigation, for the audit trail. */
43
+ export interface NavigationStep {
44
+ step: number;
45
+ /** Node ids shown to the LLM this step. */
46
+ shown: string[];
47
+ /** Node ids it chose to open further. */
48
+ expanded: string[];
49
+ /** Node ids it chose to read. */
50
+ read: string[];
51
+ /** The LLM's stated reasoning, verbatim (capped). */
52
+ reasoning?: string;
53
+ }
54
+ /** A node navigation chose, with the path that led to it. */
55
+ export interface NavigatedNode {
56
+ nodeId: string;
57
+ title: string;
58
+ /** Ancestors from the top level down, then the node itself. */
59
+ path: {
60
+ id: string;
61
+ title: string;
62
+ }[];
63
+ pageStart?: number;
64
+ pageEnd?: number;
65
+ unitStart: number;
66
+ unitEnd: number;
67
+ }
68
+ /** The auditable record of navigating one document. */
69
+ export interface DocumentNavigation {
70
+ documentId: string;
71
+ title?: string;
72
+ mode: 'single-pass' | 'beam';
73
+ steps: NavigationStep[];
74
+ nodes: NavigatedNode[];
75
+ llmCalls: number;
76
+ inputTokens: number;
77
+ outputTokens: number;
78
+ /** Why the walk stopped early, when it did. */
79
+ stoppedBy?: 'budget' | 'timeout' | 'maxSteps' | 'error' | 'not-found';
80
+ error?: string;
81
+ }
82
+ export interface NavigationResult {
83
+ passages: Passage[];
84
+ documents: DocumentNavigation[];
85
+ /** Set when {@link TreeNavigationRetriever.retrieve} had the LLM pick the documents. */
86
+ selection?: {
87
+ candidates: number;
88
+ selected: string[];
89
+ reasoning?: string;
90
+ error?: string;
91
+ };
92
+ }
93
+ export interface NavigateOptions {
94
+ /** Access filter applied to every tree read (vector-store semantics). */
95
+ filter?: Record<string, unknown>;
96
+ /** Overrides the retriever's per-document budget. */
97
+ budget?: TreeBudget;
98
+ signal?: AbortSignal;
99
+ }
100
+ /**
101
+ * Tree navigation retrieval ("vectorless", reasoning-based — PageIndex's method): an LLM reads a
102
+ * document's table of contents (titles, page ranges, summaries — no body text) and picks the
103
+ * sections that answer the question; their text comes back as passages, with the path taken and the
104
+ * model's reasoning recorded so the choice is auditable.
105
+ *
106
+ * A small tree is navigated in one call over the whole outline. A large one is walked level by
107
+ * level: the model sees one level of candidates, opens (`expand`) the promising ones and takes
108
+ * (`read`) the ones that already answer, until it reaches leaves, runs out of `maxSteps`, or runs
109
+ * out of its hard per-document {@link TreeBudget} — in which case it returns what it had.
110
+ *
111
+ * It pays off on **long structured documents** (regulations, contracts, filings, manuals) where
112
+ * chunk ranking struggles among hundreds of look-alike passages; on short notes it costs seconds and
113
+ * LLM spend for nothing. Compose it behind a first stage with {@link TwoStageRetriever}, or give it
114
+ * to the agent as a tool with {@link createNavigateDocumentTool}.
115
+ *
116
+ * As a plain `Retriever`, `retrieve(query, { filter })` navigates the trees that pass `filter`:
117
+ * all of them when there are at most `maxDocuments`, otherwise the ones the LLM picks from their
118
+ * descriptions.
119
+ */
120
+ export declare class TreeNavigationRetriever implements Retriever {
121
+ private readonly options;
122
+ readonly store: DocumentTreeStore;
123
+ private readonly llm;
124
+ constructor(options: TreeNavigationRetrieverOptions);
125
+ retrieve(query: string, options?: RetrieveOptions): Promise<Passage[]>;
126
+ /** {@link retrieve} with the audit trail: which documents, which nodes, why. */
127
+ search(query: string, options?: NavigateOptions): Promise<NavigationResult>;
128
+ /**
129
+ * Navigate the given documents (in parallel, up to `concurrency`) and return their passages in
130
+ * the order given, within `maxContextChars`. Documents without a tree, or whose tree fails
131
+ * `filter`, yield no passages and `stoppedBy: 'not-found'`.
132
+ */
133
+ navigate(query: string, documentIds: readonly string[], options?: NavigateOptions): Promise<NavigationResult>;
134
+ private walk;
135
+ private passagesOf;
136
+ }
137
+ //# sourceMappingURL=navigate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../../../../src/rag/tree/navigate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,404 @@
1
+ import { mapLimit } from './build.js';
2
+ import { BudgetedLlm, parseJsonReply, stringList, TreeBudgetExceededError, } from './llm.js';
3
+ import { indexTree, walkTree } from './types.js';
4
+ const NAVIGATE_SYSTEM = 'You navigate the table of contents of a document to find where a question is answered. You answer with JSON only.';
5
+ const DEFAULT_BUDGET = {
6
+ maxCalls: 6,
7
+ maxInputTokens: 60_000,
8
+ maxOutputTokens: 4_000,
9
+ timeoutMs: 60_000,
10
+ };
11
+ function pages(node) {
12
+ if (node.pageStart === undefined) {
13
+ return undefined;
14
+ }
15
+ return node.pageEnd === undefined || node.pageEnd === node.pageStart
16
+ ? `p. ${node.pageStart}`
17
+ : `pp. ${node.pageStart}-${node.pageEnd}`;
18
+ }
19
+ function candidate(node, summaryChars, depth) {
20
+ const shownPages = pages(node);
21
+ let summary = node.summary;
22
+ if (summary !== undefined && summary.length > summaryChars) {
23
+ summary = `${summary.slice(0, Math.max(0, summaryChars - 1))}…`;
24
+ }
25
+ if (node.keyItems !== undefined && node.keyItems.length > 0 && summaryChars > 0) {
26
+ summary = `${summary ?? ''}${summary ? ' ' : ''}Includes: ${node.keyItems.slice(0, 12).join('; ')}`;
27
+ }
28
+ return {
29
+ id: node.id,
30
+ title: node.title,
31
+ ...(summary && summaryChars > 0 ? { summary } : {}),
32
+ ...(shownPages !== undefined ? { pages: shownPages } : {}),
33
+ ...(depth !== undefined ? { depth } : { hasChildren: node.children.length > 0 }),
34
+ };
35
+ }
36
+ function render(candidates) {
37
+ return candidates
38
+ .map((entry) => {
39
+ const indent = ' '.repeat(entry.depth ?? 0);
40
+ const meta = [entry.pages, entry.hasChildren ? 'has subsections' : undefined]
41
+ .filter(Boolean)
42
+ .join(', ');
43
+ return `${indent}[${entry.id}] ${entry.title}${meta ? ` (${meta})` : ''}${entry.summary ? ` — ${entry.summary}` : ''}`;
44
+ })
45
+ .join('\n');
46
+ }
47
+ /** Candidates rendered within `maxChars`: full summaries, then shorter, then titles only. */
48
+ function fitCandidates(nodes, maxChars) {
49
+ let last;
50
+ for (const summaryChars of [400, 160, 0]) {
51
+ const candidates = nodes.map(({ node, depth }) => candidate(node, summaryChars, depth));
52
+ const text = render(candidates);
53
+ last = { candidates, text };
54
+ if (text.length <= maxChars) {
55
+ break;
56
+ }
57
+ }
58
+ return last;
59
+ }
60
+ /**
61
+ * Tree navigation retrieval ("vectorless", reasoning-based — PageIndex's method): an LLM reads a
62
+ * document's table of contents (titles, page ranges, summaries — no body text) and picks the
63
+ * sections that answer the question; their text comes back as passages, with the path taken and the
64
+ * model's reasoning recorded so the choice is auditable.
65
+ *
66
+ * A small tree is navigated in one call over the whole outline. A large one is walked level by
67
+ * level: the model sees one level of candidates, opens (`expand`) the promising ones and takes
68
+ * (`read`) the ones that already answer, until it reaches leaves, runs out of `maxSteps`, or runs
69
+ * out of its hard per-document {@link TreeBudget} — in which case it returns what it had.
70
+ *
71
+ * It pays off on **long structured documents** (regulations, contracts, filings, manuals) where
72
+ * chunk ranking struggles among hundreds of look-alike passages; on short notes it costs seconds and
73
+ * LLM spend for nothing. Compose it behind a first stage with {@link TwoStageRetriever}, or give it
74
+ * to the agent as a tool with {@link createNavigateDocumentTool}.
75
+ *
76
+ * As a plain `Retriever`, `retrieve(query, { filter })` navigates the trees that pass `filter`:
77
+ * all of them when there are at most `maxDocuments`, otherwise the ones the LLM picks from their
78
+ * descriptions.
79
+ */
80
+ export class TreeNavigationRetriever {
81
+ options;
82
+ store;
83
+ llm;
84
+ constructor(options) {
85
+ this.options = options;
86
+ this.store = options.store;
87
+ this.llm = options.llm;
88
+ }
89
+ async retrieve(query, options = {}) {
90
+ const result = await this.search(query, options.filter !== undefined ? { filter: options.filter } : {});
91
+ return result.passages.slice(0, options.topK ?? result.passages.length);
92
+ }
93
+ /** {@link retrieve} with the audit trail: which documents, which nodes, why. */
94
+ async search(query, options = {}) {
95
+ const maxDocuments = Math.max(1, this.options.maxDocuments ?? 3);
96
+ const maxCandidates = Math.max(maxDocuments, this.options.maxSelectionCandidates ?? 200);
97
+ const headers = await this.store.list({
98
+ ...(options.filter !== undefined ? { filter: options.filter } : {}),
99
+ limit: maxCandidates,
100
+ });
101
+ if (headers.length <= maxDocuments) {
102
+ return this.navigate(query, headers.map((header) => header.documentId), options);
103
+ }
104
+ const budget = new BudgetedLlm(this.llm, { ...DEFAULT_BUDGET, ...this.options.budget, ...options.budget }, options.signal);
105
+ const documents = headers.map((header) => ({
106
+ id: header.documentId,
107
+ ...(header.title !== undefined ? { title: header.title } : {}),
108
+ ...(header.description !== undefined
109
+ ? { description: header.description.slice(0, 600) }
110
+ : {}),
111
+ }));
112
+ const prompt = `Select the documents that may contain the answer to the question, most relevant first, at most ${maxDocuments}.
113
+
114
+ Question: ${query}
115
+
116
+ Documents:
117
+ ${documents.map((document) => `[${document.id}] ${document.title ?? ''}${document.description ? ` — ${document.description}` : ''}`).join('\n')}
118
+
119
+ Reply with JSON only: {"thinking": "<why>", "documents": ["<document id>", ...]} — an empty list if none is relevant.`;
120
+ const known = new Set(documents.map((document) => document.id));
121
+ try {
122
+ const reply = parseJsonReply(await budget.call({ kind: 'select', query, documents, maxDocuments }, NAVIGATE_SYSTEM, prompt, 800));
123
+ const selected = [
124
+ ...new Set(stringList(reply?.documents ?? reply?.answer).filter((id) => known.has(id))),
125
+ ].slice(0, maxDocuments);
126
+ const result = await this.navigate(query, selected, options);
127
+ const reasoning = typeof reply?.thinking === 'string' ? reply.thinking.slice(0, 2_000) : undefined;
128
+ return {
129
+ ...result,
130
+ selection: {
131
+ candidates: documents.length,
132
+ selected,
133
+ ...(reasoning !== undefined ? { reasoning } : {}),
134
+ },
135
+ };
136
+ }
137
+ catch (error) {
138
+ return {
139
+ passages: [],
140
+ documents: [],
141
+ selection: { candidates: documents.length, selected: [], error: error.message },
142
+ };
143
+ }
144
+ }
145
+ /**
146
+ * Navigate the given documents (in parallel, up to `concurrency`) and return their passages in
147
+ * the order given, within `maxContextChars`. Documents without a tree, or whose tree fails
148
+ * `filter`, yield no passages and `stoppedBy: 'not-found'`.
149
+ */
150
+ async navigate(query, documentIds, options = {}) {
151
+ const ids = [...new Set(documentIds)];
152
+ const trees = new Map((await this.store.getMany(ids, options.filter)).map((tree) => [tree.documentId, tree]));
153
+ const navigations = await mapLimit(ids, Math.max(1, this.options.concurrency ?? 3), async (id) => {
154
+ const tree = trees.get(id);
155
+ if (tree === undefined) {
156
+ return {
157
+ navigation: {
158
+ documentId: id,
159
+ mode: 'single-pass',
160
+ steps: [],
161
+ nodes: [],
162
+ llmCalls: 0,
163
+ inputTokens: 0,
164
+ outputTokens: 0,
165
+ stoppedBy: 'not-found',
166
+ },
167
+ passages: [],
168
+ };
169
+ }
170
+ const navigation = await this.walk(query, tree, options);
171
+ return { navigation, passages: await this.passagesOf(tree, navigation) };
172
+ });
173
+ // Share the context budget across documents in the order given.
174
+ const maxContextChars = this.options.maxContextChars ?? 48_000;
175
+ let used = 0;
176
+ const passages = [];
177
+ for (const entry of navigations) {
178
+ for (const passage of entry.passages) {
179
+ if (used >= maxContextChars) {
180
+ break;
181
+ }
182
+ const text = passage.text.slice(0, maxContextChars - used);
183
+ used += text.length;
184
+ passages.push({ ...passage, text });
185
+ }
186
+ }
187
+ return { passages, documents: navigations.map((entry) => entry.navigation) };
188
+ }
189
+ async walk(query, tree, options) {
190
+ const budget = new BudgetedLlm(this.llm, { ...DEFAULT_BUDGET, ...this.options.budget, ...options.budget }, options.signal);
191
+ const maxNodes = Math.max(1, this.options.maxNodes ?? 5);
192
+ const singlePassMaxChars = this.options.singlePassMaxChars ?? 40_000;
193
+ const index = indexTree(tree);
194
+ const whole = [...walkTree(tree.nodes)].map(({ node, path }) => ({ node, depth: path.length }));
195
+ const outline = fitCandidates(whole, Number.POSITIVE_INFINITY);
196
+ const title = tree.title ?? tree.source ?? tree.documentId;
197
+ const steps = [];
198
+ const chosen = [];
199
+ let stoppedBy;
200
+ let error;
201
+ const mode = outline.text.length <= singlePassMaxChars ? 'single-pass' : 'beam';
202
+ const stop = (caught) => {
203
+ if (caught instanceof TreeBudgetExceededError) {
204
+ stoppedBy = caught.limit === 'timeout' ? 'timeout' : 'budget';
205
+ }
206
+ else {
207
+ stoppedBy = 'error';
208
+ }
209
+ error = caught.message;
210
+ };
211
+ if (mode === 'single-pass') {
212
+ const prompt = `Find the sections of the document that are likely to contain the answer to the question. Prefer the most specific (deepest) sections; list at most ${maxNodes}, most relevant first.
213
+
214
+ Question: ${query}
215
+
216
+ Document: ${title}${tree.description ? `\nAbout: ${tree.description}` : ''}
217
+ Table of contents ([id] title (pages) — summary):
218
+ ${outline.text}
219
+
220
+ Reply with JSON only: {"thinking": "<which sections answer and why>", "read": ["<id>", ...]} — an empty list if none does.`;
221
+ try {
222
+ const reply = requireJson(await budget.call({ kind: 'navigate', query, mode, candidates: outline.candidates, maxNodes }, NAVIGATE_SYSTEM, prompt, 1_500));
223
+ const read = [...new Set(stringList(reply?.read ?? reply?.node_list ?? reply?.nodes))]
224
+ .map((id) => resolveId(index, id))
225
+ .filter((id) => id !== undefined)
226
+ .slice(0, maxNodes);
227
+ chosen.push(...read);
228
+ steps.push({
229
+ step: 1,
230
+ shown: outline.candidates.map((entry) => entry.id),
231
+ expanded: [],
232
+ read,
233
+ ...reasoningOf(reply),
234
+ });
235
+ }
236
+ catch (caught) {
237
+ stop(caught);
238
+ }
239
+ }
240
+ else {
241
+ const beamWidth = Math.max(1, this.options.beamWidth ?? 4);
242
+ const maxSteps = Math.max(1, this.options.maxSteps ?? 4);
243
+ let frontier = tree.nodes;
244
+ let pendingExpand = [];
245
+ for (let step = 1; frontier.length > 0 && chosen.length < maxNodes; step++) {
246
+ if (step > maxSteps) {
247
+ stoppedBy = 'maxSteps';
248
+ break;
249
+ }
250
+ const shown = fitCandidates(frontier.map((node) => ({ node })), singlePassMaxChars);
251
+ const path = index.get(frontier[0]?.id ?? '')?.path ?? [];
252
+ const where = path.length > 0 ? `\nYou are inside: ${path.map((node) => node.title).join(' > ')}` : '';
253
+ const prompt = `Find where the question is answered in the document by walking its table of contents.
254
+ For each relevant section below, either "expand" it (open its subsections, only for sections that have subsections) or "read" it (its text answers the question). Choose at most ${beamWidth} in total, most relevant first; choose none if nothing here is relevant.
255
+
256
+ Question: ${query}
257
+
258
+ Document: ${title}${tree.description ? `\nAbout: ${tree.description}` : ''}${where}
259
+ Sections ([id] title (pages) — summary):
260
+ ${shown.text}
261
+
262
+ Reply with JSON only: {"thinking": "<why>", "expand": ["<id>", ...], "read": ["<id>", ...]}`;
263
+ let reply;
264
+ try {
265
+ reply = requireJson(await budget.call({ kind: 'navigate', query, mode, candidates: shown.candidates, maxNodes: beamWidth }, NAVIGATE_SYSTEM, prompt, 1_200));
266
+ }
267
+ catch (caught) {
268
+ stop(caught);
269
+ break;
270
+ }
271
+ const onFrontier = new Set(frontier.map((node) => node.id));
272
+ const pick = (value) => [...new Set(stringList(value))]
273
+ .map((id) => resolveId(index, id))
274
+ .filter((id) => id !== undefined && onFrontier.has(id));
275
+ let expand = pick(reply?.expand);
276
+ let read = pick(reply?.read);
277
+ // A leaf cannot be expanded: reading it is what was meant.
278
+ read = [
279
+ ...read,
280
+ ...expand.filter((id) => (index.get(id)?.node.children.length ?? 0) === 0),
281
+ ];
282
+ expand = expand.filter((id) => (index.get(id)?.node.children.length ?? 0) > 0);
283
+ const limited = [...expand, ...read].slice(0, beamWidth);
284
+ expand = expand.filter((id) => limited.includes(id));
285
+ read = [...new Set(read.filter((id) => limited.includes(id)))];
286
+ steps.push({
287
+ step,
288
+ shown: shown.candidates.map((entry) => entry.id),
289
+ expanded: expand,
290
+ read,
291
+ ...reasoningOf(reply),
292
+ });
293
+ chosen.push(...read);
294
+ pendingExpand = expand;
295
+ frontier = expand.flatMap((id) => index.get(id)?.node.children ?? []);
296
+ if (frontier.length === 0) {
297
+ pendingExpand = [];
298
+ }
299
+ }
300
+ // Anything still marked for expansion when the walk stopped is read whole.
301
+ if (stoppedBy !== undefined) {
302
+ chosen.push(...pendingExpand);
303
+ }
304
+ }
305
+ // A section chosen together with one of its own subsections adds nothing but length: the
306
+ // more specific choice wins.
307
+ const unique = [...new Set(chosen)];
308
+ const specific = unique.filter((id) => !unique.some((other) => other !== id && index.get(other)?.path.some((node) => node.id === id)));
309
+ const nodes = specific.slice(0, maxNodes).flatMap((id) => {
310
+ const entry = index.get(id);
311
+ if (entry === undefined) {
312
+ return [];
313
+ }
314
+ const { node, path } = entry;
315
+ return [
316
+ {
317
+ nodeId: node.id,
318
+ title: node.title,
319
+ path: [...path, node].map((step) => ({ id: step.id, title: step.title })),
320
+ ...(node.pageStart !== undefined ? { pageStart: node.pageStart } : {}),
321
+ ...(node.pageEnd !== undefined ? { pageEnd: node.pageEnd } : {}),
322
+ unitStart: node.unitStart,
323
+ unitEnd: node.unitEnd,
324
+ },
325
+ ];
326
+ });
327
+ return {
328
+ documentId: tree.documentId,
329
+ ...(tree.title !== undefined ? { title: tree.title } : {}),
330
+ mode,
331
+ steps,
332
+ nodes,
333
+ llmCalls: budget.calls,
334
+ inputTokens: budget.inputTokens,
335
+ outputTokens: budget.outputTokens,
336
+ ...(stoppedBy !== undefined ? { stoppedBy } : {}),
337
+ ...(error !== undefined ? { error } : {}),
338
+ };
339
+ }
340
+ async passagesOf(tree, navigation) {
341
+ const maxPassageChars = this.options.maxPassageChars ?? 12_000;
342
+ const maxUnits = Math.max(1, this.options.maxUnitsPerNode ?? 25);
343
+ const reasoning = navigation.steps
344
+ .map((step) => step.reasoning)
345
+ .filter((text) => text !== undefined)
346
+ .join('\n');
347
+ const passages = [];
348
+ for (const [rank, node] of navigation.nodes.entries()) {
349
+ const units = await this.store.readUnits(tree.documentId, node.unitStart, Math.min(node.unitEnd, node.unitStart + maxUnits - 1));
350
+ let text = units.map((unit) => unit.text).join('\n\n');
351
+ if (text.length > maxPassageChars) {
352
+ text = `${text.slice(0, maxPassageChars - 1)}…`;
353
+ }
354
+ passages.push({
355
+ id: `${tree.documentId}#node:${node.nodeId}`,
356
+ text,
357
+ // Rank within the document's choice; not a similarity.
358
+ score: 1 / (rank + 1),
359
+ source: tree.source ?? tree.title ?? tree.documentId,
360
+ metadata: {
361
+ ...tree.metadata,
362
+ documentId: tree.documentId,
363
+ nodeId: node.nodeId,
364
+ title: node.title,
365
+ ...(node.pageStart !== undefined ? { pageStart: node.pageStart } : {}),
366
+ ...(node.pageEnd !== undefined ? { pageEnd: node.pageEnd } : {}),
367
+ path: node.path,
368
+ retrieval: 'tree-navigation',
369
+ ...(reasoning ? { reasoning: reasoning.slice(0, 2_000) } : {}),
370
+ },
371
+ });
372
+ }
373
+ return passages;
374
+ }
375
+ }
376
+ /** Accept `0003`, `3`, `"[0003]"` for node `0003`. */
377
+ function resolveId(index, raw) {
378
+ const id = raw.trim().replace(/^\[|\]$/g, '');
379
+ if (index.has(id)) {
380
+ return id;
381
+ }
382
+ if (/^\d+$/.test(id)) {
383
+ const padded = id.padStart(4, '0');
384
+ if (index.has(padded)) {
385
+ return padded;
386
+ }
387
+ }
388
+ return undefined;
389
+ }
390
+ /** The reply's JSON object, or an error naming what came back (a truncated or chatty reply). */
391
+ function requireJson(reply) {
392
+ const json = parseJsonReply(reply);
393
+ if (json === undefined) {
394
+ throw new Error(`navigation reply was not JSON: ${JSON.stringify(reply.slice(0, 120))}`);
395
+ }
396
+ return json;
397
+ }
398
+ function reasoningOf(reply) {
399
+ const thinking = reply?.thinking ?? reply?.reasoning;
400
+ return typeof thinking === 'string' && thinking.trim()
401
+ ? { reasoning: thinking.slice(0, 2_000) }
402
+ : {};
403
+ }
404
+ //# sourceMappingURL=navigate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../../../src/rag/tree/navigate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { LucidRawRunner } from '../../stores/lucid.js';
2
+ import { type DocumentTreeHeader, type DocumentTreeStore } from './store.js';
3
+ import type { DocumentTree, TreeUnit } from './types.js';
4
+ export interface PgDocumentTreeStoreOptions {
5
+ /** Trees table. Default `agent_rag_trees`. Validated against the identifier regex. */
6
+ table?: string;
7
+ /** Units (page/section text) table. Default `${table}_units`, i.e. `agent_rag_trees_units`. */
8
+ unitsTable?: string;
9
+ /** Unit rows per multi-row `INSERT`. Default 200. */
10
+ insertBatchSize?: number;
11
+ }
12
+ /**
13
+ * A Postgres {@link DocumentTreeStore} over Lucid's raw runner (`db` or `db.connection(name)` — the
14
+ * same structural {@link LucidRawRunner} `PgVectorStore` takes, so `@adonisjs/lucid` stays an
15
+ * optional peer): one row per tree (header columns, `metadata` as `jsonb` for filtering, the nodes as
16
+ * `jsonb`) and one row per unit of text. Filters compile through the same builder as `PgVectorStore`'s
17
+ * — scalar `@>` containment, array match-any, empty array denies — so the filter you pass the vector
18
+ * store works here unchanged.
19
+ *
20
+ * Provision it with the published `create_agent_rag_trees` migration, or {@link ensureSchema} /
21
+ * {@link schemaStatements}. Needs no extension. Writes run in one transaction when the runner has one.
22
+ */
23
+ export declare class PgDocumentTreeStore implements DocumentTreeStore {
24
+ protected readonly db: LucidRawRunner;
25
+ protected readonly table: string;
26
+ protected readonly unitsTable: string;
27
+ private readonly insertBatchSize;
28
+ constructor(db: LucidRawRunner, options?: PgDocumentTreeStoreOptions);
29
+ /** The idempotent DDL {@link ensureSchema} runs, in order. */
30
+ schemaStatements(): string[];
31
+ ensureSchema(): Promise<void>;
32
+ private write;
33
+ /** Replace the tree and its units (one transaction when the runner has one). */
34
+ put(tree: DocumentTree, units: TreeUnit[]): Promise<void>;
35
+ get(documentId: string, filter?: Record<string, unknown>): Promise<DocumentTree | undefined>;
36
+ getMany(documentIds: readonly string[], filter?: Record<string, unknown>): Promise<DocumentTree[]>;
37
+ list(options?: {
38
+ filter?: Record<string, unknown>;
39
+ documentIds?: readonly string[];
40
+ limit?: number;
41
+ }): Promise<DocumentTreeHeader[]>;
42
+ readUnits(documentId: string, start: number, end: number): Promise<TreeUnit[]>;
43
+ remove(documentId: string): Promise<void>;
44
+ }
45
+ //# sourceMappingURL=pg-tree-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-tree-store.d.ts","sourceRoot":"","sources":["../../../../src/rag/tree/pg-tree-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAY,MAAM,YAAY,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,0BAA0B;IACzC,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+FAA+F;IAC/F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAoCD;;;;;;;;;;GAUG;AACH,qBAAa,mBAAoB,YAAW,iBAAiB;IAMzD,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,cAAc;IALvC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,YACqB,EAAE,EAAE,cAAc,EACrC,OAAO,GAAE,0BAA+B,EAKzC;IAED,8DAA8D;IAC9D,gBAAgB,IAAI,MAAM,EAAE,CAuB3B;IAEK,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAIlC;YAEa,KAAK;IAYnB,gFAAgF;IAC1E,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C9D;IAEK,GAAG,CACP,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAEnC;IAEK,OAAO,CACX,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB;IAEK,IAAI,CACR,OAAO,GAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAChC,KAAK,CAAC,EAAE,MAAM,CAAC;KACX,GACL,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAoD/B;IAEK,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAanF;IAEK,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK9C;CACF"}