@aid-framework/runtime 0.0.0 → 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 +53 -0
  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 +80 -14
@@ -0,0 +1,218 @@
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 { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
23
+ import { isAbsolute, relative, sep } from 'node:path';
24
+ import { ConfigurationError, FeatureDeferredError } from '../errors.js';
25
+ import { repr } from '../internal/json.js';
26
+ function tokenizeGlob(pattern) {
27
+ const tokens = [];
28
+ for (let index = 0; index < pattern.length; index += 1) {
29
+ const char = pattern[index];
30
+ if (char === '*') {
31
+ if (pattern[index + 1] === '*') {
32
+ index += 1;
33
+ if (pattern[index + 1] === '/') {
34
+ index += 1;
35
+ tokens.push({ kind: 'globstar-segment' });
36
+ }
37
+ else {
38
+ tokens.push({ kind: 'globstar' });
39
+ }
40
+ }
41
+ else {
42
+ tokens.push({ kind: 'star' });
43
+ }
44
+ }
45
+ else if (char === '?') {
46
+ tokens.push({ kind: 'any-one' });
47
+ }
48
+ else {
49
+ tokens.push({ kind: 'literal', char });
50
+ }
51
+ }
52
+ return tokens;
53
+ }
54
+ function compileGlob(pattern) {
55
+ const tokens = tokenizeGlob(pattern);
56
+ return (path) => {
57
+ let reachable = new Array(path.length + 1).fill(false);
58
+ reachable[0] = true;
59
+ for (const token of tokens) {
60
+ const next = new Array(path.length + 1).fill(false);
61
+ switch (token.kind) {
62
+ case 'literal':
63
+ for (let end = 1; end <= path.length; end += 1) {
64
+ next[end] = reachable[end - 1] === true && path[end - 1] === token.char;
65
+ }
66
+ break;
67
+ case 'any-one':
68
+ for (let end = 1; end <= path.length; end += 1) {
69
+ next[end] = reachable[end - 1] === true && path[end - 1] !== '/';
70
+ }
71
+ break;
72
+ case 'star':
73
+ // Zero or more non-slash characters: stay put, or extend a run that has
74
+ // already stayed inside one segment.
75
+ for (let end = 0; end <= path.length; end += 1) {
76
+ const extendsRun = end > 0 && next[end - 1] === true && path[end - 1] !== '/';
77
+ next[end] = reachable[end] === true || extendsRun;
78
+ }
79
+ break;
80
+ case 'globstar':
81
+ // Zero or more of any character, slashes included.
82
+ for (let end = 0; end <= path.length; end += 1) {
83
+ const extendsRun = end > 0 && next[end - 1] === true;
84
+ next[end] = reachable[end] === true || extendsRun;
85
+ }
86
+ break;
87
+ case 'globstar-segment':
88
+ // `(?:[^/]*/)*`: zero or more whole segments, so it lands on any boundary
89
+ // that follows a slash, including the one it started on.
90
+ {
91
+ let anyBefore = false;
92
+ for (let end = 0; end <= path.length; end += 1) {
93
+ const lands = anyBefore && end > 0 && path[end - 1] === '/';
94
+ next[end] = reachable[end] === true || lands;
95
+ if (reachable[end] === true)
96
+ anyBefore = true;
97
+ }
98
+ }
99
+ break;
100
+ }
101
+ reachable = next;
102
+ }
103
+ return reachable[path.length] === true;
104
+ };
105
+ }
106
+ /** One document read from a source, before chunking. */
107
+ export class SourceDocument {
108
+ /** POSIX path relative to the source root; the document's identity everywhere. */
109
+ docId;
110
+ /** The absolute resolved location, for a human reading a citation. Never matched on. */
111
+ uri;
112
+ text;
113
+ metadata;
114
+ constructor(init) {
115
+ if (init.docId.length === 0) {
116
+ throw new ConfigurationError('docId must not be empty');
117
+ }
118
+ if (init.uri.length === 0) {
119
+ throw new ConfigurationError('uri must not be empty');
120
+ }
121
+ this.docId = init.docId;
122
+ this.uri = init.uri;
123
+ this.text = init.text;
124
+ this.metadata = { ...(init.metadata ?? {}) };
125
+ }
126
+ }
127
+ /**
128
+ * Reads `*.md`-style files under a local directory.
129
+ *
130
+ * Files are read and returned in sorted `docId` order, never in directory order:
131
+ * directory order is a filesystem accident, and a corpus whose chunk ids depend on
132
+ * it would reindex itself differently on a different machine.
133
+ */
134
+ export class FileConnector {
135
+ _root;
136
+ _glob;
137
+ constructor(root, options = {}) {
138
+ this._root = root;
139
+ if (!existsSync(this._root)) {
140
+ throw new ConfigurationError(`source path ${repr(this._root)} does not exist`);
141
+ }
142
+ if (!statSync(this._root).isDirectory()) {
143
+ throw new ConfigurationError(`source path ${repr(this._root)} is not a directory`);
144
+ }
145
+ this._glob = options.glob ?? null;
146
+ }
147
+ get kind() {
148
+ return 'file';
149
+ }
150
+ async documents() {
151
+ return this.paths().map((path) => this.read(path));
152
+ }
153
+ async close() {
154
+ return Promise.resolve();
155
+ }
156
+ paths() {
157
+ const pattern = this._glob ?? '**/*';
158
+ const matcher = compileGlob(pattern);
159
+ const found = [];
160
+ const walk = (absolute) => {
161
+ for (const entry of readdirSync(absolute, { withFileTypes: true })) {
162
+ const child = `${absolute}${sep}${entry.name}`;
163
+ if (entry.isDirectory()) {
164
+ walk(child);
165
+ continue;
166
+ }
167
+ if (!entry.isFile())
168
+ continue;
169
+ if (entry.name.startsWith('.'))
170
+ continue;
171
+ if (!matcher(this.docId(child)))
172
+ continue;
173
+ found.push(child);
174
+ }
175
+ };
176
+ walk(this._root);
177
+ return found.sort((left, right) => {
178
+ const a = this.docId(left);
179
+ const b = this.docId(right);
180
+ if (a < b)
181
+ return -1;
182
+ return a > b ? 1 : 0;
183
+ });
184
+ }
185
+ docId(path) {
186
+ return relative(this._root, path).split(sep).join('/');
187
+ }
188
+ read(path) {
189
+ const docId = this.docId(path);
190
+ const suffix = docId.includes('.') ? `.${docId.split('.').pop()}` : '';
191
+ return new SourceDocument({
192
+ docId,
193
+ uri: path,
194
+ text: readFileSync(path, 'utf8'),
195
+ metadata: { path: docId, suffix },
196
+ });
197
+ }
198
+ }
199
+ /**
200
+ * Open the connector for a source entry.
201
+ *
202
+ * `baseDir` resolves a relative source `uri`; it is explicit because the runtime
203
+ * has no opinion about a working directory, and a corpus must not depend on where a
204
+ * process happened to be started.
205
+ */
206
+ export function openConnector(spec, options = {}) {
207
+ if (spec.kind !== 'file') {
208
+ throw new FeatureDeferredError(`source kind ${repr(spec.kind)} is declared but not implemented: spec v0.1 ` +
209
+ "indexes a local 'file' source, and the remote loaders (s3, http, db, mcp) " +
210
+ 'belong to the phase that ships them');
211
+ }
212
+ let root = spec.uri;
213
+ if (!isAbsolute(root) && options.baseDir !== undefined && options.baseDir !== null) {
214
+ root = `${options.baseDir}${sep}${root}`;
215
+ }
216
+ return new FileConnector(root, { glob: spec.glob });
217
+ }
218
+ //# sourceMappingURL=connectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectors.js","sourceRoot":"","sources":["../../src/retrieval/connectors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Turning text into vectors.
3
+ *
4
+ * Two adapters, and that is the whole Phase 1 surface: one deterministic fake and
5
+ * one OpenAI-compatible HTTP client. The fake is not a testing afterthought -- it is
6
+ * the adapter the eval gate runs against, because a gate that needed an API key
7
+ * could not run offline in CI. That is the same reason the spec DSL already has
8
+ * `provider: fake` ("deterministic and keyless, which is what lets the eval gate run
9
+ * offline").
10
+ *
11
+ * The pinning rule lives in the seam, not in the adapters: `embed` takes a
12
+ * {@link PinnedEmbedding} and uses its `modelId` and `dimensions`. Nothing here
13
+ * resolves an alias, and the fake hashes the *pinned* model id into its vector, so a
14
+ * silently changed pin produces different vectors rather than a store full of
15
+ * incomparable ones.
16
+ */
17
+ import { type FetchLike } from '../providers/http.js';
18
+ import { TokenUsage } from '../types.js';
19
+ import type { PinnedEmbedding } from './types.js';
20
+ /** Vectors plus the usage that prices them. */
21
+ export declare class EmbeddingBatch {
22
+ readonly vectors: readonly (readonly number[])[];
23
+ readonly usage: TokenUsage;
24
+ constructor(init: {
25
+ readonly vectors: readonly (readonly number[])[];
26
+ readonly usage: TokenUsage;
27
+ });
28
+ }
29
+ /**
30
+ * Text to vectors, with the model pinned by the caller.
31
+ *
32
+ * `close` must be idempotent, matching `Provider`: a client's lifetime is owned by
33
+ * the caller, so closing twice is a caller's mistake that must stay harmless.
34
+ */
35
+ export interface Embedder {
36
+ readonly name: string;
37
+ embed(texts: readonly string[], init: {
38
+ readonly model: PinnedEmbedding;
39
+ }): Promise<EmbeddingBatch>;
40
+ close(): Promise<void>;
41
+ }
42
+ /** The offline token estimate used for the fake's usage and for budgets. */
43
+ export declare function estimateTokens(text: string): number;
44
+ /**
45
+ * Keyless, offline, and byte-identical across runs and platforms.
46
+ *
47
+ * Vectors come from SHAKE-128, a hash-based extensible output function, rather than
48
+ * from a seeded PRNG. The reason is the same property the rest of this runtime
49
+ * depends on: re-ingesting a corpus has to reproduce the vectors exactly, and
50
+ * re-embedding a *query* has to reproduce what ingest stored. A PRNG seeded per call
51
+ * would be stable too, but a hash makes "same text, same vector" true by
52
+ * construction rather than by discipline, and it cannot drift if a vector is later
53
+ * requested one element at a time.
54
+ *
55
+ * Similarity is meaningless here, and that is the deliberate limitation rather than
56
+ * a bug. Lexical retrieval still works over these vectors because the store keeps
57
+ * the text and hybrid search reads it; what the fake proves is the *pipeline*, and
58
+ * what it deliberately does not prove is embedding quality.
59
+ */
60
+ export declare class FakeDeterministicEmbedder implements Embedder {
61
+ private readonly _name;
62
+ constructor(init?: {
63
+ readonly name?: string;
64
+ });
65
+ get name(): string;
66
+ embed(texts: readonly string[], init: {
67
+ readonly model: PinnedEmbedding;
68
+ }): Promise<EmbeddingBatch>;
69
+ close(): Promise<void>;
70
+ private vector;
71
+ }
72
+ /** One POST to `/embeddings` on any OpenAI-compatible endpoint. */
73
+ export declare class OpenAICompatibleEmbedder implements Embedder {
74
+ private readonly _baseUrl;
75
+ private readonly _apiKey;
76
+ private readonly _name;
77
+ private readonly _maxAttempts;
78
+ private readonly _backoffSeconds;
79
+ private readonly _extraHeaders;
80
+ private readonly _fetch;
81
+ private readonly _ownsClient;
82
+ private _closed;
83
+ constructor(options?: {
84
+ readonly baseUrl?: string;
85
+ readonly apiKey?: string;
86
+ readonly name?: string;
87
+ readonly timeoutSeconds?: number;
88
+ readonly maxAttempts?: number;
89
+ readonly backoffSeconds?: number;
90
+ readonly fetchImpl?: FetchLike;
91
+ readonly extraHeaders?: Readonly<Record<string, string>>;
92
+ });
93
+ get name(): string;
94
+ embed(texts: readonly string[], init: {
95
+ readonly model: PinnedEmbedding;
96
+ }): Promise<EmbeddingBatch>;
97
+ close(): Promise<void>;
98
+ private headers;
99
+ private post;
100
+ private asObject;
101
+ private parse;
102
+ }
103
+ /**
104
+ * Pick the adapter for a pinned embedding model.
105
+ *
106
+ * This selects a *provider*, never a model: the model id and its width arrive
107
+ * already pinned, and are passed straight through to whichever adapter is chosen.
108
+ * `fake` is chosen for the same reason the spec can declare it -- so a gate runs
109
+ * keyless and offline.
110
+ */
111
+ export declare function embedderFor(model: PinnedEmbedding, options?: {
112
+ readonly apiKey?: string;
113
+ readonly baseUrl?: string;
114
+ readonly fetchImpl?: FetchLike;
115
+ }): Embedder;
116
+ //# sourceMappingURL=embedding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../../src/retrieval/embedding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,282 @@
1
+ /**
2
+ * Turning text into vectors.
3
+ *
4
+ * Two adapters, and that is the whole Phase 1 surface: one deterministic fake and
5
+ * one OpenAI-compatible HTTP client. The fake is not a testing afterthought -- it is
6
+ * the adapter the eval gate runs against, because a gate that needed an API key
7
+ * could not run offline in CI. That is the same reason the spec DSL already has
8
+ * `provider: fake` ("deterministic and keyless, which is what lets the eval gate run
9
+ * offline").
10
+ *
11
+ * The pinning rule lives in the seam, not in the adapters: `embed` takes a
12
+ * {@link PinnedEmbedding} and uses its `modelId` and `dimensions`. Nothing here
13
+ * resolves an alias, and the fake hashes the *pinned* model id into its vector, so a
14
+ * silently changed pin produces different vectors rather than a store full of
15
+ * incomparable ones.
16
+ */
17
+ import { createHash } from 'node:crypto';
18
+ import { ConfigurationError, ProviderError, ProviderResponseError } from '../errors.js';
19
+ import { repr } from '../internal/json.js';
20
+ import { stripTrailingSlashes } from '../internal/text.js';
21
+ import { DEFAULT_BASE_URL } from '../providers/http.js';
22
+ import { TokenUsage } from '../types.js';
23
+ /**
24
+ * Statuses worth a second attempt: the request was well-formed and the server was
25
+ * momentarily unwilling. Mirrors the chat provider's set so retry behaviour is one
26
+ * rule in this runtime rather than one rule per adapter.
27
+ */
28
+ const RETRYABLE_STATUS = new Set([408, 409, 425, 429, 500, 502, 503, 504]);
29
+ /**
30
+ * Rough tokeniser. Deliberately the same arithmetic as `estimatePromptCostUsd`
31
+ * (4 characters per token, rounded up), so an offline estimate and an offline charge
32
+ * cannot disagree about what a text costs.
33
+ */
34
+ const CHARS_PER_TOKEN = 4;
35
+ /** Vectors plus the usage that prices them. */
36
+ export class EmbeddingBatch {
37
+ vectors;
38
+ usage;
39
+ constructor(init) {
40
+ this.vectors = init.vectors.map((vector) => [...vector]);
41
+ this.usage = init.usage;
42
+ }
43
+ }
44
+ /** The offline token estimate used for the fake's usage and for budgets. */
45
+ export function estimateTokens(text) {
46
+ return (text.length + CHARS_PER_TOKEN - 1) >> 2;
47
+ }
48
+ /**
49
+ * Keyless, offline, and byte-identical across runs and platforms.
50
+ *
51
+ * Vectors come from SHAKE-128, a hash-based extensible output function, rather than
52
+ * from a seeded PRNG. The reason is the same property the rest of this runtime
53
+ * depends on: re-ingesting a corpus has to reproduce the vectors exactly, and
54
+ * re-embedding a *query* has to reproduce what ingest stored. A PRNG seeded per call
55
+ * would be stable too, but a hash makes "same text, same vector" true by
56
+ * construction rather than by discipline, and it cannot drift if a vector is later
57
+ * requested one element at a time.
58
+ *
59
+ * Similarity is meaningless here, and that is the deliberate limitation rather than
60
+ * a bug. Lexical retrieval still works over these vectors because the store keeps
61
+ * the text and hybrid search reads it; what the fake proves is the *pipeline*, and
62
+ * what it deliberately does not prove is embedding quality.
63
+ */
64
+ export class FakeDeterministicEmbedder {
65
+ _name;
66
+ constructor(init = {}) {
67
+ this._name = init.name ?? 'fake-embedder';
68
+ }
69
+ get name() {
70
+ return this._name;
71
+ }
72
+ async embed(texts, init) {
73
+ return new EmbeddingBatch({
74
+ vectors: texts.map((text) => this.vector(text, init.model)),
75
+ usage: new TokenUsage({
76
+ inputTokens: texts.reduce((total, text) => total + estimateTokens(text), 0),
77
+ outputTokens: 0,
78
+ }),
79
+ });
80
+ }
81
+ async close() {
82
+ return Promise.resolve();
83
+ }
84
+ vector(text, model) {
85
+ // The pinned model id is part of the input so the same text under a different
86
+ // pin embeds differently: a changed pin must invalidate stored vectors rather
87
+ // than silently mix two vector spaces in one table.
88
+ const seed = `${model.modelId}:${model.dimensions}\u0000${text}`;
89
+ const raw = createHash('shake128', { outputLength: model.dimensions * 2 })
90
+ .update(seed, 'utf8')
91
+ .digest();
92
+ const values = [];
93
+ for (let index = 0; index < model.dimensions; index += 1) {
94
+ values.push(raw.readUInt16BE(index * 2) / 32767.5 - 1.0);
95
+ }
96
+ const norm = Math.sqrt(values.reduce((total, value) => total + value * value, 0)) || 1.0;
97
+ return values.map((value) => value / norm);
98
+ }
99
+ }
100
+ /** One POST to `/embeddings` on any OpenAI-compatible endpoint. */
101
+ export class OpenAICompatibleEmbedder {
102
+ _baseUrl;
103
+ _apiKey;
104
+ _name;
105
+ _maxAttempts;
106
+ _backoffSeconds;
107
+ _extraHeaders;
108
+ _fetch;
109
+ _ownsClient;
110
+ _closed = false;
111
+ constructor(options = {}) {
112
+ const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
113
+ if (!/^https?:\/\/./i.test(baseUrl)) {
114
+ throw new ConfigurationError(`base_url must be an absolute http(s) URL, got ${repr(baseUrl)}`);
115
+ }
116
+ const maxAttempts = options.maxAttempts ?? 3;
117
+ if (maxAttempts < 1) {
118
+ throw new ConfigurationError('max_attempts must be at least 1');
119
+ }
120
+ this._baseUrl = stripTrailingSlashes(baseUrl);
121
+ this._apiKey = options.apiKey;
122
+ this._name = options.name ?? 'openai-compatible-embedder';
123
+ this._maxAttempts = maxAttempts;
124
+ this._backoffSeconds = options.backoffSeconds ?? 0.5;
125
+ this._extraHeaders = { ...(options.extraHeaders ?? {}) };
126
+ // Eager, like the chat provider: the caller may inject a transport (a test's
127
+ // stub, or a shared pool). Whoever constructed it closes it, so ownership is
128
+ // tracked rather than assumed.
129
+ this._ownsClient = options.fetchImpl === undefined;
130
+ this._fetch = options.fetchImpl ?? globalThis.fetch;
131
+ }
132
+ get name() {
133
+ return this._name;
134
+ }
135
+ async embed(texts, init) {
136
+ const body = await this.post('/embeddings', { model: init.model.modelId, input: [...texts] });
137
+ return this.parse(body, init.model);
138
+ }
139
+ async close() {
140
+ if (this._closed)
141
+ return;
142
+ this._closed = true;
143
+ // An injected transport belongs to its injector; there is nothing owned to close.
144
+ if (!this._ownsClient)
145
+ return;
146
+ return Promise.resolve();
147
+ }
148
+ headers() {
149
+ const headers = {
150
+ 'content-type': 'application/json',
151
+ ...this._extraHeaders,
152
+ };
153
+ if (this._apiKey !== undefined && this._apiKey.length > 0) {
154
+ // A real bearer token, not the chat provider's redacted placeholder: a request
155
+ // that claims to be authenticated and is not fails with a 401 that reads like a
156
+ // credentials problem at the far end.
157
+ headers.authorization = `Bearer ${this._apiKey}`;
158
+ }
159
+ return headers;
160
+ }
161
+ async post(path, payload) {
162
+ const url = `${this._baseUrl}${path}`;
163
+ let lastError = 'unknown error';
164
+ for (let attempt = 1; attempt <= this._maxAttempts; attempt += 1) {
165
+ let response;
166
+ try {
167
+ response = await this._fetch(url, {
168
+ method: 'POST',
169
+ headers: this.headers(),
170
+ body: JSON.stringify(payload),
171
+ });
172
+ }
173
+ catch (error) {
174
+ lastError = error instanceof Error ? error.message : String(error);
175
+ }
176
+ if (response !== undefined) {
177
+ const text = await response.text();
178
+ if (response.status < 400) {
179
+ return this.asObject(text);
180
+ }
181
+ const failure = `${this._name} returned HTTP ${response.status}: ${text.slice(0, 200)}`;
182
+ // A status outside the retryable set is a decision, not a hiccup: retrying a
183
+ // 400 only wastes the caller's time.
184
+ if (!RETRYABLE_STATUS.has(response.status)) {
185
+ throw new ProviderError(failure);
186
+ }
187
+ lastError = failure;
188
+ }
189
+ if (attempt < this._maxAttempts) {
190
+ await delay(this._backoffSeconds * 2 ** (attempt - 1));
191
+ }
192
+ }
193
+ throw new ProviderError(`${this._name} failed after ${this._maxAttempts} attempt(s): ${lastError}`);
194
+ }
195
+ asObject(text) {
196
+ let body;
197
+ try {
198
+ body = JSON.parse(text);
199
+ }
200
+ catch {
201
+ throw new ProviderResponseError(`${this._name} returned a body that is not JSON`);
202
+ }
203
+ if (typeof body !== 'object' || body === null || Array.isArray(body)) {
204
+ throw new ProviderResponseError(`${this._name} returned a JSON body that is not an object`);
205
+ }
206
+ return body;
207
+ }
208
+ parse(body, model) {
209
+ const entries = body.data;
210
+ if (!Array.isArray(entries) || entries.length === 0) {
211
+ throw new ProviderResponseError(`${this._name} returned no embeddings`);
212
+ }
213
+ const list = entries;
214
+ const ordered = [];
215
+ for (const [position, entry] of list.entries()) {
216
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
217
+ throw new ProviderResponseError(`${this._name} returned a non-object embedding entry`);
218
+ }
219
+ const record = entry;
220
+ const index = record.index ?? position;
221
+ if (!Number.isInteger(index)) {
222
+ throw new ProviderResponseError(`${this._name} returned a non-integer embedding index`);
223
+ }
224
+ ordered.push({ index: index, vector: record.embedding });
225
+ }
226
+ ordered.sort((left, right) => left.index - right.index);
227
+ const vectors = [];
228
+ for (const entry of ordered) {
229
+ if (!Array.isArray(entry.vector)) {
230
+ throw new ProviderResponseError(`${this._name} returned a non-list embedding`);
231
+ }
232
+ const values = [];
233
+ for (const value of entry.vector) {
234
+ const numeric = typeof value === 'number' ? value : Number(value);
235
+ if (!Number.isFinite(numeric)) {
236
+ throw new ProviderResponseError(`${this._name} returned a non-numeric embedding`);
237
+ }
238
+ values.push(numeric);
239
+ }
240
+ if (values.length !== model.dimensions) {
241
+ throw new ProviderResponseError(`${this._name} returned ${values.length} dimensions for ${repr(model.modelId)} but ` +
242
+ `${model.dimensions} are pinned; the pin and the response must agree`);
243
+ }
244
+ vectors.push(values);
245
+ }
246
+ const usage = body.usage;
247
+ const found = typeof usage === 'object' && usage !== null
248
+ ? usage.prompt_tokens
249
+ : undefined;
250
+ const promptTokens = typeof found === 'number' && Number.isInteger(found) ? found : 0;
251
+ return new EmbeddingBatch({
252
+ vectors,
253
+ usage: new TokenUsage({ inputTokens: promptTokens, outputTokens: 0 }),
254
+ });
255
+ }
256
+ }
257
+ function delay(seconds) {
258
+ if (seconds <= 0)
259
+ return Promise.resolve();
260
+ return new Promise((resolve) => {
261
+ setTimeout(resolve, seconds * 1000);
262
+ });
263
+ }
264
+ /**
265
+ * Pick the adapter for a pinned embedding model.
266
+ *
267
+ * This selects a *provider*, never a model: the model id and its width arrive
268
+ * already pinned, and are passed straight through to whichever adapter is chosen.
269
+ * `fake` is chosen for the same reason the spec can declare it -- so a gate runs
270
+ * keyless and offline.
271
+ */
272
+ export function embedderFor(model, options = {}) {
273
+ if (model.provider === 'fake') {
274
+ return new FakeDeterministicEmbedder();
275
+ }
276
+ return new OpenAICompatibleEmbedder({
277
+ baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
278
+ apiKey: options.apiKey,
279
+ fetchImpl: options.fetchImpl,
280
+ });
281
+ }
282
+ //# sourceMappingURL=embedding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../src/retrieval/embedding.ts"],"names":[],"mappings":"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"}