opencode-mem 2.1.1 → 2.3.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/README.md +60 -77
- package/dist/config.d.ts +1 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -86
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +0 -4
- package/dist/services/ai/providers/anthropic-messages.d.ts.map +1 -1
- package/dist/services/ai/providers/anthropic-messages.js +11 -17
- package/dist/services/ai/providers/openai-chat-completion.d.ts.map +1 -1
- package/dist/services/ai/providers/openai-chat-completion.js +11 -17
- package/dist/services/ai/providers/openai-responses.d.ts.map +1 -1
- package/dist/services/ai/providers/openai-responses.js +11 -17
- package/dist/services/api-handlers.d.ts +5 -3
- package/dist/services/api-handlers.d.ts.map +1 -1
- package/dist/services/api-handlers.js +165 -42
- package/dist/services/auto-capture.js +2 -2
- package/dist/services/context.d.ts +1 -1
- package/dist/services/context.d.ts.map +1 -1
- package/dist/services/context.js +1 -10
- package/dist/services/deduplication-service.d.ts.map +1 -1
- package/dist/services/deduplication-service.js +1 -3
- package/dist/services/logger.js +1 -1
- package/dist/services/user-memory-learning.d.ts +1 -1
- package/dist/services/user-memory-learning.d.ts.map +1 -1
- package/dist/services/user-memory-learning.js +5 -3
- package/dist/services/user-profile/user-profile-manager.d.ts.map +1 -1
- package/dist/services/web-server-worker.js +30 -3
- package/dist/web/app.js +254 -47
- package/dist/web/index.html +31 -15
- package/dist/web/styles.css +309 -0
- package/package.json +1 -1
|
@@ -168,24 +168,18 @@ export class OpenAIResponsesProvider extends BaseAIProvider {
|
|
|
168
168
|
if (!data || typeof data !== "object") {
|
|
169
169
|
throw new Error("Response is not an object");
|
|
170
170
|
}
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
return (m &&
|
|
174
|
-
typeof m === "object" &&
|
|
175
|
-
typeof m.summary === "string" &&
|
|
176
|
-
m.summary.trim().length > 0 &&
|
|
177
|
-
(m.scope === "user" || m.scope === "project") &&
|
|
178
|
-
typeof m.type === "string" &&
|
|
179
|
-
m.type.trim().length > 0);
|
|
180
|
-
});
|
|
181
|
-
if (validMemories.length === 0) {
|
|
182
|
-
throw new Error("No valid memories in response");
|
|
183
|
-
}
|
|
184
|
-
return { memories: validMemories };
|
|
171
|
+
if (Array.isArray(data)) {
|
|
172
|
+
throw new Error("Response cannot be an array");
|
|
185
173
|
}
|
|
186
|
-
|
|
187
|
-
|
|
174
|
+
const keys = Object.keys(data);
|
|
175
|
+
if (keys.length === 0) {
|
|
176
|
+
throw new Error("Response object is empty");
|
|
177
|
+
}
|
|
178
|
+
for (const key of keys) {
|
|
179
|
+
if (data[key] === undefined || data[key] === null) {
|
|
180
|
+
throw new Error(`Response field '${key}' is null or undefined`);
|
|
181
|
+
}
|
|
188
182
|
}
|
|
189
|
-
|
|
183
|
+
return data;
|
|
190
184
|
}
|
|
191
185
|
}
|
|
@@ -8,7 +8,6 @@ interface Memory {
|
|
|
8
8
|
id: string;
|
|
9
9
|
content: string;
|
|
10
10
|
type?: string;
|
|
11
|
-
scope: string;
|
|
12
11
|
createdAt: string;
|
|
13
12
|
updatedAt?: string;
|
|
14
13
|
metadata?: Record<string, unknown>;
|
|
@@ -37,10 +36,9 @@ interface PaginatedResponse<T> {
|
|
|
37
36
|
totalPages: number;
|
|
38
37
|
}
|
|
39
38
|
export declare function handleListTags(): Promise<ApiResponse<{
|
|
40
|
-
user: TagInfo[];
|
|
41
39
|
project: TagInfo[];
|
|
42
40
|
}>>;
|
|
43
|
-
export declare function handleListMemories(tag?: string, page?: number, pageSize?: number,
|
|
41
|
+
export declare function handleListMemories(tag?: string, page?: number, pageSize?: number, includePrompts?: boolean): Promise<ApiResponse<PaginatedResponse<Memory | any>>>;
|
|
44
42
|
export declare function handleAddMemory(data: {
|
|
45
43
|
content: string;
|
|
46
44
|
containerTag: string;
|
|
@@ -106,5 +104,9 @@ export declare function handleDeletePrompt(id: string, cascade?: boolean): Promi
|
|
|
106
104
|
export declare function handleBulkDeletePrompts(ids: string[], cascade?: boolean): Promise<ApiResponse<{
|
|
107
105
|
deleted: number;
|
|
108
106
|
}>>;
|
|
107
|
+
export declare function handleGetUserProfile(userId?: string): Promise<ApiResponse<any>>;
|
|
108
|
+
export declare function handleGetProfileChangelog(profileId: string, limit?: number): Promise<ApiResponse<any[]>>;
|
|
109
|
+
export declare function handleGetProfileSnapshot(changelogId: string): Promise<ApiResponse<any>>;
|
|
110
|
+
export declare function handleRefreshProfile(userId?: string): Promise<ApiResponse<any>>;
|
|
109
111
|
export {};
|
|
110
112
|
//# sourceMappingURL=api-handlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-handlers.d.ts","sourceRoot":"","sources":["../../src/services/api-handlers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,UAAU,WAAW,CAAC,CAAC,GAAG,GAAG;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,
|
|
1
|
+
{"version":3,"file":"api-handlers.d.ts","sourceRoot":"","sources":["../../src/services/api-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,18 +33,16 @@ function safeJSONParse(jsonString) {
|
|
|
33
33
|
function extractScopeFromTag(tag) {
|
|
34
34
|
const parts = tag.split("_");
|
|
35
35
|
if (parts.length >= 3) {
|
|
36
|
-
const scope = parts[1];
|
|
37
36
|
const hash = parts.slice(2).join("_");
|
|
38
|
-
return { scope, hash };
|
|
37
|
+
return { scope: "project", hash };
|
|
39
38
|
}
|
|
40
|
-
return { scope: "
|
|
39
|
+
return { scope: "project", hash: tag };
|
|
41
40
|
}
|
|
42
41
|
export async function handleListTags() {
|
|
43
42
|
try {
|
|
44
43
|
await embeddingService.warmup();
|
|
45
|
-
const userShards = shardManager.getAllShards("user", "");
|
|
46
44
|
const projectShards = shardManager.getAllShards("project", "");
|
|
47
|
-
const allShards = [...
|
|
45
|
+
const allShards = [...projectShards];
|
|
48
46
|
const tagsMap = new Map();
|
|
49
47
|
for (const shard of allShards) {
|
|
50
48
|
const db = connectionManager.getConnection(shard.dbPath);
|
|
@@ -63,19 +61,15 @@ export async function handleListTags() {
|
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
}
|
|
66
|
-
const userTags = [];
|
|
67
64
|
const projectTags = [];
|
|
68
65
|
for (const tagInfo of tagsMap.values()) {
|
|
69
|
-
if (tagInfo.tag.includes("
|
|
70
|
-
userTags.push(tagInfo);
|
|
71
|
-
}
|
|
72
|
-
else if (tagInfo.tag.includes("_project_")) {
|
|
66
|
+
if (tagInfo.tag.includes("_project_")) {
|
|
73
67
|
projectTags.push(tagInfo);
|
|
74
68
|
}
|
|
75
69
|
}
|
|
76
70
|
return {
|
|
77
71
|
success: true,
|
|
78
|
-
data: {
|
|
72
|
+
data: { project: projectTags },
|
|
79
73
|
};
|
|
80
74
|
}
|
|
81
75
|
catch (error) {
|
|
@@ -83,7 +77,7 @@ export async function handleListTags() {
|
|
|
83
77
|
return { success: false, error: String(error) };
|
|
84
78
|
}
|
|
85
79
|
}
|
|
86
|
-
export async function handleListMemories(tag, page = 1, pageSize = 20,
|
|
80
|
+
export async function handleListMemories(tag, page = 1, pageSize = 20, includePrompts = true) {
|
|
87
81
|
try {
|
|
88
82
|
await embeddingService.warmup();
|
|
89
83
|
let allMemories = [];
|
|
@@ -96,22 +90,12 @@ export async function handleListMemories(tag, page = 1, pageSize = 20, scope, in
|
|
|
96
90
|
allMemories.push(...memories);
|
|
97
91
|
}
|
|
98
92
|
}
|
|
99
|
-
else
|
|
100
|
-
const shards = shardManager.getAllShards(
|
|
93
|
+
else {
|
|
94
|
+
const shards = shardManager.getAllShards("project", "");
|
|
101
95
|
for (const shard of shards) {
|
|
102
96
|
const db = connectionManager.getConnection(shard.dbPath);
|
|
103
97
|
const memories = vectorSearch.getAllMemories(db);
|
|
104
|
-
allMemories.push(...memories.filter((m) => m.container_tag?.includes(`
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
const userShards = shardManager.getAllShards("user", "");
|
|
109
|
-
const projectShards = shardManager.getAllShards("project", "");
|
|
110
|
-
const allShards = [...userShards, ...projectShards];
|
|
111
|
-
for (const shard of allShards) {
|
|
112
|
-
const db = connectionManager.getConnection(shard.dbPath);
|
|
113
|
-
const memories = vectorSearch.getAllMemories(db);
|
|
114
|
-
allMemories.push(...memories);
|
|
98
|
+
allMemories.push(...memories.filter((m) => m.container_tag?.includes(`_project_`)));
|
|
115
99
|
}
|
|
116
100
|
}
|
|
117
101
|
const memoriesWithType = allMemories.map((r) => {
|
|
@@ -121,7 +105,6 @@ export async function handleListMemories(tag, page = 1, pageSize = 20, scope, in
|
|
|
121
105
|
id: r.id,
|
|
122
106
|
content: r.content,
|
|
123
107
|
memoryType: r.type,
|
|
124
|
-
scope: r.container_tag?.includes("_user_") ? "user" : "project",
|
|
125
108
|
createdAt: Number(r.created_at),
|
|
126
109
|
updatedAt: r.updated_at ? Number(r.updated_at) : undefined,
|
|
127
110
|
metadata,
|
|
@@ -136,7 +119,7 @@ export async function handleListMemories(tag, page = 1, pageSize = 20, scope, in
|
|
|
136
119
|
};
|
|
137
120
|
});
|
|
138
121
|
let timeline = memoriesWithType;
|
|
139
|
-
if (includePrompts
|
|
122
|
+
if (includePrompts) {
|
|
140
123
|
const prompts = userPromptManager.getCapturedPrompts(tag);
|
|
141
124
|
const promptsWithType = prompts.map((p) => ({
|
|
142
125
|
type: "prompt",
|
|
@@ -149,7 +132,40 @@ export async function handleListMemories(tag, page = 1, pageSize = 20, scope, in
|
|
|
149
132
|
}));
|
|
150
133
|
timeline = [...memoriesWithType, ...promptsWithType];
|
|
151
134
|
}
|
|
152
|
-
|
|
135
|
+
const linkedPairs = new Map();
|
|
136
|
+
const standalone = [];
|
|
137
|
+
for (const item of timeline) {
|
|
138
|
+
if (item.type === "memory" && item.linkedPromptId) {
|
|
139
|
+
if (!linkedPairs.has(item.linkedPromptId)) {
|
|
140
|
+
linkedPairs.set(item.linkedPromptId, { memory: item, prompt: null });
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
linkedPairs.get(item.linkedPromptId).memory = item;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (item.type === "prompt" && item.linkedMemoryId) {
|
|
147
|
+
if (!linkedPairs.has(item.id)) {
|
|
148
|
+
linkedPairs.set(item.id, { memory: null, prompt: item });
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
linkedPairs.get(item.id).prompt = item;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
standalone.push(item);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const sortedTimeline = [];
|
|
159
|
+
const pairs = Array.from(linkedPairs.values())
|
|
160
|
+
.filter((p) => p.memory && p.prompt)
|
|
161
|
+
.sort((a, b) => b.memory.createdAt - a.memory.createdAt);
|
|
162
|
+
for (const pair of pairs) {
|
|
163
|
+
sortedTimeline.push(pair.memory);
|
|
164
|
+
sortedTimeline.push(pair.prompt);
|
|
165
|
+
}
|
|
166
|
+
standalone.sort((a, b) => b.createdAt - a.createdAt);
|
|
167
|
+
sortedTimeline.push(...standalone);
|
|
168
|
+
timeline = sortedTimeline;
|
|
153
169
|
const total = timeline.length;
|
|
154
170
|
const totalPages = Math.ceil(total / pageSize);
|
|
155
171
|
const offset = (page - 1) * pageSize;
|
|
@@ -161,7 +177,6 @@ export async function handleListMemories(tag, page = 1, pageSize = 20, scope, in
|
|
|
161
177
|
id: item.id,
|
|
162
178
|
content: item.content,
|
|
163
179
|
memoryType: item.memoryType,
|
|
164
|
-
scope: item.scope,
|
|
165
180
|
createdAt: safeToISOString(item.createdAt),
|
|
166
181
|
updatedAt: item.updatedAt ? safeToISOString(item.updatedAt) : undefined,
|
|
167
182
|
metadata: item.metadata,
|
|
@@ -247,9 +262,8 @@ export async function handleDeleteMemory(id, cascade = false) {
|
|
|
247
262
|
if (!id) {
|
|
248
263
|
return { success: false, error: "id is required" };
|
|
249
264
|
}
|
|
250
|
-
const userShards = shardManager.getAllShards("user", "");
|
|
251
265
|
const projectShards = shardManager.getAllShards("project", "");
|
|
252
|
-
const allShards = [...
|
|
266
|
+
const allShards = [...projectShards];
|
|
253
267
|
let deletedPrompt = false;
|
|
254
268
|
for (const shard of allShards) {
|
|
255
269
|
const db = connectionManager.getConnection(shard.dbPath);
|
|
@@ -300,9 +314,8 @@ export async function handleUpdateMemory(id, data) {
|
|
|
300
314
|
return { success: false, error: "id is required" };
|
|
301
315
|
}
|
|
302
316
|
await embeddingService.warmup();
|
|
303
|
-
const userShards = shardManager.getAllShards("user", "");
|
|
304
317
|
const projectShards = shardManager.getAllShards("project", "");
|
|
305
|
-
const allShards = [...
|
|
318
|
+
const allShards = [...projectShards];
|
|
306
319
|
let foundShard = null;
|
|
307
320
|
let existingMemory = null;
|
|
308
321
|
for (const shard of allShards) {
|
|
@@ -369,9 +382,8 @@ export async function handleSearch(query, tag, page = 1, pageSize = 20) {
|
|
|
369
382
|
}
|
|
370
383
|
}
|
|
371
384
|
else {
|
|
372
|
-
const userShards = shardManager.getAllShards("user", "");
|
|
373
385
|
const projectShards = shardManager.getAllShards("project", "");
|
|
374
|
-
const allShards = [...
|
|
386
|
+
const allShards = [...projectShards];
|
|
375
387
|
const uniqueTags = new Set();
|
|
376
388
|
for (const shard of allShards) {
|
|
377
389
|
const db = connectionManager.getConnection(shard.dbPath);
|
|
@@ -405,7 +417,6 @@ export async function handleSearch(query, tag, page = 1, pageSize = 20) {
|
|
|
405
417
|
id: r.id,
|
|
406
418
|
content: r.memory,
|
|
407
419
|
type: r.metadata?.type,
|
|
408
|
-
scope: r.containerTag?.includes("_user_") ? "user" : "project",
|
|
409
420
|
createdAt: safeToISOString(r.metadata?.createdAt),
|
|
410
421
|
updatedAt: r.metadata?.updatedAt ? safeToISOString(r.metadata.updatedAt) : undefined,
|
|
411
422
|
similarity: Math.round(r.similarity * 100),
|
|
@@ -437,9 +448,8 @@ export async function handleSearch(query, tag, page = 1, pageSize = 20) {
|
|
|
437
448
|
export async function handleStats() {
|
|
438
449
|
try {
|
|
439
450
|
await embeddingService.warmup();
|
|
440
|
-
const userShards = shardManager.getAllShards("user", "");
|
|
441
451
|
const projectShards = shardManager.getAllShards("project", "");
|
|
442
|
-
const allShards = [...
|
|
452
|
+
const allShards = [...projectShards];
|
|
443
453
|
let userCount = 0;
|
|
444
454
|
let projectCount = 0;
|
|
445
455
|
const typeCount = {};
|
|
@@ -477,9 +487,8 @@ export async function handlePinMemory(id) {
|
|
|
477
487
|
if (!id) {
|
|
478
488
|
return { success: false, error: "id is required" };
|
|
479
489
|
}
|
|
480
|
-
const userShards = shardManager.getAllShards("user", "");
|
|
481
490
|
const projectShards = shardManager.getAllShards("project", "");
|
|
482
|
-
const allShards = [...
|
|
491
|
+
const allShards = [...projectShards];
|
|
483
492
|
for (const shard of allShards) {
|
|
484
493
|
const db = connectionManager.getConnection(shard.dbPath);
|
|
485
494
|
const memory = vectorSearch.getMemoryById(db, id);
|
|
@@ -500,9 +509,8 @@ export async function handleUnpinMemory(id) {
|
|
|
500
509
|
if (!id) {
|
|
501
510
|
return { success: false, error: "id is required" };
|
|
502
511
|
}
|
|
503
|
-
const userShards = shardManager.getAllShards("user", "");
|
|
504
512
|
const projectShards = shardManager.getAllShards("project", "");
|
|
505
|
-
const allShards = [...
|
|
513
|
+
const allShards = [...projectShards];
|
|
506
514
|
for (const shard of allShards) {
|
|
507
515
|
const db = connectionManager.getConnection(shard.dbPath);
|
|
508
516
|
const memory = vectorSearch.getMemoryById(db, id);
|
|
@@ -605,3 +613,118 @@ export async function handleBulkDeletePrompts(ids, cascade = false) {
|
|
|
605
613
|
return { success: false, error: String(error) };
|
|
606
614
|
}
|
|
607
615
|
}
|
|
616
|
+
export async function handleGetUserProfile(userId) {
|
|
617
|
+
try {
|
|
618
|
+
const { userProfileManager } = await import("./user-profile/user-profile-manager.js");
|
|
619
|
+
const { getTags } = await import("./tags.js");
|
|
620
|
+
let targetUserId = userId;
|
|
621
|
+
if (!targetUserId) {
|
|
622
|
+
const tags = getTags(process.cwd());
|
|
623
|
+
targetUserId = tags.user.userEmail || "unknown";
|
|
624
|
+
}
|
|
625
|
+
const profile = userProfileManager.getActiveProfile(targetUserId);
|
|
626
|
+
if (!profile) {
|
|
627
|
+
return {
|
|
628
|
+
success: true,
|
|
629
|
+
data: {
|
|
630
|
+
exists: false,
|
|
631
|
+
userId: targetUserId,
|
|
632
|
+
message: "No profile found. Keep chatting to build your profile.",
|
|
633
|
+
},
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
const profileData = JSON.parse(profile.profileData);
|
|
637
|
+
return {
|
|
638
|
+
success: true,
|
|
639
|
+
data: {
|
|
640
|
+
exists: true,
|
|
641
|
+
id: profile.id,
|
|
642
|
+
userId: profile.userId,
|
|
643
|
+
displayName: profile.displayName,
|
|
644
|
+
userName: profile.userName,
|
|
645
|
+
userEmail: profile.userEmail,
|
|
646
|
+
version: profile.version,
|
|
647
|
+
createdAt: safeToISOString(profile.createdAt),
|
|
648
|
+
lastAnalyzedAt: safeToISOString(profile.lastAnalyzedAt),
|
|
649
|
+
totalPromptsAnalyzed: profile.totalPromptsAnalyzed,
|
|
650
|
+
profileData,
|
|
651
|
+
},
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
catch (error) {
|
|
655
|
+
log("handleGetUserProfile: error", { error: String(error) });
|
|
656
|
+
return { success: false, error: String(error) };
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
export async function handleGetProfileChangelog(profileId, limit = 5) {
|
|
660
|
+
try {
|
|
661
|
+
if (!profileId) {
|
|
662
|
+
return { success: false, error: "profileId is required" };
|
|
663
|
+
}
|
|
664
|
+
const { userProfileManager } = await import("./user-profile/user-profile-manager.js");
|
|
665
|
+
const changelogs = userProfileManager.getProfileChangelogs(profileId, limit);
|
|
666
|
+
const formattedChangelogs = changelogs.map((c) => ({
|
|
667
|
+
id: c.id,
|
|
668
|
+
profileId: c.profileId,
|
|
669
|
+
version: c.version,
|
|
670
|
+
changeType: c.changeType,
|
|
671
|
+
changeSummary: c.changeSummary,
|
|
672
|
+
createdAt: safeToISOString(c.createdAt),
|
|
673
|
+
}));
|
|
674
|
+
return { success: true, data: formattedChangelogs };
|
|
675
|
+
}
|
|
676
|
+
catch (error) {
|
|
677
|
+
log("handleGetProfileChangelog: error", { error: String(error) });
|
|
678
|
+
return { success: false, error: String(error) };
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
export async function handleGetProfileSnapshot(changelogId) {
|
|
682
|
+
try {
|
|
683
|
+
if (!changelogId) {
|
|
684
|
+
return { success: false, error: "changelogId is required" };
|
|
685
|
+
}
|
|
686
|
+
const { userProfileManager } = await import("./user-profile/user-profile-manager.js");
|
|
687
|
+
const changelogs = userProfileManager.getProfileChangelogs("", 1000);
|
|
688
|
+
const changelog = changelogs.find((c) => c.id === changelogId);
|
|
689
|
+
if (!changelog) {
|
|
690
|
+
return { success: false, error: "Changelog not found" };
|
|
691
|
+
}
|
|
692
|
+
const profileData = JSON.parse(changelog.profileDataSnapshot);
|
|
693
|
+
return {
|
|
694
|
+
success: true,
|
|
695
|
+
data: {
|
|
696
|
+
version: changelog.version,
|
|
697
|
+
createdAt: safeToISOString(changelog.createdAt),
|
|
698
|
+
profileData,
|
|
699
|
+
},
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
catch (error) {
|
|
703
|
+
log("handleGetProfileSnapshot: error", { error: String(error) });
|
|
704
|
+
return { success: false, error: String(error) };
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
export async function handleRefreshProfile(userId) {
|
|
708
|
+
try {
|
|
709
|
+
const { getTags } = await import("./tags.js");
|
|
710
|
+
const { userPromptManager } = await import("./user-prompt/user-prompt-manager.js");
|
|
711
|
+
let targetUserId = userId;
|
|
712
|
+
if (!targetUserId) {
|
|
713
|
+
const tags = getTags(process.cwd());
|
|
714
|
+
targetUserId = tags.user.userEmail || "unknown";
|
|
715
|
+
}
|
|
716
|
+
const unanalyzedCount = userPromptManager.countUnanalyzedForUserLearning();
|
|
717
|
+
return {
|
|
718
|
+
success: true,
|
|
719
|
+
data: {
|
|
720
|
+
message: "Profile refresh queued",
|
|
721
|
+
unanalyzedPrompts: unanalyzedCount,
|
|
722
|
+
note: "Profile will be updated when threshold is reached",
|
|
723
|
+
},
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
catch (error) {
|
|
727
|
+
log("handleRefreshProfile: error", { error: String(error) });
|
|
728
|
+
return { success: false, error: String(error) };
|
|
729
|
+
}
|
|
730
|
+
}
|
|
@@ -37,7 +37,7 @@ export async function performAutoCapture(ctx, sessionID, directory) {
|
|
|
37
37
|
const tags = getTags(directory);
|
|
38
38
|
const latestMemory = await getLatestProjectMemory(tags.project.tag);
|
|
39
39
|
const context = buildMarkdownContext(prompt.content, textResponses, toolCalls, latestMemory);
|
|
40
|
-
const summaryResult = await generateSummary(
|
|
40
|
+
const summaryResult = await generateSummary(context, sessionID);
|
|
41
41
|
if (!summaryResult || summaryResult.type === "skip") {
|
|
42
42
|
log("Auto-capture: skipped non-technical conversation", { sessionID });
|
|
43
43
|
userPromptManager.deletePrompt(prompt.id);
|
|
@@ -179,7 +179,7 @@ function buildMarkdownContext(userPrompt, textResponses, toolCalls, latestMemory
|
|
|
179
179
|
}
|
|
180
180
|
return sections.join("\n");
|
|
181
181
|
}
|
|
182
|
-
async function generateSummary(
|
|
182
|
+
async function generateSummary(context, sessionID) {
|
|
183
183
|
if (!CONFIG.memoryModel || !CONFIG.memoryApiUrl || !CONFIG.memoryApiKey) {
|
|
184
184
|
throw new Error("External API not configured for auto-capture");
|
|
185
185
|
}
|
|
@@ -6,6 +6,6 @@ interface MemoryResultMinimal {
|
|
|
6
6
|
interface MemoriesResponseMinimal {
|
|
7
7
|
results?: MemoryResultMinimal[];
|
|
8
8
|
}
|
|
9
|
-
export declare function formatContextForPrompt(userId: string | null,
|
|
9
|
+
export declare function formatContextForPrompt(userId: string | null, projectMemories: MemoriesResponseMinimal): string;
|
|
10
10
|
export {};
|
|
11
11
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/services/context.ts"],"names":[],"mappings":"AAGA,UAAU,mBAAmB;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/services/context.ts"],"names":[],"mappings":"AAGA,UAAU,mBAAmB;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,eAAe,EAAE,uBAAuB,GACvC,MAAM,CAyBR"}
|
package/dist/services/context.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CONFIG } from "../config.js";
|
|
2
2
|
import { getUserProfileContext } from "./user-profile/profile-context.js";
|
|
3
|
-
export function formatContextForPrompt(userId,
|
|
3
|
+
export function formatContextForPrompt(userId, projectMemories) {
|
|
4
4
|
const parts = ["[MEMORY]"];
|
|
5
5
|
if (CONFIG.injectProfile && userId) {
|
|
6
6
|
const profileContext = getUserProfileContext(userId);
|
|
@@ -17,15 +17,6 @@ export function formatContextForPrompt(userId, userMemories, projectMemories) {
|
|
|
17
17
|
parts.push(`- [${similarity}%] ${content}`);
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
|
-
const userResults = userMemories.results || [];
|
|
21
|
-
if (userResults.length > 0) {
|
|
22
|
-
parts.push("\nRelevant Memories:");
|
|
23
|
-
userResults.forEach((mem) => {
|
|
24
|
-
const similarity = Math.round(mem.similarity * 100);
|
|
25
|
-
const content = mem.memory || mem.chunk || "";
|
|
26
|
-
parts.push(`- [${similarity}%] ${content}`);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
20
|
if (parts.length === 1) {
|
|
30
21
|
return "";
|
|
31
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deduplication-service.d.ts","sourceRoot":"","sources":["../../src/services/deduplication-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deduplication-service.d.ts","sourceRoot":"","sources":["../../src/services/deduplication-service.ts"],"names":[],"mappings":"AAMA,UAAU,cAAc;IACtB,cAAc,EAAE;QACd,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,UAAU,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ;AAED,UAAU,mBAAmB;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,mBAAmB,EAAE,cAAc,EAAE,CAAC;CACvC;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,SAAS,CAAkB;IAE7B,yBAAyB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IA+G/D,OAAO,CAAC,gBAAgB;IAoBxB,SAAS;;;;;CAOV;AAED,eAAO,MAAM,oBAAoB,sBAA6B,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { embeddingService } from "./embedding.js";
|
|
2
1
|
import { shardManager } from "./sqlite/shard-manager.js";
|
|
3
2
|
import { vectorSearch } from "./sqlite/vector-search.js";
|
|
4
3
|
import { connectionManager } from "./sqlite/connection-manager.js";
|
|
@@ -34,10 +33,9 @@ export class DeduplicationService {
|
|
|
34
33
|
}
|
|
35
34
|
contentMap.get(key).push(memory);
|
|
36
35
|
}
|
|
37
|
-
for (const [
|
|
36
|
+
for (const [, duplicates] of contentMap) {
|
|
38
37
|
if (duplicates.length > 1) {
|
|
39
38
|
duplicates.sort((a, b) => Number(b.created_at) - Number(a.created_at));
|
|
40
|
-
const keep = duplicates[0];
|
|
41
39
|
const toDelete = duplicates.slice(1);
|
|
42
40
|
for (const dup of toDelete) {
|
|
43
41
|
try {
|
package/dist/services/logger.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { appendFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
2
2
|
import { homedir } from "os";
|
|
3
|
-
import { join
|
|
3
|
+
import { join } from "path";
|
|
4
4
|
const LOG_DIR = join(homedir(), ".opencode-mem");
|
|
5
5
|
const LOG_FILE = join(LOG_DIR, "opencode-mem.log");
|
|
6
6
|
if (!existsSync(LOG_DIR)) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function performUserProfileLearning(ctx: PluginInput, directory: string): Promise<void>;
|
|
3
3
|
//# sourceMappingURL=user-memory-learning.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-memory-learning.d.ts","sourceRoot":"","sources":["../../src/services/user-memory-learning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AASvD,wBAAsB,
|
|
1
|
+
{"version":3,"file":"user-memory-learning.d.ts","sourceRoot":"","sources":["../../src/services/user-memory-learning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AASvD,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA8Ef"}
|
|
@@ -3,10 +3,10 @@ import { log } from "./logger.js";
|
|
|
3
3
|
import { CONFIG } from "../config.js";
|
|
4
4
|
import { userPromptManager } from "./user-prompt/user-prompt-manager.js";
|
|
5
5
|
import { userProfileManager } from "./user-profile/user-profile-manager.js";
|
|
6
|
-
export async function
|
|
6
|
+
export async function performUserProfileLearning(ctx, directory) {
|
|
7
7
|
try {
|
|
8
8
|
const count = userPromptManager.countUnanalyzedForUserLearning();
|
|
9
|
-
const threshold = CONFIG.
|
|
9
|
+
const threshold = CONFIG.userProfileAnalysisInterval;
|
|
10
10
|
if (count < threshold) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
@@ -135,7 +135,9 @@ Use the update_user_profile tool to save the ${existingProfile ? "updated" : "ne
|
|
|
135
135
|
type: "function",
|
|
136
136
|
function: {
|
|
137
137
|
name: "update_user_profile",
|
|
138
|
-
description: existingProfile
|
|
138
|
+
description: existingProfile
|
|
139
|
+
? "Update existing user profile with new insights"
|
|
140
|
+
: "Create new user profile",
|
|
139
141
|
parameters: {
|
|
140
142
|
type: "object",
|
|
141
143
|
properties: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-profile-manager.d.ts","sourceRoot":"","sources":["../../../src/services/user-profile/user-profile-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"user-profile-manager.d.ts","sourceRoot":"","sources":["../../../src/services/user-profile/user-profile-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIrF,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAQhC,OAAO,CAAC,YAAY;IA0CpB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAapD,aAAa,CACX,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,eAAe,EAC5B,eAAe,EAAE,MAAM,GACtB,MAAM;IA8BT,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,eAAe,EAC5B,yBAAyB,EAAE,MAAM,EACjC,aAAa,EAAE,MAAM,GACpB,IAAI;IA6BP,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,oBAAoB;IAiB5B,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,oBAAoB,EAAE;IAYnF,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IA2B7C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKtC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAOrD,oBAAoB,IAAI,WAAW,EAAE;IAMrC,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,cAAc;IAYtB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe;CAyFhG;AAED,eAAO,MAAM,kBAAkB,oBAA2B,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { join, dirname } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { handleListTags, handleListMemories, handleAddMemory, handleDeleteMemory, handleBulkDelete, handleUpdateMemory, handleSearch, handleStats, handlePinMemory, handleUnpinMemory, handleRunCleanup, handleRunDeduplication, handleDetectMigration, handleRunMigration, handleDeletePrompt, handleBulkDeletePrompts, } from "./api-handlers.js";
|
|
4
|
+
import { handleListTags, handleListMemories, handleAddMemory, handleDeleteMemory, handleBulkDelete, handleUpdateMemory, handleSearch, handleStats, handlePinMemory, handleUnpinMemory, handleRunCleanup, handleRunDeduplication, handleDetectMigration, handleRunMigration, handleDeletePrompt, handleBulkDeletePrompts, handleGetUserProfile, handleGetProfileChangelog, handleGetProfileSnapshot, handleRefreshProfile, } from "./api-handlers.js";
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = dirname(__filename);
|
|
7
7
|
let server = null;
|
|
@@ -30,9 +30,8 @@ async function handleRequest(req) {
|
|
|
30
30
|
const tag = url.searchParams.get("tag") || undefined;
|
|
31
31
|
const page = parseInt(url.searchParams.get("page") || "1");
|
|
32
32
|
const pageSize = parseInt(url.searchParams.get("pageSize") || "20");
|
|
33
|
-
const scope = url.searchParams.get("scope");
|
|
34
33
|
const includePrompts = url.searchParams.get("includePrompts") !== "false";
|
|
35
|
-
const result = await handleListMemories(tag, page, pageSize,
|
|
34
|
+
const result = await handleListMemories(tag, page, pageSize, includePrompts);
|
|
36
35
|
return jsonResponse(result);
|
|
37
36
|
}
|
|
38
37
|
if (path === "/api/memories" && method === "POST") {
|
|
@@ -133,6 +132,34 @@ async function handleRequest(req) {
|
|
|
133
132
|
const result = await handleBulkDeletePrompts(body.ids || [], cascade);
|
|
134
133
|
return jsonResponse(result);
|
|
135
134
|
}
|
|
135
|
+
if (path === "/api/user-profile" && method === "GET") {
|
|
136
|
+
const userId = url.searchParams.get("userId") || undefined;
|
|
137
|
+
const result = await handleGetUserProfile(userId);
|
|
138
|
+
return jsonResponse(result);
|
|
139
|
+
}
|
|
140
|
+
if (path === "/api/user-profile/changelog" && method === "GET") {
|
|
141
|
+
const profileId = url.searchParams.get("profileId");
|
|
142
|
+
const limit = parseInt(url.searchParams.get("limit") || "5");
|
|
143
|
+
if (!profileId) {
|
|
144
|
+
return jsonResponse({ success: false, error: "profileId parameter required" });
|
|
145
|
+
}
|
|
146
|
+
const result = await handleGetProfileChangelog(profileId, limit);
|
|
147
|
+
return jsonResponse(result);
|
|
148
|
+
}
|
|
149
|
+
if (path === "/api/user-profile/snapshot" && method === "GET") {
|
|
150
|
+
const changelogId = url.searchParams.get("chlogId");
|
|
151
|
+
if (!changelogId) {
|
|
152
|
+
return jsonResponse({ success: false, error: "changelogId parameter required" });
|
|
153
|
+
}
|
|
154
|
+
const result = await handleGetProfileSnapshot(changelogId);
|
|
155
|
+
return jsonResponse(result);
|
|
156
|
+
}
|
|
157
|
+
if (path === "/api/user-profile/refresh" && method === "POST") {
|
|
158
|
+
const body = (await req.json().catch(() => ({})));
|
|
159
|
+
const userId = body.userId || undefined;
|
|
160
|
+
const result = await handleRefreshProfile(userId);
|
|
161
|
+
return jsonResponse(result);
|
|
162
|
+
}
|
|
136
163
|
return new Response("Not Found", { status: 404 });
|
|
137
164
|
}
|
|
138
165
|
catch (error) {
|