@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
@@ -1,6 +1,6 @@
1
1
  import { Pool } from 'pg';
2
- import { C as ContextEngineConfig } from './config-Bt9bUQqU.js';
3
- import { H as Hooks } from './redaction-BmDSWJ7h.js';
2
+ import { C as ContextEngineConfig } from './config-BODDdXJ7.js';
3
+ import { H as Hooks } from './redaction-BqD_DEUQ.js';
4
4
 
5
5
  type ToolKind = "http" | "db" | "mcp" | "function";
6
6
  interface ToolConfigInit {
@@ -17,6 +17,8 @@ interface ToolConfigInit {
17
17
  approvalPolicy?: Record<string, unknown>;
18
18
  approval_policy?: Record<string, unknown>;
19
19
  enabled?: boolean;
20
+ metaData?: Record<string, unknown>;
21
+ meta_data?: Record<string, unknown>;
20
22
  }
21
23
  /**
22
24
  * Caller-facing shape for registering a tool. Kind-specific `config` is
@@ -33,6 +35,10 @@ declare class ToolConfig {
33
35
  requiresApproval: boolean;
34
36
  approvalPolicy: Record<string, unknown>;
35
37
  enabled: boolean;
38
+ /** Engine-opaque user metadata (documents have the same column). Stored
39
+ * and returned in CLEAR on the admin surface only — secrets go in
40
+ * `config`, which is encrypted. */
41
+ metaData: Record<string, unknown>;
36
42
  constructor(init: ToolConfigInit);
37
43
  static fromUnknown(body: unknown): ToolConfig;
38
44
  }
@@ -1,6 +1,6 @@
1
1
  import { Pool } from 'pg';
2
- import { C as ContextEngineConfig } from './config-Bl9U789m.cjs';
3
- import { H as Hooks } from './redaction-BmDSWJ7h.cjs';
2
+ import { C as ContextEngineConfig } from './config-C5RZ00W6.cjs';
3
+ import { H as Hooks } from './redaction-BqD_DEUQ.cjs';
4
4
 
5
5
  type ToolKind = "http" | "db" | "mcp" | "function";
6
6
  interface ToolConfigInit {
@@ -17,6 +17,8 @@ interface ToolConfigInit {
17
17
  approvalPolicy?: Record<string, unknown>;
18
18
  approval_policy?: Record<string, unknown>;
19
19
  enabled?: boolean;
20
+ metaData?: Record<string, unknown>;
21
+ meta_data?: Record<string, unknown>;
20
22
  }
21
23
  /**
22
24
  * Caller-facing shape for registering a tool. Kind-specific `config` is
@@ -33,6 +35,10 @@ declare class ToolConfig {
33
35
  requiresApproval: boolean;
34
36
  approvalPolicy: Record<string, unknown>;
35
37
  enabled: boolean;
38
+ /** Engine-opaque user metadata (documents have the same column). Stored
39
+ * and returned in CLEAR on the admin surface only — secrets go in
40
+ * `config`, which is encrypted. */
41
+ metaData: Record<string, unknown>;
36
42
  constructor(init: ToolConfigInit);
37
43
  static fromUnknown(body: unknown): ToolConfig;
38
44
  }
@@ -65,9 +65,52 @@ var init_hooks = __esm({
65
65
  }
66
66
  });
67
67
 
68
+ // src/providers/google.ts
69
+ async function buildGenaiClient(cfg, timeoutMs, purpose) {
70
+ const specifier = "@google/genai";
71
+ let mod;
72
+ try {
73
+ mod = await import(specifier);
74
+ } catch {
75
+ throw new ExtraMissingError("gemini", specifier, purpose);
76
+ }
77
+ const Ctor = mod.GoogleGenAI ?? mod.Client;
78
+ if (!Ctor) {
79
+ throw new ExtraMissingError("gemini", specifier, purpose);
80
+ }
81
+ const opts = { httpOptions: { timeout: timeoutMs } };
82
+ if (cfg.provider === "vertex_ai") {
83
+ opts.vertexai = true;
84
+ if (cfg.project || cfg.location) {
85
+ if (cfg.project) opts.project = cfg.project;
86
+ if (cfg.location) opts.location = cfg.location;
87
+ } else if (cfg.apiKey) {
88
+ opts.apiKey = cfg.apiKey;
89
+ }
90
+ } else {
91
+ opts.apiKey = cfg.apiKey ?? null;
92
+ }
93
+ try {
94
+ return new Ctor(opts);
95
+ } catch (err) {
96
+ const message = err instanceof Error ? err.message : String(err);
97
+ if (!message.includes("Authentication is not set up")) throw err;
98
+ throw new Error(
99
+ `${message} Set \`project\` on the provider config, or export GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION. Credentials themselves come from Application Default Credentials.`
100
+ );
101
+ }
102
+ }
103
+ var init_google = __esm({
104
+ "src/providers/google.ts"() {
105
+ init_errors();
106
+ }
107
+ });
108
+
68
109
  // src/providers/llm.ts
69
110
  var llm_exports = {};
70
111
  __export(llm_exports, {
112
+ CALL_TIMEOUT_MS: () => CALL_TIMEOUT_MS,
113
+ GEMINI_CALL_TIMEOUT_MS: () => GEMINI_CALL_TIMEOUT_MS,
71
114
  LLMClient: () => LLMClient,
72
115
  TIMEOUT_MS: () => TIMEOUT_MS,
73
116
  buildLlmClient: () => buildLlmClient,
@@ -98,20 +141,6 @@ function buildOpenAIChatClient(cfg) {
98
141
  maxRetries: 0
99
142
  });
100
143
  }
101
- async function loadGeminiChatClient(apiKey) {
102
- const specifier = "@google/genai";
103
- let mod;
104
- try {
105
- mod = await import(specifier);
106
- } catch {
107
- throw new ExtraMissingError("gemini", specifier, "gemini llm");
108
- }
109
- const Ctor = mod.GoogleGenAI ?? mod.Client;
110
- if (!Ctor) {
111
- throw new ExtraMissingError("gemini", specifier, "gemini llm");
112
- }
113
- return new Ctor({ apiKey: apiKey ?? null });
114
- }
115
144
  async function loadBedrockSdk() {
116
145
  const specifier = "@aws-sdk/client-bedrock-runtime";
117
146
  try {
@@ -130,7 +159,7 @@ function buildLlmClient(cfg, opts) {
130
159
  if (OPENAI_FAMILY.has(cfg.provider)) {
131
160
  return new LLMClient(cfg, { client: buildOpenAIChatClient(cfg) });
132
161
  }
133
- if (cfg.provider === "gemini" || cfg.provider === "bedrock") {
162
+ if (GOOGLE_FAMILY.has(cfg.provider) || cfg.provider === "bedrock") {
134
163
  return new LLMClient(cfg);
135
164
  }
136
165
  throw new Error(`unknown llm provider: ${JSON.stringify(cfg.provider)}`);
@@ -147,14 +176,18 @@ async function callLlm(cfg, opts) {
147
176
  await owned.aclose();
148
177
  }
149
178
  }
150
- var TIMEOUT_MS, ANTHROPIC_VERSION, ANTHROPIC_MAX_TOKENS, OPENAI_FAMILY, LLMClient;
179
+ var CALL_TIMEOUT_MS, TIMEOUT_MS, GEMINI_CALL_TIMEOUT_MS, ANTHROPIC_VERSION, ANTHROPIC_MAX_TOKENS, OPENAI_FAMILY, GOOGLE_FAMILY, LLMClient;
151
180
  var init_llm = __esm({
152
181
  "src/providers/llm.ts"() {
153
182
  init_errors();
154
- TIMEOUT_MS = 3e4;
183
+ init_google();
184
+ CALL_TIMEOUT_MS = 24e4;
185
+ TIMEOUT_MS = CALL_TIMEOUT_MS;
186
+ GEMINI_CALL_TIMEOUT_MS = CALL_TIMEOUT_MS;
155
187
  ANTHROPIC_VERSION = "2023-06-01";
156
188
  ANTHROPIC_MAX_TOKENS = 4096;
157
189
  OPENAI_FAMILY = /* @__PURE__ */ new Set(["openai", "azure_openai", "custom"]);
190
+ GOOGLE_FAMILY = /* @__PURE__ */ new Set(["gemini", "vertex_ai"]);
158
191
  LLMClient = class {
159
192
  cfg;
160
193
  provider;
@@ -179,22 +212,30 @@ var init_llm = __esm({
179
212
  await this.aclose();
180
213
  }
181
214
  async call(opts) {
182
- const { system, user, jsonMode = false, images = null } = opts;
215
+ const {
216
+ system,
217
+ user,
218
+ jsonMode = false,
219
+ images = null,
220
+ maxTokens = null,
221
+ thinkingBudget = null,
222
+ temperature = null
223
+ } = opts;
183
224
  if (this.provider === "anthropic") {
184
- return this.callAnthropic(system, user, jsonMode, images);
225
+ return this.callAnthropic(system, user, jsonMode, images, maxTokens, thinkingBudget, temperature);
185
226
  }
186
227
  if (OPENAI_FAMILY.has(this.provider)) {
187
- return this.callOpenAI(system, user, jsonMode, images);
228
+ return this.callOpenAI(system, user, jsonMode, images, maxTokens, temperature);
188
229
  }
189
- if (this.provider === "gemini") {
190
- return this.callGemini(system, user, jsonMode, images);
230
+ if (GOOGLE_FAMILY.has(this.provider)) {
231
+ return this.callGemini(system, user, jsonMode, images, maxTokens, thinkingBudget, temperature);
191
232
  }
192
233
  if (this.provider === "bedrock") {
193
- return this.callBedrock(system, user, jsonMode, images);
234
+ return this.callBedrock(system, user, jsonMode, images, maxTokens, thinkingBudget, temperature);
194
235
  }
195
236
  throw new Error(`unknown llm provider: ${JSON.stringify(this.provider)}`);
196
237
  }
197
- async callAnthropic(system, user, jsonMode, images) {
238
+ async callAnthropic(system, user, jsonMode, images, maxTokens, thinkingBudget = null, temperature = null) {
198
239
  if (!this.fetchImpl) {
199
240
  throw new Error("anthropic llm client has no fetch implementation");
200
241
  }
@@ -215,26 +256,27 @@ Respond with valid JSON only.`;
215
256
  });
216
257
  }
217
258
  content.push({ type: "text", text: user });
218
- const data = await postJson(
219
- this.fetchImpl,
220
- "https://api.anthropic.com/v1/messages",
221
- {
222
- model: this.model,
223
- max_tokens: ANTHROPIC_MAX_TOKENS,
224
- system,
225
- messages: [{ role: "user", content }]
226
- },
227
- {
228
- "x-api-key": this.cfg.apiKey ?? "",
229
- "anthropic-version": ANTHROPIC_VERSION,
230
- "content-type": "application/json"
231
- }
232
- );
259
+ const body = {
260
+ model: this.model,
261
+ max_tokens: maxTokens ?? ANTHROPIC_MAX_TOKENS,
262
+ system,
263
+ messages: [{ role: "user", content }]
264
+ };
265
+ if (thinkingBudget) {
266
+ body.thinking = { type: "enabled", budget_tokens: thinkingBudget };
267
+ } else if (temperature !== null) {
268
+ body.temperature = temperature;
269
+ }
270
+ const data = await postJson(this.fetchImpl, "https://api.anthropic.com/v1/messages", body, {
271
+ "x-api-key": this.cfg.apiKey ?? "",
272
+ "anthropic-version": ANTHROPIC_VERSION,
273
+ "content-type": "application/json"
274
+ });
233
275
  const text = data.content[0].text;
234
276
  const usage = data.usage ?? {};
235
277
  return [text, { input: usage.input_tokens ?? 0, output: usage.output_tokens ?? 0 }];
236
278
  }
237
- async callOpenAI(system, user, jsonMode, images) {
279
+ async callOpenAI(system, user, jsonMode, images, maxTokens, temperature = null) {
238
280
  if (!this.client) {
239
281
  throw new Error("openai-family llm client has no client");
240
282
  }
@@ -255,24 +297,54 @@ Respond with valid JSON only.`;
255
297
  if (jsonMode) {
256
298
  body.response_format = { type: "json_object" };
257
299
  }
300
+ if (maxTokens) {
301
+ body.max_completion_tokens = maxTokens;
302
+ }
303
+ if (temperature !== null) {
304
+ body.temperature = temperature;
305
+ }
258
306
  const resp = await this.client.chat.completions.create(body);
259
307
  const text = resp.choices[0]?.message?.content ?? "";
260
308
  const usage = resp.usage;
261
309
  return [text, { input: usage?.prompt_tokens ?? 0, output: usage?.completion_tokens ?? 0 }];
262
310
  }
263
- async callGemini(system, user, jsonMode, images) {
311
+ async callGemini(system, user, jsonMode, images, maxTokens, thinkingBudget = null, temperature = null) {
264
312
  if (!this.genaiClient) {
265
- this.genaiClient = await loadGeminiChatClient(this.cfg.apiKey);
313
+ this.genaiClient = await buildGenaiClient(
314
+ this.cfg,
315
+ GEMINI_CALL_TIMEOUT_MS,
316
+ "gemini llm"
317
+ );
266
318
  }
267
319
  const parts = [];
268
320
  for (const img of images ?? []) {
269
321
  parts.push({ inlineData: { mimeType: "image/png", data: toBase64(img) } });
270
322
  }
271
323
  parts.push({ text: user });
272
- const config = { systemInstruction: system };
324
+ const config = {
325
+ systemInstruction: system,
326
+ // ALWAYS off, and not as a preference. Automatic function calling means
327
+ // the SDK itself EXECUTES a callable it was handed as a tool and loops
328
+ // on the result — up to ten round trips — before returning anything.
329
+ // This package passes declarations only, so today nothing is executable;
330
+ // but that depends on every future caller continuing to do the same, and
331
+ // an application that gates tool execution behind human approval would
332
+ // have that gate bypassed silently, by a library, with the loop already
333
+ // run before it could object.
334
+ automaticFunctionCalling: { disable: true }
335
+ };
273
336
  if (jsonMode) {
274
337
  config.responseMimeType = "application/json";
275
338
  }
339
+ if (maxTokens) {
340
+ config.maxOutputTokens = maxTokens;
341
+ }
342
+ if (temperature !== null) {
343
+ config.temperature = temperature;
344
+ }
345
+ if (thinkingBudget !== null) {
346
+ config.thinkingConfig = { thinkingBudget };
347
+ }
276
348
  const resp = await this.genaiClient.models.generateContent({
277
349
  model: this.model,
278
350
  contents: parts,
@@ -284,7 +356,7 @@ Respond with valid JSON only.`;
284
356
  const outputTokens = usageMeta?.candidatesTokenCount ?? usageMeta?.candidates_token_count ?? 0;
285
357
  return [text, { input: inputTokens || 0, output: outputTokens || 0 }];
286
358
  }
287
- async callBedrock(system, user, jsonMode, images) {
359
+ async callBedrock(system, user, jsonMode, images, maxTokens, thinkingBudget = null, temperature = null) {
288
360
  const { BedrockRuntimeClient, ConverseCommand } = await loadBedrockSdk();
289
361
  if (jsonMode) {
290
362
  system = `${system}
@@ -308,7 +380,21 @@ Respond with valid JSON only.`;
308
380
  new ConverseCommand({
309
381
  modelId: this.model,
310
382
  system: [{ text: system }],
311
- messages: [{ role: "user", content }]
383
+ messages: [{ role: "user", content }],
384
+ ...maxTokens || temperature !== null ? {
385
+ inferenceConfig: {
386
+ ...maxTokens ? { maxTokens } : {},
387
+ ...temperature !== null ? { temperature } : {}
388
+ }
389
+ } : {},
390
+ // Anthropic-style passthrough — Converse forwards it to the model.
391
+ // Zero (the vision transcription contract) sends nothing: thinking
392
+ // is opt-in for the anthropic models bedrock hosts.
393
+ ...thinkingBudget ? {
394
+ additionalModelRequestFields: {
395
+ thinking: { type: "enabled", budget_tokens: thinkingBudget }
396
+ }
397
+ } : {}
312
398
  })
313
399
  );
314
400
  const text = result.output?.message?.content?.[0]?.text ?? "";
@@ -1150,7 +1236,8 @@ var retrieval_exports = {};
1150
1236
  __export(retrieval_exports, {
1151
1237
  buildGraphRanked: () => buildGraphRanked,
1152
1238
  corpusIsAclUniform: () => corpusIsAclUniform,
1153
- shouldUseCommunitySummaries: () => shouldUseCommunitySummaries
1239
+ shouldUseCommunitySummaries: () => shouldUseCommunitySummaries,
1240
+ vectorSeedIds: () => vectorSeedIds
1154
1241
  });
1155
1242
  function vecLiteral(vector) {
1156
1243
  return `[${vector.map((x) => Number(x)).join(",")}]`;
@@ -1176,8 +1263,8 @@ async function deriveQueryEntities(pool, chunkIds, opts) {
1176
1263
  JOIN context_engine_chunks c ON c.id = ce.chunk_id
1177
1264
  WHERE ce.chunk_id = ANY($1::uuid[]) ${SCOPE}
1178
1265
  GROUP BY e.normalized_name, e.name, e.type
1179
- ORDER BY freq DESC LIMIT $4`,
1180
- [chunkIds, opts.sourceIds, opts.principals, ENTITY_LIMIT]
1266
+ ORDER BY freq DESC LIMIT $5`,
1267
+ [chunkIds, opts.sourceIds, opts.documentIds ?? null, opts.principals, ENTITY_LIMIT]
1181
1268
  );
1182
1269
  return result.rows.map((r) => ({
1183
1270
  normalized_name: r.normalized_name,
@@ -1242,8 +1329,8 @@ async function computeCommunityScores(pool, chunkIds, vector, opts) {
1242
1329
  `SELECT ce.chunk_id::text, ce.entity_id::text
1243
1330
  FROM context_engine_chunk_entities ce
1244
1331
  JOIN context_engine_chunks c ON c.id = ce.chunk_id
1245
- WHERE ce.chunk_id = ANY($1::uuid[]) AND ce.entity_id = ANY($4::uuid[]) ${SCOPE}`,
1246
- [chunkIds, opts.sourceIds, opts.principals, Object.keys(entityScore)]
1332
+ WHERE ce.chunk_id = ANY($1::uuid[]) AND ce.entity_id = ANY($5::uuid[]) ${SCOPE}`,
1333
+ [chunkIds, opts.sourceIds, opts.documentIds ?? null, opts.principals, Object.keys(entityScore)]
1247
1334
  );
1248
1335
  const chunkScores = {};
1249
1336
  for (const row of result.rows) {
@@ -1252,13 +1339,29 @@ async function computeCommunityScores(pool, chunkIds, vector, opts) {
1252
1339
  return chunkScores;
1253
1340
  }
1254
1341
  async function vectorSeedIds(pool, vector, opts) {
1255
- const result = await pool.query(
1256
- `SELECT c.id::text FROM context_engine_chunks c
1257
- WHERE c.embedding IS NOT NULL ${SCOPE}
1258
- ORDER BY c.embedding <=> CAST($1 AS vector) LIMIT $4`,
1259
- [vecLiteral(vector), opts.sourceIds, opts.principals, SEED_LIMIT]
1260
- );
1261
- return result.rows.map((r) => String(r.id));
1342
+ const binds = [opts.sourceIds, opts.documentIds ?? null, opts.principals];
1343
+ const scoped = binds.some((v) => v !== null);
1344
+ const client = await pool.connect();
1345
+ try {
1346
+ await client.query("BEGIN");
1347
+ await opts.backend?.tuneAnnScan?.(client, SEED_LIMIT, scoped);
1348
+ const result = await client.query(
1349
+ `SELECT c.id::text FROM context_engine_chunks c
1350
+ WHERE c.embedding IS NOT NULL ${SCOPE}
1351
+ ORDER BY c.embedding <=> CAST($1 AS vector) LIMIT $5`,
1352
+ [vecLiteral(vector), ...binds, SEED_LIMIT]
1353
+ );
1354
+ await client.query("COMMIT");
1355
+ return result.rows.map((r) => String(r.id));
1356
+ } catch (err) {
1357
+ try {
1358
+ await client.query("ROLLBACK");
1359
+ } catch {
1360
+ }
1361
+ throw err;
1362
+ } finally {
1363
+ client.release();
1364
+ }
1262
1365
  }
1263
1366
  async function buildGraphRanked(query, opts) {
1264
1367
  try {
@@ -1267,11 +1370,18 @@ async function buildGraphRanked(query, opts) {
1267
1370
  const vector = vectors[0] ? [...vectors[0]] : null;
1268
1371
  if (!vector) return [];
1269
1372
  const sourceIds = opts.sourceIds ?? null;
1373
+ const documentIds = opts.documentIds ?? null;
1270
1374
  const principals = opts.principals ?? null;
1271
- const seeds = await vectorSeedIds(opts.pool, vector, { sourceIds, principals });
1375
+ const seeds = await vectorSeedIds(opts.pool, vector, {
1376
+ sourceIds,
1377
+ documentIds,
1378
+ principals,
1379
+ backend: opts.backend
1380
+ });
1272
1381
  if (!seeds.length) return [];
1273
1382
  const queryEntities = await deriveQueryEntities(opts.pool, seeds.slice(0, TOP_SEEDS_FOR_ENTITIES), {
1274
1383
  sourceIds,
1384
+ documentIds,
1275
1385
  principals
1276
1386
  });
1277
1387
  const entityNorms = queryEntities.map((e) => String(e.normalized_name));
@@ -1293,6 +1403,7 @@ async function buildGraphRanked(query, opts) {
1293
1403
  const relScores = await computeRelationshipScores(opts.pool, allIds, entityNorms);
1294
1404
  const commScores = await computeCommunityScores(opts.pool, allIds, vector, {
1295
1405
  sourceIds,
1406
+ documentIds,
1296
1407
  principals,
1297
1408
  useSummaries
1298
1409
  });
@@ -1344,7 +1455,8 @@ var init_retrieval = __esm({
1344
1455
  TOP_SEEDS_FOR_ENTITIES = 20;
1345
1456
  SCOPE = `
1346
1457
  AND ($2::text[] IS NULL OR c.source_id = ANY($2::text[]))
1347
- AND ($3::text[] IS NULL OR c.acl IS NULL OR c.acl && $3::text[])
1458
+ AND ($3::uuid[] IS NULL OR c.document_id = ANY($3::uuid[]))
1459
+ AND ($4::text[] IS NULL OR c.acl IS NULL OR c.acl && $4::text[])
1348
1460
  `;
1349
1461
  }
1350
1462
  });