@promptev/context-engine 0.0.0 → 0.0.2

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 (60) hide show
  1. package/README.md +116 -5
  2. package/dist/cli.js +1896 -552
  3. package/dist/cli.js.map +1 -1
  4. package/dist/{config-Bl9U789m.d.cts → config-BODDdXJ7.d.ts} +75 -16
  5. package/dist/{config-Bt9bUQqU.d.ts → config-C5RZ00W6.d.cts} +75 -16
  6. package/dist/express.cjs +925 -151
  7. package/dist/express.cjs.map +1 -1
  8. package/dist/express.d.cts +11 -4
  9. package/dist/express.d.ts +11 -4
  10. package/dist/express.js +926 -152
  11. package/dist/express.js.map +1 -1
  12. package/dist/fastify.cjs +923 -151
  13. package/dist/fastify.cjs.map +1 -1
  14. package/dist/fastify.d.cts +8 -4
  15. package/dist/fastify.d.ts +8 -4
  16. package/dist/fastify.js +924 -152
  17. package/dist/fastify.js.map +1 -1
  18. package/dist/{governance-XIScatRO.d.ts → governance-BLPK7NMe.d.ts} +8 -2
  19. package/dist/{governance-BDkcv4qZ.d.cts → governance-P9pRb4Ol.d.cts} +8 -2
  20. package/dist/graph/index.cjs +171 -59
  21. package/dist/graph/index.cjs.map +1 -1
  22. package/dist/graph/index.d.cts +5 -3
  23. package/dist/graph/index.d.ts +5 -3
  24. package/dist/graph/index.js +171 -59
  25. package/dist/graph/index.js.map +1 -1
  26. package/dist/hono.cjs +923 -151
  27. package/dist/hono.cjs.map +1 -1
  28. package/dist/hono.d.cts +8 -4
  29. package/dist/hono.d.ts +8 -4
  30. package/dist/hono.js +924 -152
  31. package/dist/hono.js.map +1 -1
  32. package/dist/index.cjs +2413 -1052
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +125 -107
  35. package/dist/index.d.ts +125 -107
  36. package/dist/index.js +2412 -1050
  37. package/dist/index.js.map +1 -1
  38. package/dist/mcp.cjs +100 -14
  39. package/dist/mcp.cjs.map +1 -1
  40. package/dist/mcp.d.cts +5 -0
  41. package/dist/mcp.d.ts +5 -0
  42. package/dist/mcp.js +100 -14
  43. package/dist/mcp.js.map +1 -1
  44. package/dist/migrations/sql/0003_tools.sql +2 -0
  45. package/dist/migrations/sql/0004_acl_indexes.sql +23 -2
  46. package/dist/{redaction-BmDSWJ7h.d.cts → redaction-BqD_DEUQ.d.cts} +22 -1
  47. package/dist/{redaction-BmDSWJ7h.d.ts → redaction-BqD_DEUQ.d.ts} +22 -1
  48. package/dist/redaction-presidio.d.cts +1 -1
  49. package/dist/redaction-presidio.d.ts +1 -1
  50. package/dist/{router-CrxZ2y_Z.d.ts → router-CiFwC-EN.d.cts} +17 -2
  51. package/dist/{router-OPgSoYAB.d.cts → router-D8gBzwLd.d.ts} +17 -2
  52. package/dist/skills/context-engine/SKILL.md +5 -1
  53. package/dist/storage-CJrKgJeJ.d.ts +167 -0
  54. package/dist/storage-Dvpq2xAC.d.cts +167 -0
  55. package/package.json +61 -23
  56. package/src/migrations/sql/0003_tools.sql +2 -0
  57. package/src/migrations/sql/0004_acl_indexes.sql +23 -2
  58. package/src/skills/context-engine/SKILL.md +5 -1
  59. package/dist/embeddings-B-jZ42mk.d.cts +0 -67
  60. package/dist/embeddings-DaSdAZN3.d.ts +0 -67
@@ -0,0 +1,167 @@
1
+ import { b as EmbeddingConfig } from './config-C5RZ00W6.cjs';
2
+ import { PoolClient, Pool } from 'pg';
3
+
4
+ /**
5
+ * Pluggable embeddings provider.
6
+ *
7
+ * openai / azure_openai / custom → OpenAI SDK (OpenAI-compatible, including TEI/vLLM).
8
+ * gemini / vertex_ai → lazy `@google/genai` (optional extra "gemini"). One
9
+ * code path: same SDK and models, differing only in how the client
10
+ * authenticates (API key vs ADC against a GCP project) — see
11
+ * `providers/google.ts`.
12
+ * voyage / cohere → fetch against their public REST APIs.
13
+ *
14
+ * `kind` is accepted everywhere but only voyage/cohere act on it.
15
+ * 30s timeout, no retries. Injectable `client` / `fetch` for tests.
16
+ */
17
+
18
+ type EmbedKind = "document" | "query";
19
+ type FetchImpl = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
20
+ type EmbeddingsClient = {
21
+ embeddings: {
22
+ create(body: {
23
+ model: string;
24
+ input: string[];
25
+ }): Promise<{
26
+ data: Array<{
27
+ embedding: number[];
28
+ }>;
29
+ usage?: {
30
+ total_tokens?: number;
31
+ } | null;
32
+ }>;
33
+ };
34
+ close?: () => void | Promise<void>;
35
+ timeout?: number;
36
+ baseURL?: string;
37
+ };
38
+ type EmbedderOpts = {
39
+ client?: EmbeddingsClient | null;
40
+ fetch?: FetchImpl | null;
41
+ fetchImpl?: FetchImpl | null;
42
+ };
43
+ declare class Embedder {
44
+ cfg: EmbeddingConfig;
45
+ provider: EmbeddingConfig["provider"];
46
+ model: string;
47
+ dim: number | null;
48
+ client: EmbeddingsClient | null;
49
+ fetchImpl: FetchImpl | null;
50
+ private genaiClient;
51
+ constructor(cfg: EmbeddingConfig, opts?: EmbedderOpts);
52
+ aclose(): Promise<void>;
53
+ [Symbol.asyncDispose](): Promise<void>;
54
+ /**
55
+ * Embed `texts`, returning `[vectors, tokenCount]`.
56
+ * Auto-detects `this.dim` on first success; raises on mismatch.
57
+ */
58
+ embed(texts: string[], opts?: {
59
+ kind?: EmbedKind;
60
+ }): Promise<[number[][], number]>;
61
+ /** Provider dispatch. Overridable per-instance (tests stub this). */
62
+ rawEmbed(texts: string[], kind?: EmbedKind): Promise<[number[][], number]>;
63
+ private embedOpenAI;
64
+ private embedGemini;
65
+ private embedVoyage;
66
+ private embedCohere;
67
+ private requireFetch;
68
+ }
69
+ declare function buildEmbedder(cfg: EmbeddingConfig, opts?: EmbedderOpts): Embedder;
70
+
71
+ interface ChunkRow {
72
+ idx: number;
73
+ text: string;
74
+ lang?: string | null;
75
+ embedding?: number[] | null;
76
+ meta?: Record<string, unknown>;
77
+ }
78
+ interface SearchScope {
79
+ sourceIds?: string[] | null;
80
+ /** Narrows WITHIN a source and INTERSECTS with `sourceIds` rather than
81
+ * widening it: a consumer that binds an agent to three of a source's
82
+ * documents needs a filter `sourceIds` cannot express, since every one of
83
+ * those documents shares the same source. */
84
+ documentIds?: string[] | null;
85
+ principals?: string[] | null;
86
+ limit?: number;
87
+ }
88
+ /** The ANN scan tuning the vector leg and the graph leg's seed query share.
89
+ * Named separately from `StorageBackend`, which carries it as an OPTIONAL
90
+ * member: a backend with no approximate index has no such knobs. */
91
+ interface AnnTunable {
92
+ tuneAnnScan(client: PoolClient, limit: number, scoped: boolean): Promise<void>;
93
+ }
94
+ interface StorageBackend {
95
+ supportsFts: boolean;
96
+ supportsTrgm: boolean;
97
+ supportsAnn: boolean;
98
+ upsertChunks(documentId: string, sourceId: string | null, acl: string[] | null, chunks: readonly ChunkRow[]): Promise<number>;
99
+ deleteChunks(documentId: string): Promise<void>;
100
+ updateChunkEmbeddings(documentId: string, vectors: readonly number[][]): Promise<number>;
101
+ updateChunkAcl(documentId: string, acl: string[] | null): Promise<number>;
102
+ filterIds(chunkIds: readonly string[], scope: SearchScope): Promise<string[]>;
103
+ ftsSearch(query: string, scope: SearchScope): Promise<string[]>;
104
+ trgmSearch(query: string, scope: SearchScope): Promise<string[]>;
105
+ annSearch(vector: readonly number[], scope: SearchScope): Promise<string[]>;
106
+ /** Optional: only a backend with an approximate index has a scan to tune.
107
+ * The graph leg's seed query is the second caller — see `AnnTunable`. */
108
+ tuneAnnScan?: AnnTunable["tuneAnnScan"];
109
+ }
110
+ declare class PostgresBackend implements StorageBackend {
111
+ supportsFts: boolean;
112
+ supportsTrgm: boolean;
113
+ supportsAnn: boolean;
114
+ private readonly pool;
115
+ private readonly exactThresholdOverride;
116
+ /** Tri-state: null = not yet checked. */
117
+ private iterativeScan;
118
+ constructor(pool: Pool, exactThreshold?: number | null);
119
+ private get exactThreshold();
120
+ /**
121
+ * Bind values for SCOPE + the row limit.
122
+ * `principals` is passed through UNCHANGED: null (trusted) and [] (anonymous)
123
+ * mean different things.
124
+ */
125
+ private scopeParams;
126
+ upsertChunks(documentId: string, sourceId: string | null, acl: string[] | null, chunks: readonly ChunkRow[]): Promise<number>;
127
+ deleteChunks(documentId: string): Promise<void>;
128
+ updateChunkEmbeddings(documentId: string, vectors: readonly number[][]): Promise<number>;
129
+ updateChunkAcl(documentId: string, acl: string[] | null): Promise<number>;
130
+ filterIds(chunkIds: readonly string[], scope: SearchScope): Promise<string[]>;
131
+ ftsSearch(query: string, scope: SearchScope): Promise<string[]>;
132
+ trgmSearch(query: string, scope: SearchScope): Promise<string[]>;
133
+ /**
134
+ * Set pg_trgm's similarity threshold for this query via the `set_limit()` /
135
+ * `show_limit()` FUNCTIONS — never the GUC `pg_trgm.similarity_threshold`.
136
+ *
137
+ * The GUC is registered lazily, only once pg_trgm's shared library is loaded
138
+ * into the backend process. On a fresh pooled connection that has not yet
139
+ * run any pg_trgm operation, `SHOW pg_trgm.similarity_threshold` raises
140
+ * "unrecognized configuration parameter" — and because that error aborts the
141
+ * surrounding transaction, a fallback issued on the same connection then
142
+ * fails with "current transaction is aborted". Every connection a pool hands
143
+ * out is fresh, so this is the common case, not an edge case. Calling
144
+ * `set_limit()` loads the library and does not depend on the GUC. This
145
+ * mirrors the Python backend, which was hardened against exactly this.
146
+ *
147
+ * `set_limit()` is connection-scoped and survives COMMIT and the return to
148
+ * the pool, so the previous value is captured here and restored by the
149
+ * caller.
150
+ */
151
+ private applyTrgmThreshold;
152
+ private restoreTrgmLimit;
153
+ annSearch(vector: readonly number[], scope: SearchScope): Promise<string[]>;
154
+ private eligibleIsSmall;
155
+ /** Size the HNSW candidate budget, and make it iterative when filtered.
156
+ *
157
+ * Public because the graph leg's seed query (`graph/retrieval.ts`) is the
158
+ * same shape — an ANN walk with the scope predicate as a POST-filter — and
159
+ * must not carry a second copy of this. Call it inside a transaction on the
160
+ * client the query itself will run on: every setting here is `SET LOCAL`. */
161
+ tuneAnnScan(client: PoolClient, limit: number, scoped: boolean): Promise<void>;
162
+ private scanBudget;
163
+ private enableIterativeScan;
164
+ private supportsIterativeScan;
165
+ }
166
+
167
+ export { type AnnTunable as A, type ChunkRow as C, Embedder as E, type FetchImpl as F, PostgresBackend as P, type StorageBackend as S, type EmbedKind as a, type SearchScope as b, buildEmbedder as c };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptev/context-engine",
3
- "version": "0.0.0",
3
+ "version": "0.0.2",
4
4
  "description": "Promptev Context Engine — language-agnostic ingestion + hybrid retrieval (TypeScript)",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Promptev Inc",
@@ -33,39 +33,74 @@
33
33
  },
34
34
  "exports": {
35
35
  ".": {
36
- "types": "./dist/index.d.ts",
37
- "import": "./dist/index.js",
38
- "require": "./dist/index.cjs"
36
+ "import": {
37
+ "types": "./dist/index.d.ts",
38
+ "default": "./dist/index.js"
39
+ },
40
+ "require": {
41
+ "types": "./dist/index.d.cts",
42
+ "default": "./dist/index.cjs"
43
+ }
39
44
  },
40
45
  "./hono": {
41
- "types": "./dist/hono.d.ts",
42
- "import": "./dist/hono.js",
43
- "require": "./dist/hono.cjs"
46
+ "import": {
47
+ "types": "./dist/hono.d.ts",
48
+ "default": "./dist/hono.js"
49
+ },
50
+ "require": {
51
+ "types": "./dist/hono.d.cts",
52
+ "default": "./dist/hono.cjs"
53
+ }
44
54
  },
45
55
  "./express": {
46
- "types": "./dist/express.d.ts",
47
- "import": "./dist/express.js",
48
- "require": "./dist/express.cjs"
56
+ "import": {
57
+ "types": "./dist/express.d.ts",
58
+ "default": "./dist/express.js"
59
+ },
60
+ "require": {
61
+ "types": "./dist/express.d.cts",
62
+ "default": "./dist/express.cjs"
63
+ }
49
64
  },
50
65
  "./fastify": {
51
- "types": "./dist/fastify.d.ts",
52
- "import": "./dist/fastify.js",
53
- "require": "./dist/fastify.cjs"
66
+ "import": {
67
+ "types": "./dist/fastify.d.ts",
68
+ "default": "./dist/fastify.js"
69
+ },
70
+ "require": {
71
+ "types": "./dist/fastify.d.cts",
72
+ "default": "./dist/fastify.cjs"
73
+ }
54
74
  },
55
75
  "./mcp": {
56
- "types": "./dist/mcp.d.ts",
57
- "import": "./dist/mcp.js",
58
- "require": "./dist/mcp.cjs"
76
+ "import": {
77
+ "types": "./dist/mcp.d.ts",
78
+ "default": "./dist/mcp.js"
79
+ },
80
+ "require": {
81
+ "types": "./dist/mcp.d.cts",
82
+ "default": "./dist/mcp.cjs"
83
+ }
59
84
  },
60
85
  "./graph": {
61
- "types": "./dist/graph/index.d.ts",
62
- "import": "./dist/graph/index.js",
63
- "require": "./dist/graph/index.cjs"
86
+ "import": {
87
+ "types": "./dist/graph/index.d.ts",
88
+ "default": "./dist/graph/index.js"
89
+ },
90
+ "require": {
91
+ "types": "./dist/graph/index.d.cts",
92
+ "default": "./dist/graph/index.cjs"
93
+ }
64
94
  },
65
95
  "./presidio": {
66
- "types": "./dist/redaction-presidio.d.ts",
67
- "import": "./dist/redaction-presidio.js",
68
- "require": "./dist/redaction-presidio.cjs"
96
+ "import": {
97
+ "types": "./dist/redaction-presidio.d.ts",
98
+ "default": "./dist/redaction-presidio.js"
99
+ },
100
+ "require": {
101
+ "types": "./dist/redaction-presidio.d.cts",
102
+ "default": "./dist/redaction-presidio.cjs"
103
+ }
69
104
  }
70
105
  },
71
106
  "files": [
@@ -86,7 +121,8 @@
86
121
  "typecheck": "tsc --noEmit",
87
122
  "lint": "biome check src tests",
88
123
  "lint:fix": "biome check --write src tests",
89
- "context-engine": "node dist/cli.js"
124
+ "context-engine": "node dist/cli.js",
125
+ "prepublishOnly": "npm run lint && npm run typecheck && npm run build"
90
126
  },
91
127
  "dependencies": {
92
128
  "cheerio": "^1.1.0",
@@ -172,6 +208,8 @@
172
208
  },
173
209
  "devDependencies": {
174
210
  "@biomejs/biome": "^2.1.0",
211
+ "@modelcontextprotocol/sdk": "^1.30.0",
212
+ "@napi-rs/canvas": "^1.0.6",
175
213
  "@testcontainers/postgresql": "^11.0.0",
176
214
  "@types/express": "^5.0.0",
177
215
  "@types/node": "^22.16.0",
@@ -11,6 +11,7 @@ CREATE TABLE context_engine_tools (
11
11
  requires_approval BOOLEAN NOT NULL DEFAULT false,
12
12
  approval_policy JSONB NOT NULL DEFAULT '{}'::jsonb,
13
13
  enabled BOOLEAN NOT NULL DEFAULT true,
14
+ meta_data JSONB NOT NULL DEFAULT '{}'::jsonb,
14
15
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
15
16
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
16
17
  );
@@ -22,6 +23,7 @@ CREATE TABLE context_engine_tool_approvals (
22
23
  tool_args_frozen JSONB NOT NULL DEFAULT '{}'::jsonb,
23
24
  source_id TEXT,
24
25
  principals JSONB,
26
+ approval_scope TEXT,
25
27
  status TEXT NOT NULL DEFAULT 'pending',
26
28
  approver TEXT,
27
29
  approver_meta JSONB,
@@ -1,4 +1,25 @@
1
1
  -- 0004_acl_indexes
2
+ -- IF NOT EXISTS: this file doubles as the HEAL step runMigrate applies after
3
+ -- every chain walk — see the comment in db.ts.
2
4
 
3
- CREATE INDEX ix_context_engine_chunks_acl_gin ON context_engine_chunks USING gin (acl);
4
- CREATE INDEX ix_context_engine_documents_acl_gin ON context_engine_documents USING gin (acl);
5
+ CREATE INDEX IF NOT EXISTS ix_context_engine_chunks_acl_gin ON context_engine_chunks USING gin (acl);
6
+ CREATE INDEX IF NOT EXISTS ix_context_engine_documents_acl_gin ON context_engine_documents USING gin (acl);
7
+
8
+ -- tools.meta_data (2026-08-18) — engine-opaque user metadata, added after
9
+ -- the tools chain revision shipped. Riding the heal step (this file re-runs
10
+ -- after every chain walk) converges every existing database without
11
+ -- re-parenting the chain; fresh databases also get it from 0003's CREATE.
12
+ -- The Python port does the same in cli.py `_heal_schema`.
13
+ ALTER TABLE context_engine_tools ADD COLUMN IF NOT EXISTS meta_data JSONB NOT NULL DEFAULT '{}'::jsonb;
14
+
15
+ -- tool_approvals.approval_scope (2026-09-04) — the claim scope, separate from
16
+ -- the tool-lookup source_id. The partial UNIQUE index is what makes
17
+ -- findOrCreatePending race-safe: two identical calls in one scope can only
18
+ -- ever leave one pending row. md5(jsonb::text) is stable because jsonb text
19
+ -- output is canonical. The Python port does the same in cli.py _heal_schema.
20
+ ALTER TABLE context_engine_tool_approvals ADD COLUMN IF NOT EXISTS approval_scope TEXT;
21
+ CREATE INDEX IF NOT EXISTS ix_context_engine_tool_approvals_claim
22
+ ON context_engine_tool_approvals (tool_name, approval_scope, status);
23
+ CREATE UNIQUE INDEX IF NOT EXISTS ux_context_engine_tool_approvals_pending_scope
24
+ ON context_engine_tool_approvals (tool_name, approval_scope, md5(tool_args_frozen::text))
25
+ WHERE status = 'pending' AND approval_scope IS NOT NULL;
@@ -70,7 +70,11 @@ await engine.search(q, { principals: user.groups }); // scoped
70
70
  silently loses recall — queries return fewer rows than match, or none, with
71
71
  no error. The library cannot compensate.
72
72
  - **`config.enableCodeExecution` is `false` on purpose.** `engine.compute()`
73
- executes generated code. Turn it on only deliberately.
73
+ and `computeOverFrames()` execute generated code. Turn it on only
74
+ deliberately. `computeOverFrames({ sheet: rows }, instruction, { config:
75
+ engine.config })` is the same guarded path for tables the host already holds
76
+ (no document to point at); redaction masks every string cell AND every column
77
+ header before the LLM sees a schema, and sweeps the result.
74
78
  - Filing a document under an ACL the caller does not hold returns **403**, on
75
79
  ingest and on PATCH alike.
76
80
 
@@ -1,67 +0,0 @@
1
- import { E as EmbeddingConfig } from './config-Bl9U789m.cjs';
2
-
3
- /**
4
- * Pluggable embeddings provider.
5
- *
6
- * openai / azure_openai / custom → OpenAI SDK (OpenAI-compatible, including TEI/vLLM).
7
- * gemini → lazy `@google/genai` (optional extra "gemini").
8
- * voyage / cohere → fetch against their public REST APIs.
9
- *
10
- * `kind` is accepted everywhere but only voyage/cohere act on it.
11
- * 30s timeout, no retries. Injectable `client` / `fetch` for tests.
12
- */
13
-
14
- type EmbedKind = "document" | "query";
15
- type FetchImpl = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
16
- type EmbeddingsClient = {
17
- embeddings: {
18
- create(body: {
19
- model: string;
20
- input: string[];
21
- }): Promise<{
22
- data: Array<{
23
- embedding: number[];
24
- }>;
25
- usage?: {
26
- total_tokens?: number;
27
- } | null;
28
- }>;
29
- };
30
- close?: () => void | Promise<void>;
31
- timeout?: number;
32
- baseURL?: string;
33
- };
34
- type EmbedderOpts = {
35
- client?: EmbeddingsClient | null;
36
- fetch?: FetchImpl | null;
37
- fetchImpl?: FetchImpl | null;
38
- };
39
- declare class Embedder {
40
- cfg: EmbeddingConfig;
41
- provider: EmbeddingConfig["provider"];
42
- model: string;
43
- dim: number | null;
44
- client: EmbeddingsClient | null;
45
- fetchImpl: FetchImpl | null;
46
- private genaiClient;
47
- constructor(cfg: EmbeddingConfig, opts?: EmbedderOpts);
48
- aclose(): Promise<void>;
49
- [Symbol.asyncDispose](): Promise<void>;
50
- /**
51
- * Embed `texts`, returning `[vectors, tokenCount]`.
52
- * Auto-detects `this.dim` on first success; raises on mismatch.
53
- */
54
- embed(texts: string[], opts?: {
55
- kind?: EmbedKind;
56
- }): Promise<[number[][], number]>;
57
- /** Provider dispatch. Overridable per-instance (tests stub this). */
58
- rawEmbed(texts: string[], kind?: EmbedKind): Promise<[number[][], number]>;
59
- private embedOpenAI;
60
- private embedGemini;
61
- private embedVoyage;
62
- private embedCohere;
63
- private requireFetch;
64
- }
65
- declare function buildEmbedder(cfg: EmbeddingConfig, opts?: EmbedderOpts): Embedder;
66
-
67
- export { Embedder as E, type FetchImpl as F, type EmbedKind as a, buildEmbedder as b };
@@ -1,67 +0,0 @@
1
- import { E as EmbeddingConfig } from './config-Bt9bUQqU.js';
2
-
3
- /**
4
- * Pluggable embeddings provider.
5
- *
6
- * openai / azure_openai / custom → OpenAI SDK (OpenAI-compatible, including TEI/vLLM).
7
- * gemini → lazy `@google/genai` (optional extra "gemini").
8
- * voyage / cohere → fetch against their public REST APIs.
9
- *
10
- * `kind` is accepted everywhere but only voyage/cohere act on it.
11
- * 30s timeout, no retries. Injectable `client` / `fetch` for tests.
12
- */
13
-
14
- type EmbedKind = "document" | "query";
15
- type FetchImpl = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
16
- type EmbeddingsClient = {
17
- embeddings: {
18
- create(body: {
19
- model: string;
20
- input: string[];
21
- }): Promise<{
22
- data: Array<{
23
- embedding: number[];
24
- }>;
25
- usage?: {
26
- total_tokens?: number;
27
- } | null;
28
- }>;
29
- };
30
- close?: () => void | Promise<void>;
31
- timeout?: number;
32
- baseURL?: string;
33
- };
34
- type EmbedderOpts = {
35
- client?: EmbeddingsClient | null;
36
- fetch?: FetchImpl | null;
37
- fetchImpl?: FetchImpl | null;
38
- };
39
- declare class Embedder {
40
- cfg: EmbeddingConfig;
41
- provider: EmbeddingConfig["provider"];
42
- model: string;
43
- dim: number | null;
44
- client: EmbeddingsClient | null;
45
- fetchImpl: FetchImpl | null;
46
- private genaiClient;
47
- constructor(cfg: EmbeddingConfig, opts?: EmbedderOpts);
48
- aclose(): Promise<void>;
49
- [Symbol.asyncDispose](): Promise<void>;
50
- /**
51
- * Embed `texts`, returning `[vectors, tokenCount]`.
52
- * Auto-detects `this.dim` on first success; raises on mismatch.
53
- */
54
- embed(texts: string[], opts?: {
55
- kind?: EmbedKind;
56
- }): Promise<[number[][], number]>;
57
- /** Provider dispatch. Overridable per-instance (tests stub this). */
58
- rawEmbed(texts: string[], kind?: EmbedKind): Promise<[number[][], number]>;
59
- private embedOpenAI;
60
- private embedGemini;
61
- private embedVoyage;
62
- private embedCohere;
63
- private requireFetch;
64
- }
65
- declare function buildEmbedder(cfg: EmbeddingConfig, opts?: EmbedderOpts): Embedder;
66
-
67
- export { Embedder as E, type FetchImpl as F, type EmbedKind as a, buildEmbedder as b };