@aid-framework/runtime 0.0.0-stage → 0.1.39

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 (188) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +52 -2
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/agents/deep_agents.d.ts +78 -0
  5. package/dist/agents/deep_agents.d.ts.map +1 -0
  6. package/dist/agents/deep_agents.js +477 -0
  7. package/dist/agents/deep_agents.js.map +1 -0
  8. package/dist/agents/engine.d.ts +85 -0
  9. package/dist/agents/engine.d.ts.map +1 -0
  10. package/dist/agents/engine.js +129 -0
  11. package/dist/agents/engine.js.map +1 -0
  12. package/dist/agents/gateway_chat_model.d.ts +151 -0
  13. package/dist/agents/gateway_chat_model.d.ts.map +1 -0
  14. package/dist/agents/gateway_chat_model.js +350 -0
  15. package/dist/agents/gateway_chat_model.js.map +1 -0
  16. package/dist/agents/guardrail_middleware.d.ts +57 -0
  17. package/dist/agents/guardrail_middleware.d.ts.map +1 -0
  18. package/dist/agents/guardrail_middleware.js +85 -0
  19. package/dist/agents/guardrail_middleware.js.map +1 -0
  20. package/dist/agents/guardrails.d.ts +124 -0
  21. package/dist/agents/guardrails.d.ts.map +1 -0
  22. package/dist/agents/guardrails.js +336 -0
  23. package/dist/agents/guardrails.js.map +1 -0
  24. package/dist/agents/index.d.ts +15 -0
  25. package/dist/agents/index.d.ts.map +1 -0
  26. package/dist/agents/index.js +15 -0
  27. package/dist/agents/index.js.map +1 -0
  28. package/dist/agents/ir.d.ts +144 -0
  29. package/dist/agents/ir.d.ts.map +1 -0
  30. package/dist/agents/ir.js +513 -0
  31. package/dist/agents/ir.js.map +1 -0
  32. package/dist/agents/loop.d.ts +145 -0
  33. package/dist/agents/loop.d.ts.map +1 -0
  34. package/dist/agents/loop.js +1025 -0
  35. package/dist/agents/loop.js.map +1 -0
  36. package/dist/agents/memory.d.ts +115 -0
  37. package/dist/agents/memory.d.ts.map +1 -0
  38. package/dist/agents/memory.js +258 -0
  39. package/dist/agents/memory.js.map +1 -0
  40. package/dist/agents/state.d.ts +137 -0
  41. package/dist/agents/state.d.ts.map +1 -0
  42. package/dist/agents/state.js +255 -0
  43. package/dist/agents/state.js.map +1 -0
  44. package/dist/concurrency.d.ts +36 -0
  45. package/dist/concurrency.d.ts.map +1 -0
  46. package/dist/concurrency.js +86 -0
  47. package/dist/concurrency.js.map +1 -0
  48. package/dist/control.d.ts +116 -0
  49. package/dist/control.d.ts.map +1 -0
  50. package/dist/control.js +281 -0
  51. package/dist/control.js.map +1 -0
  52. package/dist/cost.d.ts +95 -0
  53. package/dist/cost.d.ts.map +1 -0
  54. package/dist/cost.js +161 -0
  55. package/dist/cost.js.map +1 -0
  56. package/dist/errors.d.ts +213 -0
  57. package/dist/errors.d.ts.map +1 -0
  58. package/dist/errors.js +316 -0
  59. package/dist/errors.js.map +1 -0
  60. package/dist/evals/dataset.d.ts +45 -0
  61. package/dist/evals/dataset.d.ts.map +1 -0
  62. package/dist/evals/dataset.js +147 -0
  63. package/dist/evals/dataset.js.map +1 -0
  64. package/dist/evals/gate.d.ts +236 -0
  65. package/dist/evals/gate.d.ts.map +1 -0
  66. package/dist/evals/gate.js +572 -0
  67. package/dist/evals/gate.js.map +1 -0
  68. package/dist/evals/metrics.d.ts +141 -0
  69. package/dist/evals/metrics.d.ts.map +1 -0
  70. package/dist/evals/metrics.js +364 -0
  71. package/dist/evals/metrics.js.map +1 -0
  72. package/dist/evals/predicate.d.ts +79 -0
  73. package/dist/evals/predicate.d.ts.map +1 -0
  74. package/dist/evals/predicate.js +178 -0
  75. package/dist/evals/predicate.js.map +1 -0
  76. package/dist/evals/runner.d.ts +94 -0
  77. package/dist/evals/runner.d.ts.map +1 -0
  78. package/dist/evals/runner.js +202 -0
  79. package/dist/evals/runner.js.map +1 -0
  80. package/dist/gateway.d.ts +118 -0
  81. package/dist/gateway.d.ts.map +1 -0
  82. package/dist/gateway.js +250 -0
  83. package/dist/gateway.js.map +1 -0
  84. package/dist/index.d.ts +83 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +59 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/internal/json.d.ts +44 -0
  89. package/dist/internal/json.d.ts.map +1 -0
  90. package/dist/internal/json.js +90 -0
  91. package/dist/internal/json.js.map +1 -0
  92. package/dist/internal/text.d.ts +17 -0
  93. package/dist/internal/text.d.ts.map +1 -0
  94. package/dist/internal/text.js +22 -0
  95. package/dist/internal/text.js.map +1 -0
  96. package/dist/pipeline.d.ts +80 -0
  97. package/dist/pipeline.d.ts.map +1 -0
  98. package/dist/pipeline.js +159 -0
  99. package/dist/pipeline.js.map +1 -0
  100. package/dist/policy.d.ts +52 -0
  101. package/dist/policy.d.ts.map +1 -0
  102. package/dist/policy.js +199 -0
  103. package/dist/policy.js.map +1 -0
  104. package/dist/prompts.d.ts +86 -0
  105. package/dist/prompts.d.ts.map +1 -0
  106. package/dist/prompts.js +337 -0
  107. package/dist/prompts.js.map +1 -0
  108. package/dist/providers/base.d.ts +19 -0
  109. package/dist/providers/base.d.ts.map +1 -0
  110. package/dist/providers/base.js +13 -0
  111. package/dist/providers/base.js.map +1 -0
  112. package/dist/providers/fake.d.ts +98 -0
  113. package/dist/providers/fake.d.ts.map +1 -0
  114. package/dist/providers/fake.js +181 -0
  115. package/dist/providers/fake.js.map +1 -0
  116. package/dist/providers/http.d.ts +62 -0
  117. package/dist/providers/http.d.ts.map +1 -0
  118. package/dist/providers/http.js +245 -0
  119. package/dist/providers/http.js.map +1 -0
  120. package/dist/retrieval/chunking.d.ts +88 -0
  121. package/dist/retrieval/chunking.d.ts.map +1 -0
  122. package/dist/retrieval/chunking.js +188 -0
  123. package/dist/retrieval/chunking.js.map +1 -0
  124. package/dist/retrieval/citations.d.ts +98 -0
  125. package/dist/retrieval/citations.d.ts.map +1 -0
  126. package/dist/retrieval/citations.js +134 -0
  127. package/dist/retrieval/citations.js.map +1 -0
  128. package/dist/retrieval/connectors.d.ts +74 -0
  129. package/dist/retrieval/connectors.d.ts.map +1 -0
  130. package/dist/retrieval/connectors.js +218 -0
  131. package/dist/retrieval/connectors.js.map +1 -0
  132. package/dist/retrieval/embedding.d.ts +116 -0
  133. package/dist/retrieval/embedding.d.ts.map +1 -0
  134. package/dist/retrieval/embedding.js +282 -0
  135. package/dist/retrieval/embedding.js.map +1 -0
  136. package/dist/retrieval/gate.d.ts +52 -0
  137. package/dist/retrieval/gate.d.ts.map +1 -0
  138. package/dist/retrieval/gate.js +91 -0
  139. package/dist/retrieval/gate.js.map +1 -0
  140. package/dist/retrieval/hybrid.d.ts +76 -0
  141. package/dist/retrieval/hybrid.d.ts.map +1 -0
  142. package/dist/retrieval/hybrid.js +150 -0
  143. package/dist/retrieval/hybrid.js.map +1 -0
  144. package/dist/retrieval/metrics.d.ts +126 -0
  145. package/dist/retrieval/metrics.d.ts.map +1 -0
  146. package/dist/retrieval/metrics.js +200 -0
  147. package/dist/retrieval/metrics.js.map +1 -0
  148. package/dist/retrieval/pgvector.d.ts +62 -0
  149. package/dist/retrieval/pgvector.d.ts.map +1 -0
  150. package/dist/retrieval/pgvector.js +262 -0
  151. package/dist/retrieval/pgvector.js.map +1 -0
  152. package/dist/retrieval/rerank.d.ts +61 -0
  153. package/dist/retrieval/rerank.d.ts.map +1 -0
  154. package/dist/retrieval/rerank.js +105 -0
  155. package/dist/retrieval/rerank.js.map +1 -0
  156. package/dist/retrieval/retriever.d.ts +125 -0
  157. package/dist/retrieval/retriever.d.ts.map +1 -0
  158. package/dist/retrieval/retriever.js +281 -0
  159. package/dist/retrieval/retriever.js.map +1 -0
  160. package/dist/retrieval/stores.d.ts +106 -0
  161. package/dist/retrieval/stores.d.ts.map +1 -0
  162. package/dist/retrieval/stores.js +142 -0
  163. package/dist/retrieval/stores.js.map +1 -0
  164. package/dist/retrieval/types.d.ts +314 -0
  165. package/dist/retrieval/types.d.ts.map +1 -0
  166. package/dist/retrieval/types.js +388 -0
  167. package/dist/retrieval/types.js.map +1 -0
  168. package/dist/steps.d.ts +156 -0
  169. package/dist/steps.d.ts.map +1 -0
  170. package/dist/steps.js +199 -0
  171. package/dist/steps.js.map +1 -0
  172. package/dist/structured.d.ts +91 -0
  173. package/dist/structured.d.ts.map +1 -0
  174. package/dist/structured.js +155 -0
  175. package/dist/structured.js.map +1 -0
  176. package/dist/tools.d.ts +100 -0
  177. package/dist/tools.d.ts.map +1 -0
  178. package/dist/tools.js +201 -0
  179. package/dist/tools.js.map +1 -0
  180. package/dist/tracing.d.ts +104 -0
  181. package/dist/tracing.d.ts.map +1 -0
  182. package/dist/tracing.js +155 -0
  183. package/dist/tracing.js.map +1 -0
  184. package/dist/types.d.ts +240 -0
  185. package/dist/types.d.ts.map +1 -0
  186. package/dist/types.js +357 -0
  187. package/dist/types.js.map +1 -0
  188. package/package.json +77 -3
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Turning documents into deterministic, size-bounded chunks.
3
+ *
4
+ * The IR declares a strategy, a size and an overlap; it does not declare the split
5
+ * algorithm. This module pins one, and the pin is the spec validator's own reading
6
+ * of the intent: *"spec v0.1 chunks by size (fixed, recursive, code)"*. `semantic`
7
+ * is refused because it needs an embedding pass over the whole source at ingest --
8
+ * a different shape of job, not a different boundary rule.
9
+ *
10
+ * So all three implemented strategies are size-bounded splitters and the only thing
11
+ * that distinguishes them is **where a boundary is allowed to fall**:
12
+ *
13
+ * `fixed`
14
+ * Anywhere. The window always fills to `size`, cutting mid-word when that is
15
+ * where the budget ends. This is the honest baseline other strategies improve on.
16
+ * `recursive`
17
+ * Prefer the last paragraph break, then the last line break, then the last
18
+ * sentence end, then the last word break inside the window.
19
+ * `code`
20
+ * Prefer the last blank line, then the last line break, then the last statement
21
+ * end. Code is line-structured, so a blank line is the closest thing it has to a
22
+ * paragraph, and cutting mid-statement is the failure worth avoiding.
23
+ *
24
+ * Chunks are pure functions of the text, so the same input always produces the same
25
+ * chunks with the same ids in the same order -- which is what makes re-ingesting a
26
+ * corpus a no-op instead of a duplicate.
27
+ */
28
+ import { ConfigurationError, FeatureDeferredError } from '../errors.js';
29
+ import { repr } from '../internal/json.js';
30
+ import { Chunk, chunkIdFor } from './types.js';
31
+ /**
32
+ * A boundary found in the first half of a window is ignored and the window is
33
+ * filled to `size` instead. Without this, one early paragraph break near the end of
34
+ * a split would produce a stream of very short chunks, and a chunker that emits
35
+ * 5-character chunks is worse than one that cuts a sentence in half.
36
+ */
37
+ const MIN_FILL_NUMERATOR = 1;
38
+ const MIN_FILL_DENOMINATOR = 2;
39
+ /** Shared windowing. Subclasses only choose where a boundary may fall. */
40
+ class SizeChunker {
41
+ _size;
42
+ _overlap;
43
+ _keep;
44
+ constructor(init) {
45
+ if (init.size <= 0) {
46
+ throw new ConfigurationError('chunking size must be positive');
47
+ }
48
+ if (init.overlap < 0) {
49
+ throw new ConfigurationError('chunking overlap must not be negative');
50
+ }
51
+ if (init.overlap >= init.size) {
52
+ throw new ConfigurationError(`chunking overlap ${init.overlap} must be smaller than size ${init.size}; otherwise a ` +
53
+ 'window would not advance and chunking would never terminate');
54
+ }
55
+ this._size = init.size;
56
+ this._overlap = init.overlap;
57
+ this._keep = [...(init.keepMetadata ?? [])];
58
+ }
59
+ chunk(document) {
60
+ const text = document.text;
61
+ const chunks = [];
62
+ let start = 0;
63
+ while (start < text.length) {
64
+ const limit = Math.min(start + this._size, text.length);
65
+ let end = limit >= text.length ? limit : this.cut(text, start, limit);
66
+ // A boundary at or before `start` would stall the loop, so progress is
67
+ // guaranteed here rather than trusted from the strategy hook.
68
+ end = Math.max(end, start + 1);
69
+ const window = text.slice(start, end);
70
+ if (window.trim().length > 0) {
71
+ chunks.push(this.build(document, chunks.length, start, end, window));
72
+ }
73
+ if (end >= text.length) {
74
+ break;
75
+ }
76
+ start = Math.max(end - this._overlap, start + 1);
77
+ }
78
+ return chunks;
79
+ }
80
+ build(document, index, start, end, text) {
81
+ const metadata = {};
82
+ for (const key of this._keep) {
83
+ const value = document.metadata[key];
84
+ if (value !== undefined)
85
+ metadata[key] = value;
86
+ }
87
+ return new Chunk({
88
+ chunkId: chunkIdFor(document.docId, index, text),
89
+ docId: document.docId,
90
+ uri: document.uri,
91
+ index,
92
+ start,
93
+ end,
94
+ text,
95
+ metadata,
96
+ });
97
+ }
98
+ /**
99
+ * The end offset of the last `marker` in `text.slice(start, limit)`, if usable.
100
+ *
101
+ * `null` means "no boundary worth taking", and the caller falls back to `limit`.
102
+ * The minimum-fill rule is applied here rather than by each strategy so no
103
+ * strategy can forget it.
104
+ */
105
+ boundary(text, start, limit, markers) {
106
+ const floor = start + Math.floor((this._size * MIN_FILL_NUMERATOR) / MIN_FILL_DENOMINATOR);
107
+ const window = text.slice(start, limit);
108
+ for (const marker of markers) {
109
+ const position = window.lastIndexOf(marker);
110
+ if (position === -1)
111
+ continue;
112
+ const end = start + position + marker.length;
113
+ if (end >= Math.max(floor, start + 1)) {
114
+ return end;
115
+ }
116
+ }
117
+ return null;
118
+ }
119
+ /** The first usable boundary from `markerGroups`, in preference order. */
120
+ fill(text, start, limit, markerGroups) {
121
+ for (const markers of markerGroups) {
122
+ const found = this.boundary(text, start, limit, markers);
123
+ if (found !== null)
124
+ return found;
125
+ }
126
+ return limit;
127
+ }
128
+ }
129
+ /** Cuts on size alone. */
130
+ export class FixedChunker extends SizeChunker {
131
+ get strategy() {
132
+ return 'fixed';
133
+ }
134
+ cut(_text, _start, limit) {
135
+ return limit;
136
+ }
137
+ }
138
+ /** Prefers prose boundaries: paragraph, then line, then sentence, then word. */
139
+ export class RecursiveChunker extends SizeChunker {
140
+ get strategy() {
141
+ return 'recursive';
142
+ }
143
+ cut(text, start, limit) {
144
+ return this.fill(text, start, limit, [['\n\n'], ['\n'], ['. ', '! ', '? '], [' ']]);
145
+ }
146
+ }
147
+ /** Prefers code boundaries: blank line, then line, then statement, then token. */
148
+ export class CodeChunker extends SizeChunker {
149
+ get strategy() {
150
+ return 'code';
151
+ }
152
+ cut(text, start, limit) {
153
+ return this.fill(text, start, limit, [['\n\n'], ['\n'], [';\n', ';\r\n', '; '], [' ']]);
154
+ }
155
+ }
156
+ /**
157
+ * Resolve a chunking block to an implementation.
158
+ *
159
+ * `semantic` is refused here as well as in the spec validator, because the runtime
160
+ * is reachable from generated code the validator never saw.
161
+ */
162
+ export function chunkerFor(spec) {
163
+ const options = {
164
+ size: spec.size,
165
+ overlap: spec.overlap,
166
+ keepMetadata: spec.keepMetadata,
167
+ };
168
+ switch (spec.strategy) {
169
+ case 'fixed':
170
+ return new FixedChunker(options);
171
+ case 'recursive':
172
+ return new RecursiveChunker(options);
173
+ case 'code':
174
+ return new CodeChunker(options);
175
+ case 'semantic':
176
+ throw new FeatureDeferredError(`chunking strategy ${repr(spec.strategy)} is declared but not implemented: spec ` +
177
+ 'v0.1 chunks by size (fixed, recursive, code), and semantic chunking needs an ' +
178
+ 'embedding pass over the whole source at ingest');
179
+ /* istanbul ignore next -- unreachable while the union above is exhaustive */
180
+ default:
181
+ throw new FeatureDeferredError(`chunking strategy ${repr(String(spec.strategy))} is declared but not implemented`);
182
+ }
183
+ }
184
+ /** Chunk one document with the strategy the spec names. */
185
+ export function chunkDocument(document, spec) {
186
+ return chunkerFor(spec).chunk(document);
187
+ }
188
+ //# sourceMappingURL=chunking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunking.js","sourceRoot":"","sources":["../../src/retrieval/chunking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Retrieved passages, their provenance, and the context they assemble into.
3
+ *
4
+ * A retrieved set is only useful to a model if the passages arrive with provenance
5
+ * the model can repeat back, so ranking and citation are one type here rather than a
6
+ * search result plus a separate lookup table. {@link RetrievalResult} is the
7
+ * runtime's answer type: it is what a `retrieve` step produces and what every
8
+ * retrieval metric scores.
9
+ *
10
+ * The assembled context is numbered by **rank**, not by position in the array. The
11
+ * two are the same in practice because ranks are assigned contiguously from 1, but
12
+ * naming the rank is what makes a model's `[2]` resolvable by the caller without
13
+ * re-running the search.
14
+ */
15
+ import type { Chunk } from './types.js';
16
+ /**
17
+ * Where one retrieved passage came from.
18
+ *
19
+ * `docId` is the document identity the IR's retrieval metric already uses
20
+ * (`expectDocs: [getting-started.md]`), so a citation and a gate expectation are the
21
+ * same vocabulary rather than two spellings of the same thing.
22
+ */
23
+ export declare class Citation {
24
+ readonly docId: string;
25
+ readonly chunkId: string;
26
+ readonly uri: string;
27
+ readonly index: number;
28
+ constructor(init: {
29
+ readonly docId: string;
30
+ readonly chunkId: string;
31
+ readonly uri?: string;
32
+ readonly index: number;
33
+ });
34
+ toString(): string;
35
+ }
36
+ /** One ranked passage: the chunk, its score, and its provenance. */
37
+ export declare class RetrievedItem {
38
+ readonly chunk: Chunk;
39
+ readonly score: number;
40
+ readonly rank: number;
41
+ readonly citation: Citation;
42
+ constructor(init: {
43
+ readonly chunk: Chunk;
44
+ readonly score: number;
45
+ readonly rank: number;
46
+ readonly citation: Citation;
47
+ });
48
+ }
49
+ /**
50
+ * What a `retrieve` step returns.
51
+ *
52
+ * `items` is rank-ordered and may be empty -- "the corpus has nothing for this
53
+ * query" is a result, not an error, and a caller that needs a non-empty answer says
54
+ * so with a metric rather than by crashing.
55
+ */
56
+ export declare class RetrievalResult {
57
+ readonly retriever: string;
58
+ readonly query: string;
59
+ readonly items: readonly RetrievedItem[];
60
+ constructor(init: {
61
+ readonly retriever: string;
62
+ readonly query: string;
63
+ readonly items?: readonly RetrievedItem[];
64
+ });
65
+ get length(): number;
66
+ /** The first `k` items, or all of them when the result is shorter. */
67
+ top(k: number): readonly RetrievedItem[];
68
+ /** The numbered excerpts a prompt binds. */
69
+ get context(): string;
70
+ /** One citation per item, in rank order. */
71
+ get citations(): readonly Citation[];
72
+ /**
73
+ * Rank-ordered, de-duplicated document ids.
74
+ *
75
+ * De-duplicated because recall is about *documents found*, and a document that
76
+ * contributed three passages was found once. First occurrence wins, so the order
77
+ * still reflects relevance.
78
+ */
79
+ get docIds(): readonly string[];
80
+ }
81
+ /**
82
+ * The citation for a chunk.
83
+ *
84
+ * Derived from the chunk rather than passed alongside it, so a citation cannot drift
85
+ * from the passage it names.
86
+ */
87
+ export declare function cite(chunk: Chunk): Citation;
88
+ /**
89
+ * Render ranked items as numbered excerpts, each tagged with its citation.
90
+ *
91
+ * An empty retrieval renders as the empty string rather than as a header with nothing
92
+ * under it: a header alone reads to a model as "sources were found", and a prompt
93
+ * that invites a model to invent a source is worse than an empty prompt.
94
+ */
95
+ export declare function assembleContext(items: readonly RetrievedItem[], options?: {
96
+ readonly separator?: string;
97
+ }): string;
98
+ //# sourceMappingURL=citations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citations.d.ts","sourceRoot":"","sources":["../../src/retrieval/citations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;GAMG;AACH,qBAAa,QAAQ;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,IAAI,EAAE;QAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;KACxB,EAYA;IAED,QAAQ,IAAI,MAAM,CAEjB;CACF;AAED,oEAAoE;AACpE,qBAAa,aAAa;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B,YAAY,IAAI,EAAE;QAChB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;KAC7B,EAQA;CACF;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAEzC,YAAY,IAAI,EAAE;QAChB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;KAC3C,EAOA;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,sEAAsE;IACtE,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,aAAa,EAAE,CAEvC;IAED,4CAA4C;IAC5C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,4CAA4C;IAC5C,IAAI,SAAS,IAAI,SAAS,QAAQ,EAAE,CAEnC;IAED;;;;;;OAMG;IACH,IAAI,MAAM,IAAI,SAAS,MAAM,EAAE,CAE9B;CACF;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,CAO3C;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,OAAO,GAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,MAAM,CAKR"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Retrieved passages, their provenance, and the context they assemble into.
3
+ *
4
+ * A retrieved set is only useful to a model if the passages arrive with provenance
5
+ * the model can repeat back, so ranking and citation are one type here rather than a
6
+ * search result plus a separate lookup table. {@link RetrievalResult} is the
7
+ * runtime's answer type: it is what a `retrieve` step produces and what every
8
+ * retrieval metric scores.
9
+ *
10
+ * The assembled context is numbered by **rank**, not by position in the array. The
11
+ * two are the same in practice because ranks are assigned contiguously from 1, but
12
+ * naming the rank is what makes a model's `[2]` resolvable by the caller without
13
+ * re-running the search.
14
+ */
15
+ import { ConfigurationError } from '../errors.js';
16
+ /**
17
+ * Where one retrieved passage came from.
18
+ *
19
+ * `docId` is the document identity the IR's retrieval metric already uses
20
+ * (`expectDocs: [getting-started.md]`), so a citation and a gate expectation are the
21
+ * same vocabulary rather than two spellings of the same thing.
22
+ */
23
+ export class Citation {
24
+ docId;
25
+ chunkId;
26
+ uri;
27
+ index;
28
+ constructor(init) {
29
+ if (init.docId.length === 0)
30
+ throw new ConfigurationError('citation docId must not be empty');
31
+ if (init.chunkId.length === 0) {
32
+ throw new ConfigurationError('citation chunkId must not be empty');
33
+ }
34
+ if (!Number.isInteger(init.index) || init.index < 0) {
35
+ throw new ConfigurationError('citation index must be a non-negative integer');
36
+ }
37
+ this.docId = init.docId;
38
+ this.chunkId = init.chunkId;
39
+ this.uri = init.uri ?? '';
40
+ this.index = init.index;
41
+ }
42
+ toString() {
43
+ return `${this.docId}#${this.index}`;
44
+ }
45
+ }
46
+ /** One ranked passage: the chunk, its score, and its provenance. */
47
+ export class RetrievedItem {
48
+ chunk;
49
+ score;
50
+ rank;
51
+ citation;
52
+ constructor(init) {
53
+ if (!Number.isInteger(init.rank) || init.rank < 1) {
54
+ throw new ConfigurationError('retrieved item rank must be at least 1');
55
+ }
56
+ this.chunk = init.chunk;
57
+ this.score = init.score;
58
+ this.rank = init.rank;
59
+ this.citation = init.citation;
60
+ }
61
+ }
62
+ /**
63
+ * What a `retrieve` step returns.
64
+ *
65
+ * `items` is rank-ordered and may be empty -- "the corpus has nothing for this
66
+ * query" is a result, not an error, and a caller that needs a non-empty answer says
67
+ * so with a metric rather than by crashing.
68
+ */
69
+ export class RetrievalResult {
70
+ retriever;
71
+ query;
72
+ items;
73
+ constructor(init) {
74
+ if (init.retriever.length === 0) {
75
+ throw new ConfigurationError('retriever must not be empty');
76
+ }
77
+ this.retriever = init.retriever;
78
+ this.query = init.query;
79
+ this.items = [...(init.items ?? [])];
80
+ }
81
+ get length() {
82
+ return this.items.length;
83
+ }
84
+ /** The first `k` items, or all of them when the result is shorter. */
85
+ top(k) {
86
+ return this.items.slice(0, k);
87
+ }
88
+ /** The numbered excerpts a prompt binds. */
89
+ get context() {
90
+ return assembleContext(this.items);
91
+ }
92
+ /** One citation per item, in rank order. */
93
+ get citations() {
94
+ return this.items.map((item) => item.citation);
95
+ }
96
+ /**
97
+ * Rank-ordered, de-duplicated document ids.
98
+ *
99
+ * De-duplicated because recall is about *documents found*, and a document that
100
+ * contributed three passages was found once. First occurrence wins, so the order
101
+ * still reflects relevance.
102
+ */
103
+ get docIds() {
104
+ return [...new Set(this.items.map((item) => item.citation.docId))];
105
+ }
106
+ }
107
+ /**
108
+ * The citation for a chunk.
109
+ *
110
+ * Derived from the chunk rather than passed alongside it, so a citation cannot drift
111
+ * from the passage it names.
112
+ */
113
+ export function cite(chunk) {
114
+ return new Citation({
115
+ docId: chunk.docId,
116
+ chunkId: chunk.chunkId,
117
+ uri: chunk.uri,
118
+ index: chunk.index,
119
+ });
120
+ }
121
+ /**
122
+ * Render ranked items as numbered excerpts, each tagged with its citation.
123
+ *
124
+ * An empty retrieval renders as the empty string rather than as a header with nothing
125
+ * under it: a header alone reads to a model as "sources were found", and a prompt
126
+ * that invites a model to invent a source is worse than an empty prompt.
127
+ */
128
+ export function assembleContext(items, options = {}) {
129
+ const separator = options.separator ?? '\n\n';
130
+ return items
131
+ .map((item) => `[${item.rank}] ${item.citation.toString()} :: ${item.chunk.text}`)
132
+ .join(separator);
133
+ }
134
+ //# sourceMappingURL=citations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citations.js","sourceRoot":"","sources":["../../src/retrieval/citations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Reading a `file` source.
3
+ *
4
+ * The IR names five source kinds and Phase 1 implements one. That is the spec
5
+ * validator's own position ("spec v0.1 indexes a local `file` source; the remote
6
+ * loaders belong to the phase that ships them"), so the other four raise
7
+ * {@link FeatureDeferredError} here rather than indexing an empty corpus and
8
+ * looking healthy.
9
+ *
10
+ * **Document identity is the POSIX path relative to the source root.** That is
11
+ * the vocabulary the IR's retrieval metric already uses -- its `expectDocs` hold
12
+ * `getting-started.md`, not `./docs/getting-started.md` -- and it is
13
+ * machine-independent, so the same corpus indexed on Windows and on Linux yields
14
+ * the same ids and the same eval outcome. Absolute paths would make a baseline
15
+ * non-portable.
16
+ *
17
+ * The protocol is `async` even though the only implementation reads local files
18
+ * synchronously, because the kinds that follow (`s3`, `http`, `db`, `mcp`) are
19
+ * genuinely concurrent. Making it sync now would be a breaking change to the seam
20
+ * exactly when the first real loader arrives.
21
+ */
22
+ import type { SourceKind, SourceSpec } from './types.js';
23
+ /** One document read from a source, before chunking. */
24
+ export declare class SourceDocument {
25
+ /** POSIX path relative to the source root; the document's identity everywhere. */
26
+ readonly docId: string;
27
+ /** The absolute resolved location, for a human reading a citation. Never matched on. */
28
+ readonly uri: string;
29
+ readonly text: string;
30
+ readonly metadata: Readonly<Record<string, string>>;
31
+ constructor(init: {
32
+ readonly docId: string;
33
+ readonly uri: string;
34
+ readonly text: string;
35
+ readonly metadata?: Readonly<Record<string, string>>;
36
+ });
37
+ }
38
+ /** A source that yields documents in a deterministic order. */
39
+ export interface Connector {
40
+ readonly kind: SourceKind;
41
+ documents(): Promise<readonly SourceDocument[]>;
42
+ close(): Promise<void>;
43
+ }
44
+ /**
45
+ * Reads `*.md`-style files under a local directory.
46
+ *
47
+ * Files are read and returned in sorted `docId` order, never in directory order:
48
+ * directory order is a filesystem accident, and a corpus whose chunk ids depend on
49
+ * it would reindex itself differently on a different machine.
50
+ */
51
+ export declare class FileConnector implements Connector {
52
+ private readonly _root;
53
+ private readonly _glob;
54
+ constructor(root: string, options?: {
55
+ readonly glob?: string | null;
56
+ });
57
+ get kind(): SourceKind;
58
+ documents(): Promise<readonly SourceDocument[]>;
59
+ close(): Promise<void>;
60
+ private paths;
61
+ private docId;
62
+ private read;
63
+ }
64
+ /**
65
+ * Open the connector for a source entry.
66
+ *
67
+ * `baseDir` resolves a relative source `uri`; it is explicit because the runtime
68
+ * has no opinion about a working directory, and a corpus must not depend on where a
69
+ * process happened to be started.
70
+ */
71
+ export declare function openConnector(spec: SourceSpec, options?: {
72
+ readonly baseDir?: string | null;
73
+ }): Connector;
74
+ //# sourceMappingURL=connectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectors.d.ts","sourceRoot":"","sources":["../../src/retrieval/connectors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAqGzD,wDAAwD;AACxD,qBAAa,cAAc;IACzB,kFAAkF;IAClF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wFAAwF;IACxF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEpD,YAAY,IAAI,EAAE;QAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;KACtD,EAWA;CACF;AAED,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,SAAS,IAAI,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAAC;IAChD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;GAMG;AACH,qBAAa,aAAc,YAAW,SAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IAEtC,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAO,EASxE;IAED,IAAI,IAAI,IAAI,UAAU,CAErB;IAEK,SAAS,IAAI,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAEpD;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAED,OAAO,CAAC,KAAK;IA0Bb,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,IAAI;CAUb;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GACjD,SAAS,CAaX"}