@tangleai/context 0.21.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.
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Validate structure and references, without interpreting prose or making requests.
3
+ * Supplied artifacts are the host's allow-list; matching ids must retain their
4
+ * admitted descriptor. Without an external list, the envelope is self-contained.
5
+ * @param {any} envelope
6
+ * @param {{ artifacts?: import('./schemas/evidence.js').ArtifactRecord[] }} [options]
7
+ */
8
+ export function validateClaimEvidence(envelope: any, options?: {
9
+ artifacts?: import("./schemas/evidence.js").ArtifactRecord[];
10
+ }): {
11
+ valid: boolean;
12
+ errors: any[];
13
+ };
14
+ /**
15
+ * A second guarded-document consumer: replace or patch a claim envelope using
16
+ * host persistence and an explicit artifact admission list.
17
+ * @param {{ read: () => Promise<any>, apply: (document: any, proposal: any) => any,
18
+ * validateProposal: (proposal: any) => any, commit: (document: any) => Promise<any>,
19
+ * artifacts: import('./schemas/evidence.js').ArtifactRecord[],
20
+ * snapshot?: () => Promise<any>, restore?: (token: any) => Promise<any> }} options
21
+ */
22
+ export function createClaimRefiner(options: {
23
+ read: () => Promise<any>;
24
+ apply: (document: any, proposal: any) => any;
25
+ validateProposal: (proposal: any) => any;
26
+ commit: (document: any) => Promise<any>;
27
+ artifacts: import("./schemas/evidence.js").ArtifactRecord[];
28
+ snapshot?: () => Promise<any>;
29
+ restore?: (token: any) => Promise<any>;
30
+ }): {
31
+ prepare: (document: any, proposal: any) => {
32
+ valid: boolean;
33
+ errors: any;
34
+ next?: undefined;
35
+ plan?: undefined;
36
+ } | {
37
+ valid: boolean;
38
+ errors: never[];
39
+ next: any;
40
+ plan: any;
41
+ };
42
+ commitPrepared: (previous: any, prepared: any) => Promise<{
43
+ ok: boolean;
44
+ stage: string;
45
+ errors: any;
46
+ cause?: undefined;
47
+ snapshot?: undefined;
48
+ value?: undefined;
49
+ } | {
50
+ ok: boolean;
51
+ stage: string;
52
+ cause: unknown;
53
+ errors: {
54
+ code: any;
55
+ docPath: any;
56
+ message: any;
57
+ stage: any;
58
+ }[];
59
+ snapshot?: undefined;
60
+ value?: undefined;
61
+ } | {
62
+ stage?: undefined;
63
+ cause?: undefined;
64
+ errors?: undefined;
65
+ ok: boolean;
66
+ value: any;
67
+ snapshot: any;
68
+ } | {
69
+ ok: boolean;
70
+ stage: string;
71
+ cause: unknown;
72
+ snapshot: any;
73
+ restoreError?: {} | null | undefined;
74
+ errors: {
75
+ code: any;
76
+ docPath: any;
77
+ message: any;
78
+ stage: any;
79
+ }[];
80
+ value?: undefined;
81
+ }>;
82
+ commit: (proposal: any) => Promise<{
83
+ ok: boolean;
84
+ stage: string;
85
+ errors: any;
86
+ cause?: undefined;
87
+ snapshot?: undefined;
88
+ value?: undefined;
89
+ } | {
90
+ ok: boolean;
91
+ stage: string;
92
+ cause: unknown;
93
+ errors: {
94
+ code: any;
95
+ docPath: any;
96
+ message: any;
97
+ stage: any;
98
+ }[];
99
+ snapshot?: undefined;
100
+ value?: undefined;
101
+ } | {
102
+ stage?: undefined;
103
+ cause?: undefined;
104
+ errors?: undefined;
105
+ ok: boolean;
106
+ value: any;
107
+ snapshot: any;
108
+ } | {
109
+ ok: boolean;
110
+ stage: string;
111
+ cause: unknown;
112
+ snapshot: any;
113
+ restoreError?: {} | null | undefined;
114
+ errors: {
115
+ code: any;
116
+ docPath: any;
117
+ message: any;
118
+ stage: any;
119
+ }[];
120
+ value?: undefined;
121
+ }>;
122
+ };
@@ -0,0 +1,71 @@
1
+ //@ts-check
2
+ import { JarenValidator } from '@jarenjs/validate';
3
+ import { checkOutcome } from '@jarenjs/core/check';
4
+ import { CLAIM_EVIDENCE_SCHEMA } from './schemas/evidence.js';
5
+ import { createGuardedRefiner } from '@jarenjs/core/guarded';
6
+ const check = new JarenValidator({ collectErrors: true, skipErrors: false }).compile(CLAIM_EVIDENCE_SCHEMA);
7
+
8
+ /**
9
+ * Validate structure and references, without interpreting prose or making requests.
10
+ * Supplied artifacts are the host's allow-list; matching ids must retain their
11
+ * admitted descriptor. Without an external list, the envelope is self-contained.
12
+ * @param {any} envelope
13
+ * @param {{ artifacts?: import('./schemas/evidence.js').ArtifactRecord[] }} [options]
14
+ */
15
+ export function validateClaimEvidence(envelope, options = {}) {
16
+ const shape = checkOutcome(check(envelope));
17
+ if (!shape.valid) return shape;
18
+ const errors = [];
19
+ const add = (code, docPath, message) => errors.push({ code, docPath, instancePath: docPath, message });
20
+ const sets = {};
21
+ for (const kind of ['artifacts', 'evidence', 'claims']) {
22
+ const ids = new Set();
23
+ envelope[kind].forEach((record, index) => {
24
+ if (ids.has(record.id)) add('EVIDENCE_DUPLICATE', `/${kind}/${index}/id`, `duplicate ${kind} id '${record.id}'`);
25
+ ids.add(record.id);
26
+ });
27
+ sets[kind] = ids;
28
+ }
29
+ if (options.artifacts) {
30
+ const admitted = new Map(options.artifacts.map((artifact) => [artifact.id, artifact]));
31
+ envelope.artifacts.forEach((artifact, i) => {
32
+ const held = admitted.get(artifact.id);
33
+ if (!held || ['kind', 'locator', 'digest'].some((field) => artifact[field] !== held[field]))
34
+ add('EVIDENCE_UNADMITTED', `/artifacts/${i}`, `artifact '${artifact.id}' is not admitted with this descriptor`);
35
+ });
36
+ }
37
+ envelope.evidence.forEach((record, i) => {
38
+ if (!sets.artifacts.has(record.artifact))
39
+ add('EVIDENCE_ARTIFACT', `/evidence/${i}/artifact`, `unknown artifact '${record.artifact}'`);
40
+ });
41
+ const visible = new Set(envelope.visibleEvidence);
42
+ envelope.visibleEvidence.forEach((id, i) => {
43
+ if (!sets.evidence.has(id)) add('EVIDENCE_REFERENCE', `/visibleEvidence/${i}`, `unknown evidence '${id}'`);
44
+ });
45
+ envelope.claims.forEach((claim, i) => {
46
+ if (claim.critical && (claim.status === 'unresolved' || claim.evidence.length === 0))
47
+ add('EVIDENCE_CRITICAL', `/claims/${i}/status`, `critical claim '${claim.id}' is unresolved`);
48
+ claim.evidence.forEach((id, j) => {
49
+ if (!sets.evidence.has(id)) add('EVIDENCE_REFERENCE', `/claims/${i}/evidence/${j}`, `unknown evidence '${id}'`);
50
+ else if (!visible.has(id)) add('EVIDENCE_HIDDEN', `/claims/${i}/evidence/${j}`, `evidence '${id}' is outside the visible view`);
51
+ });
52
+ });
53
+ errors.sort((a, b) => a.docPath < b.docPath ? -1 : a.docPath > b.docPath ? 1 : a.code.localeCompare(b.code));
54
+ return { valid: errors.length === 0, errors };
55
+ }
56
+
57
+ /**
58
+ * A second guarded-document consumer: replace or patch a claim envelope using
59
+ * host persistence and an explicit artifact admission list.
60
+ * @param {{ read: () => Promise<any>, apply: (document: any, proposal: any) => any,
61
+ * validateProposal: (proposal: any) => any, commit: (document: any) => Promise<any>,
62
+ * artifacts: import('./schemas/evidence.js').ArtifactRecord[],
63
+ * snapshot?: () => Promise<any>, restore?: (token: any) => Promise<any> }} options
64
+ */
65
+ export function createClaimRefiner(options) {
66
+ const artifacts = JSON.parse(JSON.stringify(options.artifacts));
67
+ return createGuardedRefiner({ ...options,
68
+ validateCandidate: (next) => validateClaimEvidence(next, { artifacts }),
69
+ planCommit: (next) => next,
70
+ });
71
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export { createMemoryStorage } from "./storage/memory.js";
2
+ export { RECALL_TOOL_NAME, createRecallTool, roundSlotName, indexSlotName, slotRef, slotAddress, slotAddressesIn } from "./recall.js";
3
+ export { createLedger, sameIdentity, describeIdentity } from "./ledger.js";
4
+ export { createEnvironment, environmentTools, chunkSlotName, chunkFamily, CHUNK_KIND } from "./environment.js";
5
+ export { LEDGER_SCHEMAS, GOAL_SCHEMA, MEMORY_SCHEMA, SKILL_SCHEMA, SLOT_SCHEMA } from "./schemas/ledger.js";
6
+ export { REFINEMENT_PATCH_SCHEMA, refinementPatchSchema, REFINEMENT_PATH_PATTERN, DEFAULT_MAX_OPS, MEMORY_PROPOSAL_SCHEMA, SKILL_PROPOSAL_SCHEMA, PROGRESS_PROPOSAL_SCHEMA } from "./schemas/patch.js";
7
+ export { validateClaimEvidence, createClaimRefiner } from "./evidence.js";
8
+ export { CLAIM_EVIDENCE_SCHEMA, ARTIFACT_SCHEMA, EVIDENCE_SCHEMA, CLAIM_SCHEMA } from "./schemas/evidence.js";
9
+ export { ledgerFootprint, checkpointProgress, validateCheckpoint, goalPrompt } from "./retention.js";
package/src/index.js ADDED
@@ -0,0 +1,11 @@
1
+ //@ts-check
2
+ /** context: public AI mechanisms over injected Jaren foundations. */
3
+ export { RECALL_TOOL_NAME, createRecallTool, roundSlotName, indexSlotName, slotRef, slotAddress, slotAddressesIn } from './recall.js';
4
+ export { createLedger, sameIdentity, describeIdentity } from './ledger.js';
5
+ export { createEnvironment, environmentTools, chunkSlotName, chunkFamily, CHUNK_KIND } from './environment.js';
6
+ export { createMemoryStorage } from './storage/memory.js';
7
+ export { LEDGER_SCHEMAS, GOAL_SCHEMA, MEMORY_SCHEMA, SKILL_SCHEMA, SLOT_SCHEMA } from './schemas/ledger.js';
8
+ export { REFINEMENT_PATCH_SCHEMA, refinementPatchSchema, REFINEMENT_PATH_PATTERN, DEFAULT_MAX_OPS, MEMORY_PROPOSAL_SCHEMA, SKILL_PROPOSAL_SCHEMA, PROGRESS_PROPOSAL_SCHEMA } from './schemas/patch.js';
9
+ export { validateClaimEvidence, createClaimRefiner } from './evidence.js';
10
+ export { CLAIM_EVIDENCE_SCHEMA, ARTIFACT_SCHEMA, EVIDENCE_SCHEMA, CLAIM_SCHEMA } from './schemas/evidence.js';
11
+ export { ledgerFootprint, checkpointProgress, validateCheckpoint, goalPrompt } from './retention.js';
@@ -0,0 +1,354 @@
1
+ /**
2
+ * Whether two vector identities name the same space: the same model at
3
+ * the same width. The rule the ledger applies before any arithmetic
4
+ * happens, exported because it is not the ledger's alone — a storage
5
+ * adapter's optional `rank` selects the records whose `embeddedBy` is
6
+ * the query's, and a host keeping its own vector store beside the
7
+ * ledger has to refuse the same mixtures. A second implementation of a
8
+ * one-line predicate is a second chance to get its edges wrong, and
9
+ * both edges below are ones a re-derivation usually misses.
10
+ *
11
+ * Total, and false rather than a throw for anything malformed, so it
12
+ * can be applied straight to what a store handed back.
13
+ *
14
+ * **Two absent identities are NOT the same.** A record with no identity
15
+ * has no space to share; "unknown" must never rank against "unknown",
16
+ * or an un-embedded record would compare equal to every other one.
17
+ * **A width alone is not an identity either** — two models at 768 dims
18
+ * produce vectors whose cosine is arithmetic without meaning, which is
19
+ * why `dims` matching is necessary and never sufficient.
20
+ *
21
+ * @param {LedgerEmbeddedBy | undefined | null} a
22
+ * @param {LedgerEmbeddedBy | undefined | null} b
23
+ * @returns {boolean} whether both are identities naming one space
24
+ * @example
25
+ * sameIdentity({ model: 'm', dims: 4 }, { model: 'm', dims: 4 }); // true
26
+ * sameIdentity({ model: 'm', dims: 4 }, { model: 'm', dims: 8 }); // false — a re-embed, not a match
27
+ * sameIdentity(undefined, undefined); // false — no space is not a shared space
28
+ */
29
+ export function sameIdentity(a: LedgerEmbeddedBy | undefined | null, b: LedgerEmbeddedBy | undefined | null): boolean;
30
+ /**
31
+ * An identity as a refusal names it — `"text-embedding-3-small (1536
32
+ * dims)"`. Exported for the same reason as {@link sameIdentity}: it is
33
+ * the wording the ledger's mixture refusals use, so a host reporting
34
+ * the same condition reports it in the same words, and it is a stable
35
+ * key for collecting the DISTINCT identities a `rank` adapter owes its
36
+ * caller.
37
+ *
38
+ * @param {LedgerEmbeddedBy} identity
39
+ * @returns {string}
40
+ */
41
+ export function describeIdentity(identity: LedgerEmbeddedBy): string;
42
+ /**
43
+ * Create a ledger.
44
+ *
45
+ * @param {{ storage?: { get: (key: string) => Promise<any>,
46
+ * set: (key: string, value: any) => Promise<void>,
47
+ * delete: (key: string) => Promise<void>,
48
+ * keys: (prefix?: string) => Promise<string[]>,
49
+ * status?: () => any,
50
+ * mutate?: import('./storage/transaction.js').StorageMutation,
51
+ * rank?: (request: { prefix: string, vector: number[], model: string, dims: number,
52
+ * limit?: number, minScore?: number }) => Promise<{ hits: { key: string, score: number }[],
53
+ * skipped: number, identities: LedgerEmbeddedBy[], ranking?: LedgerRanking }> },
54
+ * compileQuery?: (document: any) => (data: any) => any,
55
+ * embedder?: Embedder,
56
+ * embedOnWrite?: boolean,
57
+ * validator?: any,
58
+ * now?: () => string,
59
+ * archiveLimits?: { maxItems?: number, maxBytes?: number },
60
+ * goalLimits?: { maxEntries?: number, maxBytes?: number, maxChars?: number },
61
+ * checkpointReducer?: (goal: any) => any,
62
+ * artifacts?: import('./schemas/evidence.js').ArtifactRecord[] }} [options]
63
+ * - `storage` defaults to an in-memory adapter, so a ledger works with
64
+ * nothing wired. Anything durable is the host's to inject. Its four
65
+ * methods are the contract; an adapter that can rank vectors itself
66
+ * declares an optional fifth (`rank`) and `recall({ near })` asks it
67
+ * instead of reading every record.
68
+ * - `compileQuery` is the retrieval seam — `compileJsonQuery` from
69
+ * `@jarenjs/json/query`, or absent. With it, `recall` filters with a
70
+ * real query document; without it, retrieval degrades to tag match
71
+ * and recency, and a caller-supplied predicate is refused rather
72
+ * than silently ignored.
73
+ * - `embedder` is the meaning seam — `createEmbeddingClient(...)`,
74
+ * `createHashEmbedder()`, or any host `{ embed, model, dims }` whose
75
+ * `embed` returns a Promise and rejects rather than throws. With it,
76
+ * `recall({ near })` ranks and `embedMissing()` sweeps; without it,
77
+ * both refuse naming the seam. Every stored vector is compared
78
+ * against the embedder's `{ model, dims }` before any arithmetic.
79
+ * - `embedOnWrite` (default `false`) embeds a memory or skill that
80
+ * arrives without a vector inside its own write. Off by default on
81
+ * purpose: a write must not silently acquire a network dependency.
82
+ * On, a seam failure stores the record un-embedded and reports it on
83
+ * the returned record (`embedError`) — never a dropped write.
84
+ * - `now` returns an RFC 3339 timestamp (injected for deterministic
85
+ * tests, exactly as the rest of the suite injects its environment).
86
+ */
87
+ export function createLedger(options?: {
88
+ storage?: {
89
+ get: (key: string) => Promise<any>;
90
+ set: (key: string, value: any) => Promise<void>;
91
+ delete: (key: string) => Promise<void>;
92
+ keys: (prefix?: string) => Promise<string[]>;
93
+ status?: () => any;
94
+ mutate?: import("./storage/transaction.js").StorageMutation;
95
+ rank?: (request: {
96
+ prefix: string;
97
+ vector: number[];
98
+ model: string;
99
+ dims: number;
100
+ limit?: number;
101
+ minScore?: number;
102
+ }) => Promise<{
103
+ hits: {
104
+ key: string;
105
+ score: number;
106
+ }[];
107
+ skipped: number;
108
+ identities: LedgerEmbeddedBy[];
109
+ ranking?: LedgerRanking;
110
+ }>;
111
+ };
112
+ compileQuery?: (document: any) => (data: any) => any;
113
+ embedder?: Embedder;
114
+ embedOnWrite?: boolean;
115
+ validator?: any;
116
+ now?: () => string;
117
+ archiveLimits?: {
118
+ maxItems?: number;
119
+ maxBytes?: number;
120
+ };
121
+ goalLimits?: {
122
+ maxEntries?: number;
123
+ maxBytes?: number;
124
+ maxChars?: number;
125
+ };
126
+ checkpointReducer?: (goal: any) => any;
127
+ artifacts?: import("./schemas/evidence.js").ArtifactRecord[];
128
+ }): {
129
+ storageStatus: () => any;
130
+ concurrency: string;
131
+ validate: (kind: "goal" | "memory" | "skill" | "slot", record: any) => null | {
132
+ error: string;
133
+ errors: any[];
134
+ inputSchema: any;
135
+ };
136
+ setGoal: (input: {
137
+ objective: string;
138
+ createdAt?: string;
139
+ status?: string;
140
+ progress?: any[];
141
+ }) => Promise<LedgerGoal | LedgerRejection>;
142
+ getGoal: () => Promise<LedgerGoal | null>;
143
+ listArchivedGoals: () => Promise<LedgerGoal[]>;
144
+ recordProgress: (entry: {
145
+ note: string;
146
+ evidence: string;
147
+ at?: string;
148
+ }) => Promise<LedgerGoal | LedgerRejection | {
149
+ error: string;
150
+ }>;
151
+ setGoalStatus: (status: "active" | "done" | "abandoned" | "superseded") => Promise<LedgerGoal | LedgerRejection | {
152
+ error: string;
153
+ }>;
154
+ composeGoal: () => Promise<{
155
+ error: string;
156
+ errors: any[];
157
+ inputSchema: any;
158
+ } | {
159
+ text: string;
160
+ error?: undefined;
161
+ code?: undefined;
162
+ } | {
163
+ error: string;
164
+ code: string;
165
+ text?: undefined;
166
+ }>;
167
+ addMemory: (input: {
168
+ id?: string;
169
+ text: string;
170
+ evidence: LedgerMemory["evidence"];
171
+ tags?: string[];
172
+ at?: string;
173
+ } & LedgerEmbeddingPair) => Promise<(LedgerMemory & {
174
+ embedError?: string;
175
+ }) | LedgerRejection>;
176
+ getMemory: (id: string) => Promise<LedgerMemory | null>;
177
+ listMemories: () => Promise<LedgerMemory[]>;
178
+ deleteMemory: (id: string) => Promise<boolean>;
179
+ addSkill: (input: {
180
+ id?: string;
181
+ name: string;
182
+ when: string;
183
+ instructions: string;
184
+ tools?: string[];
185
+ at?: string;
186
+ program?: LedgerSkill["program"];
187
+ } & LedgerEmbeddingPair) => Promise<(LedgerSkill & {
188
+ embedError?: string;
189
+ }) | LedgerRejection>;
190
+ getSkill: (id: string) => Promise<LedgerSkill | null>;
191
+ listSkills: () => Promise<LedgerSkill[]>;
192
+ deleteSkill: (id: string) => Promise<boolean>;
193
+ recall: (query?: LedgerQuery) => Promise<LedgerMemory[] | LedgerRankedMemories | {
194
+ error: string;
195
+ }>;
196
+ recallSkills: (query?: LedgerQuery) => Promise<LedgerSkill[] | LedgerRankedSkills | {
197
+ error: string;
198
+ }>;
199
+ embedMissing: (options?: {
200
+ limit?: number;
201
+ batch?: number;
202
+ }) => Promise<{
203
+ embedded: number;
204
+ remaining: number;
205
+ error?: string;
206
+ }>;
207
+ putSlot: (name: string, content: string, meta?: {
208
+ kind?: string;
209
+ at?: string;
210
+ count?: number;
211
+ pinned?: boolean;
212
+ }) => Promise<LedgerSlot | LedgerRejection>;
213
+ getSlot: (name: string) => Promise<LedgerSlot | null>;
214
+ readSlot: (name: string) => Promise<string | undefined | {
215
+ status: "evicted";
216
+ name: string;
217
+ bytes: number;
218
+ reason: string;
219
+ }>;
220
+ listSlots: () => Promise<LedgerSlot[]>;
221
+ deleteSlot: (name: string) => Promise<boolean>;
222
+ putArchive: (entries: any, protection?: {}) => Promise<{
223
+ error: string;
224
+ code: string;
225
+ retention?: undefined;
226
+ next?: undefined;
227
+ report?: undefined;
228
+ footprint?: undefined;
229
+ } | {
230
+ error: string;
231
+ code: string;
232
+ retention: {
233
+ refused: boolean;
234
+ limits: any;
235
+ current: {
236
+ items: number;
237
+ bytes: number;
238
+ };
239
+ attempted: {
240
+ items: number;
241
+ bytes: number;
242
+ };
243
+ };
244
+ next?: undefined;
245
+ report?: undefined;
246
+ footprint?: undefined;
247
+ } | {
248
+ next: any;
249
+ report: {
250
+ version: number;
251
+ policy: string;
252
+ evicted: any[];
253
+ written: any;
254
+ };
255
+ footprint: {
256
+ items: number;
257
+ bytes: number;
258
+ };
259
+ error?: undefined;
260
+ code?: undefined;
261
+ retention?: undefined;
262
+ } | {
263
+ error: string;
264
+ errors: any[];
265
+ inputSchema: any;
266
+ } | {
267
+ ok: boolean;
268
+ retention: {
269
+ version: number;
270
+ policy: string;
271
+ evicted: any[];
272
+ written: any;
273
+ };
274
+ footprint: {
275
+ items: number;
276
+ bytes: number;
277
+ };
278
+ }>;
279
+ clearArchives: (prefix?: string) => Promise<boolean>;
280
+ retentionReport: () => Promise<any>;
281
+ snapshot: () => Promise<string>;
282
+ rollback: (token: string) => Promise<true | {
283
+ error: string;
284
+ }>;
285
+ transaction: (expected: any, work: (ledger: any) => Promise<any>) => Promise<any>;
286
+ };
287
+ export type LedgerGoal = import("./schemas/ledger.js").LedgerGoal;
288
+ export type LedgerMemory = import("./schemas/ledger.js").LedgerMemory;
289
+ export type LedgerSkill = import("./schemas/ledger.js").LedgerSkill;
290
+ export type LedgerSlot = import("./schemas/ledger.js").LedgerSlot;
291
+ export type LedgerRejection = import("./schemas/ledger.js").LedgerRejection;
292
+ export type LedgerEmbeddingPair = import("./schemas/ledger.js").LedgerEmbeddingPair;
293
+ export type LedgerEmbeddedBy = import("./schemas/ledger.js").LedgerEmbeddedBy;
294
+ export type Embedder = import("@tangleai/models/embed").Embedder;
295
+ /**
296
+ * What `recall({ near })` answers: the memories that carry a comparable
297
+ * vector, ranked by cosine similarity (descending; ties by recency, then
298
+ * id), one score per memory in the same order, and the count of records
299
+ * that passed the filter but carry no vector and were therefore skipped
300
+ * — reported, never scored.
301
+ */
302
+ export type LedgerRankedMemories = {
303
+ memories: LedgerMemory[];
304
+ scores: number[];
305
+ skipped: number;
306
+ /**
307
+ * - which path answered: the ledger's
308
+ * own read-and-rank, or the adapter's `rank` capability
309
+ */
310
+ via: "sweep" | "adapter";
311
+ /**
312
+ * - candidate selection provenance, not a quality guarantee
313
+ */
314
+ ranking: LedgerRanking;
315
+ };
316
+ /**
317
+ * What `recallSkills({ near })` answers — see {@link LedgerRankedMemories}.
318
+ */
319
+ export type LedgerRankedSkills = {
320
+ skills: LedgerSkill[];
321
+ scores: number[];
322
+ skipped: number;
323
+ /**
324
+ * - see {@link LedgerRankedMemories}
325
+ */
326
+ via: "sweep" | "adapter";
327
+ /**
328
+ * - see {@link LedgerRankedMemories}
329
+ */
330
+ ranking: LedgerRanking;
331
+ };
332
+ /**
333
+ * Optional storage rank metadata. Legacy adapters normalize to exhaustive.
334
+ * Exhaustive means exact candidate selection, not that every record is returned.
335
+ * Candidate count is the number returned before ledger filtering and capping.
336
+ */
337
+ export type LedgerRanking = {
338
+ algorithm: string;
339
+ exhaustive: boolean;
340
+ candidateCount: number;
341
+ };
342
+ /**
343
+ * The query both recalls take. `near` is the string to rank by meaning
344
+ * against, and needs the embedder seam; `minScore` filters the ranked
345
+ * result (cosine, in [-1, 1]); `tags` and `where` narrow the candidates
346
+ * first, exactly as they do without `near`.
347
+ */
348
+ export type LedgerQuery = {
349
+ tags?: string[];
350
+ where?: any;
351
+ limit?: number;
352
+ near?: string;
353
+ minScore?: number;
354
+ };