@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.
- package/LICENSE +21 -0
- package/README.md +163 -0
- package/dist/extraction-key.d.ts +20 -0
- package/dist/extraction-key.d.ts.map +1 -0
- package/dist/extraction-key.js +43 -0
- package/dist/extraction-key.js.map +1 -0
- package/dist/index-file.d.ts +77 -0
- package/dist/index-file.d.ts.map +1 -0
- package/dist/index-file.js +169 -0
- package/dist/index-file.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/jobs/types.d.ts +133 -0
- package/dist/jobs/types.d.ts.map +1 -0
- package/dist/jobs/types.js +12 -0
- package/dist/jobs/types.js.map +1 -0
- package/dist/prompts/consolidator.d.ts +18 -0
- package/dist/prompts/consolidator.d.ts.map +1 -0
- package/dist/prompts/consolidator.js +76 -0
- package/dist/prompts/consolidator.js.map +1 -0
- package/dist/prompts/extractor.d.ts +34 -0
- package/dist/prompts/extractor.d.ts.map +1 -0
- package/dist/prompts/extractor.js +60 -0
- package/dist/prompts/extractor.js.map +1 -0
- package/dist/prompts/inject.d.ts +20 -0
- package/dist/prompts/inject.d.ts.map +1 -0
- package/dist/prompts/inject.js +58 -0
- package/dist/prompts/inject.js.map +1 -0
- package/dist/provider.d.ts +47 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +101 -0
- package/dist/provider.js.map +1 -0
- package/dist/sanitize.d.ts +29 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +88 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/schema.d.ts +60 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +144 -0
- package/dist/schema.js.map +1 -0
- package/dist/scope.d.ts +62 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +136 -0
- package/dist/scope.js.map +1 -0
- package/dist/search-evidence.d.ts +34 -0
- package/dist/search-evidence.d.ts.map +1 -0
- package/dist/search-evidence.js +40 -0
- package/dist/search-evidence.js.map +1 -0
- package/dist/store/loredex.d.ts +61 -0
- package/dist/store/loredex.d.ts.map +1 -0
- package/dist/store/loredex.js +558 -0
- package/dist/store/loredex.js.map +1 -0
- package/dist/store/memory.d.ts +31 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +156 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/tools.d.ts +91 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +389 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +130 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- 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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"}
|
package/dist/types.d.ts
ADDED
|
@@ -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":"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"}
|
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
|
+
}
|