opencode-mem 2.7.5 → 2.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +99 -37
- package/dist/services/client.d.ts +27 -0
- package/dist/services/client.d.ts.map +1 -1
- package/dist/services/client.js +38 -0
- package/dist/services/sqlite/vector-search.d.ts +1 -0
- package/dist/services/sqlite/vector-search.d.ts.map +1 -1
- package/dist/services/sqlite/vector-search.js +13 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -72,6 +72,18 @@ Configure at `~/.config/opencode/opencode-mem.jsonc`:
|
|
|
72
72
|
|
|
73
73
|
"userProfileAnalysisInterval": 10,
|
|
74
74
|
"maxMemories": 10,
|
|
75
|
+
|
|
76
|
+
"compaction": {
|
|
77
|
+
"enabled": true,
|
|
78
|
+
"memoryLimit": 10,
|
|
79
|
+
},
|
|
80
|
+
"chatMessage": {
|
|
81
|
+
"enabled": true,
|
|
82
|
+
"maxMemories": 3,
|
|
83
|
+
"excludeCurrentSession": true,
|
|
84
|
+
"maxAgeDays": undefined,
|
|
85
|
+
"injectOn": "first",
|
|
86
|
+
},
|
|
75
87
|
}
|
|
76
88
|
```
|
|
77
89
|
|
package/dist/config.d.ts
CHANGED
|
@@ -39,6 +39,17 @@ export declare const CONFIG: {
|
|
|
39
39
|
showAutoCaptureToasts: boolean;
|
|
40
40
|
showUserProfileToasts: boolean;
|
|
41
41
|
showErrorToasts: boolean;
|
|
42
|
+
compaction: {
|
|
43
|
+
enabled: boolean | undefined;
|
|
44
|
+
memoryLimit: number | undefined;
|
|
45
|
+
};
|
|
46
|
+
chatMessage: {
|
|
47
|
+
enabled: boolean | undefined;
|
|
48
|
+
maxMemories: number | undefined;
|
|
49
|
+
excludeCurrentSession: boolean | undefined;
|
|
50
|
+
maxAgeDays: number | undefined;
|
|
51
|
+
injectOn: "first" | "always";
|
|
52
|
+
};
|
|
42
53
|
};
|
|
43
54
|
export declare function isConfigured(): boolean;
|
|
44
55
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AA8ZA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;oBA2Bb,aAAa,GACb,kBAAkB,GAClB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAwCT,OAAO,GACP,QAAQ;;CAEf,CAAC;AAEF,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
|
package/dist/config.js
CHANGED
|
@@ -45,6 +45,17 @@ const DEFAULTS = {
|
|
|
45
45
|
showAutoCaptureToasts: true,
|
|
46
46
|
showUserProfileToasts: true,
|
|
47
47
|
showErrorToasts: true,
|
|
48
|
+
compaction: {
|
|
49
|
+
enabled: true,
|
|
50
|
+
memoryLimit: 10,
|
|
51
|
+
},
|
|
52
|
+
chatMessage: {
|
|
53
|
+
enabled: true,
|
|
54
|
+
maxMemories: 3,
|
|
55
|
+
excludeCurrentSession: true,
|
|
56
|
+
maxAgeDays: undefined,
|
|
57
|
+
injectOn: "first",
|
|
58
|
+
},
|
|
48
59
|
};
|
|
49
60
|
function expandPath(path) {
|
|
50
61
|
if (path.startsWith("~/")) {
|
|
@@ -355,6 +366,17 @@ export const CONFIG = {
|
|
|
355
366
|
showAutoCaptureToasts: fileConfig.showAutoCaptureToasts ?? DEFAULTS.showAutoCaptureToasts,
|
|
356
367
|
showUserProfileToasts: fileConfig.showUserProfileToasts ?? DEFAULTS.showUserProfileToasts,
|
|
357
368
|
showErrorToasts: fileConfig.showErrorToasts ?? DEFAULTS.showErrorToasts,
|
|
369
|
+
compaction: {
|
|
370
|
+
enabled: fileConfig.compaction?.enabled ?? DEFAULTS.compaction.enabled,
|
|
371
|
+
memoryLimit: fileConfig.compaction?.memoryLimit ?? DEFAULTS.compaction.memoryLimit,
|
|
372
|
+
},
|
|
373
|
+
chatMessage: {
|
|
374
|
+
enabled: fileConfig.chatMessage?.enabled ?? DEFAULTS.chatMessage.enabled,
|
|
375
|
+
maxMemories: fileConfig.chatMessage?.maxMemories ?? DEFAULTS.chatMessage.maxMemories,
|
|
376
|
+
excludeCurrentSession: fileConfig.chatMessage?.excludeCurrentSession ?? DEFAULTS.chatMessage.excludeCurrentSession,
|
|
377
|
+
maxAgeDays: fileConfig.chatMessage?.maxAgeDays,
|
|
378
|
+
injectOn: (fileConfig.chatMessage?.injectOn ?? DEFAULTS.chatMessage.injectOn),
|
|
379
|
+
},
|
|
358
380
|
};
|
|
359
381
|
export function isConfigured() {
|
|
360
382
|
return true;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAkB/D,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAkB/D,eAAO,MAAM,iBAAiB,EAAE,MA+Z/B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -98,7 +98,7 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
98
98
|
process.on("SIGTERM", shutdownHandler);
|
|
99
99
|
return {
|
|
100
100
|
"chat.message": async (input, output) => {
|
|
101
|
-
if (!isConfigured())
|
|
101
|
+
if (!isConfigured() || !CONFIG.chatMessage.enabled)
|
|
102
102
|
return;
|
|
103
103
|
try {
|
|
104
104
|
const textParts = output.parts.filter((p) => p.type === "text");
|
|
@@ -108,42 +108,52 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
108
108
|
if (!userMessage.trim())
|
|
109
109
|
return;
|
|
110
110
|
userPromptManager.savePrompt(input.sessionID, output.message.id, directory, userMessage);
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
111
|
+
const messagesResponse = await ctx.client.session.messages({
|
|
112
|
+
path: { id: input.sessionID },
|
|
113
|
+
});
|
|
114
|
+
const messages = messagesResponse.data || [];
|
|
115
|
+
const hasNonSyntheticUserMessages = messages.some((m) => m.info.role === "user" &&
|
|
116
|
+
!m.parts.every((p) => p.type !== "text" || p.synthetic === true));
|
|
117
|
+
const lastMessage = messages.length > 0 ? messages[messages.length - 1] : null;
|
|
118
|
+
const isAfterCompaction = lastMessage?.info?.summary === true;
|
|
119
|
+
const shouldInject = CONFIG.chatMessage.injectOn === "always" ||
|
|
120
|
+
!hasNonSyntheticUserMessages ||
|
|
121
|
+
(isAfterCompaction &&
|
|
122
|
+
messages.filter((m) => m.info.role === "user" &&
|
|
123
|
+
!m.parts.every((p) => p.type !== "text" || p.synthetic === true)).length === 1);
|
|
124
|
+
if (!shouldInject)
|
|
125
|
+
return;
|
|
126
|
+
const listResult = await memoryClient.listMemories(tags.project.tag, CONFIG.chatMessage.maxMemories);
|
|
127
|
+
let memories = listResult.success ? listResult.memories : [];
|
|
128
|
+
if (CONFIG.chatMessage.excludeCurrentSession) {
|
|
129
|
+
memories = memories.filter((m) => m.metadata?.sessionID !== input.sessionID);
|
|
130
|
+
}
|
|
131
|
+
if (CONFIG.chatMessage.maxAgeDays) {
|
|
132
|
+
const cutoffDate = Date.now() - CONFIG.chatMessage.maxAgeDays * 86400000;
|
|
133
|
+
memories = memories.filter((m) => new Date(m.createdAt).getTime() > cutoffDate);
|
|
134
|
+
}
|
|
135
|
+
if (memories.length === 0)
|
|
136
|
+
return;
|
|
137
|
+
const projectMemories = {
|
|
138
|
+
results: memories.map((m) => ({
|
|
139
|
+
similarity: 1.0,
|
|
140
|
+
memory: m.summary,
|
|
141
|
+
})),
|
|
142
|
+
total: memories.length,
|
|
143
|
+
timing: 0,
|
|
144
|
+
};
|
|
145
|
+
const userId = tags.user.userEmail || null;
|
|
146
|
+
const memoryContext = formatContextForPrompt(userId, projectMemories);
|
|
147
|
+
if (memoryContext) {
|
|
148
|
+
const contextPart = {
|
|
149
|
+
id: `memory-context-${Date.now()}`,
|
|
150
|
+
sessionID: input.sessionID,
|
|
151
|
+
messageID: output.message.id,
|
|
152
|
+
type: "text",
|
|
153
|
+
text: memoryContext,
|
|
154
|
+
synthetic: true,
|
|
155
|
+
};
|
|
156
|
+
output.parts.unshift(contextPart);
|
|
147
157
|
}
|
|
148
158
|
}
|
|
149
159
|
catch (error) {
|
|
@@ -315,6 +325,47 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
315
325
|
}
|
|
316
326
|
}, 10000);
|
|
317
327
|
}
|
|
328
|
+
if (event.type === "session.compacted") {
|
|
329
|
+
if (!isConfigured() || !CONFIG.compaction.enabled)
|
|
330
|
+
return;
|
|
331
|
+
const sessionID = event.properties?.sessionID;
|
|
332
|
+
if (!sessionID)
|
|
333
|
+
return;
|
|
334
|
+
try {
|
|
335
|
+
const tags = getTags(directory);
|
|
336
|
+
const memoriesResult = await memoryClient.searchMemoriesBySessionID(sessionID, tags.project.tag, CONFIG.compaction.memoryLimit);
|
|
337
|
+
if (!memoriesResult.success || memoriesResult.results.length === 0) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const memoryContext = formatMemoriesForCompaction(memoriesResult.results);
|
|
341
|
+
await ctx.client.session.prompt({
|
|
342
|
+
path: { id: sessionID },
|
|
343
|
+
body: {
|
|
344
|
+
parts: [{ type: "text", text: memoryContext }],
|
|
345
|
+
noReply: true,
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
if (ctx.client?.tui) {
|
|
349
|
+
await ctx.client.tui
|
|
350
|
+
.showToast({
|
|
351
|
+
body: {
|
|
352
|
+
title: "Memory Restored",
|
|
353
|
+
message: `${memoriesResult.results.length} memories injected after compaction`,
|
|
354
|
+
variant: "success",
|
|
355
|
+
duration: 3000,
|
|
356
|
+
},
|
|
357
|
+
})
|
|
358
|
+
.catch(() => { });
|
|
359
|
+
}
|
|
360
|
+
log("Compaction memory injected", {
|
|
361
|
+
sessionID,
|
|
362
|
+
count: memoriesResult.results.length,
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
log("Compaction handler error", { error: String(error) });
|
|
367
|
+
}
|
|
368
|
+
}
|
|
318
369
|
},
|
|
319
370
|
};
|
|
320
371
|
};
|
|
@@ -331,3 +382,14 @@ function formatSearchResults(query, results, limit) {
|
|
|
331
382
|
})),
|
|
332
383
|
});
|
|
333
384
|
}
|
|
385
|
+
function formatMemoriesForCompaction(memories) {
|
|
386
|
+
let output = `## Restored Session Memory\n\n`;
|
|
387
|
+
memories.forEach((m, i) => {
|
|
388
|
+
output += `### Memory ${i + 1}\n`;
|
|
389
|
+
output += `${m.memory}\n\n`;
|
|
390
|
+
if (m.tags && m.tags.length > 0) {
|
|
391
|
+
output += `Tags: ${m.tags.join(", ")}\n\n`;
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
return output;
|
|
395
|
+
}
|
|
@@ -86,6 +86,33 @@ export declare class LocalMemoryClient {
|
|
|
86
86
|
totalPages: number;
|
|
87
87
|
};
|
|
88
88
|
}>;
|
|
89
|
+
searchMemoriesBySessionID(sessionID: string, containerTag: string, limit?: number): Promise<{
|
|
90
|
+
success: true;
|
|
91
|
+
results: {
|
|
92
|
+
id: any;
|
|
93
|
+
memory: any;
|
|
94
|
+
similarity: number;
|
|
95
|
+
tags: any;
|
|
96
|
+
metadata: any;
|
|
97
|
+
containerTag: any;
|
|
98
|
+
displayName: any;
|
|
99
|
+
userName: any;
|
|
100
|
+
userEmail: any;
|
|
101
|
+
projectPath: any;
|
|
102
|
+
projectName: any;
|
|
103
|
+
gitRepoUrl: any;
|
|
104
|
+
createdAt: any;
|
|
105
|
+
}[];
|
|
106
|
+
total: number;
|
|
107
|
+
timing: number;
|
|
108
|
+
error?: undefined;
|
|
109
|
+
} | {
|
|
110
|
+
success: false;
|
|
111
|
+
error: string;
|
|
112
|
+
results: never[];
|
|
113
|
+
total: number;
|
|
114
|
+
timing: number;
|
|
115
|
+
}>;
|
|
89
116
|
}
|
|
90
117
|
export declare const memoryClient: LocalMemoryClient;
|
|
91
118
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/services/client.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA4CpD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,aAAa,CAAkB;;YAIzB,UAAU;IAiBlB,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjE,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAIjC,SAAS,IAAI;QACX,WAAW,EAAE,OAAO,CAAC;QACrB,WAAW,EAAE,OAAO,CAAC;QACrB,KAAK,EAAE,OAAO,CAAC;KAChB;IAQD,KAAK,IAAI,IAAI;IAIP,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;IA6BlD,SAAS,CACb,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,UAAU,CAAC;QAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,cAAc,GAAG,QAAQ,GAAG,KAAK,CAAC;QACtD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB;;;;;;;;;IA+DG,YAAY,CAAC,QAAQ,EAAE,MAAM;;;;;;;IA2B7B,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,SAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/services/client.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA4CpD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,aAAa,CAAkB;;YAIzB,UAAU;IAiBlB,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjE,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAIjC,SAAS,IAAI;QACX,WAAW,EAAE,OAAO,CAAC;QACrB,WAAW,EAAE,OAAO,CAAC;QACrB,KAAK,EAAE,OAAO,CAAC;KAChB;IAQD,KAAK,IAAI,IAAI;IAIP,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;IA6BlD,SAAS,CACb,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,UAAU,CAAC;QAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,cAAc,GAAG,QAAQ,GAAG,KAAK,CAAC;QACtD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB;;;;;;;;;IA+DG,YAAY,CAAC,QAAQ,EAAE,MAAM;;;;;;;IA2B7B,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,SAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuD7C,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4C5F;AAED,eAAO,MAAM,YAAY,mBAA0B,CAAC"}
|
package/dist/services/client.js
CHANGED
|
@@ -209,5 +209,43 @@ export class LocalMemoryClient {
|
|
|
209
209
|
};
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
|
+
async searchMemoriesBySessionID(sessionID, containerTag, limit = 10) {
|
|
213
|
+
try {
|
|
214
|
+
await this.initialize();
|
|
215
|
+
const { scope, hash } = extractScopeFromContainerTag(containerTag);
|
|
216
|
+
const shards = shardManager.getAllShards(scope, hash);
|
|
217
|
+
if (shards.length === 0) {
|
|
218
|
+
return { success: true, results: [], total: 0, timing: 0 };
|
|
219
|
+
}
|
|
220
|
+
const allMemories = [];
|
|
221
|
+
for (const shard of shards) {
|
|
222
|
+
const db = connectionManager.getConnection(shard.dbPath);
|
|
223
|
+
const memories = vectorSearch.getMemoriesBySessionID(db, sessionID);
|
|
224
|
+
allMemories.push(...memories);
|
|
225
|
+
}
|
|
226
|
+
allMemories.sort((a, b) => b.created_at - a.created_at);
|
|
227
|
+
const results = allMemories.slice(0, limit).map((row) => ({
|
|
228
|
+
id: row.id,
|
|
229
|
+
memory: row.content,
|
|
230
|
+
similarity: 1.0,
|
|
231
|
+
tags: row.tags || [],
|
|
232
|
+
metadata: row.metadata || {},
|
|
233
|
+
containerTag: row.container_tag,
|
|
234
|
+
displayName: row.display_name,
|
|
235
|
+
userName: row.user_name,
|
|
236
|
+
userEmail: row.user_email,
|
|
237
|
+
projectPath: row.project_path,
|
|
238
|
+
projectName: row.project_name,
|
|
239
|
+
gitRepoUrl: row.git_repo_url,
|
|
240
|
+
createdAt: row.created_at,
|
|
241
|
+
}));
|
|
242
|
+
return { success: true, results, total: results.length, timing: 0 };
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
246
|
+
log("searchMemoriesBySessionID: error", { error: errorMessage });
|
|
247
|
+
return { success: false, error: errorMessage, results: [], total: 0, timing: 0 };
|
|
248
|
+
}
|
|
249
|
+
}
|
|
212
250
|
}
|
|
213
251
|
export const memoryClient = new LocalMemoryClient();
|
|
@@ -9,6 +9,7 @@ export declare class VectorSearch {
|
|
|
9
9
|
listMemories(db: Database, containerTag: string, limit: number): any[];
|
|
10
10
|
getAllMemories(db: Database): any[];
|
|
11
11
|
getMemoryById(db: Database, memoryId: string): any | null;
|
|
12
|
+
getMemoriesBySessionID(db: Database, sessionID: string): any[];
|
|
12
13
|
countVectors(db: Database, containerTag: string): number;
|
|
13
14
|
countAllVectors(db: Database): number;
|
|
14
15
|
getDistinctTags(db: Database): any[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector-search.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/vector-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExE,qBAAa,YAAY;IACvB,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI;IA0CtD,aAAa,CACX,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,GACjB,YAAY,EAAE;IA0FX,kBAAkB,CACtB,MAAM,EAAE,SAAS,EAAE,EACnB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,MAAM,EAC3B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC;IAiB1B,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMlD,YAAY,CACV,EAAE,EAAE,QAAQ,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,EACpB,UAAU,CAAC,EAAE,YAAY,GACxB,IAAI;IAkBP,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE;IAWtE,cAAc,CAAC,EAAE,EAAE,QAAQ,GAAG,GAAG,EAAE;IAKnC,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI;IAKzD,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAMxD,eAAe,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM;IAMrC,eAAe,CAAC,EAAE,EAAE,QAAQ,GAAG,GAAG,EAAE;IAepC,SAAS,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK/C,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAIlD;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"vector-search.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/vector-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExE,qBAAa,YAAY;IACvB,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI;IA0CtD,aAAa,CACX,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,GACjB,YAAY,EAAE;IA0FX,kBAAkB,CACtB,MAAM,EAAE,SAAS,EAAE,EACnB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,MAAM,EAC3B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC;IAiB1B,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMlD,YAAY,CACV,EAAE,EAAE,QAAQ,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,EACpB,UAAU,CAAC,EAAE,YAAY,GACxB,IAAI;IAkBP,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE;IAWtE,cAAc,CAAC,EAAE,EAAE,QAAQ,GAAG,GAAG,EAAE;IAKnC,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI;IAKzD,sBAAsB,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,GAAG,EAAE;IAgB9D,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAMxD,eAAe,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM;IAMrC,eAAe,CAAC,EAAE,EAAE,QAAQ,GAAG,GAAG,EAAE;IAepC,SAAS,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK/C,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAIlD;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
|
|
@@ -140,6 +140,19 @@ export class VectorSearch {
|
|
|
140
140
|
const stmt = db.prepare(`SELECT * FROM memories WHERE id = ?`);
|
|
141
141
|
return stmt.get(memoryId);
|
|
142
142
|
}
|
|
143
|
+
getMemoriesBySessionID(db, sessionID) {
|
|
144
|
+
const stmt = db.prepare(`
|
|
145
|
+
SELECT * FROM memories
|
|
146
|
+
WHERE metadata LIKE ?
|
|
147
|
+
ORDER BY created_at DESC
|
|
148
|
+
`);
|
|
149
|
+
const rows = stmt.all(`%"sessionID":"${sessionID}"%`);
|
|
150
|
+
return rows.map((row) => ({
|
|
151
|
+
...row,
|
|
152
|
+
tags: row.tags ? row.tags.split(",") : [],
|
|
153
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : {},
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
143
156
|
countVectors(db, containerTag) {
|
|
144
157
|
const stmt = db.prepare(`SELECT COUNT(*) as count FROM memories WHERE container_tag = ?`);
|
|
145
158
|
const result = stmt.get(containerTag);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-mem",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.6",
|
|
4
4
|
"description": "OpenCode plugin that gives coding agents persistent memory using local vector database",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/plugin.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@xenova/transformers": "^2.17.2",
|
|
38
38
|
"franc-min": "^6.2.0",
|
|
39
39
|
"iso-639-3": "^3.0.1",
|
|
40
|
-
"sqlite-vec": "
|
|
40
|
+
"sqlite-vec": "0.1.7-alpha.2"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/bun": "^1.3.8",
|