@mingxy/cerebro 1.15.13 → 1.16.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/client.d.ts +5 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -0
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +2 -6
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -8
- package/dist/config.js.map +1 -1
- package/dist/hooks.d.ts +3 -34
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +118 -727
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -90
- package/dist/index.js.map +1 -1
- package/dist/tools.d.ts +2 -2
- package/package.json +1 -1
- package/schema.json +7 -31
- package/src/client.ts +9 -1
- package/src/config.ts +5 -17
- package/src/hooks.ts +184 -817
- package/src/index.ts +8 -90
package/src/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { join, dirname } from "node:path";
|
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { CerebroClient } from "./client.js";
|
|
7
|
-
import { autoRecallHook,
|
|
7
|
+
import { autoRecallHook, autocontinueHook, compactingHook, keywordDetectionHook, sessionIdleHook, showToast as hooksShowToast } from "./hooks.js";
|
|
8
8
|
import { getUserTag, getProjectTag } from "./tags.js";
|
|
9
9
|
import { buildTools } from "./tools.js";
|
|
10
10
|
import { logInfo, logDebug, logError } from "./logger.js";
|
|
@@ -42,24 +42,6 @@ export function setAutoStoreEnabled(sessionId: string, enabled: boolean): void {
|
|
|
42
42
|
|
|
43
43
|
(globalThis as any).__cerebro_autoStoreMap = autoStoreSessions;
|
|
44
44
|
|
|
45
|
-
function showToast(tui: any, title: string, message?: string, variant: string = "info", duration: number = 5000) {
|
|
46
|
-
if (!tui) return;
|
|
47
|
-
setTimeout(() => {
|
|
48
|
-
try {
|
|
49
|
-
const body: any = { variant, duration };
|
|
50
|
-
if (message) {
|
|
51
|
-
body.title = title;
|
|
52
|
-
body.message = message;
|
|
53
|
-
} else {
|
|
54
|
-
body.message = title;
|
|
55
|
-
}
|
|
56
|
-
tui.showToast({ body });
|
|
57
|
-
} catch (err) {
|
|
58
|
-
logError("showToast failed", { error: String(err) });
|
|
59
|
-
}
|
|
60
|
-
}, 3000);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
45
|
const OmemPlugin: Plugin = async (input) => {
|
|
64
46
|
const { directory, client } = input;
|
|
65
47
|
// Proxy: dynamically resolve client.tui on each access so toast works
|
|
@@ -85,14 +67,14 @@ const OmemPlugin: Plugin = async (input) => {
|
|
|
85
67
|
// 启动时检测连接状态
|
|
86
68
|
try {
|
|
87
69
|
await cerebroClient.getStats();
|
|
88
|
-
|
|
70
|
+
hooksShowToast(tui, "🧠 Cerebro · Connected", `Version v${pluginVersion}`, "success", 6000);
|
|
89
71
|
logInfo(`Connected to ${config.connection.apiUrl}`);
|
|
90
72
|
} catch (err) {
|
|
91
73
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
92
74
|
logError(`Connection failed: ${errMsg}`);
|
|
93
75
|
if (errMsg.includes("[cerebro]")) {
|
|
94
76
|
const cleanMsg = errMsg.replace(/^\[cerebro\]\s*/, "");
|
|
95
|
-
|
|
77
|
+
hooksShowToast(
|
|
96
78
|
tui,
|
|
97
79
|
`🧠 Cerebro v${pluginVersion} · Server Error`,
|
|
98
80
|
cleanMsg.substring(0, 150),
|
|
@@ -100,7 +82,7 @@ const OmemPlugin: Plugin = async (input) => {
|
|
|
100
82
|
8000
|
|
101
83
|
);
|
|
102
84
|
} else {
|
|
103
|
-
|
|
85
|
+
hooksShowToast(
|
|
104
86
|
tui,
|
|
105
87
|
`🧠 Cerebro v${pluginVersion} · Connection Failed`,
|
|
106
88
|
`Unable to reach ${config.connection.apiUrl}`,
|
|
@@ -119,50 +101,7 @@ const OmemPlugin: Plugin = async (input) => {
|
|
|
119
101
|
let mainSessionLocked = false;
|
|
120
102
|
let cachedAgentName: string | undefined;
|
|
121
103
|
|
|
122
|
-
const
|
|
123
|
-
// ── Soul Whisper: inject to system prompt (v2 — system.transform) ──
|
|
124
|
-
if (config.soulWhisper?.enabled !== false) {
|
|
125
|
-
const sid = input.sessionID || "_default";
|
|
126
|
-
const sessionCalls = pendingToolCalls.get(sid);
|
|
127
|
-
if (sessionCalls && sessionCalls.size > 0) {
|
|
128
|
-
const toolNames = [...new Set([...sessionCalls.values()].map(v => v.toolName))];
|
|
129
|
-
const maxToolNames = config.soulWhisper?.maxToolNames ?? 3;
|
|
130
|
-
const whisperText = buildWhisperText(toolNames, maxToolNames);
|
|
131
|
-
if (whisperText) {
|
|
132
|
-
if (output.system.length > 0) {
|
|
133
|
-
output.system[0] += "\n\n" + whisperText;
|
|
134
|
-
} else {
|
|
135
|
-
output.system.push(whisperText);
|
|
136
|
-
}
|
|
137
|
-
logDebug("soulWhisper injected to output.system", { sessionId: sid, toolNames });
|
|
138
|
-
}
|
|
139
|
-
pendingToolCalls.delete(sid);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
// ── Fallback strategy: "parts" (new) vs "system" (legacy) ──
|
|
145
|
-
const strategy = config.injectionStrategy ?? "parts";
|
|
146
|
-
|
|
147
|
-
const chatMessageHook = strategy === "parts"
|
|
148
|
-
? async (input: any, output: any) => {
|
|
149
|
-
// New path: keyword detection + memory injection
|
|
150
|
-
await keywordDetectionHook(cerebroClient, containerTags, config.ingest.autoCaptureThreshold, tui, config.ingest.ingestMode, config, agentId)(input, output);
|
|
151
|
-
await memoryInjectionHook(cerebroClient, containerTags, tui, config, () => cachedAgentName || agentId, directory)(input, output);
|
|
152
|
-
}
|
|
153
|
-
: async (input: any, output: any) => {
|
|
154
|
-
// Fallback: keyword detection only (memory injection via system.transform legacy autoRecallHook)
|
|
155
|
-
await keywordDetectionHook(cerebroClient, containerTags, config.ingest.autoCaptureThreshold, tui, config.ingest.ingestMode, config, agentId)(input, output);
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
const systemTransformHook = strategy === "parts"
|
|
159
|
-
? soulWhisperSystemHook
|
|
160
|
-
: async (input: any, output: any) => {
|
|
161
|
-
// Fallback: legacy autoRecallHook + soulWhisper
|
|
162
|
-
const recallHook = autoRecallHook(cerebroClient, containerTags, tui, config, () => cachedAgentName || agentId, directory);
|
|
163
|
-
await recallHook(input, output);
|
|
164
|
-
await soulWhisperSystemHook(input, output);
|
|
165
|
-
};
|
|
104
|
+
const recallHook = autoRecallHook(cerebroClient, containerTags, tui, config, () => cachedAgentName || agentId, directory);
|
|
166
105
|
|
|
167
106
|
return {
|
|
168
107
|
config: async (cfg: any) => {
|
|
@@ -173,40 +112,19 @@ const OmemPlugin: Plugin = async (input) => {
|
|
|
173
112
|
};
|
|
174
113
|
},
|
|
175
114
|
"experimental.chat.system.transform": async (input: any, output: any) => {
|
|
176
|
-
logDebug("transform input", { sessionID: input.sessionID
|
|
115
|
+
logDebug("transform input", { sessionID: input.sessionID });
|
|
177
116
|
if (input.sessionID && !mainSessionLocked) {
|
|
178
117
|
mainSessionId = input.sessionID;
|
|
179
118
|
mainSessionLocked = true;
|
|
180
119
|
logInfo("mainSessionId locked", { sessionId: input.sessionID });
|
|
181
120
|
}
|
|
182
|
-
|
|
183
|
-
if (sid) {
|
|
184
|
-
const cached = recallCache.get(sid);
|
|
185
|
-
if (!cached || !cached.profileBlock) {
|
|
186
|
-
cerebroClient.getProfile().then(profile => {
|
|
187
|
-
if (profile) {
|
|
188
|
-
const built = buildProfileBlock(profile);
|
|
189
|
-
if (built) {
|
|
190
|
-
recallCache.set(sid, {
|
|
191
|
-
profileBlock: built.block,
|
|
192
|
-
recallResult: null as any,
|
|
193
|
-
profileData: { countText: built.countText },
|
|
194
|
-
timestamp: Date.now(),
|
|
195
|
-
});
|
|
196
|
-
profileInjectedSessions.set(sid, Date.now());
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}).catch(() => {});
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
return systemTransformHook(input, output);
|
|
121
|
+
return recallHook(input, output);
|
|
203
122
|
},
|
|
204
|
-
"chat.message":
|
|
123
|
+
"chat.message": keywordDetectionHook(cerebroClient, containerTags, config.ingest.autoCaptureThreshold, tui, config.ingest.ingestMode, config, agentId),
|
|
205
124
|
"experimental.session.compacting": compactingHook(cerebroClient, containerTags, tui, config.ingest.ingestMode, isAutoStoreEnabled, () => mainSessionId, client, config, agentId, directory),
|
|
206
125
|
"experimental.compaction.autocontinue": autocontinueHook(cerebroClient, containerTags, tui, config.ingest.ingestMode, isAutoStoreEnabled, () => mainSessionId, client, config, agentId, directory),
|
|
207
126
|
tool: buildTools(cerebroClient, containerTags, { agentId, getSessionId: () => mainSessionId, getAgentName: () => cachedAgentName || agentId, getProjectPath: () => directory }),
|
|
208
127
|
event: sessionIdleHook(cerebroClient, containerTags, tui, client, config.ingest.ingestMode, config.ingest.autoCaptureThreshold, () => mainSessionId, isAutoStoreEnabled, agentId, config, (name: string) => { cachedAgentName = name; }, directory),
|
|
209
|
-
"tool.execute.before": (() => { const tracker = soulWhisperToolTracker(config); return tracker; })(),
|
|
210
128
|
"shell.env": async (_input: any, output: any) => {
|
|
211
129
|
if (directory) {
|
|
212
130
|
output.env.OMEM_PROJECT_DIR = directory;
|