opencode-mem 2.3.7 → 2.5.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 +15 -19
- package/dist/config.d.ts +4 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +33 -39
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -82
- package/dist/services/ai/validators/user-profile-validator.d.ts +0 -1
- package/dist/services/ai/validators/user-profile-validator.d.ts.map +1 -1
- package/dist/services/ai/validators/user-profile-validator.js +0 -17
- package/dist/services/api-handlers.d.ts +32 -3
- package/dist/services/api-handlers.d.ts.map +1 -1
- package/dist/services/api-handlers.js +89 -13
- package/dist/services/auto-capture.d.ts.map +1 -1
- package/dist/services/auto-capture.js +34 -34
- package/dist/services/language-detector.d.ts +3 -0
- package/dist/services/language-detector.d.ts.map +1 -0
- package/dist/services/language-detector.js +16 -0
- package/dist/services/secret-resolver.d.ts +2 -0
- package/dist/services/secret-resolver.d.ts.map +1 -0
- package/dist/services/secret-resolver.js +55 -0
- package/dist/services/user-memory-learning.d.ts.map +1 -1
- package/dist/services/user-memory-learning.js +27 -33
- package/dist/services/user-profile/types.d.ts +0 -5
- package/dist/services/user-profile/types.d.ts.map +1 -1
- package/dist/services/user-profile/user-profile-manager.d.ts.map +1 -1
- package/dist/services/user-profile/user-profile-manager.js +0 -7
- package/dist/services/user-prompt/user-prompt-manager.d.ts +2 -0
- package/dist/services/user-prompt/user-prompt-manager.d.ts.map +1 -1
- package/dist/services/user-prompt/user-prompt-manager.js +21 -0
- package/dist/web/app.js +191 -112
- package/dist/web/styles.css +202 -122
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -55,35 +55,31 @@ Configure at `~/.config/opencode/opencode-mem.jsonc`:
|
|
|
55
55
|
"embeddingModel": "Xenova/nomic-embed-text-v1",
|
|
56
56
|
"webServerEnabled": true,
|
|
57
57
|
"webServerPort": 4747,
|
|
58
|
+
|
|
58
59
|
"autoCaptureEnabled": true,
|
|
60
|
+
"autoCaptureLanguage": "auto",
|
|
59
61
|
"memoryProvider": "openai-chat",
|
|
60
|
-
"memoryModel": "gpt-
|
|
62
|
+
"memoryModel": "gpt-4o-mini",
|
|
63
|
+
"memoryApiUrl": "https://api.openai.com/v1",
|
|
64
|
+
"memoryApiKey": "sk-...",
|
|
65
|
+
|
|
66
|
+
"showAutoCaptureToasts": true,
|
|
67
|
+
"showUserProfileToasts": true,
|
|
68
|
+
"showErrorToasts": true,
|
|
69
|
+
|
|
61
70
|
"userProfileAnalysisInterval": 10,
|
|
62
71
|
"maxMemories": 10
|
|
63
72
|
}
|
|
64
73
|
```
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
## Important: v2.3 Breaking Changes
|
|
69
|
-
|
|
70
|
-
User-scoped memories removed. All memories now project-scoped. Update configuration:
|
|
71
|
-
|
|
75
|
+
**API Key Formats:**
|
|
72
76
|
```jsonc
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
"maxProjectMemories": 10
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// NEW: Use only
|
|
80
|
-
{
|
|
81
|
-
"userProfileAnalysisInterval": 10,
|
|
82
|
-
"maxMemories": 10
|
|
83
|
-
}
|
|
77
|
+
"memoryApiKey": "sk-..."
|
|
78
|
+
"memoryApiKey": "file://~/.config/opencode/api-key.txt"
|
|
79
|
+
"memoryApiKey": "env://OPENAI_API_KEY"
|
|
84
80
|
```
|
|
85
81
|
|
|
86
|
-
|
|
82
|
+
Full documentation available in our [Configuration Guide](https://github.com/tickernelz/opencode-mem/wiki/Configuration-Guide).
|
|
87
83
|
|
|
88
84
|
## Documentation
|
|
89
85
|
|
package/dist/config.d.ts
CHANGED
|
@@ -10,10 +10,10 @@ export declare const CONFIG: {
|
|
|
10
10
|
maxProfileItems: number;
|
|
11
11
|
injectProfile: boolean;
|
|
12
12
|
containerTagPrefix: string;
|
|
13
|
-
keywordPatterns: string[];
|
|
14
13
|
autoCaptureEnabled: boolean;
|
|
15
14
|
autoCaptureMaxIterations: number;
|
|
16
15
|
autoCaptureIterationTimeout: number;
|
|
16
|
+
autoCaptureLanguage: string | undefined;
|
|
17
17
|
memoryProvider: "openai-chat" | "openai-responses" | "anthropic";
|
|
18
18
|
memoryModel: string | undefined;
|
|
19
19
|
memoryApiUrl: string | undefined;
|
|
@@ -33,6 +33,9 @@ export declare const CONFIG: {
|
|
|
33
33
|
userProfileMaxWorkflows: number;
|
|
34
34
|
userProfileConfidenceDecayDays: number;
|
|
35
35
|
userProfileChangelogRetentionCount: number;
|
|
36
|
+
showAutoCaptureToasts: boolean;
|
|
37
|
+
showUserProfileToasts: boolean;
|
|
38
|
+
showErrorToasts: boolean;
|
|
36
39
|
};
|
|
37
40
|
export declare function isConfigured(): boolean;
|
|
38
41
|
//# 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":"AAuXA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;oBAyBb,aAAa,GACb,kBAAkB,GAClB,WAAW;;;;;;;;;;;;;;;;;;;;;;CA4BhB,CAAC;AAEF,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
|
package/dist/config.js
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { stripJsoncComments } from "./services/jsonc.js";
|
|
5
|
+
import { resolveSecretValue } from "./services/secret-resolver.js";
|
|
5
6
|
const CONFIG_DIR = join(homedir(), ".config", "opencode");
|
|
6
7
|
const DATA_DIR = join(homedir(), ".opencode-mem");
|
|
7
8
|
const CONFIG_FILES = [
|
|
@@ -14,24 +15,6 @@ if (!existsSync(CONFIG_DIR)) {
|
|
|
14
15
|
if (!existsSync(DATA_DIR)) {
|
|
15
16
|
mkdirSync(DATA_DIR, { recursive: true });
|
|
16
17
|
}
|
|
17
|
-
const DEFAULT_KEYWORD_PATTERNS = [
|
|
18
|
-
"remember",
|
|
19
|
-
"memorize",
|
|
20
|
-
"save\\s+this",
|
|
21
|
-
"note\\s+this",
|
|
22
|
-
"keep\\s+in\\s+mind",
|
|
23
|
-
"don'?t\\s+forget",
|
|
24
|
-
"learn\\s+this",
|
|
25
|
-
"store\\s+this",
|
|
26
|
-
"record\\s+this",
|
|
27
|
-
"make\\s+a\\s+note",
|
|
28
|
-
"take\\s+note",
|
|
29
|
-
"jot\\s+down",
|
|
30
|
-
"commit\\s+to\\s+memory",
|
|
31
|
-
"remember\\s+that",
|
|
32
|
-
"never\\s+forget",
|
|
33
|
-
"always\\s+remember",
|
|
34
|
-
];
|
|
35
18
|
const DEFAULTS = {
|
|
36
19
|
storagePath: join(DATA_DIR, "data"),
|
|
37
20
|
embeddingModel: "Xenova/nomic-embed-text-v1",
|
|
@@ -41,7 +24,6 @@ const DEFAULTS = {
|
|
|
41
24
|
maxProfileItems: 5,
|
|
42
25
|
injectProfile: true,
|
|
43
26
|
containerTagPrefix: "opencode",
|
|
44
|
-
keywordPatterns: [],
|
|
45
27
|
autoCaptureEnabled: true,
|
|
46
28
|
autoCaptureMaxIterations: 5,
|
|
47
29
|
autoCaptureIterationTimeout: 30000,
|
|
@@ -60,16 +42,10 @@ const DEFAULTS = {
|
|
|
60
42
|
userProfileMaxWorkflows: 10,
|
|
61
43
|
userProfileConfidenceDecayDays: 30,
|
|
62
44
|
userProfileChangelogRetentionCount: 5,
|
|
45
|
+
showAutoCaptureToasts: true,
|
|
46
|
+
showUserProfileToasts: true,
|
|
47
|
+
showErrorToasts: true,
|
|
63
48
|
};
|
|
64
|
-
function isValidRegex(pattern) {
|
|
65
|
-
try {
|
|
66
|
-
new RegExp(pattern);
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
49
|
function expandPath(path) {
|
|
74
50
|
if (path.startsWith("~/")) {
|
|
75
51
|
return join(homedir(), path.slice(2));
|
|
@@ -186,6 +162,11 @@ const CONFIG_TEMPLATE = `{
|
|
|
186
162
|
"memoryModel": "gpt-4o-mini",
|
|
187
163
|
"memoryApiUrl": "https://api.openai.com/v1",
|
|
188
164
|
"memoryApiKey": "sk-...",
|
|
165
|
+
|
|
166
|
+
// API Key Formats:
|
|
167
|
+
// Direct value: "sk-..."
|
|
168
|
+
// From file: "file://~/.config/litellm-key.txt"
|
|
169
|
+
// From env variable: "env://LITELLM_API_KEY"
|
|
189
170
|
|
|
190
171
|
// Examples for different providers:
|
|
191
172
|
// OpenAI Chat Completion (default, backward compatible):
|
|
@@ -221,6 +202,23 @@ const CONFIG_TEMPLATE = `{
|
|
|
221
202
|
// Days to keep AI session history before cleanup
|
|
222
203
|
"aiSessionRetentionDays": 7,
|
|
223
204
|
|
|
205
|
+
// Language for auto-capture summaries (default: "auto" for auto-detection)
|
|
206
|
+
// Options: "auto", "en", "id", "zh", "ja", "es", "fr", "de", "ru", "pt", "ar", "ko"
|
|
207
|
+
// "autoCaptureLanguage": "auto",
|
|
208
|
+
|
|
209
|
+
// ============================================
|
|
210
|
+
// Toast Notifications
|
|
211
|
+
// ============================================
|
|
212
|
+
|
|
213
|
+
// Show toast when memory is auto-captured
|
|
214
|
+
"showAutoCaptureToasts": true,
|
|
215
|
+
|
|
216
|
+
// Show toast when user profile is updated
|
|
217
|
+
"showUserProfileToasts": true,
|
|
218
|
+
|
|
219
|
+
// Show toast for error messages
|
|
220
|
+
"showErrorToasts": true,
|
|
221
|
+
|
|
224
222
|
// ============================================
|
|
225
223
|
// User Profile System
|
|
226
224
|
// ============================================
|
|
@@ -268,11 +266,7 @@ const CONFIG_TEMPLATE = `{
|
|
|
268
266
|
// ============================================
|
|
269
267
|
|
|
270
268
|
// Inject user profile into AI context (preferences, patterns, workflows)
|
|
271
|
-
"injectProfile": true
|
|
272
|
-
|
|
273
|
-
// Additional regex patterns to trigger manual memory capture
|
|
274
|
-
// Default patterns: "remember", "memorize", "save this", "note this", etc.
|
|
275
|
-
"keywordPatterns": []
|
|
269
|
+
"injectProfile": true
|
|
276
270
|
}
|
|
277
271
|
`;
|
|
278
272
|
function ensureConfigExists() {
|
|
@@ -317,24 +311,21 @@ export const CONFIG = {
|
|
|
317
311
|
getEmbeddingDimensions(fileConfig.embeddingModel ?? DEFAULTS.embeddingModel),
|
|
318
312
|
embeddingApiUrl: fileConfig.embeddingApiUrl,
|
|
319
313
|
embeddingApiKey: fileConfig.embeddingApiUrl
|
|
320
|
-
? (fileConfig.embeddingApiKey ?? process.env.OPENAI_API_KEY)
|
|
314
|
+
? resolveSecretValue(fileConfig.embeddingApiKey ?? process.env.OPENAI_API_KEY)
|
|
321
315
|
: undefined,
|
|
322
316
|
similarityThreshold: fileConfig.similarityThreshold ?? DEFAULTS.similarityThreshold,
|
|
323
317
|
maxMemories: fileConfig.maxMemories ?? DEFAULTS.maxMemories,
|
|
324
318
|
maxProfileItems: fileConfig.maxProfileItems ?? DEFAULTS.maxProfileItems,
|
|
325
319
|
injectProfile: fileConfig.injectProfile ?? DEFAULTS.injectProfile,
|
|
326
320
|
containerTagPrefix: fileConfig.containerTagPrefix ?? DEFAULTS.containerTagPrefix,
|
|
327
|
-
keywordPatterns: [
|
|
328
|
-
...DEFAULT_KEYWORD_PATTERNS,
|
|
329
|
-
...(fileConfig.keywordPatterns ?? []).filter(isValidRegex),
|
|
330
|
-
],
|
|
331
321
|
autoCaptureEnabled: fileConfig.autoCaptureEnabled ?? DEFAULTS.autoCaptureEnabled,
|
|
332
322
|
autoCaptureMaxIterations: fileConfig.autoCaptureMaxIterations ?? DEFAULTS.autoCaptureMaxIterations,
|
|
333
323
|
autoCaptureIterationTimeout: fileConfig.autoCaptureIterationTimeout ?? DEFAULTS.autoCaptureIterationTimeout,
|
|
324
|
+
autoCaptureLanguage: fileConfig.autoCaptureLanguage,
|
|
334
325
|
memoryProvider: (fileConfig.memoryProvider ?? "openai-chat"),
|
|
335
326
|
memoryModel: fileConfig.memoryModel,
|
|
336
327
|
memoryApiUrl: fileConfig.memoryApiUrl,
|
|
337
|
-
memoryApiKey: fileConfig.memoryApiKey,
|
|
328
|
+
memoryApiKey: resolveSecretValue(fileConfig.memoryApiKey),
|
|
338
329
|
aiSessionRetentionDays: fileConfig.aiSessionRetentionDays ?? DEFAULTS.aiSessionRetentionDays,
|
|
339
330
|
webServerEnabled: fileConfig.webServerEnabled ?? DEFAULTS.webServerEnabled,
|
|
340
331
|
webServerPort: fileConfig.webServerPort ?? DEFAULTS.webServerPort,
|
|
@@ -350,6 +341,9 @@ export const CONFIG = {
|
|
|
350
341
|
userProfileMaxWorkflows: fileConfig.userProfileMaxWorkflows ?? DEFAULTS.userProfileMaxWorkflows,
|
|
351
342
|
userProfileConfidenceDecayDays: fileConfig.userProfileConfidenceDecayDays ?? DEFAULTS.userProfileConfidenceDecayDays,
|
|
352
343
|
userProfileChangelogRetentionCount: fileConfig.userProfileChangelogRetentionCount ?? DEFAULTS.userProfileChangelogRetentionCount,
|
|
344
|
+
showAutoCaptureToasts: fileConfig.showAutoCaptureToasts ?? DEFAULTS.showAutoCaptureToasts,
|
|
345
|
+
showUserProfileToasts: fileConfig.showUserProfileToasts ?? DEFAULTS.showUserProfileToasts,
|
|
346
|
+
showErrorToasts: fileConfig.showErrorToasts ?? DEFAULTS.showErrorToasts,
|
|
353
347
|
};
|
|
354
348
|
export function isConfigured() {
|
|
355
349
|
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;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAiB/D,eAAO,MAAM,iBAAiB,EAAE,MA6c/B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,30 +9,9 @@ import { userPromptManager } from "./services/user-prompt/user-prompt-manager.js
|
|
|
9
9
|
import { startWebServer, WebServer } from "./services/web-server.js";
|
|
10
10
|
import { isConfigured, CONFIG } from "./config.js";
|
|
11
11
|
import { log } from "./services/logger.js";
|
|
12
|
-
const CODE_BLOCK_PATTERN = /```[\s\S]*?```/g;
|
|
13
|
-
const INLINE_CODE_PATTERN = /`[^`]+`/g;
|
|
14
|
-
const MEMORY_KEYWORD_PATTERN = new RegExp(`\\b(${CONFIG.keywordPatterns.join("|")})\\b`, "i");
|
|
15
|
-
const MEMORY_NUDGE_MESSAGE = `[MEMORY TRIGGER DETECTED]
|
|
16
|
-
The user wants you to remember something. You MUST use the \`memory\` tool with \`mode: "add"\` to save this information.
|
|
17
|
-
|
|
18
|
-
Extract the key information the user wants remembered and save it as a concise, searchable memory.
|
|
19
|
-
- Use \`scope: "project"\` for project-specific knowledge (e.g., "run lint with tests", architecture decisions)
|
|
20
|
-
- Choose an appropriate \`type\`: "preference", "project-config", "learned-pattern", etc.
|
|
21
|
-
|
|
22
|
-
Note: User preferences are automatically learned through the user profile system. Only store project-specific information.
|
|
23
|
-
|
|
24
|
-
DO NOT skip this step. The user explicitly asked you to remember.`;
|
|
25
|
-
function removeCodeBlocks(text) {
|
|
26
|
-
return text.replace(CODE_BLOCK_PATTERN, "").replace(INLINE_CODE_PATTERN, "");
|
|
27
|
-
}
|
|
28
|
-
function detectMemoryKeyword(text) {
|
|
29
|
-
const textWithoutCode = removeCodeBlocks(text);
|
|
30
|
-
return MEMORY_KEYWORD_PATTERN.test(textWithoutCode);
|
|
31
|
-
}
|
|
32
12
|
export const OpenCodeMemPlugin = async (ctx) => {
|
|
33
13
|
const { directory } = ctx;
|
|
34
14
|
const tags = getTags(directory);
|
|
35
|
-
const injectedSessions = new Set();
|
|
36
15
|
let webServer = null;
|
|
37
16
|
if (!isConfigured()) {
|
|
38
17
|
log("Plugin disabled - memory system not configured");
|
|
@@ -129,53 +108,47 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
129
108
|
if (!userMessage.trim())
|
|
130
109
|
return;
|
|
131
110
|
userPromptManager.savePrompt(input.sessionID, output.message.id, directory, userMessage);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
memory: m.summary,
|
|
154
|
-
similarity: 1,
|
|
155
|
-
title: m.title,
|
|
156
|
-
metadata: m.metadata,
|
|
157
|
-
})),
|
|
158
|
-
total: projectMemoriesList.memories?.length || 0,
|
|
159
|
-
timing: 0,
|
|
160
|
-
};
|
|
161
|
-
const userId = tags.user.userEmail || null;
|
|
162
|
-
const memoryContext = formatContextForPrompt(userId, projectMemories);
|
|
163
|
-
if (memoryContext) {
|
|
164
|
-
const contextPart = {
|
|
165
|
-
id: `memory-context-${Date.now()}`,
|
|
166
|
-
sessionID: input.sessionID,
|
|
167
|
-
messageID: output.message.id,
|
|
168
|
-
type: "text",
|
|
169
|
-
text: memoryContext,
|
|
170
|
-
synthetic: true,
|
|
111
|
+
const searchResult = await memoryClient.searchMemories(userMessage, tags.project.tag);
|
|
112
|
+
if (searchResult.success && searchResult.results.length > 0) {
|
|
113
|
+
const relevantMemories = searchResult.results
|
|
114
|
+
.filter((m) => {
|
|
115
|
+
const memorySessionId = m.metadata?.sessionID;
|
|
116
|
+
const isFromOtherSession = memorySessionId !== input.sessionID;
|
|
117
|
+
const isRelevant = m.similarity > 0.65;
|
|
118
|
+
return isFromOtherSession && isRelevant;
|
|
119
|
+
})
|
|
120
|
+
.slice(0, 3);
|
|
121
|
+
if (relevantMemories.length > 0) {
|
|
122
|
+
const projectMemories = {
|
|
123
|
+
results: relevantMemories.map((m) => ({
|
|
124
|
+
id: m.id,
|
|
125
|
+
memory: m.memory,
|
|
126
|
+
similarity: m.similarity,
|
|
127
|
+
title: m.displayName,
|
|
128
|
+
metadata: m.metadata,
|
|
129
|
+
})),
|
|
130
|
+
total: relevantMemories.length,
|
|
131
|
+
timing: 0,
|
|
171
132
|
};
|
|
172
|
-
|
|
133
|
+
const userId = tags.user.userEmail || null;
|
|
134
|
+
const memoryContext = formatContextForPrompt(userId, projectMemories);
|
|
135
|
+
if (memoryContext) {
|
|
136
|
+
const contextPart = {
|
|
137
|
+
id: `memory-context-${Date.now()}`,
|
|
138
|
+
sessionID: input.sessionID,
|
|
139
|
+
messageID: output.message.id,
|
|
140
|
+
type: "text",
|
|
141
|
+
text: memoryContext,
|
|
142
|
+
synthetic: true,
|
|
143
|
+
};
|
|
144
|
+
output.parts.unshift(contextPart);
|
|
145
|
+
}
|
|
173
146
|
}
|
|
174
147
|
}
|
|
175
148
|
}
|
|
176
149
|
catch (error) {
|
|
177
150
|
log("chat.message: ERROR", { error: String(error) });
|
|
178
|
-
if (ctx.client?.tui) {
|
|
151
|
+
if (ctx.client?.tui && CONFIG.showErrorToasts) {
|
|
179
152
|
await ctx.client.tui
|
|
180
153
|
.showToast({
|
|
181
154
|
body: {
|
|
@@ -191,11 +164,9 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
191
164
|
},
|
|
192
165
|
tool: {
|
|
193
166
|
memory: tool({
|
|
194
|
-
description: "Manage and query
|
|
167
|
+
description: "Manage and query local persistent memory. Use 'search' to find relevant memories, 'add' to store new knowledge (MATCH USER LANGUAGE), 'profile' to view user preferences, 'list' to see recent memories, 'forget' to remove a memory.",
|
|
195
168
|
args: {
|
|
196
|
-
mode: tool.schema
|
|
197
|
-
.enum(["add", "search", "profile", "list", "forget", "help", "capture-now"])
|
|
198
|
-
.optional(),
|
|
169
|
+
mode: tool.schema.enum(["add", "search", "profile", "list", "forget", "help"]).optional(),
|
|
199
170
|
content: tool.schema.string().optional(),
|
|
200
171
|
query: tool.schema.string().optional(),
|
|
201
172
|
type: tool.schema.string().optional(),
|
|
@@ -226,12 +197,12 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
226
197
|
commands: [
|
|
227
198
|
{
|
|
228
199
|
command: "add",
|
|
229
|
-
description: "Store a new project memory",
|
|
200
|
+
description: "Store a new project memory (MATCH USER LANGUAGE)",
|
|
230
201
|
args: ["content", "type?"],
|
|
231
202
|
},
|
|
232
203
|
{
|
|
233
204
|
command: "search",
|
|
234
|
-
description: "Search project memories",
|
|
205
|
+
description: "Search project memories (MATCH USER LANGUAGE)",
|
|
235
206
|
args: ["query"],
|
|
236
207
|
},
|
|
237
208
|
{
|
|
@@ -249,11 +220,6 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
249
220
|
description: "Remove a project memory",
|
|
250
221
|
args: ["memoryId"],
|
|
251
222
|
},
|
|
252
|
-
{
|
|
253
|
-
command: "capture-now",
|
|
254
|
-
description: "Manually trigger memory capture for current session",
|
|
255
|
-
args: [],
|
|
256
|
-
},
|
|
257
223
|
],
|
|
258
224
|
note: "User preferences are automatically learned through the user profile system. Only project-specific memories can be added manually.",
|
|
259
225
|
typeGuidance: "Choose appropriate type: preference, architecture, workflow, bug-fix, configuration, pattern, request, context, etc. Be specific and descriptive with categories.",
|
|
@@ -377,14 +343,6 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
377
343
|
message: `Memory ${args.memoryId} removed`,
|
|
378
344
|
});
|
|
379
345
|
}
|
|
380
|
-
case "capture-now": {
|
|
381
|
-
const sessionID = toolCtx.sessionID;
|
|
382
|
-
await performAutoCapture(ctx, sessionID, directory);
|
|
383
|
-
return JSON.stringify({
|
|
384
|
-
success: true,
|
|
385
|
-
message: "Manual capture triggered",
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
346
|
default:
|
|
389
347
|
return JSON.stringify({
|
|
390
348
|
success: false,
|
|
@@ -434,7 +392,7 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
434
392
|
})
|
|
435
393
|
.catch((err) => {
|
|
436
394
|
log("Auto-cleanup failed", { error: String(err) });
|
|
437
|
-
if (ctx.client?.tui) {
|
|
395
|
+
if (ctx.client?.tui && CONFIG.showErrorToasts) {
|
|
438
396
|
ctx.client.tui
|
|
439
397
|
.showToast({
|
|
440
398
|
body: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-profile-validator.d.ts","sourceRoot":"","sources":["../../../../src/services/ai/validators/user-profile-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB;
|
|
1
|
+
{"version":3,"file":"user-profile-validator.d.ts","sourceRoot":"","sources":["../../../../src/services/ai/validators/user-profile-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB;IAsC5C,OAAO,CAAC,MAAM,CAAC,mBAAmB;IA6BlC,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAqB/B,OAAO,CAAC,MAAM,CAAC,iBAAiB;CAsBjC"}
|
|
@@ -31,10 +31,6 @@ export class UserProfileValidator {
|
|
|
31
31
|
const workflowErrors = this.validateWorkflows(data.workflows);
|
|
32
32
|
errors.push(...workflowErrors);
|
|
33
33
|
}
|
|
34
|
-
if (data.skillLevel) {
|
|
35
|
-
const skillErrors = this.validateSkillLevel(data.skillLevel);
|
|
36
|
-
errors.push(...skillErrors);
|
|
37
|
-
}
|
|
38
34
|
if (errors.length > 0) {
|
|
39
35
|
return { valid: false, errors };
|
|
40
36
|
}
|
|
@@ -112,17 +108,4 @@ export class UserProfileValidator {
|
|
|
112
108
|
}
|
|
113
109
|
return errors;
|
|
114
110
|
}
|
|
115
|
-
static validateSkillLevel(skillLevel) {
|
|
116
|
-
const errors = [];
|
|
117
|
-
if (typeof skillLevel !== "object") {
|
|
118
|
-
return ["skillLevel must be an object"];
|
|
119
|
-
}
|
|
120
|
-
if (!skillLevel.overall || typeof skillLevel.overall !== "string") {
|
|
121
|
-
errors.push("skillLevel.overall is missing or invalid");
|
|
122
|
-
}
|
|
123
|
-
if (!skillLevel.domains || typeof skillLevel.domains !== "object") {
|
|
124
|
-
errors.push("skillLevel.domains must be an object");
|
|
125
|
-
}
|
|
126
|
-
return errors;
|
|
127
|
-
}
|
|
128
111
|
}
|
|
@@ -62,9 +62,38 @@ export declare function handleUpdateMemory(id: string, data: {
|
|
|
62
62
|
content?: string;
|
|
63
63
|
type?: MemoryType;
|
|
64
64
|
}): Promise<ApiResponse<void>>;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
interface FormattedPrompt {
|
|
66
|
+
type: "prompt";
|
|
67
|
+
id: string;
|
|
68
|
+
sessionId: string;
|
|
69
|
+
content: string;
|
|
70
|
+
createdAt: string;
|
|
71
|
+
projectPath: string | null;
|
|
72
|
+
linkedMemoryId: string | null;
|
|
73
|
+
similarity?: number;
|
|
74
|
+
isContext?: boolean;
|
|
75
|
+
}
|
|
76
|
+
interface FormattedMemory {
|
|
77
|
+
type: "memory";
|
|
78
|
+
id: string;
|
|
79
|
+
content: string;
|
|
80
|
+
memoryType?: string;
|
|
81
|
+
createdAt: string;
|
|
82
|
+
updatedAt?: string;
|
|
83
|
+
similarity?: number;
|
|
84
|
+
metadata?: Record<string, unknown>;
|
|
85
|
+
displayName?: string;
|
|
86
|
+
userName?: string;
|
|
87
|
+
userEmail?: string;
|
|
88
|
+
projectPath?: string;
|
|
89
|
+
projectName?: string;
|
|
90
|
+
gitRepoUrl?: string;
|
|
91
|
+
isPinned?: boolean;
|
|
92
|
+
linkedPromptId?: string;
|
|
93
|
+
isContext?: boolean;
|
|
94
|
+
}
|
|
95
|
+
type SearchResultItem = FormattedPrompt | FormattedMemory;
|
|
96
|
+
export declare function handleSearch(query: string, tag?: string, page?: number, pageSize?: number): Promise<ApiResponse<PaginatedResponse<SearchResultItem>>>;
|
|
68
97
|
export declare function handleStats(): Promise<ApiResponse<{
|
|
69
98
|
total: number;
|
|
70
99
|
byScope: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-handlers.d.ts","sourceRoot":"","sources":["../../src/services/api-handlers.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"api-handlers.d.ts","sourceRoot":"","sources":["../../src/services/api-handlers.ts"],"names":[],"mappings":"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"}
|