@moxxy/plugin-memory 0.27.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/LICENSE +21 -0
- package/dist/consolidate.d.ts +62 -0
- package/dist/consolidate.d.ts.map +1 -0
- package/dist/consolidate.js +417 -0
- package/dist/consolidate.js.map +1 -0
- package/dist/embedding-cache.d.ts +32 -0
- package/dist/embedding-cache.d.ts.map +1 -0
- package/dist/embedding-cache.js +146 -0
- package/dist/embedding-cache.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +217 -0
- package/dist/index.js.map +1 -0
- package/dist/parse.d.ts +5 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +9 -0
- package/dist/parse.js.map +1 -0
- package/dist/stm.d.ts +20 -0
- package/dist/stm.d.ts.map +1 -0
- package/dist/stm.js +38 -0
- package/dist/stm.js.map +1 -0
- package/dist/store/io.d.ts +13 -0
- package/dist/store/io.d.ts.map +1 -0
- package/dist/store/io.js +124 -0
- package/dist/store/io.js.map +1 -0
- package/dist/store/search.d.ts +10 -0
- package/dist/store/search.d.ts.map +1 -0
- package/dist/store/search.js +160 -0
- package/dist/store/search.js.map +1 -0
- package/dist/store/types.d.ts +33 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +11 -0
- package/dist/store/types.js.map +1 -0
- package/dist/store.d.ts +95 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +220 -0
- package/dist/store.js.map +1 -0
- package/dist/tfidf.d.ts +29 -0
- package/dist/tfidf.d.ts.map +1 -0
- package/dist/tfidf.js +103 -0
- package/dist/tfidf.js.map +1 -0
- package/package.json +62 -0
- package/src/consolidate-nudge.test.ts +98 -0
- package/src/consolidate.test.ts +328 -0
- package/src/consolidate.ts +535 -0
- package/src/discovery.test.ts +33 -0
- package/src/embedding-cache.test.ts +268 -0
- package/src/embedding-cache.ts +156 -0
- package/src/index.test.ts +67 -0
- package/src/index.ts +247 -0
- package/src/parse.ts +12 -0
- package/src/stm.test.ts +69 -0
- package/src/stm.ts +48 -0
- package/src/store/io.test.ts +100 -0
- package/src/store/io.ts +138 -0
- package/src/store/search.test.ts +185 -0
- package/src/store/search.ts +197 -0
- package/src/store/types.ts +23 -0
- package/src/store.test.ts +186 -0
- package/src/store.ts +292 -0
- package/src/tfidf.test.ts +59 -0
- package/src/tfidf.ts +105 -0
- package/src/vector-recall.test.ts +88 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Moxxy (moxxy.ai)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type LLMProvider, type Plugin } from '@moxxy/sdk';
|
|
2
|
+
import type { MemoryStore } from './store.js';
|
|
3
|
+
import { type MemoryEntry } from './store.js';
|
|
4
|
+
export interface ConsolidatePlan {
|
|
5
|
+
readonly clusters: ReadonlyArray<{
|
|
6
|
+
readonly key: string;
|
|
7
|
+
readonly members: ReadonlyArray<string>;
|
|
8
|
+
}>;
|
|
9
|
+
readonly stable: ReadonlyArray<string>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Group memories into clusters by shared tag, sharing 2+ tokens in the
|
|
13
|
+
* description, or both. Each cluster has at least 2 members; singletons are
|
|
14
|
+
* reported as `stable` and left alone.
|
|
15
|
+
*/
|
|
16
|
+
export declare function planConsolidation(entries: ReadonlyArray<MemoryEntry>, opts?: {
|
|
17
|
+
tag?: string;
|
|
18
|
+
}): ConsolidatePlan;
|
|
19
|
+
export interface ConsolidateOptions {
|
|
20
|
+
readonly tag?: string;
|
|
21
|
+
readonly dryRun?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Upper bound (ms) on each per-cluster provider stream. A hung/stalled
|
|
24
|
+
* provider must not let `memory_consolidate` block forever — without this the
|
|
25
|
+
* `for await` loop has no timeout and waits indefinitely for the next event.
|
|
26
|
+
* The timeout aborts that one stream; the cluster is recorded as not-merged.
|
|
27
|
+
* Default {@link DEFAULT_CONSOLIDATE_TIMEOUT_MS}. Set to 0 to disable.
|
|
28
|
+
*/
|
|
29
|
+
readonly timeoutMs?: number;
|
|
30
|
+
/** Optional caller abort (e.g. session shutdown); combined with the timeout. */
|
|
31
|
+
readonly signal?: AbortSignal;
|
|
32
|
+
}
|
|
33
|
+
/** Default per-cluster provider-stream timeout for {@link consolidateMemory}. */
|
|
34
|
+
export declare const DEFAULT_CONSOLIDATE_TIMEOUT_MS = 60000;
|
|
35
|
+
export interface ConsolidationOutcome {
|
|
36
|
+
readonly clusters: ReadonlyArray<{
|
|
37
|
+
readonly key: string;
|
|
38
|
+
readonly merged: ReadonlyArray<string>;
|
|
39
|
+
readonly into: string | null;
|
|
40
|
+
readonly dryRun: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
readonly stable: ReadonlyArray<string>;
|
|
43
|
+
}
|
|
44
|
+
export declare function consolidateMemory(store: MemoryStore, provider: LLMProvider, opts?: ConsolidateOptions): Promise<ConsolidationOutcome>;
|
|
45
|
+
export interface BuildMemoryConsolidateOptions {
|
|
46
|
+
/**
|
|
47
|
+
* When memory.list().length crosses this number, the plugin appends a hint
|
|
48
|
+
* to the next provider request's system prompt nudging the agent to call
|
|
49
|
+
* `memory_consolidate`. Default: 30. Set to 0 to disable the nudge.
|
|
50
|
+
*/
|
|
51
|
+
readonly autoNudgeThreshold?: number;
|
|
52
|
+
}
|
|
53
|
+
export declare function buildMemoryConsolidatePlugin(store: MemoryStore, getProvider: () => LLMProvider, opts?: BuildMemoryConsolidateOptions): Plugin;
|
|
54
|
+
/**
|
|
55
|
+
* Discovery-loadable default export: resolves the long-term store (`'memory'`,
|
|
56
|
+
* published by @moxxy/plugin-memory) and the active provider (via the `'providers'`
|
|
57
|
+
* registry) from the inter-plugin service registry in `onInit`, so it no longer
|
|
58
|
+
* needs the `(store, getProvider)` closure. @moxxy/plugin-memory is registered
|
|
59
|
+
* first, so its onInit publishes the store before this one resolves it.
|
|
60
|
+
*/
|
|
61
|
+
export declare const memoryConsolidatePlugin: Plugin;
|
|
62
|
+
//# sourceMappingURL=consolidate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidate.d.ts","sourceRoot":"","sources":["../src/consolidate.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,MAAM,EACZ,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAC,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAoB,KAAK,WAAW,EAAmB,MAAM,YAAY,CAAC;AAsBjF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;QAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;KACzC,CAAC,CAAC;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,EACnC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1B,eAAe,CAkEjB;AASD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,iFAAiF;AACjF,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;QAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;KAC1B,CAAC,CAAC;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,WAAW,EACrB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAoI/B;AAwGD,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AASD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,MAAM,WAAW,EAC9B,IAAI,GAAE,6BAAkC,GACvC,MAAM,CAGR;AAED;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,MA0BlC,CAAC"}
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import { z, defineTool, definePlugin, } from '@moxxy/sdk';
|
|
2
|
+
import { memoryTypeSchema } from './store.js';
|
|
3
|
+
const SYSTEM_PROMPT = `You are consolidating overlapping long-term memory entries.
|
|
4
|
+
|
|
5
|
+
You receive a cluster of 2 or more entries that touch the same topic. Produce a single canonical entry that:
|
|
6
|
+
- preserves every distinct fact from the cluster (no information loss)
|
|
7
|
+
- removes duplication
|
|
8
|
+
- keeps the body under 30 lines
|
|
9
|
+
- picks the most informative description (one sentence, ≤120 chars)
|
|
10
|
+
- inherits a single 'type' from the cluster (vote: fact / preference / project / reference)
|
|
11
|
+
|
|
12
|
+
Output ONLY a JSON object with keys: { "name", "type", "description", "body", "tags" }
|
|
13
|
+
where name is a kebab-case slug (use the most descriptive name from the cluster).`;
|
|
14
|
+
const consolidatedSchema = z.object({
|
|
15
|
+
name: z.string().min(1).regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
16
|
+
type: memoryTypeSchema,
|
|
17
|
+
description: z.string().min(1).max(280),
|
|
18
|
+
body: z.string().min(1).max(4000),
|
|
19
|
+
tags: z.array(z.string().min(1)).optional(),
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* Group memories into clusters by shared tag, sharing 2+ tokens in the
|
|
23
|
+
* description, or both. Each cluster has at least 2 members; singletons are
|
|
24
|
+
* reported as `stable` and left alone.
|
|
25
|
+
*/
|
|
26
|
+
export function planConsolidation(entries, opts = {}) {
|
|
27
|
+
const filtered = opts.tag
|
|
28
|
+
? entries.filter((e) => (e.frontmatter.tags ?? []).includes(opts.tag))
|
|
29
|
+
: entries;
|
|
30
|
+
if (filtered.length < 2) {
|
|
31
|
+
return { clusters: [], stable: filtered.map((e) => e.frontmatter.name) };
|
|
32
|
+
}
|
|
33
|
+
// Primary cluster key: a shared tag. If no tag, fall back to
|
|
34
|
+
// overlap of >=2 tokens in description.
|
|
35
|
+
const byTag = new Map();
|
|
36
|
+
const tagless = [];
|
|
37
|
+
for (const e of filtered) {
|
|
38
|
+
const tags = e.frontmatter.tags ?? [];
|
|
39
|
+
if (tags.length === 0) {
|
|
40
|
+
tagless.push(e);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// Use the first tag as the cluster key (deterministic, simple)
|
|
44
|
+
const key = tags[0];
|
|
45
|
+
const list = byTag.get(key) ?? [];
|
|
46
|
+
list.push(e);
|
|
47
|
+
byTag.set(key, list);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Description-overlap clustering for the tagless tail. O(n²) but acceptable
|
|
51
|
+
// for the scale we expect (hundreds of memories).
|
|
52
|
+
const descClusters = [];
|
|
53
|
+
for (const entry of tagless) {
|
|
54
|
+
const tokens = new Set(tokenize(entry.frontmatter.description).concat(tokenize(entry.frontmatter.name)));
|
|
55
|
+
let placed = false;
|
|
56
|
+
for (const cluster of descClusters) {
|
|
57
|
+
const clusterTokens = new Set(cluster.members.flatMap((m) => tokenize(m.frontmatter.description)));
|
|
58
|
+
const overlap = [...tokens].filter((t) => clusterTokens.has(t)).length;
|
|
59
|
+
if (overlap >= 2) {
|
|
60
|
+
cluster.members.push(entry);
|
|
61
|
+
placed = true;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!placed) {
|
|
66
|
+
descClusters.push({ key: `desc:${entry.frontmatter.name}`, members: [entry] });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const clusters = [];
|
|
70
|
+
const stable = [];
|
|
71
|
+
for (const [key, members] of byTag) {
|
|
72
|
+
if (members.length >= 2) {
|
|
73
|
+
clusters.push({ key: `tag:${key}`, members: members.map((m) => m.frontmatter.name) });
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
stable.push(members[0].frontmatter.name);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const cluster of descClusters) {
|
|
80
|
+
if (cluster.members.length >= 2) {
|
|
81
|
+
clusters.push({ key: cluster.key, members: cluster.members.map((m) => m.frontmatter.name) });
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
stable.push(cluster.members[0].frontmatter.name);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return { clusters, stable };
|
|
88
|
+
}
|
|
89
|
+
function tokenize(text) {
|
|
90
|
+
return text
|
|
91
|
+
.toLowerCase()
|
|
92
|
+
.split(/[^a-z0-9_-]+/)
|
|
93
|
+
.filter((t) => t.length >= 3);
|
|
94
|
+
}
|
|
95
|
+
/** Default per-cluster provider-stream timeout for {@link consolidateMemory}. */
|
|
96
|
+
export const DEFAULT_CONSOLIDATE_TIMEOUT_MS = 60_000;
|
|
97
|
+
export async function consolidateMemory(store, provider, opts = {}) {
|
|
98
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_CONSOLIDATE_TIMEOUT_MS;
|
|
99
|
+
const all = await store.list();
|
|
100
|
+
const plan = planConsolidation(all, { tag: opts.tag });
|
|
101
|
+
const byName = new Map(all.map((e) => [e.frontmatter.name, e]));
|
|
102
|
+
// Names produced by merges earlier in THIS run. They aren't in `byName`
|
|
103
|
+
// (which is a snapshot of the initial store), so without tracking them a
|
|
104
|
+
// later cluster could pick the same name and silently clobber an
|
|
105
|
+
// already-consolidated entry — the very data loss the collision guard exists
|
|
106
|
+
// to prevent.
|
|
107
|
+
const produced = new Set();
|
|
108
|
+
const outcomes = [];
|
|
109
|
+
for (const cluster of plan.clusters) {
|
|
110
|
+
const members = cluster.members.map((n) => byName.get(n)).filter((e) => Boolean(e));
|
|
111
|
+
if (members.length < 2)
|
|
112
|
+
continue;
|
|
113
|
+
if (opts.dryRun) {
|
|
114
|
+
outcomes.push({ key: cluster.key, merged: cluster.members, into: null, dryRun: true });
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const prompt = members
|
|
118
|
+
.map((m, i) => `[${i + 1}] name: ${m.frontmatter.name}\ntype: ${m.frontmatter.type}\ndescription: ${m.frontmatter.description}\nbody: ${m.body}`)
|
|
119
|
+
.join('\n\n');
|
|
120
|
+
// Bound the per-cluster stream: a hung provider must not stall consolidation
|
|
121
|
+
// forever. Combine an optional caller signal with a timeout abort, and clear
|
|
122
|
+
// the timer in finally so it never leaks past this cluster. We RACE each
|
|
123
|
+
// iterator step against the abort signal so even a provider that ignores
|
|
124
|
+
// `req.signal` (and never yields again) can't hang us — we abandon its
|
|
125
|
+
// iterator and move on. The cluster is recorded as not-merged.
|
|
126
|
+
const signal = combineAbort(opts.signal, timeoutMs);
|
|
127
|
+
let response = '';
|
|
128
|
+
let aborted = false;
|
|
129
|
+
const iterable = provider.stream({
|
|
130
|
+
model: provider.models[0]?.id ?? 'unknown',
|
|
131
|
+
system: SYSTEM_PROMPT,
|
|
132
|
+
messages: [{ role: 'user', content: [{ type: 'text', text: prompt }] }],
|
|
133
|
+
maxTokens: 2000,
|
|
134
|
+
...(signal.signal ? { signal: signal.signal } : {}),
|
|
135
|
+
});
|
|
136
|
+
const iterator = iterable[Symbol.asyncIterator]();
|
|
137
|
+
try {
|
|
138
|
+
for (;;) {
|
|
139
|
+
const step = await raceAbort(iterator.next(), signal.signal);
|
|
140
|
+
if (step === ABORTED) {
|
|
141
|
+
aborted = true;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
if (step.done)
|
|
145
|
+
break;
|
|
146
|
+
const event = step.value;
|
|
147
|
+
if (event.type === 'text_delta')
|
|
148
|
+
response += event.delta;
|
|
149
|
+
if (event.type === 'error') {
|
|
150
|
+
throw new Error(`consolidate: provider error: ${event.message}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
// A provider that honors the signal by throwing also degrades cleanly.
|
|
156
|
+
if (signal.signal?.aborted || isAbortError(err)) {
|
|
157
|
+
aborted = true;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
throw err;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
// Abandon a non-cooperative iterator so it can release resources; ignore
|
|
165
|
+
// any return() error — we're already moving on.
|
|
166
|
+
if (aborted)
|
|
167
|
+
void iterator.return?.(undefined).catch(() => { });
|
|
168
|
+
signal.dispose();
|
|
169
|
+
}
|
|
170
|
+
if (aborted) {
|
|
171
|
+
console.warn(`[plugin-memory] consolidate: provider stream aborted for cluster ${cluster.key} (timeout ${timeoutMs}ms)`);
|
|
172
|
+
outcomes.push({ key: cluster.key, merged: cluster.members, into: null, dryRun: false });
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const extracted = extractJson(response);
|
|
176
|
+
const parsed = consolidatedSchema.parse(extracted);
|
|
177
|
+
// Guard: if the LLM picked a name that already exists OUTSIDE this
|
|
178
|
+
// cluster, writing it would silently clobber an unrelated memory. Skip
|
|
179
|
+
// the merge and record the cluster as not-merged rather than destroy
|
|
180
|
+
// data. `byName` is a snapshot taken before any provider streaming, so it
|
|
181
|
+
// can be stale by now — re-read the live entry from disk to also catch an
|
|
182
|
+
// entry created by a concurrent writer since the snapshot.
|
|
183
|
+
const clusterNames = new Set(cluster.members);
|
|
184
|
+
const liveCollision = !clusterNames.has(parsed.name) && (await store.get(parsed.name)) !== null;
|
|
185
|
+
if ((byName.has(parsed.name) || produced.has(parsed.name) || liveCollision) &&
|
|
186
|
+
!clusterNames.has(parsed.name)) {
|
|
187
|
+
outcomes.push({
|
|
188
|
+
key: cluster.key,
|
|
189
|
+
merged: cluster.members,
|
|
190
|
+
into: null,
|
|
191
|
+
dryRun: false,
|
|
192
|
+
});
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
await store.save({
|
|
196
|
+
name: parsed.name,
|
|
197
|
+
type: parsed.type,
|
|
198
|
+
description: parsed.description,
|
|
199
|
+
body: parsed.body,
|
|
200
|
+
...(parsed.tags ? { tags: parsed.tags } : {}),
|
|
201
|
+
});
|
|
202
|
+
produced.add(parsed.name);
|
|
203
|
+
// Delete merged entries except the one we just saved (if it overlaps).
|
|
204
|
+
for (const member of members) {
|
|
205
|
+
if (member.frontmatter.name !== parsed.name) {
|
|
206
|
+
await store.forget(member.frontmatter.name);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
outcomes.push({
|
|
210
|
+
key: cluster.key,
|
|
211
|
+
merged: cluster.members,
|
|
212
|
+
into: parsed.name,
|
|
213
|
+
dryRun: false,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return { clusters: outcomes, stable: plan.stable };
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Combine an optional caller signal with a timeout into one AbortSignal,
|
|
220
|
+
* returning a `dispose()` that clears the timer so it can't fire (and keep the
|
|
221
|
+
* event loop alive) after the stream finishes. Returns `{ signal: undefined }`
|
|
222
|
+
* when neither bound applies, so we don't pass an always-open signal needlessly.
|
|
223
|
+
*/
|
|
224
|
+
function combineAbort(caller, timeoutMs) {
|
|
225
|
+
const useTimeout = Number.isFinite(timeoutMs) && timeoutMs > 0;
|
|
226
|
+
if (!caller && !useTimeout)
|
|
227
|
+
return { signal: undefined, dispose: () => { } };
|
|
228
|
+
const controller = new AbortController();
|
|
229
|
+
const onAbort = () => controller.abort(caller?.reason);
|
|
230
|
+
if (caller) {
|
|
231
|
+
if (caller.aborted)
|
|
232
|
+
controller.abort(caller.reason);
|
|
233
|
+
else
|
|
234
|
+
caller.addEventListener('abort', onAbort, { once: true });
|
|
235
|
+
}
|
|
236
|
+
let timer;
|
|
237
|
+
if (useTimeout && !controller.signal.aborted) {
|
|
238
|
+
timer = setTimeout(() => controller.abort(new Error('consolidate: provider stream timed out')), timeoutMs);
|
|
239
|
+
// Don't keep the process alive solely for this watchdog.
|
|
240
|
+
timer.unref?.();
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
signal: controller.signal,
|
|
244
|
+
dispose: () => {
|
|
245
|
+
if (timer)
|
|
246
|
+
clearTimeout(timer);
|
|
247
|
+
caller?.removeEventListener('abort', onAbort);
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/** Sentinel resolved by {@link raceAbort} when the signal fires first. */
|
|
252
|
+
const ABORTED = Symbol('aborted');
|
|
253
|
+
/**
|
|
254
|
+
* Race a pending step against an abort signal. Returns the step's result if it
|
|
255
|
+
* settles first, or {@link ABORTED} if the signal fires first — so a provider
|
|
256
|
+
* that ignores `req.signal` and never yields again can't stall the loop. The
|
|
257
|
+
* abandoned `next()` promise is left to settle on its own (its rejection, if
|
|
258
|
+
* any, is swallowed); the caller stops consuming the iterator.
|
|
259
|
+
*/
|
|
260
|
+
function raceAbort(step, signal) {
|
|
261
|
+
if (!signal)
|
|
262
|
+
return step;
|
|
263
|
+
if (signal.aborted) {
|
|
264
|
+
void step.catch(() => { });
|
|
265
|
+
return Promise.resolve(ABORTED);
|
|
266
|
+
}
|
|
267
|
+
return new Promise((resolve, reject) => {
|
|
268
|
+
const onAbort = () => {
|
|
269
|
+
void step.catch(() => { });
|
|
270
|
+
resolve(ABORTED);
|
|
271
|
+
};
|
|
272
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
273
|
+
step.then((v) => {
|
|
274
|
+
signal.removeEventListener('abort', onAbort);
|
|
275
|
+
resolve(v);
|
|
276
|
+
}, (e) => {
|
|
277
|
+
signal.removeEventListener('abort', onAbort);
|
|
278
|
+
reject(e);
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function isAbortError(err) {
|
|
283
|
+
return ((err instanceof Error && err.name === 'AbortError') ||
|
|
284
|
+
(typeof err === 'object' && err !== null && err.name === 'AbortError'));
|
|
285
|
+
}
|
|
286
|
+
// Upper bound on the JSON span we'll JSON.parse from a model response. The
|
|
287
|
+
// consolidated entry is tiny (description ≤280, body ≤4000), so a span far
|
|
288
|
+
// past this is a malformed/hostile response, not a real entry — refuse it
|
|
289
|
+
// before handing an unbounded string to JSON.parse.
|
|
290
|
+
const MAX_JSON_SPAN = 64 * 1024;
|
|
291
|
+
function extractJson(text) {
|
|
292
|
+
// Take the span from the first `{` to the last `}` in the response. Some
|
|
293
|
+
// providers wrap the object in ```json ... ```, which we strip first.
|
|
294
|
+
const fenced = /```(?:json)?\n?([\s\S]*?)```/.exec(text);
|
|
295
|
+
const candidate = fenced ? fenced[1] : text;
|
|
296
|
+
const start = candidate.indexOf('{');
|
|
297
|
+
const end = candidate.lastIndexOf('}');
|
|
298
|
+
// `end <= start` (e.g. a stray `}` before the first `{`) means there's no
|
|
299
|
+
// well-formed object span; surface the intended message instead of letting
|
|
300
|
+
// slice() yield garbage that JSON.parse fails on with an opaque error.
|
|
301
|
+
if (start === -1 || end <= start)
|
|
302
|
+
throw new Error('consolidate: model returned no JSON object');
|
|
303
|
+
const span = candidate.slice(start, end + 1);
|
|
304
|
+
if (span.length > MAX_JSON_SPAN) {
|
|
305
|
+
throw new Error('consolidate: model JSON object too large to parse');
|
|
306
|
+
}
|
|
307
|
+
return JSON.parse(span);
|
|
308
|
+
}
|
|
309
|
+
export function buildMemoryConsolidatePlugin(store, getProvider, opts = {}) {
|
|
310
|
+
// Host-injected store + provider accessor (available immediately).
|
|
311
|
+
return makeMemoryConsolidatePlugin(() => store, getProvider, opts);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Discovery-loadable default export: resolves the long-term store (`'memory'`,
|
|
315
|
+
* published by @moxxy/plugin-memory) and the active provider (via the `'providers'`
|
|
316
|
+
* registry) from the inter-plugin service registry in `onInit`, so it no longer
|
|
317
|
+
* needs the `(store, getProvider)` closure. @moxxy/plugin-memory is registered
|
|
318
|
+
* first, so its onInit publishes the store before this one resolves it.
|
|
319
|
+
*/
|
|
320
|
+
export const memoryConsolidatePlugin = (() => {
|
|
321
|
+
let store = null;
|
|
322
|
+
let providers = null;
|
|
323
|
+
const onInit = (ctx) => {
|
|
324
|
+
store = ctx.services.get('memory') ?? null;
|
|
325
|
+
providers = ctx.services.get('providers') ?? null;
|
|
326
|
+
};
|
|
327
|
+
return makeMemoryConsolidatePlugin(() => {
|
|
328
|
+
if (!store) {
|
|
329
|
+
throw new Error('@moxxy/memory-consolidate: the "memory" service is unavailable — @moxxy/plugin-memory must load first');
|
|
330
|
+
}
|
|
331
|
+
return store;
|
|
332
|
+
}, () => {
|
|
333
|
+
const p = providers?.getActive();
|
|
334
|
+
if (!p) {
|
|
335
|
+
throw new Error('@moxxy/memory-consolidate: no active provider to consolidate with');
|
|
336
|
+
}
|
|
337
|
+
return p;
|
|
338
|
+
}, {}, onInit);
|
|
339
|
+
})();
|
|
340
|
+
function makeMemoryConsolidatePlugin(getStore, getProvider, opts = {}, extraOnInit) {
|
|
341
|
+
const threshold = opts.autoNudgeThreshold ?? 30;
|
|
342
|
+
let nudged = false;
|
|
343
|
+
const nudgeHook = threshold > 0
|
|
344
|
+
? {
|
|
345
|
+
onBeforeProviderCall: async (req) => {
|
|
346
|
+
if (nudged)
|
|
347
|
+
return; // one nudge per session
|
|
348
|
+
// Count only — capStatus() serves the in-memory index-row cache,
|
|
349
|
+
// so a below-threshold store doesn't re-scan + re-parse every
|
|
350
|
+
// memory file on every single provider call for the whole session
|
|
351
|
+
// (store.list() did a full disk read+parse each time).
|
|
352
|
+
const count = (await getStore().capStatus()).count;
|
|
353
|
+
if (count <= threshold)
|
|
354
|
+
return;
|
|
355
|
+
nudged = true;
|
|
356
|
+
const hint = `\n\n[memory note] long-term memory has ${count} entries (threshold: ${threshold}). ` +
|
|
357
|
+
`consider running \`memory_consolidate\` when there's a natural break to merge overlapping entries.`;
|
|
358
|
+
return { ...req, system: (req.system ?? '') + hint };
|
|
359
|
+
},
|
|
360
|
+
}
|
|
361
|
+
: {};
|
|
362
|
+
const hooks = extraOnInit
|
|
363
|
+
? { ...nudgeHook, onInit: extraOnInit }
|
|
364
|
+
: nudgeHook;
|
|
365
|
+
return definePlugin({
|
|
366
|
+
name: '@moxxy/memory-consolidate',
|
|
367
|
+
version: '0.0.0',
|
|
368
|
+
hooks,
|
|
369
|
+
tools: [
|
|
370
|
+
defineTool({
|
|
371
|
+
name: 'memory_consolidate',
|
|
372
|
+
description: 'Merge overlapping long-term memory entries into single canonical ones. ' +
|
|
373
|
+
'Clusters by shared tag or shared tokens in name+description. ' +
|
|
374
|
+
'Use dryRun=true to preview the plan without modifying anything.',
|
|
375
|
+
inputSchema: z.object({
|
|
376
|
+
tag: z.string().optional(),
|
|
377
|
+
dryRun: z.boolean().optional().default(false),
|
|
378
|
+
}),
|
|
379
|
+
permission: { action: 'prompt' },
|
|
380
|
+
isolation: {
|
|
381
|
+
capabilities: {
|
|
382
|
+
fs: { read: ['~/.moxxy/memory/**'], write: ['~/.moxxy/memory/**'] },
|
|
383
|
+
// Each cluster merge streams from the active LLMProvider; the
|
|
384
|
+
// inproc isolator can't pin the host (provider-config dependent).
|
|
385
|
+
net: { mode: 'any' },
|
|
386
|
+
// Many clusters × the 60s per-cluster provider-stream bound.
|
|
387
|
+
timeMs: 600_000,
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
handler: async ({ tag, dryRun }) => {
|
|
391
|
+
const outcome = await consolidateMemory(getStore(), getProvider(), {
|
|
392
|
+
...(tag ? { tag } : {}),
|
|
393
|
+
...(dryRun !== undefined ? { dryRun } : {}),
|
|
394
|
+
});
|
|
395
|
+
return outcome;
|
|
396
|
+
},
|
|
397
|
+
}),
|
|
398
|
+
defineTool({
|
|
399
|
+
name: 'memory_consolidate_plan',
|
|
400
|
+
description: 'Return the consolidation plan (clusters that would be merged) without invoking the model.',
|
|
401
|
+
inputSchema: z.object({ tag: z.string().optional() }),
|
|
402
|
+
isolation: {
|
|
403
|
+
capabilities: {
|
|
404
|
+
fs: { read: ['~/.moxxy/memory/**'] },
|
|
405
|
+
net: { mode: 'none' },
|
|
406
|
+
timeMs: 15_000,
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
handler: async ({ tag }) => {
|
|
410
|
+
const all = await getStore().list();
|
|
411
|
+
return planConsolidation(all, { ...(tag ? { tag } : {}) });
|
|
412
|
+
},
|
|
413
|
+
}),
|
|
414
|
+
],
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
//# sourceMappingURL=consolidate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidate.js","sourceRoot":"","sources":["../src/consolidate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persists computed embeddings to `<memoryDir>/.embeddings.json` keyed by
|
|
3
|
+
* content hash. The cache is invalidated when the embedder name OR its
|
|
4
|
+
* dimensionality changes — a name alone is too coarse (e.g. the OpenAI embedder
|
|
5
|
+
* reports a fixed name across models/`dimensions` settings, so a 1536→3072
|
|
6
|
+
* model switch must invalidate on the dim mismatch or recall compares
|
|
7
|
+
* incomparable vectors).
|
|
8
|
+
*/
|
|
9
|
+
export declare class EmbeddingIndex {
|
|
10
|
+
private readonly dir;
|
|
11
|
+
private readonly embedderName;
|
|
12
|
+
private readonly dim?;
|
|
13
|
+
private cache;
|
|
14
|
+
private dirty;
|
|
15
|
+
private loaded;
|
|
16
|
+
constructor(dir: string, embedderName: string, dim?: number | "dynamic" | undefined);
|
|
17
|
+
static hash(text: string): string;
|
|
18
|
+
private get filePath();
|
|
19
|
+
load(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* For a `(name, body)` pair, return either the cached vector (if the body
|
|
22
|
+
* hash matches) or `null` (miss). Callers re-embed the misses and call
|
|
23
|
+
* `set()` with the fresh vectors.
|
|
24
|
+
*/
|
|
25
|
+
lookup(name: string, body: string): ReadonlyArray<number> | null;
|
|
26
|
+
set(name: string, body: string, vector: ReadonlyArray<number>): void;
|
|
27
|
+
/** Drop entries that no longer correspond to existing memories. */
|
|
28
|
+
prune(currentNames: ReadonlyArray<string>): void;
|
|
29
|
+
flush(): Promise<void>;
|
|
30
|
+
get size(): number;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=embedding-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding-cache.d.ts","sourceRoot":"","sources":["../src/embedding-cache.ts"],"names":[],"mappings":"AAqBA;;;;;;;GAOG;AACH,qBAAa,cAAc;IAMvB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;IAPvB,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;gBAGJ,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,YAAA;IAG3C,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIjC,OAAO,KAAK,QAAQ,GAEnB;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC3B;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI;IAOhE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI;IAQpE,mEAAmE;IACnE,KAAK,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI;IAU1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|