@promptev/context-engine 0.0.0 → 0.0.1
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.
- package/README.md +93 -5
- package/dist/cli.js +1761 -501
- package/dist/cli.js.map +1 -1
- package/dist/{config-Bt9bUQqU.d.ts → config-CNnASw5X.d.cts} +42 -5
- package/dist/{config-Bl9U789m.d.cts → config-CdlSkKgV.d.ts} +42 -5
- package/dist/express.cjs +925 -151
- package/dist/express.cjs.map +1 -1
- package/dist/express.d.cts +11 -4
- package/dist/express.d.ts +11 -4
- package/dist/express.js +926 -152
- package/dist/express.js.map +1 -1
- package/dist/fastify.cjs +923 -151
- package/dist/fastify.cjs.map +1 -1
- package/dist/fastify.d.cts +8 -4
- package/dist/fastify.d.ts +8 -4
- package/dist/fastify.js +924 -152
- package/dist/fastify.js.map +1 -1
- package/dist/{governance-BDkcv4qZ.d.cts → governance-D8g6Wyvb.d.cts} +8 -2
- package/dist/{governance-XIScatRO.d.ts → governance-XFVgtEdV.d.ts} +8 -2
- package/dist/graph/index.cjs +122 -43
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +5 -3
- package/dist/graph/index.d.ts +5 -3
- package/dist/graph/index.js +122 -43
- package/dist/graph/index.js.map +1 -1
- package/dist/hono.cjs +923 -151
- package/dist/hono.cjs.map +1 -1
- package/dist/hono.d.cts +8 -4
- package/dist/hono.d.ts +8 -4
- package/dist/hono.js +924 -152
- package/dist/hono.js.map +1 -1
- package/dist/index.cjs +2186 -910
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -107
- package/dist/index.d.ts +70 -107
- package/dist/index.js +2186 -908
- package/dist/index.js.map +1 -1
- package/dist/mcp.cjs +100 -14
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.d.cts +5 -0
- package/dist/mcp.d.ts +5 -0
- package/dist/mcp.js +100 -14
- package/dist/mcp.js.map +1 -1
- package/dist/migrations/sql/0003_tools.sql +2 -0
- package/dist/migrations/sql/0004_acl_indexes.sql +23 -2
- package/dist/{redaction-BmDSWJ7h.d.cts → redaction-BqD_DEUQ.d.cts} +22 -1
- package/dist/{redaction-BmDSWJ7h.d.ts → redaction-BqD_DEUQ.d.ts} +22 -1
- package/dist/redaction-presidio.d.cts +1 -1
- package/dist/redaction-presidio.d.ts +1 -1
- package/dist/{router-CrxZ2y_Z.d.ts → router-B_DTkQgU.d.ts} +17 -2
- package/dist/{router-OPgSoYAB.d.cts → router-Dsv3fv0R.d.cts} +17 -2
- package/dist/storage-DU1JRno5.d.cts +164 -0
- package/dist/storage-Dvt2ZxsV.d.ts +164 -0
- package/package.json +61 -23
- package/src/migrations/sql/0003_tools.sql +2 -0
- package/src/migrations/sql/0004_acl_indexes.sql +23 -2
- package/dist/embeddings-B-jZ42mk.d.cts +0 -67
- package/dist/embeddings-DaSdAZN3.d.ts +0 -67
package/README.md
CHANGED
|
@@ -9,9 +9,15 @@
|
|
|
9
9
|
as a TypeScript library, on your own Postgres.</b>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
>
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/@promptev/context-engine"><img src="https://img.shields.io/npm/v/@promptev/context-engine?label=npm&color=CB3837" alt="npm"></a>
|
|
14
|
+
<a href="https://pypi.org/project/promptev-context-engine/"><img src="https://img.shields.io/pypi/v/promptev-context-engine?label=PyPI%20(python)&color=3775A9" alt="PyPI"></a>
|
|
15
|
+
<a href="https://github.com/promptev/context-engine/actions/workflows/js.yml"><img src="https://github.com/promptev/context-engine/actions/workflows/js.yml/badge.svg" alt="CI"></a>
|
|
16
|
+
<img src="https://img.shields.io/badge/node-22%2B-339933" alt="Node 22+">
|
|
17
|
+
<img src="https://img.shields.io/badge/types-included-3178C6" alt="TypeScript types included">
|
|
18
|
+
<a href="../LICENSE.md"><img src="https://img.shields.io/badge/license-Apache--2.0-blue" alt="Apache-2.0"></a>
|
|
19
|
+
</p>
|
|
20
|
+
|
|
15
21
|
|
|
16
22
|
It is a **library, not a server**. BYO database, embedding provider, and LLM.
|
|
17
23
|
`npm install`, point it at Postgres you already run, call `engine.search()`.
|
|
@@ -22,16 +28,52 @@ optional graph). PII redaction runs **before** a hosted reranker sees hits and
|
|
|
22
28
|
|
|
23
29
|
📖 **Docs:** https://promptev.ai/documentation/context-engine/ · **[access control](../docs/access-control.md)**
|
|
24
30
|
|
|
31
|
+
## Why you'd choose this
|
|
32
|
+
|
|
33
|
+
**1. Access control that survives the vector index.** Filtering an approximate
|
|
34
|
+
index with a `WHERE` clause is a *post-filter* — the index picks candidates
|
|
35
|
+
first, your ACL discards them second, and the query returns short. We measured
|
|
36
|
+
it on 200k public documents at production embedding width, and because real
|
|
37
|
+
permissions are topically clustered rather than random, the loss is about
|
|
38
|
+
twice what a conventional benchmark reports: **recall 0.473 against 0.980 at
|
|
39
|
+
identical visibility, a quarter of queries empty, no error raised.** Tuning
|
|
40
|
+
does not fully close it, so this library decides between an exact and an
|
|
41
|
+
approximate scan per query instead. [Method](../benchmarks/acl_recall/).
|
|
42
|
+
|
|
43
|
+
**2. Redaction that runs in the right place.** Not more detectors — better
|
|
44
|
+
*placement*. Hits are masked **before** a hosted reranker sees them and
|
|
45
|
+
**before** the audit row is written, so the masked value is the only one that
|
|
46
|
+
leaves the process.
|
|
47
|
+
|
|
48
|
+
**3. It's a library, so the data never moves.** No server, no corpus handed
|
|
49
|
+
over. It only ever calls the Postgres, embedding endpoint, and LLM you
|
|
50
|
+
configure.
|
|
51
|
+
|
|
52
|
+
**4. Governed tool execution in the same place as retrieval.** ACL-scoped
|
|
53
|
+
tools, encrypted credentials, a fail-closed approval gate, and an audit row
|
|
54
|
+
per call — see [Tools](#tools) below.
|
|
55
|
+
|
|
56
|
+
**Prove it on your own data** — one read-only command, offline, no embedding
|
|
57
|
+
provider called:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx context-engine check-acl-exposure --database-url postgresql://...
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
It reports, for the ACL values that actually occur in your corpus, what a bare
|
|
64
|
+
scoped query returns versus what this library returns — both scored against an
|
|
65
|
+
exact oracle computed inside Postgres.
|
|
66
|
+
|
|
25
67
|
## Install
|
|
26
68
|
|
|
27
69
|
```bash
|
|
28
70
|
npm install @promptev/context-engine pg
|
|
29
71
|
```
|
|
30
72
|
|
|
31
|
-
Needs **Node.js
|
|
73
|
+
Needs **Node.js 22+** and **Postgres** with `vector`, `pg_trgm`, and `unaccent`
|
|
32
74
|
(created by `context-engine migrate` if the role has `CREATE EXTENSION`).
|
|
33
75
|
|
|
34
|
-
`pg` is a peer dependency
|
|
76
|
+
`pg` is a peer dependency, and it — like everything else here — is MIT/BSD/Apache, so a bare install pulls **no copyleft at all**.
|
|
35
77
|
|
|
36
78
|
Optional peers — install only what you use:
|
|
37
79
|
|
|
@@ -65,6 +107,13 @@ const engine = new ContextEngine(config);
|
|
|
65
107
|
|
|
66
108
|
Or from `CE_`-prefixed env vars (`CE_EMBEDDING__PROVIDER`, nested with `__`).
|
|
67
109
|
|
|
110
|
+
`storage` holds the deployment knobs: `annExactThreshold` (the vector leg's
|
|
111
|
+
exact/approximate crossover) and the `pg.Pool` settings — `poolMax` (10),
|
|
112
|
+
`poolIdleTimeoutMs` (10000) and `poolConnectionTimeoutMs` (30000). Reachable
|
|
113
|
+
as env vars too, e.g. `CE_STORAGE__POOL_MAX`. (`pg` has no pre-ping, so unlike
|
|
114
|
+
the Python client there is nothing to turn on: a connection the database has
|
|
115
|
+
dropped fails once and is replaced.)
|
|
116
|
+
|
|
68
117
|
## Provision
|
|
69
118
|
|
|
70
119
|
```bash
|
|
@@ -85,6 +134,7 @@ await engine.ingest({
|
|
|
85
134
|
|
|
86
135
|
const result = await engine.search("how much annual leave do I get", {
|
|
87
136
|
sourceIds: ["hr-handbook"],
|
|
137
|
+
documentIds: null, // optionally pin to specific documents WITHIN the sources
|
|
88
138
|
principals: ["group:hr"], // TRUSTED = skip ACL; [] = anonymous
|
|
89
139
|
topK: 10,
|
|
90
140
|
});
|
|
@@ -107,6 +157,44 @@ const router = createHonoRouter(engine, { auth: myAuth, principals: myPrincipals
|
|
|
107
157
|
|
|
108
158
|
`auth` and `principals` are required. Identical routes exist for Express and Fastify.
|
|
109
159
|
|
|
160
|
+
## Tools
|
|
161
|
+
|
|
162
|
+
Register a governed tool — HTTP, SQL, MCP, or a plain function — and every call
|
|
163
|
+
is ACL-scoped, credential-encrypted, optionally approval-gated, and audited.
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { ToolConfig, resolveApproval } from "@promptev/context-engine";
|
|
167
|
+
|
|
168
|
+
await engine.registerTool(new ToolConfig({
|
|
169
|
+
name: "get_weather",
|
|
170
|
+
kind: "http",
|
|
171
|
+
description: "Fetch the current weather for a city",
|
|
172
|
+
config: { method: "GET", url: "https://api.example.com/weather" },
|
|
173
|
+
acl: ["group:ops"],
|
|
174
|
+
requiresApproval: true, // pauses for a human before it runs
|
|
175
|
+
}));
|
|
176
|
+
|
|
177
|
+
const out = await engine.executeTool("http_get_weather", { city: "Lahore" }, {
|
|
178
|
+
principals: ["group:ops"],
|
|
179
|
+
approvalScope: "run-42", // opaque, chosen by you — a run id is the usual shape
|
|
180
|
+
});
|
|
181
|
+
// -> { approval_required: { approval_id: "...", expires_at: "...", ... } } (not executed yet)
|
|
182
|
+
|
|
183
|
+
await resolveApproval(engine, approvalId, "approved", "boss");
|
|
184
|
+
// the same call, same approvalScope, runs for real — exactly once
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
`approvalScope` is the claim scope: an approved record is consumed only by the
|
|
188
|
+
same call in the same scope (and, when the record carries principals, by a
|
|
189
|
+
caller who overlaps them). Within a scope, identical pending requests share one
|
|
190
|
+
record. Resolve it server-side — on the adapters and the MCP gateway it is an
|
|
191
|
+
`approvalScope` resolver beside `principals`, never a request field. Omitting it
|
|
192
|
+
still works this release, unscoped and with a `DeprecationWarning`; the next
|
|
193
|
+
release refuses a gated call with no scope.
|
|
194
|
+
|
|
195
|
+
A caller may only register or relabel a tool under principals it holds — filing
|
|
196
|
+
one under another group's ACL is a 403.
|
|
197
|
+
|
|
110
198
|
## License
|
|
111
199
|
|
|
112
200
|
Apache-2.0. See `LICENSE.md` and `NOTICE`.
|