@promptev/context-engine 0.0.2 → 0.0.4
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 +81 -0
- package/dist/cli.js +12494 -11031
- package/dist/cli.js.map +1 -1
- package/dist/express.cjs.map +1 -1
- package/dist/express.js.map +1 -1
- package/dist/fastify.cjs.map +1 -1
- package/dist/fastify.js.map +1 -1
- package/dist/graph/index.cjs +6 -5
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.js +6 -5
- package/dist/graph/index.js.map +1 -1
- package/dist/hono.cjs.map +1 -1
- package/dist/hono.js.map +1 -1
- package/dist/index.cjs +8064 -6538
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +334 -26
- package/dist/index.d.ts +334 -26
- package/dist/index.js +8045 -6525
- package/dist/index.js.map +1 -1
- package/dist/mcp-uirRbluA.d.cts +208 -0
- package/dist/mcp-uirRbluA.d.ts +208 -0
- package/dist/mcp.cjs +936 -70
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.d.cts +2 -31
- package/dist/mcp.d.ts +2 -31
- package/dist/mcp.js +936 -70
- package/dist/mcp.js.map +1 -1
- package/dist/skills/context-engine/SKILL.md +58 -2
- package/package.json +1 -1
- package/src/skills/context-engine/SKILL.md +58 -2
|
@@ -62,6 +62,59 @@ await engine.search(q, { principals: user.groups }); // scoped
|
|
|
62
62
|
no default. If you hit a `TypeError`, supply real ones — do **not** silence
|
|
63
63
|
it with `principals: () => null`, which disables access control on a public
|
|
64
64
|
port. Anonymous is `() => []`. Trusted is `() => TRUSTED`.
|
|
65
|
+
- **Search picks its own mode unless you name one.** `search({ mode: null })` (the
|
|
66
|
+
default) adds the graph leg when the deployment has a graph AND something in
|
|
67
|
+
scope was ingested with `mode: "graph"` — a model cannot know which documents
|
|
68
|
+
those are, so it is not asked. Pass `mode: "hybrid"` to force the old
|
|
69
|
+
behaviour. INGESTION is unchanged and stays explicit. An unreachable graph
|
|
70
|
+
database is skipped rather than waited on, and every graph failure degrades
|
|
71
|
+
to the hybrid legs instead of failing the search.
|
|
72
|
+
- **The knowledge tool is one call with THIRTEEN actions** — `discover`,
|
|
73
|
+
`search`, `get_doc`, `get_docs`, `get_chunks`, `list`, `query_meta`,
|
|
74
|
+
`compute`, `map_reduce`, `get_neighbors`, `traverse`, `find_related`,
|
|
75
|
+
`community_summary`.
|
|
76
|
+
`engine.searchKnowledgeBase({ action, principals, scope })` is the
|
|
77
|
+
same function `createMcpApp` serves. `discover` returns the SCHEMA, not
|
|
78
|
+
just an inventory, and for EVERY document type. Each listed document carries
|
|
79
|
+
`structure` — `sheets` (name, column headers, row count; the sheet name is
|
|
80
|
+
the key `compute` exposes in `dfs`) for a workbook, `sections` and
|
|
81
|
+
`last_page` for a document with headings, `keys` for JSON, and `chunks` for
|
|
82
|
+
anything else — plus `document_type` and `mode`. Every list inside a
|
|
83
|
+
`structure` is capped, with the remainder reported as `more_columns` /
|
|
84
|
+
`more_sections` / `more_keys` / `more_sheets` (absent when nothing was cut)
|
|
85
|
+
and, while the remainder is worth fetching, a filled-in `next_action`. Past
|
|
86
|
+
`MAX_INVITED_ITEMS` the invitation is WITHHELD and replaced by `instead` —
|
|
87
|
+
a model cannot know what a full list costs until it has paid for it, so
|
|
88
|
+
offering a sixteen-thousand-column fetch would be the tool's decision, not
|
|
89
|
+
the caller's; a list that long is a signal to compute over the sheet or read
|
|
90
|
+
the document, never to list it. **The cap is for the call that did NOT name
|
|
91
|
+
its documents:** `discover` (and `list`) now accept `document_ids`, filtered
|
|
92
|
+
in SQL, and a `discover` scoped to specific documents answers their
|
|
93
|
+
structure WHOLE and narrows `fields_by_type` and `document_types` to them
|
|
94
|
+
too. The host's `scope` ceiling still wins — a named id outside it is
|
|
95
|
+
dropped, never reached.
|
|
96
|
+
Alongside them, `fields_by_type` and `document_types` are BOTH keyed by
|
|
97
|
+
`(kind, type)` — a `document_type` is a label an LLM wrote, so a PDF invoice
|
|
98
|
+
and a CSV of invoice rows can share one, and keying on the label alone would
|
|
99
|
+
merge their fields. `fields_by_type` rows carry `fields` (name, data type,
|
|
100
|
+
how many in-scope documents) plus `more_fields` (names past the cap);
|
|
101
|
+
`document_types` rows carry `documents` and `with_fields`. `type` is written
|
|
102
|
+
only where `extract_structured` was opted into, so it is null on a default
|
|
103
|
+
deployment — which is why `kind` is there. All of it is ACL- and
|
|
104
|
+
scope-filtered and masked by an output redaction policy. `list` returns the
|
|
105
|
+
same page WITHOUT the structure — browsing does not pay for it. `knowledgeToolDefinition()` gives
|
|
106
|
+
the name, description and JSON Schema if you are wiring it into your own
|
|
107
|
+
agent loop. `compute` and `mapReduce` accept a host callable that REPLACES
|
|
108
|
+
the built-in one — that is the seam for your own permission, billing and
|
|
109
|
+
approval rules, and supplying one makes the action available regardless of
|
|
110
|
+
the deployment's own gate.
|
|
111
|
+
- **`scope` is REQUIRED on `createMcpApp`** and on
|
|
112
|
+
`engine.searchKnowledgeBase`: the ceiling of source ids the tool may ever
|
|
113
|
+
reach. Like `principals` it is host-supplied and NEVER a tool argument — a
|
|
114
|
+
model can name any source id, and a tool that believed it would cross
|
|
115
|
+
tenants. Pass `scope: UNSCOPED` only to mean the whole corpus on purpose. A
|
|
116
|
+
caller narrows within the ceiling; an id outside it is dropped silently, and
|
|
117
|
+
a request left with nothing returns nothing (never everything).
|
|
65
118
|
- **`acl=null` on `updateDocument` UNRESTRICTS the document.** "Leave it
|
|
66
119
|
alone" is expressed by omitting the argument (the `UNSET` sentinel), because
|
|
67
120
|
`null` already means unrestricted and cannot also mean absent. Same for
|
|
@@ -130,11 +183,14 @@ app.route(
|
|
|
130
183
|
`createFastifyPlugin` (`@promptev/context-engine/fastify`) and
|
|
131
184
|
`createMcpApp` (`@promptev/context-engine/mcp`) take the same two
|
|
132
185
|
arguments. MCP has no request object: `principals` is a zero-argument
|
|
133
|
-
callable resolved fresh on every tool call
|
|
186
|
+
callable resolved fresh on every tool call, and `createMcpApp` also requires
|
|
187
|
+
`scope` — the source-id ceiling, resolved the same way. The CLI `context-engine mcp`
|
|
134
188
|
binds `127.0.0.1` and answers as anonymous (`principals=[]`).
|
|
135
189
|
|
|
136
190
|
Not on a supported framework? Call `engine.search()` / `engine.ingest()`
|
|
137
|
-
from your own handler — the routers are thin wrappers over the same core.
|
|
191
|
+
from your own handler — the routers are thin wrappers over the same core. For
|
|
192
|
+
an agent, `engine.searchKnowledgeBase({ action, principals, scope })` is the
|
|
193
|
+
same one tool the MCP server serves, with no transport in the way.
|
|
138
194
|
|
|
139
195
|
## Lifecycle
|
|
140
196
|
|
package/package.json
CHANGED
|
@@ -62,6 +62,59 @@ await engine.search(q, { principals: user.groups }); // scoped
|
|
|
62
62
|
no default. If you hit a `TypeError`, supply real ones — do **not** silence
|
|
63
63
|
it with `principals: () => null`, which disables access control on a public
|
|
64
64
|
port. Anonymous is `() => []`. Trusted is `() => TRUSTED`.
|
|
65
|
+
- **Search picks its own mode unless you name one.** `search({ mode: null })` (the
|
|
66
|
+
default) adds the graph leg when the deployment has a graph AND something in
|
|
67
|
+
scope was ingested with `mode: "graph"` — a model cannot know which documents
|
|
68
|
+
those are, so it is not asked. Pass `mode: "hybrid"` to force the old
|
|
69
|
+
behaviour. INGESTION is unchanged and stays explicit. An unreachable graph
|
|
70
|
+
database is skipped rather than waited on, and every graph failure degrades
|
|
71
|
+
to the hybrid legs instead of failing the search.
|
|
72
|
+
- **The knowledge tool is one call with THIRTEEN actions** — `discover`,
|
|
73
|
+
`search`, `get_doc`, `get_docs`, `get_chunks`, `list`, `query_meta`,
|
|
74
|
+
`compute`, `map_reduce`, `get_neighbors`, `traverse`, `find_related`,
|
|
75
|
+
`community_summary`.
|
|
76
|
+
`engine.searchKnowledgeBase({ action, principals, scope })` is the
|
|
77
|
+
same function `createMcpApp` serves. `discover` returns the SCHEMA, not
|
|
78
|
+
just an inventory, and for EVERY document type. Each listed document carries
|
|
79
|
+
`structure` — `sheets` (name, column headers, row count; the sheet name is
|
|
80
|
+
the key `compute` exposes in `dfs`) for a workbook, `sections` and
|
|
81
|
+
`last_page` for a document with headings, `keys` for JSON, and `chunks` for
|
|
82
|
+
anything else — plus `document_type` and `mode`. Every list inside a
|
|
83
|
+
`structure` is capped, with the remainder reported as `more_columns` /
|
|
84
|
+
`more_sections` / `more_keys` / `more_sheets` (absent when nothing was cut)
|
|
85
|
+
and, while the remainder is worth fetching, a filled-in `next_action`. Past
|
|
86
|
+
`MAX_INVITED_ITEMS` the invitation is WITHHELD and replaced by `instead` —
|
|
87
|
+
a model cannot know what a full list costs until it has paid for it, so
|
|
88
|
+
offering a sixteen-thousand-column fetch would be the tool's decision, not
|
|
89
|
+
the caller's; a list that long is a signal to compute over the sheet or read
|
|
90
|
+
the document, never to list it. **The cap is for the call that did NOT name
|
|
91
|
+
its documents:** `discover` (and `list`) now accept `document_ids`, filtered
|
|
92
|
+
in SQL, and a `discover` scoped to specific documents answers their
|
|
93
|
+
structure WHOLE and narrows `fields_by_type` and `document_types` to them
|
|
94
|
+
too. The host's `scope` ceiling still wins — a named id outside it is
|
|
95
|
+
dropped, never reached.
|
|
96
|
+
Alongside them, `fields_by_type` and `document_types` are BOTH keyed by
|
|
97
|
+
`(kind, type)` — a `document_type` is a label an LLM wrote, so a PDF invoice
|
|
98
|
+
and a CSV of invoice rows can share one, and keying on the label alone would
|
|
99
|
+
merge their fields. `fields_by_type` rows carry `fields` (name, data type,
|
|
100
|
+
how many in-scope documents) plus `more_fields` (names past the cap);
|
|
101
|
+
`document_types` rows carry `documents` and `with_fields`. `type` is written
|
|
102
|
+
only where `extract_structured` was opted into, so it is null on a default
|
|
103
|
+
deployment — which is why `kind` is there. All of it is ACL- and
|
|
104
|
+
scope-filtered and masked by an output redaction policy. `list` returns the
|
|
105
|
+
same page WITHOUT the structure — browsing does not pay for it. `knowledgeToolDefinition()` gives
|
|
106
|
+
the name, description and JSON Schema if you are wiring it into your own
|
|
107
|
+
agent loop. `compute` and `mapReduce` accept a host callable that REPLACES
|
|
108
|
+
the built-in one — that is the seam for your own permission, billing and
|
|
109
|
+
approval rules, and supplying one makes the action available regardless of
|
|
110
|
+
the deployment's own gate.
|
|
111
|
+
- **`scope` is REQUIRED on `createMcpApp`** and on
|
|
112
|
+
`engine.searchKnowledgeBase`: the ceiling of source ids the tool may ever
|
|
113
|
+
reach. Like `principals` it is host-supplied and NEVER a tool argument — a
|
|
114
|
+
model can name any source id, and a tool that believed it would cross
|
|
115
|
+
tenants. Pass `scope: UNSCOPED` only to mean the whole corpus on purpose. A
|
|
116
|
+
caller narrows within the ceiling; an id outside it is dropped silently, and
|
|
117
|
+
a request left with nothing returns nothing (never everything).
|
|
65
118
|
- **`acl=null` on `updateDocument` UNRESTRICTS the document.** "Leave it
|
|
66
119
|
alone" is expressed by omitting the argument (the `UNSET` sentinel), because
|
|
67
120
|
`null` already means unrestricted and cannot also mean absent. Same for
|
|
@@ -130,11 +183,14 @@ app.route(
|
|
|
130
183
|
`createFastifyPlugin` (`@promptev/context-engine/fastify`) and
|
|
131
184
|
`createMcpApp` (`@promptev/context-engine/mcp`) take the same two
|
|
132
185
|
arguments. MCP has no request object: `principals` is a zero-argument
|
|
133
|
-
callable resolved fresh on every tool call
|
|
186
|
+
callable resolved fresh on every tool call, and `createMcpApp` also requires
|
|
187
|
+
`scope` — the source-id ceiling, resolved the same way. The CLI `context-engine mcp`
|
|
134
188
|
binds `127.0.0.1` and answers as anonymous (`principals=[]`).
|
|
135
189
|
|
|
136
190
|
Not on a supported framework? Call `engine.search()` / `engine.ingest()`
|
|
137
|
-
from your own handler — the routers are thin wrappers over the same core.
|
|
191
|
+
from your own handler — the routers are thin wrappers over the same core. For
|
|
192
|
+
an agent, `engine.searchKnowledgeBase({ action, principals, scope })` is the
|
|
193
|
+
same one tool the MCP server serves, with no transport in the way.
|
|
138
194
|
|
|
139
195
|
## Lifecycle
|
|
140
196
|
|