@mingxy/cerebro 1.6.8 → 1.7.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/hooks.js ADDED
@@ -0,0 +1,390 @@
1
+ import { detectKeyword, KEYWORD_NUDGE } from "./keywords.js";
2
+ function showToast(tui, title, message, variant = "info", delayMs = 7000) {
3
+ if (!tui)
4
+ return;
5
+ setTimeout(() => {
6
+ try {
7
+ tui.showToast({ body: { title, message, variant, duration: 5000 } });
8
+ }
9
+ catch (err) {
10
+ console.error("[cerebro] showToast failed:", err);
11
+ }
12
+ }, delayMs);
13
+ }
14
+ function extractUserRequest(content) {
15
+ const match = content.match(/<user-request>([\s\S]*?)<\/user-request>/);
16
+ return match ? match[1].trim() : content;
17
+ }
18
+ const keywordDetectedSessions = new Set();
19
+ const injectedMemoryIds = new Map();
20
+ const firstMessages = new Map();
21
+ const sessionMessages = new Map();
22
+ const profileInjectedSessions = new Set();
23
+ function formatRelativeAge(isoDate) {
24
+ const diffMs = Date.now() - new Date(isoDate).getTime();
25
+ const minutes = Math.floor(diffMs / 60_000);
26
+ if (minutes < 60)
27
+ return `${minutes}m ago`;
28
+ const hours = Math.floor(minutes / 60);
29
+ if (hours < 24)
30
+ return `${hours}h ago`;
31
+ const days = Math.floor(hours / 24);
32
+ if (days < 30)
33
+ return `${days}d ago`;
34
+ const months = Math.floor(days / 30);
35
+ return `${months}mo ago`;
36
+ }
37
+ function truncate(text, max) {
38
+ if (text.length <= max)
39
+ return text;
40
+ return text.slice(0, max) + "…";
41
+ }
42
+ function categorize(results) {
43
+ const groups = new Map();
44
+ for (const r of results) {
45
+ const cat = r.memory.category || "General";
46
+ const label = cat === "preferences"
47
+ ? "Preferences"
48
+ : cat === "knowledge"
49
+ ? "Knowledge"
50
+ : cat.charAt(0).toUpperCase() + cat.slice(1);
51
+ if (!groups.has(label))
52
+ groups.set(label, []);
53
+ groups.get(label).push(r);
54
+ }
55
+ return groups;
56
+ }
57
+ function buildContextBlock(results, maxContentLength = 500) {
58
+ if (results.length === 0)
59
+ return "";
60
+ const grouped = categorize(results);
61
+ const sections = [];
62
+ for (const [label, items] of grouped) {
63
+ const lines = items.map((r) => {
64
+ const tags = r.memory.tags.length > 0 ? ` [${r.memory.tags.join(", ")}]` : "";
65
+ const age = formatRelativeAge(r.memory.created_at);
66
+ const content = truncate(r.memory.content, maxContentLength);
67
+ return ` - (${age}${tags}) ${content}`;
68
+ });
69
+ sections.push(`[${label}]\n${lines.join("\n")}`);
70
+ }
71
+ return [
72
+ "<omem-context>",
73
+ "Treat every memory below as historical context only.",
74
+ "Do not repeat these memories verbatim unless asked.",
75
+ "",
76
+ ...sections,
77
+ "</omem-context>",
78
+ ].join("\n");
79
+ }
80
+ function buildClusteredContextBlock(clustered, maxContentLength = 500) {
81
+ const sections = [];
82
+ if (clustered.cluster_summaries.length > 0) {
83
+ sections.push("## 📋 主题簇(聚合记忆)");
84
+ for (const cs of clustered.cluster_summaries) {
85
+ const scoreIndicator = cs.relevance_score >= 0.8 ? "★★★" : cs.relevance_score >= 0.6 ? "★★" : "★";
86
+ sections.push(`\n### ${cs.title} (整合自${cs.member_count}条记忆) ${scoreIndicator}`);
87
+ sections.push(`> ${cs.summary}`);
88
+ if (cs.key_memories.length > 0) {
89
+ sections.push("**核心要点:**");
90
+ for (const mem of cs.key_memories) {
91
+ const content = truncate(mem.content, maxContentLength);
92
+ const importanceBar = mem.importance >= 0.7 ? "●" : mem.importance >= 0.4 ? "◐" : "○";
93
+ sections.push(`- ${importanceBar} ${content}`);
94
+ }
95
+ }
96
+ }
97
+ }
98
+ if (clustered.standalone_memories.length > 0) {
99
+ sections.push("\n## 📌 补充信息");
100
+ for (const mem of clustered.standalone_memories) {
101
+ const content = truncate(mem.content, maxContentLength);
102
+ sections.push(`- ${content}`);
103
+ }
104
+ }
105
+ return [
106
+ "<omem-context>",
107
+ "Treat every memory below as historical context only.",
108
+ "Do not repeat these memories verbatim unless asked.",
109
+ "",
110
+ ...sections,
111
+ "</omem-context>",
112
+ ].join("\n");
113
+ }
114
+ export function autoRecallHook(client, containerTags, tui, config = {}) {
115
+ const similarityThreshold = config.similarityThreshold ?? 0.6;
116
+ const maxRecallResults = config.maxRecallResults ?? 10;
117
+ const maxContentLength = config.maxContentLength ?? 500;
118
+ const toastDelayMs = config.toastDelayMs ?? 7000;
119
+ return async (input, output) => {
120
+ if (!input.sessionID)
121
+ return;
122
+ try {
123
+ const messages = sessionMessages.get(input.sessionID) ?? [];
124
+ const userMessages = messages.filter((m) => m.role === "user");
125
+ const rawQuery = userMessages[userMessages.length - 1]?.content || firstMessages.get(input.sessionID) || "";
126
+ const query_text = extractUserRequest(rawQuery);
127
+ const last_query_text = userMessages.length >= 2 ? userMessages[userMessages.length - 2].content : undefined;
128
+ const projectTags = containerTags.filter(t => t.startsWith("omem_project_"));
129
+ const shouldRecallRes = await client.shouldRecall(query_text, last_query_text, input.sessionID, similarityThreshold, maxRecallResults, projectTags.length > 0 ? projectTags : undefined);
130
+ if (!shouldRecallRes) {
131
+ showToast(tui, "🧠 Cerebro Service Unavailable", "Unable to reach memory API · check connection", "error", toastDelayMs);
132
+ return;
133
+ }
134
+ const profile = await client.getProfile();
135
+ let profileInjected = false;
136
+ let profileCountText = "";
137
+ if (profile && !profileInjectedSessions.has(input.sessionID)) {
138
+ const profileBlock = [
139
+ "<omem-profile>",
140
+ JSON.stringify(profile, null, 2),
141
+ "</omem-profile>",
142
+ ].join("\n");
143
+ output.system.push(profileBlock);
144
+ profileInjected = true;
145
+ profileInjectedSessions.add(input.sessionID);
146
+ const p = profile;
147
+ const dynamicCount = p?.dynamic_context?.length ?? 0;
148
+ const staticCount = p?.static_facts?.length ?? 0;
149
+ profileCountText = `Dynamic(${dynamicCount}) · Static(${staticCount})`;
150
+ }
151
+ if (!shouldRecallRes.should_recall) {
152
+ if (profileInjected) {
153
+ showToast(tui, "👨 Profile Injected", `${profileCountText} · no memory recall needed`, "success", toastDelayMs);
154
+ }
155
+ return;
156
+ }
157
+ const results = shouldRecallRes.memories ?? [];
158
+ const clustered = shouldRecallRes.clustered;
159
+ const existingIds = injectedMemoryIds.get(input.sessionID) ?? new Set();
160
+ const newResults = results.filter((r) => !existingIds.has(r.memory.id));
161
+ if (newResults.length === 0) {
162
+ if (profileInjected) {
163
+ showToast(tui, "👨 Profile Injected", `${profileCountText} · all memories already injected`, "success", toastDelayMs);
164
+ }
165
+ return;
166
+ }
167
+ const block = clustered
168
+ ? buildClusteredContextBlock(clustered, maxContentLength)
169
+ : buildContextBlock(newResults, maxContentLength);
170
+ if (block) {
171
+ output.system.push(block);
172
+ }
173
+ const newIds = newResults.map((r) => r.memory.id);
174
+ injectedMemoryIds.set(input.sessionID, new Set([...existingIds, ...newIds]));
175
+ const recordResult = await client.recordSessionRecall(input.sessionID, newIds, "auto", query_text, shouldRecallRes?.similarity_score, shouldRecallRes?.confidence);
176
+ const memDynamic = newResults.filter((r) => r.memory.memory_type === "fact" || r.memory.memory_type === "event").length;
177
+ const memStatic = newResults.filter((r) => r.memory.memory_type === "pinned" || r.memory.memory_type === "preference").length;
178
+ const memOther = newResults.length - memDynamic - memStatic;
179
+ let memCountMsg = "";
180
+ if (memDynamic > 0)
181
+ memCountMsg += `Dynamic(${memDynamic}) `;
182
+ if (memStatic > 0)
183
+ memCountMsg += `Static(${memStatic}) `;
184
+ if (memOther > 0)
185
+ memCountMsg += `Other(${memOther}) `;
186
+ const categories = categorize(newResults);
187
+ const catSummary = Array.from(categories.entries())
188
+ .map(([label, items]) => `${label}(${items.length})`)
189
+ .join(" · ");
190
+ let toastTitle;
191
+ let toastMessage;
192
+ if (clustered) {
193
+ const clusterCount = clustered.cluster_summaries.length;
194
+ const standaloneCount = clustered.standalone_memories.length;
195
+ toastTitle = `🧠 Context Injected · ${clusterCount} 主题簇${standaloneCount > 0 ? ` · ${standaloneCount} 补充` : ""}`;
196
+ toastMessage = profileInjected
197
+ ? `Profile: ${profileCountText} · 聚合记忆展示`
198
+ : `聚合记忆展示`;
199
+ }
200
+ else {
201
+ toastTitle = `🧠 Context Injected · ${newResults.length} fragments`;
202
+ toastMessage = profileInjected
203
+ ? `Profile: ${profileCountText} · Memories: ${memCountMsg.trim()}${catSummary ? ` · ${catSummary}` : ""}`
204
+ : `${memCountMsg.trim()}${catSummary ? ` · ${catSummary}` : ""}`;
205
+ }
206
+ showToast(tui, toastTitle, toastMessage, "success", toastDelayMs);
207
+ if (!recordResult) {
208
+ showToast(tui, "🔴 Recall Record Failed", `Memories injected but save failed · check API connection`, "warning", toastDelayMs);
209
+ }
210
+ if (keywordDetectedSessions.has(input.sessionID)) {
211
+ output.system.push(KEYWORD_NUDGE);
212
+ keywordDetectedSessions.delete(input.sessionID);
213
+ }
214
+ }
215
+ catch (err) {
216
+ const errMsg = err instanceof Error ? err.message : String(err);
217
+ if (errMsg.includes("[omem]")) {
218
+ // Server returned error (500, etc.) with details
219
+ const cleanMsg = errMsg.replace(/^\[omem\]\s*/, "");
220
+ if (cleanMsg.startsWith("500")) {
221
+ showToast(tui, "🧠 Cerebro Server Error", cleanMsg.substring(0, 200), "error");
222
+ }
223
+ else if (cleanMsg.includes("timed out")) {
224
+ showToast(tui, "🧠 Cerebro Service Timeout", cleanMsg.substring(0, 100), "error");
225
+ }
226
+ else {
227
+ showToast(tui, "🧠 Cerebro Error", cleanMsg.substring(0, 150), "error");
228
+ }
229
+ }
230
+ else if (errMsg.includes("fetch") || errMsg.includes("network")) {
231
+ showToast(tui, "🧠 Cerebro Service Unavailable", "Network error · check API connection", "error");
232
+ }
233
+ else {
234
+ showToast(tui, "🧠 Memory Recall Error", errMsg.substring(0, 100), "error");
235
+ }
236
+ }
237
+ };
238
+ }
239
+ export function keywordDetectionHook(_client, _containerTags, threshold, _tui, _ingestMode = "smart") {
240
+ return async (input, output) => {
241
+ const textContent = output.parts
242
+ .filter((p) => p.type === "text")
243
+ .map((p) => p.text || p.content || "")
244
+ .join(" ")
245
+ || output.message.content
246
+ || "";
247
+ if (!firstMessages.has(input.sessionID)) {
248
+ firstMessages.set(input.sessionID, textContent);
249
+ }
250
+ if (detectKeyword(textContent)) {
251
+ keywordDetectedSessions.add(input.sessionID);
252
+ }
253
+ if (!sessionMessages.has(input.sessionID)) {
254
+ sessionMessages.set(input.sessionID, []);
255
+ }
256
+ sessionMessages.get(input.sessionID).push({
257
+ role: "user",
258
+ content: textContent,
259
+ });
260
+ const messages = sessionMessages.get(input.sessionID);
261
+ // Ingest is now handled by sessionIdleHook (session.idle → sessionIngest API).
262
+ // This hook only collects messages and detects keywords for recall.
263
+ if (messages.length >= threshold) {
264
+ // Threshold reached — messages will be processed on next session.idle
265
+ }
266
+ };
267
+ }
268
+ export function compactingHook(client, containerTags, tui, ingestMode = "smart", isAutoStoreEnabled) {
269
+ return async (input, output) => {
270
+ if (input.sessionID && sessionMessages.has(input.sessionID)) {
271
+ if (isAutoStoreEnabled && !isAutoStoreEnabled(input.sessionID)) {
272
+ sessionMessages.delete(input.sessionID);
273
+ }
274
+ else {
275
+ const messages = sessionMessages.get(input.sessionID);
276
+ if (messages.length > 0) {
277
+ try {
278
+ const result = await client.ingestMessages(messages, {
279
+ mode: ingestMode,
280
+ tags: [...containerTags, "auto-capture"],
281
+ sessionId: input.sessionID,
282
+ });
283
+ if (result === null) {
284
+ showToast(tui, "🔴 Archive Failed", "Session archive blocked · check spiritual realm status", "error");
285
+ }
286
+ else {
287
+ showToast(tui, "📦 Session Archived", `${messages.length} residual dialogues archived · merged into the realm`, "success");
288
+ }
289
+ }
290
+ catch {
291
+ showToast(tui, "🔴 Archive Failed", "Session archive blocked · spiritual pulse anomaly", "error");
292
+ }
293
+ sessionMessages.delete(input.sessionID);
294
+ }
295
+ }
296
+ }
297
+ try {
298
+ const results = await client.searchMemories("*", 20, undefined, containerTags);
299
+ const block = buildContextBlock(results);
300
+ if (block) {
301
+ output.context.push(block);
302
+ }
303
+ }
304
+ catch {
305
+ }
306
+ };
307
+ }
308
+ const processedMessageIds = new Set();
309
+ const pluginStartTime = Date.now();
310
+ export function sessionIdleHook(omemClient, _containerTags, tui, sdkClient, _ingestMode = "smart", threshold = 0, getMainSessionId, isAutoStoreEnabled) {
311
+ let idleTimeout = null;
312
+ let isCapturing = false;
313
+ return async (input) => {
314
+ if (input.event.type !== "session.idle")
315
+ return;
316
+ const sessionID = input.event.properties?.sessionID;
317
+ if (!sessionID)
318
+ return;
319
+ if (isAutoStoreEnabled && !isAutoStoreEnabled(sessionID))
320
+ return;
321
+ if (getMainSessionId) {
322
+ const mainId = getMainSessionId();
323
+ if (mainId && sessionID !== mainId)
324
+ return;
325
+ }
326
+ if (idleTimeout)
327
+ clearTimeout(idleTimeout);
328
+ idleTimeout = setTimeout(async () => {
329
+ if (isCapturing)
330
+ return;
331
+ isCapturing = true;
332
+ try {
333
+ const response = await sdkClient.session.messages({ path: { id: sessionID } });
334
+ if (!response?.data)
335
+ return;
336
+ const messages = response.data;
337
+ const conversationMessages = [];
338
+ const newMessageIds = [];
339
+ let hasNewMessages = false;
340
+ for (const msg of messages) {
341
+ const msgId = msg.info?.id;
342
+ if (!msgId || processedMessageIds.has(msgId))
343
+ continue;
344
+ // Skip messages created before this plugin instance started
345
+ // (prevents replaying entire session history on restart)
346
+ const msgTime = msg.info?.createdAt ? new Date(msg.info.createdAt).getTime() : 0;
347
+ if (msgTime > 0 && msgTime < pluginStartTime)
348
+ continue;
349
+ const role = msg.info?.role;
350
+ if (role !== "user" && role !== "assistant")
351
+ continue;
352
+ const textParts = (msg.parts || [])
353
+ .filter((p) => p.type === "text" && p.text)
354
+ .map((p) => p.text);
355
+ const text = textParts.join("\n").trim();
356
+ if (!text)
357
+ continue;
358
+ hasNewMessages = true;
359
+ newMessageIds.push(msgId);
360
+ conversationMessages.push({ role, content: text });
361
+ }
362
+ if (!hasNewMessages || conversationMessages.length === 0)
363
+ return;
364
+ if (threshold > 1 && conversationMessages.length < threshold) {
365
+ // Log that we're waiting for more messages
366
+ return;
367
+ }
368
+ try {
369
+ await omemClient.sessionIngest(conversationMessages, sessionID);
370
+ for (const id of newMessageIds) {
371
+ processedMessageIds.add(id);
372
+ }
373
+ showToast(tui, "🧠 Memory Sealed", `${conversationMessages.length} dialogues captured · entrusted to the heavens for refinement`, "success");
374
+ }
375
+ catch (err) {
376
+ showToast(tui, "🔴 Session Capture Failed", String(err).substring(0, 100), "error");
377
+ }
378
+ }
379
+ catch (err) {
380
+ const errMsg = err instanceof Error ? err.message : String(err);
381
+ showToast(tui, "🔴 Idle Capture Error", errMsg.substring(0, 100), "error");
382
+ }
383
+ finally {
384
+ isCapturing = false;
385
+ idleTimeout = null;
386
+ }
387
+ }, 10000);
388
+ };
389
+ }
390
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ export declare function isAutoStoreEnabled(sessionId: string | undefined): boolean;
3
+ export declare function setAutoStoreEnabled(sessionId: string, enabled: boolean): void;
4
+ declare const OmemPlugin: Plugin;
5
+ export { OmemPlugin };
6
+ declare const _default: {
7
+ id: string;
8
+ server: Plugin;
9
+ };
10
+ export default _default;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAyBlD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGzE;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAE7E;AAuBD,QAAA,MAAM,UAAU,EAAE,MAgGjB,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,CAAC;;;;;AAEtB,wBAGE"}
package/dist/index.js ADDED
@@ -0,0 +1,142 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join, dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { OmemClient } from "./client.js";
5
+ import { autoRecallHook, compactingHook, keywordDetectionHook, sessionIdleHook } from "./hooks.js";
6
+ import { getUserTag, getProjectTag } from "./tags.js";
7
+ import { buildTools } from "./tools.js";
8
+ import { logInfo, logError } from "./logger.js";
9
+ import { loadPluginConfig } from "./config.js";
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+ let pluginVersion = "unknown";
13
+ try {
14
+ const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
15
+ if (pkg?.version && typeof pkg.version === "string") {
16
+ pluginVersion = pkg.version;
17
+ }
18
+ }
19
+ catch { }
20
+ // Per-session auto-store toggle: sessionId → enabled (default: true = auto-store on)
21
+ const autoStoreSessions = new Map();
22
+ export function isAutoStoreEnabled(sessionId) {
23
+ if (!sessionId)
24
+ return true;
25
+ return autoStoreSessions.get(sessionId) ?? true;
26
+ }
27
+ export function setAutoStoreEnabled(sessionId, enabled) {
28
+ autoStoreSessions.set(sessionId, enabled);
29
+ }
30
+ // Bridge for TUI plugin (same process, different module graph)
31
+ globalThis.__cerebro_autoStore = isAutoStoreEnabled;
32
+ function showToast(tui, title, message, variant = "info", duration = 5000) {
33
+ if (!tui)
34
+ return;
35
+ setTimeout(() => {
36
+ try {
37
+ const body = { variant, duration };
38
+ if (message) {
39
+ body.title = title;
40
+ body.message = message;
41
+ }
42
+ else {
43
+ body.message = title;
44
+ }
45
+ tui.showToast({ body });
46
+ }
47
+ catch (err) {
48
+ console.error("[cerebro] showToast failed:", err);
49
+ }
50
+ }, 3000);
51
+ }
52
+ const OmemPlugin = async (input) => {
53
+ const { directory, client } = input;
54
+ // Proxy: dynamically resolve client.tui on each access so toast works
55
+ // even if client.tui isn't ready yet at plugin init time
56
+ const tui = new Proxy({}, {
57
+ get(_, prop) {
58
+ return client?.tui?.[prop];
59
+ },
60
+ });
61
+ // Load overrides from opencode.json plugin_config
62
+ let overrides = {};
63
+ try {
64
+ const ocCfg = JSON.parse(readFileSync(join(directory, "opencode.json"), "utf-8"));
65
+ const pc = ocCfg?.plugin_config?.["@mingxy/omem"] || ocCfg?.plugin_config?.["@ourmem/opencode"];
66
+ if (pc)
67
+ overrides = pc;
68
+ }
69
+ catch { }
70
+ const config = loadPluginConfig(overrides);
71
+ const omemClient = new OmemClient(config.apiUrl, config.apiKey, config);
72
+ // 启动时检测连接状态
73
+ try {
74
+ await omemClient.getStats();
75
+ showToast(tui, "🧠 Cerebro", `v${pluginVersion} · Connected`, "success", 6000);
76
+ logInfo(`Connected to ${config.apiUrl}`);
77
+ }
78
+ catch (err) {
79
+ const errMsg = err instanceof Error ? err.message : String(err);
80
+ logError(`Connection failed: ${errMsg}`);
81
+ if (errMsg.includes("[omem]")) {
82
+ const cleanMsg = errMsg.replace(/^\[omem\]\s*/, "");
83
+ showToast(tui, `🧠 Cerebro v${pluginVersion} · Server Error`, cleanMsg.substring(0, 150), "error", 8000);
84
+ }
85
+ else {
86
+ showToast(tui, `🧠 Cerebro v${pluginVersion} · Connection Failed`, `Unable to reach ${config.apiUrl}`, "error", 8000);
87
+ }
88
+ }
89
+ const email = process.env.GIT_AUTHOR_EMAIL || process.env.USER || "unknown";
90
+ const cwd = directory || process.cwd();
91
+ const containerTags = [getUserTag(email), getProjectTag(cwd)];
92
+ const agentId = process.env.OMEM_AGENT_ID || "opencode";
93
+ let currentSessionId;
94
+ const recallHook = autoRecallHook(omemClient, containerTags, tui, config);
95
+ return {
96
+ config: async (cfg) => {
97
+ cfg.command ??= {};
98
+ cfg.command["memory-toggle"] = {
99
+ template: "Toggle Cerebro auto-store to $ARGUMENTS for this session.",
100
+ description: "Toggle Cerebro auto-store ON or OFF for current session",
101
+ };
102
+ },
103
+ "command.execute.before": async (input, output) => {
104
+ if (input.command !== "memory-toggle")
105
+ return;
106
+ const arg = input.arguments.trim().toLowerCase();
107
+ const sessionId = input.sessionID;
108
+ if (arg === "off") {
109
+ setAutoStoreEnabled(sessionId, false);
110
+ output.parts = [{ type: "text", text: "⏸️ Cerebro auto-store: OFF — manual memory_store still works" }];
111
+ }
112
+ else if (arg === "on") {
113
+ setAutoStoreEnabled(sessionId, true);
114
+ output.parts = [{ type: "text", text: "✅ Cerebro auto-store: ON" }];
115
+ }
116
+ else {
117
+ const current = isAutoStoreEnabled(sessionId);
118
+ output.parts = [{ type: "text", text: `Cerebro auto-store: ${current ? "✅ ON" : "⏸️ OFF"}\nUsage: /memory-toggle on | off` }];
119
+ }
120
+ },
121
+ "experimental.chat.system.transform": async (input, output) => {
122
+ if (input.sessionID)
123
+ currentSessionId = input.sessionID;
124
+ return recallHook(input, output);
125
+ },
126
+ "chat.message": keywordDetectionHook(omemClient, containerTags, config.autoCaptureThreshold, tui, config.ingestMode),
127
+ "experimental.session.compacting": compactingHook(omemClient, containerTags, tui, config.ingestMode, isAutoStoreEnabled),
128
+ tool: buildTools(omemClient, containerTags, { agentId, getSessionId: () => currentSessionId }),
129
+ event: sessionIdleHook(omemClient, containerTags, tui, client, config.ingestMode, config.autoCaptureThreshold, () => currentSessionId, isAutoStoreEnabled),
130
+ "shell.env": async (_input, output) => {
131
+ if (directory) {
132
+ output.env.OMEM_PROJECT_DIR = directory;
133
+ }
134
+ },
135
+ };
136
+ };
137
+ export { OmemPlugin };
138
+ export default {
139
+ id: "ourmem",
140
+ server: OmemPlugin,
141
+ };
142
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function detectKeyword(text: string): boolean;
2
+ export declare const KEYWORD_NUDGE: string;
3
+ //# sourceMappingURL=keywords.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keywords.d.ts","sourceRoot":"","sources":["../src/keywords.ts"],"names":[],"mappings":"AAeA,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED,eAAO,MAAM,aAAa,QAE+D,CAAC"}
@@ -0,0 +1,21 @@
1
+ const KEYWORDS = [
2
+ "remember",
3
+ "save this",
4
+ "don't forget",
5
+ "keep in mind",
6
+ "note that",
7
+ "store this",
8
+ "memorize",
9
+ "记住",
10
+ "记一下",
11
+ "保存",
12
+ "记下来",
13
+ "别忘了",
14
+ ];
15
+ export function detectKeyword(text) {
16
+ const lower = text.toLowerCase();
17
+ return KEYWORDS.some((kw) => lower.includes(kw));
18
+ }
19
+ export const KEYWORD_NUDGE = "The user appears to want you to remember something. " +
20
+ "Consider using the `memory_store` tool to save this information for future reference.";
21
+ //# sourceMappingURL=keywords.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keywords.js","sourceRoot":"","sources":["../src/keywords.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAsB;IAClC,UAAU;IACV,WAAW;IACX,cAAc;IACd,cAAc;IACd,WAAW;IACX,YAAY;IACZ,UAAU;IACV,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,KAAK;IACL,KAAK;CACG,CAAC;AAEX,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GACxB,sDAAsD;IACtD,uFAAuF,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function logInfo(...args: unknown[]): void;
2
+ export declare function logWarn(...args: unknown[]): void;
3
+ export declare function logError(...args: unknown[]): void;
4
+ export declare function logDebug(...args: unknown[]): void;
5
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AA+BA,wBAAgB,OAAO,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAEhD;AAED,wBAAgB,OAAO,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAEhD;AAED,wBAAgB,QAAQ,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAEjD;AAED,wBAAgB,QAAQ,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAEjD"}