@keb-org/consol 0.1.1 → 0.3.0
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 +91 -53
- package/dist/consol.d.ts +2 -2
- package/dist/errors.d.ts +1 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +128 -418
- package/dist/mcp.d.ts +2 -0
- package/dist/mcp.js +20422 -0
- package/dist/native.d.ts +96 -0
- package/dist/transport.d.ts +3 -2
- package/dist/types.d.ts +86 -95
- package/dist/vault.d.ts +43 -98
- package/package.json +14 -10
- package/dist/stdio.d.ts +0 -120
package/README.md
CHANGED
|
@@ -1,28 +1,64 @@
|
|
|
1
1
|
# @keb-org/consol
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The consol memory engine as one package: the MCP server (`npx -y @keb-org/consol`) and a TypeScript SDK.
|
|
4
|
+
The SDK has three uses:
|
|
4
5
|
|
|
5
|
-
1. **Local**: a vault on disk (or S3) in your own process
|
|
6
|
+
1. **Local**: a vault on disk (or S3), with the engine running in your own process as a native addon.
|
|
6
7
|
2. **Hosted client**: the same `Vault` methods against a backend over HTTP.
|
|
7
8
|
3. **Backend**: `Consol.handle` behind your own HTTP route, so clients of any language can use it.
|
|
8
9
|
|
|
9
10
|
Node >= 22 or Bun, no dependencies; `import` and `require` share one implementation. The behaviour
|
|
10
11
|
is the same in every mode.
|
|
11
12
|
|
|
12
|
-
##
|
|
13
|
+
## MCP server
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
`npx -y @keb-org/consol --vault PATH --agent NAME` serves MCP on stdio for one vault that already
|
|
16
|
+
exists (`consol create --vault PATH` makes it; the MCP never creates a vault). The engine runs in
|
|
17
|
+
its process through the same addon as the SDK, so it needs the database too: every `CONSOL_*`
|
|
18
|
+
variable of its process is an engine setting (`CONSOL_DB_URL` is required, `CONSOL_EMBED_*` turn on
|
|
19
|
+
embeddings). Engine logs go to stderr at the level of `RUST_LOG` (default `warn`).
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
| Flag | Variable | |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `--vault` | `CONSOL_VAULT` | a directory or `s3://bucket/prefix/name`; with `--remote`, the vault's name on the backend |
|
|
24
|
+
| `--remote` | `CONSOL_REMOTE_URL` | a backend URL (use 3) to forward to, instead of opening a vault; its headers come from `CONSOL_REMOTE_HEADERS` (one `Name: value` per line) |
|
|
25
|
+
| `--agent` | `CONSOL_AGENT` | the default agent of every call; a call's `agent` argument overrides it |
|
|
26
|
+
|
|
27
|
+
In an MCP client, or in Claude Code (the options go before the name):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
claude mcp add --env CONSOL_DB_URL=postgres://postgres:pw@127.0.0.1:5432/postgres \
|
|
31
|
+
consol -- npx -y @keb-org/consol --vault /abs/path/vault --agent assistant
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{ "mcpServers": { "consol": {
|
|
36
|
+
"command": "npx",
|
|
37
|
+
"args": ["-y", "@keb-org/consol", "--vault", "/abs/path/vault", "--agent", "assistant"],
|
|
38
|
+
"env": { "CONSOL_DB_URL": "postgres://postgres:pw@127.0.0.1:5432/postgres" }
|
|
39
|
+
} } }
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A hosted backend needs no database here:
|
|
43
|
+
`npx -y @keb-org/consol --remote https://api.acme.dev/v1/consol --vault demo --agent assistant`, with the
|
|
44
|
+
backend's credentials in `CONSOL_REMOTE_HEADERS`. The
|
|
45
|
+
tool list, the instructions and each result are the engine's, the same ones `consol serve` mounts
|
|
46
|
+
over streamable HTTP at `<path>/mcp`, which is unchanged.
|
|
47
|
+
|
|
48
|
+
## The engine addon and database
|
|
49
|
+
|
|
50
|
+
The engine is the native addon `consol.node`, loaded the first time you start a vault or a
|
|
51
|
+
`Consol` (importing the SDK loads nothing). The SDK uses the first of these:
|
|
52
|
+
|
|
53
|
+
1. the `addonPath` option,
|
|
54
|
+
2. the `CONSOL_ADDON` environment variable,
|
|
55
|
+
3. the platform package `@keb-org/consol-<platform>-<arch>`, resolved from the SDK's own location.
|
|
20
56
|
|
|
21
|
-
|
|
22
|
-
of falling through to the next place.
|
|
23
|
-
`
|
|
57
|
+
An `addonPath` or `CONSOL_ADDON` that points nowhere, or at a file that does not load, fails at
|
|
58
|
+
once with `addon_not_found` instead of falling through to the next place. The platform package
|
|
59
|
+
also ships the `consol` CLI as `bin/consol`.
|
|
24
60
|
|
|
25
|
-
The engine needs a database, PostgreSQL with pgvector or CockroachDB: pass `db` or set
|
|
61
|
+
The engine still needs a database, PostgreSQL with pgvector or CockroachDB: pass `db` or set
|
|
26
62
|
`CONSOL_DB_URL` in your process (the one `CONSOL_*` variable the SDK takes from its host).
|
|
27
63
|
|
|
28
64
|
## 1. Local
|
|
@@ -44,8 +80,8 @@ try {
|
|
|
44
80
|
```
|
|
45
81
|
|
|
46
82
|
`createVault` fails with `vault_exists` when the directory already holds a vault, `openVault`
|
|
47
|
-
(same options) with `vault_not_found` when it does not. Both
|
|
48
|
-
version matches the SDK's major.minor before they return.
|
|
83
|
+
(same options) with `vault_not_found` when it does not. Both open the engine and check that the
|
|
84
|
+
addon's version matches the SDK's major.minor before they return.
|
|
49
85
|
|
|
50
86
|
## 2. Hosted client
|
|
51
87
|
|
|
@@ -109,19 +145,25 @@ Each method takes one object with the tool's wire argument names, plus optional
|
|
|
109
145
|
|
|
110
146
|
| Method | Arguments | Returns |
|
|
111
147
|
|---|---|---|
|
|
112
|
-
| `recall` | `{ query,
|
|
148
|
+
| `recall` | `{ query, agent? }` | `RecallResult`: `text` is the progressive disclosure to give a model (cards by tier, the blocks the query's symbols ask for, hints); `candidates` are the same cards as data. Cards are leads: read a note before relying on it |
|
|
113
149
|
| `read` | `{ id, continuation?, agent? }` | `ReadResult`; `text` is the exact file |
|
|
114
|
-
| `remember` | `{ id, content?, expected_version?, summary?, entities?, facets?, scope?, team?, valid_from?, valid_to
|
|
115
|
-
| `remove` | `{ id, expected_version,
|
|
116
|
-
| `reflect` |
|
|
150
|
+
| `remember` | `{ id, content?, meta?, expected_version?, token?, agent? }`; `meta` is `{ summary?, entities?, facets?, scope?, team?, valid_from?, valid_to? }` | `RememberResult` |
|
|
151
|
+
| `remove` | `{ id, expected_version, token?, agent? }` | `RemoveResult`: the note is archived, its body stays readable |
|
|
152
|
+
| `reflect` | `{ focus?, decisions?, agent? }`; call it with no arguments and follow `next` | `ReflectResult`: `next`, the delivered `items` (sources carry their `text`), every unresolved `writes` entry, the `blocked` tokens |
|
|
117
153
|
| `callTool` | `(name, args)` with raw wire arguments | the raw `Reply`; tool errors come back as `reply.error` |
|
|
118
154
|
| `close` | | final and idempotent |
|
|
119
155
|
|
|
120
156
|
- `remember` without `expected_version` is create-only. To update, pass `source.content_version`
|
|
121
|
-
from your last `read`; a stale one fails with `version_conflict`. Omitted or `null`
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
157
|
+
from your last `read`; a stale one fails with `version_conflict`. Omitted or `null` `content` keeps
|
|
158
|
+
the body. In `meta` a key left out keeps its stored value, `null`, `""` or `[]` clears it (not
|
|
159
|
+
`scope` or `team`); a key the server does not know is ignored and listed in the receipt's
|
|
160
|
+
`ignored`.
|
|
161
|
+
- `token` on `remember` and `remove` is an item's work token from `reflect`: it binds that one write to the
|
|
162
|
+
work (the server derives the write's key). `{ token, agent? }` alone, with a write token from
|
|
163
|
+
`reflect().writes` or a write receipt, resumes that write.
|
|
164
|
+
- `reflect` holds nothing between calls: a cold `reflect()` lists every unresolved write, the open work and
|
|
165
|
+
the blocked work. Decide an item with `{ token, verdict, reason, refs?, outputs? }`, `verdict` one of the
|
|
166
|
+
item's `verdicts`; the server sizes each batch (about 64 KiB of source Markdown, at most 16 items).
|
|
125
167
|
- `byte_range` values are UTF-8 byte offsets: `sliceUtf8(text, start, end)` slices a JS string by them.
|
|
126
168
|
- `vault.serverVersion` is the server version of the last reply. An agent exists from its first
|
|
127
169
|
`remember`; reading as an agent that wrote nothing finds nothing.
|
|
@@ -147,7 +189,7 @@ Markdown inline.
|
|
|
147
189
|
|
|
148
190
|
The tool list is not on the wire. `consol schema` prints its JSON Schema: `oneOf` holds one
|
|
149
191
|
envelope per tool, with the `args` schema and the description the model reads. An MCP client can
|
|
150
|
-
use
|
|
192
|
+
use the MCP server of this package instead (above).
|
|
151
193
|
|
|
152
194
|
## Loading many notes
|
|
153
195
|
|
|
@@ -181,16 +223,16 @@ try {
|
|
|
181
223
|
```
|
|
182
224
|
|
|
183
225
|
- `ConsolError.is(error)` also works across duplicate copies of the package, where `instanceof` fails.
|
|
184
|
-
- `field` names the input at fault, relative to the call's arguments (`
|
|
185
|
-
`decisions[2].
|
|
226
|
+
- `field` names the input at fault, relative to the call's arguments (`query`,
|
|
227
|
+
`decisions[2].refs[0]`), `tool` the tool, and `result` keeps the raw `Reply` of a failed tool
|
|
186
228
|
call, including the durable state of a pending write (`error.result.result`).
|
|
187
229
|
- Tool codes (contract section 4; accept unknown future ones): `invalid_argument`, `forbidden`,
|
|
188
230
|
`not_found`, `already_exists`, `version_conflict`, `team_not_attached`, `secret_rejected`,
|
|
189
231
|
`content_too_large`, `unsupported`, `work_not_found`, `basis_mismatch`, `already_decided`,
|
|
190
232
|
`unresolved_writes`, `postcondition_failed`, `index_unavailable`, `storage_unavailable`, `vault_busy`, `internal`.
|
|
191
233
|
Vault codes: `vault_exists`, `vault_not_found`.
|
|
192
|
-
- SDK codes: `request_failed` (`status?`), `
|
|
193
|
-
major.minor differs from the SDK's), `
|
|
234
|
+
- SDK codes: `request_failed` (`status?`), `addon_not_found`, `incompatible_server` (addon or
|
|
235
|
+
server major.minor differs from the SDK's), `timeout`, `aborted`, `closed`.
|
|
194
236
|
- `retryable: true` (`vault_busy`, `index_unavailable`, `storage_unavailable`, `request_failed` on a connect error or
|
|
195
237
|
502/503/504) means the identical request may succeed later. The SDK never retries by itself.
|
|
196
238
|
|
|
@@ -198,22 +240,17 @@ try {
|
|
|
198
240
|
|
|
199
241
|
- `close()` is final and idempotent: in-flight and later calls fail with `closed`, and concurrent
|
|
200
242
|
calls share one completion. `await using vault = await openVault(...)` closes it for you.
|
|
201
|
-
- An idle local vault does not keep Node or Bun alive: a script that forgets `close()` still
|
|
202
|
-
exits, and its server exits with it.
|
|
203
243
|
- Every call has a deadline: 300 s by default, `timeoutMs` per vault or per call, `0` disables it.
|
|
204
244
|
`signal` aborts a call. Both only stop waiting: a write may still complete, so read the note
|
|
205
245
|
before you retry.
|
|
206
|
-
-
|
|
207
|
-
|
|
208
|
-
- Servers on one vault take turns on its lock, a lease in the database; a wait over 5 s fails with
|
|
209
|
-
`vault_busy`.
|
|
246
|
+
- Engines on one vault, in this process or another, take turns on its lock, a lease in the
|
|
247
|
+
database; a wait over 5 s fails with `vault_busy`.
|
|
210
248
|
|
|
211
249
|
## Configuration and logging
|
|
212
250
|
|
|
213
|
-
Options of `createVault`, `openVault` (local) and `Consol.start` become the
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
vault.
|
|
251
|
+
Options of `createVault`, `openVault` (local) and `Consol.start` become the engine's settings (the
|
|
252
|
+
`CONSOL_*` names). Your process's own `CONSOL_*` variables are not read (except `CONSOL_DB_URL` as
|
|
253
|
+
the default for `db`), so a stray host variable cannot change the agent or the vault.
|
|
217
254
|
|
|
218
255
|
| Option | Meaning |
|
|
219
256
|
|---|---|
|
|
@@ -221,16 +258,16 @@ vault.
|
|
|
221
258
|
| `vaultRoot` / `vault` | `Consol.start`: a directory or `s3://` prefix of many vaults, or one vault |
|
|
222
259
|
| `agent` | default agent of every call; a call's `agent` argument overrides it |
|
|
223
260
|
| `db` | database URL (`CONSOL_DB_URL`): PostgreSQL with pgvector, or CockroachDB |
|
|
224
|
-
| `embedding` | `{ url, model, apiKey?, dims?,
|
|
261
|
+
| `embedding` | `{ url, model, apiKey?, dims?, timeoutMs? }` (`CONSOL_EMBED_*`); without it recall is lexical-only |
|
|
225
262
|
| `jev` | `{ url?, apiKey?, model?, auto? }` (`CONSOL_JEV_*`); experimental advice |
|
|
226
|
-
| `env` | any other
|
|
227
|
-
| `
|
|
263
|
+
| `env` | any other engine setting (a `CONSOL_*` name), applied last |
|
|
264
|
+
| `addonPath` | the `consol.node` to load, see above |
|
|
228
265
|
| `timeoutMs` | default per-call deadline in ms |
|
|
229
|
-
| `onLog` | `(line) => void`, receives each
|
|
266
|
+
| `onLog` | `(line) => void`, receives each engine log line |
|
|
267
|
+
| `logLevel` | which lines reach `onLog`, such as `info` or `consol_engine=debug` (default `warn`) |
|
|
230
268
|
|
|
231
|
-
The
|
|
232
|
-
|
|
233
|
-
last lines in its message and in `stderrTail`.
|
|
269
|
+
The addon has one log sink per process: every engine's `onLog` receives the same lines at the
|
|
270
|
+
latest `logLevel` set, and the sink is released when the last of them closes.
|
|
234
271
|
|
|
235
272
|
## Types and stability
|
|
236
273
|
|
|
@@ -246,21 +283,22 @@ decisions, and every `jev`, `jev_triage` and `jev_advisory` field (typed as plai
|
|
|
246
283
|
bun install
|
|
247
284
|
bun run build # dist/index.js (CJS), dist/index.mjs (ESM wrapper), dist/*.d.ts
|
|
248
285
|
bun run typecheck # tsc over src
|
|
249
|
-
#
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
bun run test
|
|
253
|
-
|
|
286
|
+
bun run test:offline # pure checks, hosted-client stub, fake-addon transport checks, strict tsc incl. conformance
|
|
287
|
+
# the rest needs the real addon and a database:
|
|
288
|
+
export CONSOL_ADDON=/abs/consol.node CONSOL_DB_URL=postgres://...
|
|
289
|
+
bun run test # the offline checks plus the real-addon suite on Node
|
|
290
|
+
CONSOL_BIN=/abs/consol bun run test:consumers # packed tarballs in Bun, Node ESM, Node CJS and platform-package projects
|
|
291
|
+
node test/capture.mjs # recapture test/fixtures from the real engine (without CONSOL_ADDON it only regenerates the types check)
|
|
254
292
|
```
|
|
255
293
|
|
|
256
294
|
`bun run test`, not `bun test` (that is Bun's own runner). Consumer logs go to
|
|
257
295
|
`consumers/<project>.log`.
|
|
258
296
|
|
|
259
|
-
## Publishing platform
|
|
297
|
+
## Publishing platform packages
|
|
260
298
|
|
|
261
299
|
1. `bun run build`
|
|
262
|
-
2. `bun scripts/make-platform-package.mjs <binary> <platform> <arch> <outDir>` per target
|
|
263
|
-
(win32-x64, darwin-arm64, darwin-x64, linux-x64, linux-arm64); the binary is stored as
|
|
264
|
-
`bin/consol[.exe]` whatever
|
|
300
|
+
2. `bun scripts/make-platform-package.mjs <binary> <addon> <platform> <arch> <outDir>` per target
|
|
301
|
+
(win32-x64, darwin-arm64, darwin-x64, linux-x64, linux-arm64); the CLI binary is stored as
|
|
302
|
+
`bin/consol[.exe]` and the addon as `consol.node`, whatever their file names
|
|
265
303
|
3. Publish each platform package, then `bun scripts/inject-optional-deps.mjs <publish-copy-of-package.json>`
|
|
266
304
|
4. `bun publish` the main package (`publishConfig.access` is `public`)
|
package/dist/consol.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type EngineOptions } from "./
|
|
1
|
+
import { type EngineOptions } from "./native";
|
|
2
2
|
import type { CallOptions, Context } from "./transport";
|
|
3
3
|
import type { Reply } from "./types";
|
|
4
4
|
/** Exactly one of `vaultRoot` / `vault`, plus the engine settings (`db`, `embedding`, `jev`, ...). */
|
|
@@ -10,7 +10,7 @@ export interface ConsolOptions extends EngineOptions {
|
|
|
10
10
|
}
|
|
11
11
|
export declare function httpStatus(reply: Reply): number;
|
|
12
12
|
/**
|
|
13
|
-
* The engine in your own backend:
|
|
13
|
+
* The engine in your own backend: the in-process engine behind `handle`. A backend authorizes
|
|
14
14
|
* the request itself, then passes the result as `ctx`.
|
|
15
15
|
*
|
|
16
16
|
* SECURITY: `ctx` (the vaults the caller may use, the agent they are) must come from YOUR auth,
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { Reply } from "./types";
|
|
2
2
|
/** Branchable error codes: wire tool codes (contract section 4) plus the SDK codes of section 6. */
|
|
3
|
-
export type ConsolErrorCode = "invalid_argument" | "not_found" | "already_exists" | "version_conflict" | "team_not_attached" | "secret_rejected" | "content_too_large" | "unsupported" | "work_not_found" | "basis_mismatch" | "already_decided" | "unresolved_writes" | "postcondition_failed" | "index_unavailable" | "storage_unavailable" | "vault_busy" | "forbidden" | "vault_exists" | "vault_not_found" | "internal" | "request_failed" | "
|
|
3
|
+
export type ConsolErrorCode = "invalid_argument" | "not_found" | "already_exists" | "version_conflict" | "team_not_attached" | "secret_rejected" | "content_too_large" | "unsupported" | "work_not_found" | "basis_mismatch" | "already_decided" | "unresolved_writes" | "postcondition_failed" | "index_unavailable" | "storage_unavailable" | "vault_busy" | "forbidden" | "vault_exists" | "vault_not_found" | "internal" | "request_failed" | "addon_not_found" | "incompatible_server" | "timeout" | "aborted" | "closed" | (string & {});
|
|
4
4
|
export interface ConsolErrorDetails {
|
|
5
5
|
retryable?: boolean;
|
|
6
6
|
field?: string;
|
|
7
7
|
tool?: string;
|
|
8
8
|
/** HTTP status of a `request_failed` / `forbidden` that came from the transport, not the engine. */
|
|
9
9
|
status?: number;
|
|
10
|
-
stderrTail?: string;
|
|
11
10
|
result?: Reply;
|
|
12
11
|
cause?: unknown;
|
|
13
12
|
}
|
|
@@ -18,7 +17,6 @@ export declare class ConsolError extends Error {
|
|
|
18
17
|
readonly field?: string;
|
|
19
18
|
readonly tool?: string;
|
|
20
19
|
readonly status?: number;
|
|
21
|
-
readonly stderrTail?: string;
|
|
22
20
|
/** Raw reply of a failed typed call: durable write state (`result.result`) survives the throw. */
|
|
23
21
|
readonly result?: Reply;
|
|
24
22
|
constructor(code: ConsolErrorCode, message: string, details?: ConsolErrorDetails);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ConsolError, type ConsolErrorCode } from "./errors";
|
|
2
2
|
export { Consol, httpStatus, type ConsolOptions } from "./consol";
|
|
3
3
|
export type { CallOptions, Context } from "./transport";
|
|
4
|
-
export type { EmbeddingOptions, EngineOptions, JevOptions } from "./
|
|
5
|
-
export { Vault, createVault, openVault, sliceUtf8, type VaultOptions, type HostedOptions, type RecallArgs, type ReadArgs, type RememberArgs, type RemoveArgs, type ResumeArgs, type ReflectArgs, type
|
|
6
|
-
export type { Reply, ToolError, Unavailable, Status, ByteRange, Scope, SourceRef, RelationshipKind, Relationship, RecallRetrieval, SourceExcerpt, RecallCard, RecallResult, ReadResult, RememberResult, RemoveResult, ReflectResult, AffectedDoc, EntityAffectedGroup, WriteState, WriteFailureCode, WriteReceipt, WriteResolution, WriteOutcome,
|
|
4
|
+
export type { EmbeddingOptions, EngineOptions, JevOptions } from "./native";
|
|
5
|
+
export { Vault, createVault, openVault, sliceUtf8, type VaultOptions, type HostedOptions, type RecallArgs, type ReadArgs, type RememberArgs, type RemoveArgs, type ResumeArgs, type ReflectArgs, type Decision, } from "./vault";
|
|
6
|
+
export type { Reply, ToolError, Unavailable, Status, ByteRange, Scope, SourceRef, RelationshipKind, Relationship, RecallRetrieval, SourceExcerpt, RecallCard, RecallResult, ReadResult, RememberResult, RemoveResult, ReflectResult, AffectedDoc, EntityAffectedGroup, WriteState, WriteFailureCode, WriteReceipt, WriteResolution, WriteOutcome, UnresolvedWrite, ReflectItem, SourceItem, PairItem, HubItem, PromotionItem, DeliveredSource, DecisionReceipt, FocusError, ReflectNext, } from "./types";
|