opencode-mem 2.3.7 → 2.4.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/dist/config.d.ts +0 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -37
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -80
- 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.js +10 -3
- package/dist/services/user-memory-learning.js +3 -13
- 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 +1 -1
package/dist/config.d.ts
CHANGED
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":"AAuVA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;oBAwBb,aAAa,GACb,kBAAkB,GAClB,WAAW;;;;;;;;;;;;;;;;;;;CAyBhB,CAAC;AAEF,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
|
package/dist/config.js
CHANGED
|
@@ -14,24 +14,6 @@ if (!existsSync(CONFIG_DIR)) {
|
|
|
14
14
|
if (!existsSync(DATA_DIR)) {
|
|
15
15
|
mkdirSync(DATA_DIR, { recursive: true });
|
|
16
16
|
}
|
|
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
17
|
const DEFAULTS = {
|
|
36
18
|
storagePath: join(DATA_DIR, "data"),
|
|
37
19
|
embeddingModel: "Xenova/nomic-embed-text-v1",
|
|
@@ -41,7 +23,6 @@ const DEFAULTS = {
|
|
|
41
23
|
maxProfileItems: 5,
|
|
42
24
|
injectProfile: true,
|
|
43
25
|
containerTagPrefix: "opencode",
|
|
44
|
-
keywordPatterns: [],
|
|
45
26
|
autoCaptureEnabled: true,
|
|
46
27
|
autoCaptureMaxIterations: 5,
|
|
47
28
|
autoCaptureIterationTimeout: 30000,
|
|
@@ -61,15 +42,6 @@ const DEFAULTS = {
|
|
|
61
42
|
userProfileConfidenceDecayDays: 30,
|
|
62
43
|
userProfileChangelogRetentionCount: 5,
|
|
63
44
|
};
|
|
64
|
-
function isValidRegex(pattern) {
|
|
65
|
-
try {
|
|
66
|
-
new RegExp(pattern);
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
45
|
function expandPath(path) {
|
|
74
46
|
if (path.startsWith("~/")) {
|
|
75
47
|
return join(homedir(), path.slice(2));
|
|
@@ -268,11 +240,7 @@ const CONFIG_TEMPLATE = `{
|
|
|
268
240
|
// ============================================
|
|
269
241
|
|
|
270
242
|
// 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": []
|
|
243
|
+
"injectProfile": true
|
|
276
244
|
}
|
|
277
245
|
`;
|
|
278
246
|
function ensureConfigExists() {
|
|
@@ -324,10 +292,6 @@ export const CONFIG = {
|
|
|
324
292
|
maxProfileItems: fileConfig.maxProfileItems ?? DEFAULTS.maxProfileItems,
|
|
325
293
|
injectProfile: fileConfig.injectProfile ?? DEFAULTS.injectProfile,
|
|
326
294
|
containerTagPrefix: fileConfig.containerTagPrefix ?? DEFAULTS.containerTagPrefix,
|
|
327
|
-
keywordPatterns: [
|
|
328
|
-
...DEFAULT_KEYWORD_PATTERNS,
|
|
329
|
-
...(fileConfig.keywordPatterns ?? []).filter(isValidRegex),
|
|
330
|
-
],
|
|
331
295
|
autoCaptureEnabled: fileConfig.autoCaptureEnabled ?? DEFAULTS.autoCaptureEnabled,
|
|
332
296
|
autoCaptureMaxIterations: fileConfig.autoCaptureMaxIterations ?? DEFAULTS.autoCaptureMaxIterations,
|
|
333
297
|
autoCaptureIterationTimeout: fileConfig.autoCaptureIterationTimeout ?? DEFAULTS.autoCaptureIterationTimeout,
|
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,47 +108,41 @@ 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
|
}
|
|
@@ -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,
|
|
@@ -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":"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,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,OAAO;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,iBAAiB,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAwDD,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAAE,OAAO,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAAC,CA4CnF;AAED,wBAAsB,kBAAkB,CACtC,GAAG,CAAC,EAAE,MAAM,EACZ,IAAI,GAAE,MAAU,EAChB,QAAQ,GAAE,MAAW,EACrB,cAAc,GAAE,OAAc,GAC7B,OAAO,CAAC,WAAW,CAAC,iBAAiB,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAyJvD;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,WAAW,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA4CvC;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,OAAe,GACvB,OAAO,CAAC,WAAW,CAAC;IAAE,aAAa,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAqClD;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EAAE,EACb,OAAO,GAAE,OAAe,GACvB,OAAO,CAAC,WAAW,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAmB3C;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,CAAA;CAAE,GAC5C,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CA6D5B;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,MAAM,EACZ,IAAI,GAAE,MAAU,EAChB,QAAQ,GAAE,MAAW,GACpB,OAAO,CAAC,WAAW,CAAC,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"api-handlers.d.ts","sourceRoot":"","sources":["../../src/services/api-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -381,19 +381,22 @@ export async function handleSearch(query, tag, page = 1, pageSize = 20) {
|
|
|
381
381
|
}
|
|
382
382
|
await embeddingService.warmup();
|
|
383
383
|
const queryVector = await embeddingService.embedWithTimeout(query);
|
|
384
|
-
let
|
|
384
|
+
let memoryResults = [];
|
|
385
|
+
let promptResults = [];
|
|
385
386
|
if (tag) {
|
|
386
387
|
const { scope, hash } = extractScopeFromTag(tag);
|
|
387
388
|
const shards = shardManager.getAllShards(scope, hash);
|
|
388
389
|
for (const shard of shards) {
|
|
389
390
|
try {
|
|
390
391
|
const results = vectorSearch.searchInShard(shard, queryVector, tag, pageSize * 2);
|
|
391
|
-
|
|
392
|
+
memoryResults.push(...results);
|
|
392
393
|
}
|
|
393
394
|
catch (error) {
|
|
394
395
|
log("Shard search error", { shardId: shard.id, error: String(error) });
|
|
395
396
|
}
|
|
396
397
|
}
|
|
398
|
+
const projectPath = getProjectPathFromTag(tag);
|
|
399
|
+
promptResults = userPromptManager.searchPrompts(query, projectPath, pageSize * 2);
|
|
397
400
|
}
|
|
398
401
|
else {
|
|
399
402
|
const projectShards = shardManager.getAllShards("project", "");
|
|
@@ -414,26 +417,33 @@ export async function handleSearch(query, tag, page = 1, pageSize = 20) {
|
|
|
414
417
|
for (const shard of shards) {
|
|
415
418
|
try {
|
|
416
419
|
const results = vectorSearch.searchInShard(shard, queryVector, containerTag, pageSize);
|
|
417
|
-
|
|
420
|
+
memoryResults.push(...results);
|
|
418
421
|
}
|
|
419
422
|
catch (error) {
|
|
420
423
|
log("Shard search error", { shardId: shard.id, error: String(error) });
|
|
421
424
|
}
|
|
422
425
|
}
|
|
423
426
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
427
|
+
promptResults = userPromptManager.searchPrompts(query, undefined, pageSize * 2);
|
|
428
|
+
}
|
|
429
|
+
const formattedPrompts = promptResults.map((p) => ({
|
|
430
|
+
type: "prompt",
|
|
431
|
+
id: p.id,
|
|
432
|
+
sessionId: p.sessionId,
|
|
433
|
+
content: p.content,
|
|
434
|
+
createdAt: safeToISOString(p.createdAt),
|
|
435
|
+
projectPath: p.projectPath,
|
|
436
|
+
linkedMemoryId: p.linkedMemoryId,
|
|
437
|
+
similarity: 1.0,
|
|
438
|
+
}));
|
|
439
|
+
const formattedMemories = memoryResults.map((r) => ({
|
|
440
|
+
type: "memory",
|
|
431
441
|
id: r.id,
|
|
432
442
|
content: r.memory,
|
|
433
|
-
|
|
443
|
+
memoryType: r.metadata?.type,
|
|
434
444
|
createdAt: safeToISOString(r.metadata?.createdAt),
|
|
435
445
|
updatedAt: r.metadata?.updatedAt ? safeToISOString(r.metadata.updatedAt) : undefined,
|
|
436
|
-
similarity:
|
|
446
|
+
similarity: r.similarity,
|
|
437
447
|
metadata: r.metadata,
|
|
438
448
|
displayName: r.displayName,
|
|
439
449
|
userName: r.userName,
|
|
@@ -442,11 +452,77 @@ export async function handleSearch(query, tag, page = 1, pageSize = 20) {
|
|
|
442
452
|
projectName: r.projectName,
|
|
443
453
|
gitRepoUrl: r.gitRepoUrl,
|
|
444
454
|
isPinned: r.isPinned === 1,
|
|
455
|
+
linkedPromptId: r.metadata?.promptId,
|
|
445
456
|
}));
|
|
457
|
+
const combinedResults = [...formattedMemories, ...formattedPrompts].sort((a, b) => (b.similarity || 0) - (a.similarity || 0) || b.createdAt.localeCompare(a.createdAt));
|
|
458
|
+
const total = combinedResults.length;
|
|
459
|
+
const totalPages = Math.ceil(total / pageSize);
|
|
460
|
+
const offset = (page - 1) * pageSize;
|
|
461
|
+
const paginatedResults = combinedResults.slice(offset, offset + pageSize);
|
|
462
|
+
const missingPromptIds = new Set();
|
|
463
|
+
const missingMemoryIds = new Set();
|
|
464
|
+
for (const item of paginatedResults) {
|
|
465
|
+
if (item.type === "memory" && item.linkedPromptId) {
|
|
466
|
+
const hasPrompt = paginatedResults.some((p) => p.id === item.linkedPromptId);
|
|
467
|
+
if (!hasPrompt)
|
|
468
|
+
missingPromptIds.add(item.linkedPromptId);
|
|
469
|
+
}
|
|
470
|
+
else if (item.type === "prompt" && item.linkedMemoryId) {
|
|
471
|
+
const hasMemory = paginatedResults.some((m) => m.id === item.linkedMemoryId);
|
|
472
|
+
if (!hasMemory)
|
|
473
|
+
missingMemoryIds.add(item.linkedMemoryId);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
if (missingPromptIds.size > 0) {
|
|
477
|
+
const extraPrompts = userPromptManager.getPromptsByIds(Array.from(missingPromptIds));
|
|
478
|
+
for (const p of extraPrompts) {
|
|
479
|
+
paginatedResults.push({
|
|
480
|
+
type: "prompt",
|
|
481
|
+
id: p.id,
|
|
482
|
+
sessionId: p.sessionId,
|
|
483
|
+
content: p.content,
|
|
484
|
+
createdAt: safeToISOString(p.createdAt),
|
|
485
|
+
projectPath: p.projectPath,
|
|
486
|
+
linkedMemoryId: p.linkedMemoryId,
|
|
487
|
+
similarity: 0,
|
|
488
|
+
isContext: true,
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
if (missingMemoryIds.size > 0) {
|
|
493
|
+
const projectShards = shardManager.getAllShards("project", "");
|
|
494
|
+
for (const shard of projectShards) {
|
|
495
|
+
const db = connectionManager.getConnection(shard.dbPath);
|
|
496
|
+
for (const mid of missingMemoryIds) {
|
|
497
|
+
const m = vectorSearch.getMemoryById(db, mid);
|
|
498
|
+
if (m && !paginatedResults.some((existing) => existing.id === m.id)) {
|
|
499
|
+
paginatedResults.push({
|
|
500
|
+
type: "memory",
|
|
501
|
+
id: m.id,
|
|
502
|
+
content: m.content,
|
|
503
|
+
memoryType: m.type,
|
|
504
|
+
createdAt: safeToISOString(m.created_at),
|
|
505
|
+
updatedAt: m.updated_at ? safeToISOString(m.updated_at) : undefined,
|
|
506
|
+
similarity: 0,
|
|
507
|
+
metadata: safeJSONParse(m.metadata),
|
|
508
|
+
displayName: m.display_name,
|
|
509
|
+
userName: m.user_name,
|
|
510
|
+
userEmail: m.user_email,
|
|
511
|
+
projectPath: m.project_path,
|
|
512
|
+
projectName: m.project_name,
|
|
513
|
+
gitRepoUrl: m.git_repo_url,
|
|
514
|
+
isPinned: m.is_pinned === 1,
|
|
515
|
+
linkedPromptId: safeJSONParse(m.metadata)?.promptId,
|
|
516
|
+
isContext: true,
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
446
522
|
return {
|
|
447
523
|
success: true,
|
|
448
524
|
data: {
|
|
449
|
-
items:
|
|
525
|
+
items: paginatedResults,
|
|
450
526
|
total,
|
|
451
527
|
page,
|
|
452
528
|
pageSize,
|
|
@@ -200,24 +200,31 @@ RULES:
|
|
|
200
200
|
2. SKIP non-technical by returning type="skip"
|
|
201
201
|
3. NO meta-commentary or behavior analysis
|
|
202
202
|
4. Include specific file names, functions, technical details
|
|
203
|
+
5. DETECT the language used by the user. You MUST write the summary and reasoning in that SAME language.
|
|
203
204
|
|
|
204
205
|
FORMAT:
|
|
205
206
|
## Request
|
|
206
|
-
[1-2 sentences: what was requested]
|
|
207
|
+
[1-2 sentences: what was requested, in user's language]
|
|
207
208
|
|
|
208
209
|
## Outcome
|
|
209
|
-
[1-2 sentences: what was done, include files/functions]
|
|
210
|
+
[1-2 sentences: what was done, include files/functions, in user's language]
|
|
210
211
|
|
|
211
212
|
SKIP if: greetings, casual chat, no code/decisions made
|
|
212
213
|
CAPTURE if: code changed, bug fixed, feature added, decision made
|
|
213
214
|
|
|
214
215
|
EXAMPLES:
|
|
215
|
-
Technical → type="feature":
|
|
216
|
+
Technical (English) → type="feature":
|
|
216
217
|
## Request
|
|
217
218
|
Fix function returning null.
|
|
218
219
|
## Outcome
|
|
219
220
|
Changed searchMemories() to listMemories() in auto-capture.ts:166.
|
|
220
221
|
|
|
222
|
+
Technical (Indonesian) → type="feature":
|
|
223
|
+
## Request
|
|
224
|
+
Perbaiki fungsi yang mengembalikan null.
|
|
225
|
+
## Outcome
|
|
226
|
+
Mengubah searchMemories() menjadi listMemories() di auto-capture.ts:166.
|
|
227
|
+
|
|
221
228
|
Non-technical → type="skip", summary="":
|
|
222
229
|
User greeted, AI introduced capabilities.`;
|
|
223
230
|
const userPrompt = `${context}
|
|
@@ -112,10 +112,6 @@ Identify and ${existingProfile ? "update" : "create"}:
|
|
|
112
112
|
- Development sequences, habits, learning style
|
|
113
113
|
- Break down into steps if applicable
|
|
114
114
|
|
|
115
|
-
4. **Skill Level**
|
|
116
|
-
- Overall: beginner/intermediate/advanced
|
|
117
|
-
- Per-domain assessment (e.g., typescript: advanced, docker: beginner)
|
|
118
|
-
|
|
119
115
|
${existingProfile ? "Merge with existing profile, incrementing frequencies and updating confidence scores." : "Create initial profile with conservative confidence scores."}`;
|
|
120
116
|
}
|
|
121
117
|
async function analyzeUserProfile(context, existingProfile) {
|
|
@@ -140,6 +136,8 @@ async function analyzeUserProfile(context, existingProfile) {
|
|
|
140
136
|
|
|
141
137
|
Your task is to analyze user prompts and ${existingProfile ? "update" : "create"} a comprehensive user profile.
|
|
142
138
|
|
|
139
|
+
CRITICAL: Detect the language used by the user. You MUST output all descriptions and text in the SAME language as the user's prompts.
|
|
140
|
+
|
|
143
141
|
Use the update_user_profile tool to save the ${existingProfile ? "updated" : "new"} profile.`;
|
|
144
142
|
const toolSchema = {
|
|
145
143
|
type: "function",
|
|
@@ -186,16 +184,8 @@ Use the update_user_profile tool to save the ${existingProfile ? "updated" : "ne
|
|
|
186
184
|
required: ["description", "steps"],
|
|
187
185
|
},
|
|
188
186
|
},
|
|
189
|
-
skillLevel: {
|
|
190
|
-
type: "object",
|
|
191
|
-
properties: {
|
|
192
|
-
overall: { type: "string", enum: ["beginner", "intermediate", "advanced"] },
|
|
193
|
-
domains: { type: "object", additionalProperties: { type: "string" } },
|
|
194
|
-
},
|
|
195
|
-
required: ["overall", "domains"],
|
|
196
|
-
},
|
|
197
187
|
},
|
|
198
|
-
required: ["preferences", "patterns", "workflows"
|
|
188
|
+
required: ["preferences", "patterns", "workflows"],
|
|
199
189
|
},
|
|
200
190
|
},
|
|
201
191
|
};
|
|
@@ -16,15 +16,10 @@ export interface UserProfileWorkflow {
|
|
|
16
16
|
steps: string[];
|
|
17
17
|
frequency: number;
|
|
18
18
|
}
|
|
19
|
-
export interface UserProfileSkillLevel {
|
|
20
|
-
overall: string;
|
|
21
|
-
domains: Record<string, string>;
|
|
22
|
-
}
|
|
23
19
|
export interface UserProfileData {
|
|
24
20
|
preferences: UserProfilePreference[];
|
|
25
21
|
patterns: UserProfilePattern[];
|
|
26
22
|
workflows: UserProfileWorkflow[];
|
|
27
|
-
skillLevel: UserProfileSkillLevel;
|
|
28
23
|
}
|
|
29
24
|
export interface UserProfile {
|
|
30
25
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/user-profile/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/user-profile/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,qBAAqB,EAAE,CAAC;IACrC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,EAAE,mBAAmB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -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,EAAE,WAAW,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKrF,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;
|
|
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;AAKrF,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;CAmFhG;AAED,eAAO,MAAM,kBAAkB,oBAA2B,CAAC"}
|
|
@@ -194,7 +194,6 @@ export class UserProfileManager {
|
|
|
194
194
|
preferences: safeArray(existing?.preferences),
|
|
195
195
|
patterns: safeArray(existing?.patterns),
|
|
196
196
|
workflows: safeArray(existing?.workflows),
|
|
197
|
-
skillLevel: safeObject(existing?.skillLevel, { overall: "intermediate", domains: {} }),
|
|
198
197
|
};
|
|
199
198
|
if (updates.preferences) {
|
|
200
199
|
for (const newPref of updates.preferences) {
|
|
@@ -258,12 +257,6 @@ export class UserProfileManager {
|
|
|
258
257
|
merged.workflows.sort((a, b) => b.frequency - a.frequency);
|
|
259
258
|
merged.workflows = merged.workflows.slice(0, CONFIG.userProfileMaxWorkflows);
|
|
260
259
|
}
|
|
261
|
-
if (updates.skillLevel) {
|
|
262
|
-
merged.skillLevel = {
|
|
263
|
-
overall: updates.skillLevel.overall || merged.skillLevel.overall,
|
|
264
|
-
domains: { ...merged.skillLevel.domains, ...safeObject(updates.skillLevel.domains, {}) },
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
260
|
return merged;
|
|
268
261
|
}
|
|
269
262
|
}
|