@intentface/latch-memory 0.9.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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +163 -0
  3. package/dist/extraction-key.d.ts +20 -0
  4. package/dist/extraction-key.d.ts.map +1 -0
  5. package/dist/extraction-key.js +43 -0
  6. package/dist/extraction-key.js.map +1 -0
  7. package/dist/index-file.d.ts +77 -0
  8. package/dist/index-file.d.ts.map +1 -0
  9. package/dist/index-file.js +169 -0
  10. package/dist/index-file.js.map +1 -0
  11. package/dist/index.d.ts +23 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +23 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/jobs/types.d.ts +133 -0
  16. package/dist/jobs/types.d.ts.map +1 -0
  17. package/dist/jobs/types.js +12 -0
  18. package/dist/jobs/types.js.map +1 -0
  19. package/dist/prompts/consolidator.d.ts +18 -0
  20. package/dist/prompts/consolidator.d.ts.map +1 -0
  21. package/dist/prompts/consolidator.js +76 -0
  22. package/dist/prompts/consolidator.js.map +1 -0
  23. package/dist/prompts/extractor.d.ts +34 -0
  24. package/dist/prompts/extractor.d.ts.map +1 -0
  25. package/dist/prompts/extractor.js +60 -0
  26. package/dist/prompts/extractor.js.map +1 -0
  27. package/dist/prompts/inject.d.ts +20 -0
  28. package/dist/prompts/inject.d.ts.map +1 -0
  29. package/dist/prompts/inject.js +58 -0
  30. package/dist/prompts/inject.js.map +1 -0
  31. package/dist/provider.d.ts +47 -0
  32. package/dist/provider.d.ts.map +1 -0
  33. package/dist/provider.js +101 -0
  34. package/dist/provider.js.map +1 -0
  35. package/dist/sanitize.d.ts +29 -0
  36. package/dist/sanitize.d.ts.map +1 -0
  37. package/dist/sanitize.js +88 -0
  38. package/dist/sanitize.js.map +1 -0
  39. package/dist/schema.d.ts +60 -0
  40. package/dist/schema.d.ts.map +1 -0
  41. package/dist/schema.js +144 -0
  42. package/dist/schema.js.map +1 -0
  43. package/dist/scope.d.ts +62 -0
  44. package/dist/scope.d.ts.map +1 -0
  45. package/dist/scope.js +136 -0
  46. package/dist/scope.js.map +1 -0
  47. package/dist/search-evidence.d.ts +34 -0
  48. package/dist/search-evidence.d.ts.map +1 -0
  49. package/dist/search-evidence.js +40 -0
  50. package/dist/search-evidence.js.map +1 -0
  51. package/dist/store/loredex.d.ts +61 -0
  52. package/dist/store/loredex.d.ts.map +1 -0
  53. package/dist/store/loredex.js +558 -0
  54. package/dist/store/loredex.js.map +1 -0
  55. package/dist/store/memory.d.ts +31 -0
  56. package/dist/store/memory.d.ts.map +1 -0
  57. package/dist/store/memory.js +156 -0
  58. package/dist/store/memory.js.map +1 -0
  59. package/dist/tools.d.ts +91 -0
  60. package/dist/tools.d.ts.map +1 -0
  61. package/dist/tools.js +389 -0
  62. package/dist/tools.js.map +1 -0
  63. package/dist/types.d.ts +130 -0
  64. package/dist/types.d.ts.map +1 -0
  65. package/dist/types.js +13 -0
  66. package/dist/types.js.map +1 -0
  67. package/package.json +60 -0
package/dist/tools.js ADDED
@@ -0,0 +1,389 @@
1
+ import { tool, jsonSchema } from "ai";
2
+ import { IndexValidationError, MEMORY_INDEX_FILENAME, parseIndex } from "./index-file.js";
3
+ import { isUnderScopeRoot } from "./scope.js";
4
+ import { schemaSectionWarnings } from "./schema.js";
5
+ import { createSafetyOf, entryEvidence, EVIDENCE_RANK } from "./search-evidence.js";
6
+ import { sanitizeMemoryText } from "./sanitize.js";
7
+ /** One scope's search pass: backend hits + index-evidence merge + synthetic hits. */
8
+ async function searchOneScope(bound, query, limit) {
9
+ const hits = await bound.store.search(bound.principal, bound.scope, query, limit);
10
+ // Evidence pass over the compiled index: the backend ranks free text,
11
+ // but create_safety needs EXACT signals (normalized alias equality) the
12
+ // backend can't provide — so match active entries ourselves and merge,
13
+ // strongest signal winning per result. Index unavailability degrades to
14
+ // body-only evidence, never a failed search.
15
+ let entries = [];
16
+ try {
17
+ const index = await bound.store.readIndex(bound.principal, bound.scope);
18
+ if (index)
19
+ entries = parseIndex(index).entries.filter((e) => !e.archived);
20
+ }
21
+ catch {
22
+ // body-only evidence
23
+ }
24
+ const evidenceById = new Map();
25
+ for (const e of entries) {
26
+ const evidence = entryEvidence(query, e);
27
+ if (evidence)
28
+ evidenceById.set(e.id, evidence);
29
+ }
30
+ const unverifiedIds = new Set(entries.filter((e) => e.unverified).map((e) => e.id));
31
+ const results = hits.map((h) => {
32
+ let matchedOn = "body";
33
+ // Trust mark: label (never hide) hits on unverified entries/episodes.
34
+ let unverified = /^status:\s*unverified\b/m.test(h.snippet);
35
+ for (const id of h.memoryIds) {
36
+ const evidence = evidenceById.get(id);
37
+ if (evidence && EVIDENCE_RANK[evidence] > EVIDENCE_RANK[matchedOn]) {
38
+ matchedOn = evidence;
39
+ }
40
+ if (unverifiedIds.has(id))
41
+ unverified = true;
42
+ }
43
+ return {
44
+ path: h.path,
45
+ snippet: sanitizeMemoryText(h.snippet),
46
+ matchedOn,
47
+ ...(unverified ? { unverified: true } : {}),
48
+ };
49
+ });
50
+ // Index entries with evidence the backend didn't surface (e.g. an alias
51
+ // spelled differently than the stored text ranks): synthesize a hit from
52
+ // the entry line itself so the exact match is never lost.
53
+ const surfacedIds = new Set(hits.flatMap((h) => h.memoryIds));
54
+ const syntheticIds = [];
55
+ for (const e of entries) {
56
+ const evidence = evidenceById.get(e.id);
57
+ if (!evidence || surfacedIds.has(e.id))
58
+ continue;
59
+ syntheticIds.push(e.id);
60
+ results.push({
61
+ path: `${bound.scope.root}/${MEMORY_INDEX_FILENAME}`,
62
+ snippet: sanitizeMemoryText(e.raw),
63
+ matchedOn: evidence,
64
+ ...(e.unverified ? { unverified: true } : {}),
65
+ });
66
+ }
67
+ const recalledIds = Array.from(new Set([...hits.flatMap((h) => h.memoryIds), ...syntheticIds]));
68
+ return { results, recalledIds };
69
+ }
70
+ export function memorySearchTool(targets, opts) {
71
+ const multi = targets.length > 1;
72
+ return tool({
73
+ description: "Search your long-term episodic memory (notes from past sessions plus archived facts). " +
74
+ "Use it when the conversation touches something you may already know — a preference, " +
75
+ "an earlier decision, an ongoing issue — before asking the user to repeat themselves. " +
76
+ (multi
77
+ ? "It searches every one of your memory levels at once; each hit is tagged with its level. "
78
+ : "") +
79
+ "Search is keyword-based: prefer the vocabulary of your memory index (in your " +
80
+ "instructions) — its exact terms and aliases match best — and when no index line " +
81
+ "obviously matches, keep the user's key words in the query too. " +
82
+ "Each hit carries matchedOn evidence (alias-exact | description | body) and the response " +
83
+ "carries create_safety — consult it before creating anything with memory_save.",
84
+ inputSchema: jsonSchema({
85
+ type: "object",
86
+ properties: {
87
+ query: { type: "string", description: "What to look for (topic, name, event)." },
88
+ limit: { type: "number", description: multi ? "Max results per level (default 6)." : "Max results (default 6)." },
89
+ },
90
+ required: ["query"],
91
+ additionalProperties: false,
92
+ }),
93
+ execute: async ({ query, limit }) => {
94
+ // Fan out across levels; a single-target search returns exactly the
95
+ // classic shape (no level tags). Per-level failures degrade to empty
96
+ // results rather than failing the whole search.
97
+ const perScope = await Promise.all(targets.map(async (t) => {
98
+ try {
99
+ return { t, ...(await searchOneScope(t.bound, query, limit ?? 6)) };
100
+ }
101
+ catch {
102
+ return { t, results: [], recalledIds: [] };
103
+ }
104
+ }));
105
+ const merged = perScope.flatMap(({ t, results }) => results.map((r) => (multi ? { level: t.level, ...r } : r)));
106
+ // create_safety spans ALL levels: an exact match anywhere means the
107
+ // memory exists — the safe signal for memory_save dedup.
108
+ const create_safety = createSafetyOf(merged.map((r) => r.matchedOn));
109
+ if (opts?.recordUsage) {
110
+ for (const { t, recalledIds } of perScope) {
111
+ if (recalledIds.length === 0)
112
+ continue;
113
+ // Fire-and-forget: retention bookkeeping must never fail or slow recall.
114
+ void Promise.resolve(opts.recordUsage(t.bound.scope.key, recalledIds)).catch(() => { });
115
+ }
116
+ }
117
+ return merged.length > 0
118
+ ? { hits: merged, create_safety }
119
+ : { hits: [], create_safety, note: "no matching memories" };
120
+ },
121
+ });
122
+ }
123
+ export function memorySaveTool(bound, opts) {
124
+ return tool({
125
+ description: "Save a durable note to your long-term memory NOW — use when the user explicitly asks " +
126
+ "you to remember something, or states a lasting fact, preference, or decision. " +
127
+ "Search first: call memory_search and only save something NEW when its create_safety " +
128
+ 'is not "exists". When it IS "exists", update the existing memory instead — save a ' +
129
+ "correction/update note that names it (quote its [m-…] id) rather than restating the " +
130
+ "fact as if new. Not for transient task details.",
131
+ inputSchema: jsonSchema({
132
+ type: "object",
133
+ properties: {
134
+ note: {
135
+ type: "string",
136
+ description: "The durable fact(s) to remember, stated plainly (1-5 sentences).",
137
+ },
138
+ slug: {
139
+ type: "string",
140
+ description: "Short kebab-case topic for the note's filename (e.g. 'race-goal').",
141
+ },
142
+ },
143
+ required: ["note"],
144
+ additionalProperties: false,
145
+ }),
146
+ execute: async ({ note, slug }) => {
147
+ const meta = {
148
+ agent: opts.agent,
149
+ extractedAt: new Date().toISOString(),
150
+ provenance: "user-requested",
151
+ };
152
+ const written = await bound.store.writeEpisode(bound.principal, bound.scope, {
153
+ slug: slug ?? "remember",
154
+ meta,
155
+ summary: note.slice(0, 120),
156
+ body: `## Facts\n- (user-requested) ${note.replace(/\n+/g, " ").trim()}`,
157
+ });
158
+ if (!written)
159
+ return { saved: false, error: "memory store unreachable" };
160
+ opts.invalidate?.();
161
+ if (opts.onEpisodeWritten) {
162
+ void Promise.resolve(opts.onEpisodeWritten(written)).catch(() => { });
163
+ }
164
+ return { saved: true, path: written.path };
165
+ },
166
+ });
167
+ }
168
+ // ---------------------------------------------------------------------------
169
+ // Job-facing tools (extractor / consolidator)
170
+ // ---------------------------------------------------------------------------
171
+ export function memoryReadIndexTool(bound) {
172
+ return tool({
173
+ description: "Read the current compiled memory index (MEMORY.md) for this scope. " +
174
+ "Returns null when no index exists yet.",
175
+ inputSchema: jsonSchema({
176
+ type: "object",
177
+ properties: {},
178
+ additionalProperties: false,
179
+ }),
180
+ execute: async () => {
181
+ const index = await bound.store.readIndex(bound.principal, bound.scope);
182
+ return { index: index ?? null };
183
+ },
184
+ });
185
+ }
186
+ /**
187
+ * The extractor's cross-level index read: every participating level's compiled
188
+ * index in one call, so "what is already known" covers each level it may
189
+ * write to.
190
+ */
191
+ export function memoryReadIndexesTool(targets) {
192
+ return tool({
193
+ description: "Read the current compiled memory index (MEMORY.md) of every memory level in your task. " +
194
+ "Returns null for levels with no index yet.",
195
+ inputSchema: jsonSchema({
196
+ type: "object",
197
+ properties: {},
198
+ additionalProperties: false,
199
+ }),
200
+ execute: async () => {
201
+ const indexes = await Promise.all(targets.map(async (t) => {
202
+ const index = await t.bound.store.readIndex(t.bound.principal, t.bound.scope);
203
+ return { level: t.level, index: index ?? null };
204
+ }));
205
+ return { indexes };
206
+ },
207
+ });
208
+ }
209
+ export function memoryWriteEpisodeTool(targets, opts) {
210
+ const multi = targets.length > 1;
211
+ const levels = targets.map((t) => t.level);
212
+ return tool({
213
+ description: "Write ONE immutable episode file capturing the durable memories from this transcript" +
214
+ (multi
215
+ ? " for ONE memory level. Call at most once per level, and only for levels with something durable to store."
216
+ : ". Call at most once per run, and only when there is something durable to store."),
217
+ inputSchema: jsonSchema({
218
+ type: "object",
219
+ properties: {
220
+ // Always accepted — the extractor prompt says "call with that level's
221
+ // `level` value" regardless of level count, and a single-target
222
+ // binding routes everything to its one scope anyway. Only REQUIRED
223
+ // when there is a real choice to make.
224
+ level: {
225
+ type: "string",
226
+ enum: levels,
227
+ description: "The memory level this episode belongs to (see your task).",
228
+ },
229
+ slug: {
230
+ type: "string",
231
+ description: "Short kebab-case topic for the filename (e.g. 'calf-strain-week2').",
232
+ },
233
+ summary: { type: "string", description: "One-line summary of the episode." },
234
+ happened: {
235
+ type: "string",
236
+ description: "2-4 sentences of session context (optional).",
237
+ },
238
+ facts: {
239
+ type: "array",
240
+ description: "The durable facts, each tagged with its origin.",
241
+ items: {
242
+ type: "object",
243
+ properties: {
244
+ text: { type: "string" },
245
+ provenance: { type: "string", enum: ["user-said", "tool-derived"] },
246
+ },
247
+ required: ["text", "provenance"],
248
+ additionalProperties: false,
249
+ },
250
+ },
251
+ aliases: {
252
+ type: "array",
253
+ items: { type: "string" },
254
+ description: "Alternate lookup terms for the facts: names/spellings/nicknames of entities " +
255
+ "(e.g. ['Robert Smith', 'Bob']) plus everyday recall keys when a fact's own " +
256
+ "wording is technical or unusual (e.g. 'coffee' for a caffeine rule) — so " +
257
+ "later keyword recall matches any form.",
258
+ },
259
+ },
260
+ required: [...(multi ? ["level"] : []), "slug", "summary", "facts"],
261
+ additionalProperties: false,
262
+ }),
263
+ execute: async ({ level, slug, summary, happened, facts, aliases }) => {
264
+ // Route to the requested level; a single-target binding ignores the
265
+ // param (there is nowhere else to go).
266
+ const target = multi ? targets.find((t) => t.level === level) : targets[0];
267
+ if (!target) {
268
+ return {
269
+ saved: false,
270
+ error: `unknown level ${JSON.stringify(level)} — this run's levels are: ${levels.join(", ")}`,
271
+ };
272
+ }
273
+ const bound = target.bound;
274
+ // An empty facts list is not a store failure — the model chose to write
275
+ // nothing. Left unreported so it stays a normal zero-yield run rather
276
+ // than forcing a retry.
277
+ if (facts.length === 0)
278
+ return { saved: false, error: "no facts provided" };
279
+ const provs = new Set(facts.map((f) => f.provenance));
280
+ const provenance = provs.size === 1 ? [...provs][0] : "mixed";
281
+ const meta = {
282
+ chat: opts.chatId,
283
+ agent: opts.agent,
284
+ extractedAt: new Date().toISOString(),
285
+ provenance,
286
+ ...(aliases?.length ? { aliases } : {}),
287
+ // Trust mark: everything the background extractor writes is
288
+ // machine-inferred until the consolidator sees corroboration —
289
+ // explicit memory_save episodes carry no status.
290
+ status: "unverified",
291
+ };
292
+ const body = [
293
+ ...(happened ? ["## What happened", happened.trim(), ""] : []),
294
+ "## Facts",
295
+ ...facts.map((f) => `- (${f.provenance}) ${f.text.replace(/\n+/g, " ").trim()}`),
296
+ ].join("\n");
297
+ const written = await bound.store.writeEpisode(bound.principal, bound.scope, {
298
+ slug,
299
+ meta,
300
+ summary,
301
+ body,
302
+ });
303
+ if (!written) {
304
+ opts.onWriteAttempt?.(false);
305
+ return { saved: false, error: "memory store unreachable" };
306
+ }
307
+ opts.onWriteAttempt?.(true);
308
+ if (opts.onEpisodeWritten) {
309
+ void Promise.resolve(opts.onEpisodeWritten({ level: target.level, scope: bound.scope, ...written })).catch(() => { });
310
+ }
311
+ return { saved: true, ...(multi ? { level: target.level } : {}), path: written.path };
312
+ },
313
+ });
314
+ }
315
+ export function memoryReadEpisodesTool(bound) {
316
+ return tool({
317
+ description: "Read episode files by path (the paths listed in your task).",
318
+ inputSchema: jsonSchema({
319
+ type: "object",
320
+ properties: {
321
+ paths: { type: "array", items: { type: "string" } },
322
+ },
323
+ required: ["paths"],
324
+ additionalProperties: false,
325
+ }),
326
+ execute: async ({ paths }) => {
327
+ // Scope lock: only paths strictly under this scope's root are readable
328
+ // (segment-wise — a bare startsWith would pass `root-evil/x` and `..`).
329
+ const inScope = paths.filter((p) => isUnderScopeRoot(bound.scope.root, p));
330
+ const episodes = await bound.store.readEpisodes(bound.principal, bound.scope, inScope);
331
+ return { episodes };
332
+ },
333
+ });
334
+ }
335
+ export function memoryWriteIndexTool(bound, opts) {
336
+ // Schema adherence is ADVISORY: the first off-schema rewrite gets bounced
337
+ // once through the problems loop so the model can self-correct; after that
338
+ // the write always proceeds (with warnings) — a sweep must never wedge on
339
+ // schema drift, unlike the hard rules validateIndexRewrite enforces.
340
+ let schemaNudged = false;
341
+ return tool({
342
+ description: "Replace the compiled memory index (MEMORY.md) with a new version. The previous " +
343
+ "version is snapshotted automatically. The rewrite is validated: hard line cap, no " +
344
+ "duplicate ids, and no previously-active entry may disappear (move superseded/expired " +
345
+ "entries under '## Archive'). On rejection you get the problems back — fix and retry.",
346
+ inputSchema: jsonSchema({
347
+ type: "object",
348
+ properties: {
349
+ content: { type: "string", description: "The complete new MEMORY.md content." },
350
+ },
351
+ required: ["content"],
352
+ additionalProperties: false,
353
+ }),
354
+ execute: async ({ content }) => {
355
+ const warnings = opts?.schema ? schemaSectionWarnings(opts.schema, content) : [];
356
+ if (warnings.length > 0 && !schemaNudged) {
357
+ schemaNudged = true;
358
+ // Counts as a FAILED attempt: nothing was stored, so a model that
359
+ // gives up right after the nudge must not read as "nothing needed
360
+ // writing" — that would consume pending episodes with no index write.
361
+ opts?.onWriteAttempt?.(false);
362
+ return {
363
+ ok: false,
364
+ problems: warnings.map((w) => `${w} (schema advisory — fix, or resubmit as-is to override)`),
365
+ };
366
+ }
367
+ try {
368
+ await bound.store.writeIndex(bound.principal, bound.scope, content);
369
+ opts?.invalidate?.();
370
+ opts?.onWriteAttempt?.(true);
371
+ return warnings.length > 0 ? { ok: true, warnings } : { ok: true };
372
+ }
373
+ catch (error) {
374
+ opts?.onWriteAttempt?.(false);
375
+ if (error instanceof IndexValidationError) {
376
+ return { ok: false, problems: error.problems };
377
+ }
378
+ return {
379
+ ok: false,
380
+ error: String(error),
381
+ // The model's own instructions say to re-read and retry once; say it
382
+ // here too, where it lands next to the failure it applies to.
383
+ retry: "Call memory_read_index, rebuild the rewrite on what it returns now, and retry once.",
384
+ };
385
+ }
386
+ },
387
+ });
388
+ }
389
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ import type { MemoryConfig } from "@intentface/latch-core";
2
+ /**
3
+ * Where a memory came from. Tool-derived facts are less trustworthy than
4
+ * things the user said directly (a prompt-injection persistence vector), so
5
+ * every stored fact carries its origin and the consolidator preserves it.
6
+ */
7
+ export type Provenance = "user-said" | "tool-derived" | "user-requested" | "mixed";
8
+ /**
9
+ * A resolved memory scope: WHERE one memory store lives.
10
+ *
11
+ * - `key` is the canonical scope identity used everywhere outside the store
12
+ * (DB rows, caches, leases): `${connection}:${root}`.
13
+ * - `root` is the folder inside the connection's workspace, e.g.
14
+ * `__private_root/_memory/running-coach/u-usr123` for per-user scopes (the
15
+ * `__private_root` head resolves to the authenticated caller's Loredex
16
+ * private root) or `_memory/<agent>/org` for `agent-org`.
17
+ */
18
+ export interface ScopeRef {
19
+ key: string;
20
+ connection: string;
21
+ root: string;
22
+ }
23
+ /** Frontmatter of one episode file. */
24
+ export interface EpisodeMeta {
25
+ /** Source chat id (absent for `memory_save` episodes). */
26
+ chat?: string;
27
+ agent: string;
28
+ /** ISO timestamp; also drives the episode's filename stamp. */
29
+ extractedAt: string;
30
+ provenance: Provenance;
31
+ /**
32
+ * Alternate names/spellings/nicknames of entities the episode mentions —
33
+ * the consolidator carries them onto index entries (`aka:`) so recall
34
+ * matches any form.
35
+ */
36
+ aliases?: string[];
37
+ /**
38
+ * Trust mark: `unverified` on episodes written by the background extractor
39
+ * (auto-extracted, unconfirmed). Explicit `memory_save` episodes carry no
40
+ * status. The consolidator labels/promotes index entries accordingly.
41
+ */
42
+ status?: "unverified";
43
+ }
44
+ export interface MemorySearchHit {
45
+ path: string;
46
+ snippet: string;
47
+ /**
48
+ * Memory identities this hit touches, for usage/retention tracking: `[m-…]`
49
+ * entry ids found in the snippet plus the file path itself.
50
+ */
51
+ memoryIds: string[];
52
+ }
53
+ /**
54
+ * Thrown by `writeIndex` when the backing store can't be reached (unauthorized
55
+ * connection, missing workspace) — the one operation with no in-band way to
56
+ * signal "nothing was written". Distinguishable from `IndexValidationError`:
57
+ * this means "retry later", that means "fix the content and retry".
58
+ */
59
+ export declare class MemoryStoreUnreachableError extends Error {
60
+ constructor(message?: string);
61
+ }
62
+ /**
63
+ * The storage seam. One implementation per backing (Loredex first); everything
64
+ * above it (provider, tools, jobs) is backend-agnostic.
65
+ *
66
+ * Contract: read-side operations NEVER throw for "store unreachable"
67
+ * (unauthorized connection, missing workspace) — they return `undefined`/empty
68
+ * so a memory failure degrades gracefully. `writeIndex` is the carve-out: it
69
+ * returns nothing, so unreachability there throws
70
+ * `MemoryStoreUnreachableError`. Operations MAY also throw for contract
71
+ * violations (e.g. an index rewrite that fails validation →
72
+ * `IndexValidationError`), which tool wrappers surface to the model as
73
+ * structured errors.
74
+ */
75
+ export interface MemoryStore<P> {
76
+ /** Cheap probe: is the scope's backing reachable for this principal? */
77
+ available(principal: P, scope: ScopeRef): Promise<boolean>;
78
+ /** The compiled index (MEMORY.md) text, or undefined if absent/unreachable. */
79
+ readIndex(principal: P, scope: ScopeRef): Promise<string | undefined>;
80
+ /**
81
+ * Replace the compiled index. Snapshots the previous version to
82
+ * `archive/index-snapshots/` first and validates the rewrite via
83
+ * `validateIndexRewrite` (throws `IndexValidationError` on violation).
84
+ */
85
+ writeIndex(principal: P, scope: ScopeRef, text: string): Promise<void>;
86
+ /**
87
+ * Write one immutable episode file under `episodes/`. Returns its path, or
88
+ * undefined when the store is unreachable.
89
+ */
90
+ writeEpisode(principal: P, scope: ScopeRef, episode: {
91
+ slug: string;
92
+ meta: EpisodeMeta;
93
+ summary: string;
94
+ body: string;
95
+ }): Promise<{
96
+ path: string;
97
+ name: string;
98
+ } | undefined>;
99
+ /** Batch-read episode files by path (missing files are skipped). */
100
+ readEpisodes(principal: P, scope: ScopeRef, paths: string[]): Promise<Array<{
101
+ path: string;
102
+ text: string;
103
+ }>>;
104
+ /** Hybrid search scoped to this memory folder. */
105
+ search(principal: P, scope: ScopeRef, query: string, limit?: number): Promise<MemorySearchHit[]>;
106
+ /**
107
+ * Read one well-known auxiliary file by workspace-relative path (e.g. the
108
+ * shared user-level SCHEMA.md). Not scope-bound — callers pass fixed,
109
+ * code-owned paths only, never model-chosen ones. `undefined` when absent
110
+ * or unreachable (read-side never throws).
111
+ */
112
+ readFile(principal: P, args: {
113
+ connection: string;
114
+ path: string;
115
+ }): Promise<string | undefined>;
116
+ /**
117
+ * Create-or-replace one auxiliary file by workspace-relative path (schema
118
+ * editors). Ensures parent folders. Throws `MemoryStoreUnreachableError`
119
+ * when the backing can't be reached.
120
+ */
121
+ writeFile(principal: P, args: {
122
+ connection: string;
123
+ path: string;
124
+ content: string;
125
+ summary?: string;
126
+ }): Promise<void>;
127
+ }
128
+ /** Re-exported for convenience so platform code can import from one place. */
129
+ export type { MemoryConfig };
130
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,gBAAgB,GAAG,OAAO,CAAC;AAEnF;;;;;;;;;GASG;AACH,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,uCAAuC;AACvC,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;GAKG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,SAA6B;CAIjD;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,wEAAwE;IACxE,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,+EAA+E;IAC/E,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtE;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE;;;OAGG;IACH,YAAY,CACV,SAAS,EAAE,CAAC,EACZ,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAC1E,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IACvD,oEAAoE;IACpE,YAAY,CACV,SAAS,EAAE,CAAC,EACZ,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAClD,kDAAkD;IAClD,MAAM,CACJ,SAAS,EAAE,CAAC,EACZ,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAChG;;;;OAIG;IACH,SAAS,CACP,SAAS,EAAE,CAAC,EACZ,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5E,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,8EAA8E;AAC9E,YAAY,EAAE,YAAY,EAAE,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Thrown by `writeIndex` when the backing store can't be reached (unauthorized
3
+ * connection, missing workspace) — the one operation with no in-band way to
4
+ * signal "nothing was written". Distinguishable from `IndexValidationError`:
5
+ * this means "retry later", that means "fix the content and retry".
6
+ */
7
+ export class MemoryStoreUnreachableError extends Error {
8
+ constructor(message = "memory store unreachable") {
9
+ super(message);
10
+ this.name = "MemoryStoreUnreachableError";
11
+ }
12
+ }
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAyDA;;;;;GAKG;AACH,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IACpD,YAAY,OAAO,GAAG,0BAA0B;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@intentface/latch-memory",
3
+ "version": "0.9.1",
4
+ "description": "Latch agent memory — always-loaded compiled index, searchable episodic store, and background extraction/consolidation over a pluggable MemoryStore (Loredex-backed first).",
5
+ "keywords": [
6
+ "ai",
7
+ "ai-sdk",
8
+ "agents",
9
+ "llm",
10
+ "agent-memory"
11
+ ],
12
+ "license": "MIT",
13
+ "type": "module",
14
+ "main": "./dist/index.js",
15
+ "module": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "sideEffects": false,
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "registry": "https://registry.npmjs.org"
30
+ },
31
+ "dependencies": {
32
+ "@intentface/latch-core": "^0.9.1"
33
+ },
34
+ "peerDependencies": {
35
+ "ai": ">=7.0.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^22",
39
+ "ai": "^7.0.2",
40
+ "tsx": "^4.19.0",
41
+ "typescript": "^5.7.0",
42
+ "vitest": "^4",
43
+ "@intentface/latch-mcp": "0.9.1"
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/Intentface/intentface-latch.git",
48
+ "directory": "packages/memory"
49
+ },
50
+ "scripts": {
51
+ "build": "tsc -p tsconfig.build.json",
52
+ "typecheck": "tsc -p tsconfig.json --noEmit",
53
+ "test": "vitest run",
54
+ "eval:memory-search": "tsx evals/run.ts",
55
+ "eval:auth-live": "tsx evals/live/auth.ts",
56
+ "eval:memory-search:live": "tsx evals/live/run-live.ts",
57
+ "eval:seed-live": "tsx evals/live/seed.ts",
58
+ "eval:regen-fixtures": "tsx evals/generate.ts"
59
+ }
60
+ }