@mingxy/cerebro 1.12.0 → 1.12.2
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/package.json +1 -1
- package/src/hooks.ts +14 -6
- package/src/tools.ts +7 -7
package/package.json
CHANGED
package/src/hooks.ts
CHANGED
|
@@ -323,7 +323,7 @@ export function autoRecallHook(client: CerebroClient, containerTags: string[], t
|
|
|
323
323
|
if (policy === "none") return;
|
|
324
324
|
|
|
325
325
|
try {
|
|
326
|
-
logDebug("autoRecallHook start", { sessionId: input.sessionID, agentId, policy });
|
|
326
|
+
logDebug("autoRecallHook start", { sessionId: input.sessionID, agentId, policy, similarityThreshold, maxRecallResults, fetchMultiplier, topkCapMultiplier, mmrJaccardThreshold, mmrPenaltyFactor, phase2Multiplier, llmMaxEval, refineStrategy, refineMediumChars });
|
|
327
327
|
const messages = sessionMessages.get(input.sessionID) ?? [];
|
|
328
328
|
const userMessages = messages.filter((m) => m.role === "user");
|
|
329
329
|
|
|
@@ -379,13 +379,13 @@ export function autoRecallHook(client: CerebroClient, containerTags: string[], t
|
|
|
379
379
|
let profileCountText = "";
|
|
380
380
|
let profileBlock = "";
|
|
381
381
|
const lastInjected = profileInjectedSessions.get(input.sessionID);
|
|
382
|
-
const ttlExpired = !lastInjected || (Date.now() - lastInjected >
|
|
382
|
+
const ttlExpired = !lastInjected || (Date.now() - lastInjected > 30 * 60 * 1000);
|
|
383
383
|
const isFirstInjection = !lastInjected;
|
|
384
384
|
if (profile && ttlExpired) {
|
|
385
385
|
const prefs = ((profile as any)?.static_facts ?? [])
|
|
386
386
|
.filter((sf: any) => {
|
|
387
387
|
const t: string[] = sf.tags ?? [];
|
|
388
|
-
return t.includes("preferences")
|
|
388
|
+
return t.includes("preferences");
|
|
389
389
|
})
|
|
390
390
|
.map((sf: any) => sf.l2_content ?? sf.content ?? "")
|
|
391
391
|
.filter(Boolean);
|
|
@@ -633,6 +633,13 @@ export function compactingHook(client: CerebroClient, containerTags: string[], t
|
|
|
633
633
|
output.context.push(block);
|
|
634
634
|
output.context.push(FETCH_POLICY);
|
|
635
635
|
}
|
|
636
|
+
// 将compacting搜索结果的ID写入injectedMemoryIds,避免后续autoRecall重复注入
|
|
637
|
+
if (input.sessionID && results.length > 0) {
|
|
638
|
+
const compactingIds = results.map((r) => r.memory.id);
|
|
639
|
+
const existing = injectedMemoryIds.get(input.sessionID) ?? new Set<string>();
|
|
640
|
+
injectedMemoryIds.set(input.sessionID, new Set([...existing, ...compactingIds]));
|
|
641
|
+
logDebug("compactingHook updated injectedMemoryIds", { sessionId: input.sessionID, addedCount: compactingIds.length, totalExisting: existing.size });
|
|
642
|
+
}
|
|
636
643
|
} catch {
|
|
637
644
|
}
|
|
638
645
|
|
|
@@ -652,7 +659,6 @@ export function compactingHook(client: CerebroClient, containerTags: string[], t
|
|
|
652
659
|
if (input.sessionID) {
|
|
653
660
|
sessionMessages.delete(input.sessionID);
|
|
654
661
|
profileInjectedSessions.delete(input.sessionID);
|
|
655
|
-
injectedMemoryIds.delete(input.sessionID);
|
|
656
662
|
firstMessages.delete(input.sessionID);
|
|
657
663
|
}
|
|
658
664
|
return;
|
|
@@ -679,7 +685,6 @@ export function compactingHook(client: CerebroClient, containerTags: string[], t
|
|
|
679
685
|
if (isAutoStoreEnabled && !isAutoStoreEnabled(input.sessionID)) {
|
|
680
686
|
sessionMessages.delete(input.sessionID);
|
|
681
687
|
profileInjectedSessions.delete(input.sessionID);
|
|
682
|
-
injectedMemoryIds.delete(input.sessionID);
|
|
683
688
|
firstMessages.delete(input.sessionID);
|
|
684
689
|
} else {
|
|
685
690
|
const messages = sessionMessages.get(input.sessionID)!;
|
|
@@ -708,8 +713,11 @@ export function compactingHook(client: CerebroClient, containerTags: string[], t
|
|
|
708
713
|
// Cleanup tracked messages regardless of ingest result
|
|
709
714
|
sessionMessages.delete(input.sessionID);
|
|
710
715
|
profileInjectedSessions.delete(input.sessionID);
|
|
711
|
-
injectedMemoryIds.delete(input.sessionID);
|
|
712
716
|
firstMessages.delete(input.sessionID);
|
|
717
|
+
// Evict stale injectedMemoryIds if over size cap (200 sessions)
|
|
718
|
+
if (injectedMemoryIds.size > 200) {
|
|
719
|
+
injectedMemoryIds.clear();
|
|
720
|
+
}
|
|
713
721
|
}
|
|
714
722
|
|
|
715
723
|
// Phase 2: compact inserts "[restore checkpointed" user message — poll for that marker
|
package/src/tools.ts
CHANGED
|
@@ -52,17 +52,17 @@ export function buildTools(client: CerebroClient, containerTags: string[], conte
|
|
|
52
52
|
"Do NOT overuse 'private' for normal work notes — default 'global' is correct for most cases."
|
|
53
53
|
),
|
|
54
54
|
category: tool.schema
|
|
55
|
-
.
|
|
55
|
+
.enum(["cases", "preferences", "entities", "events", "profile", "patterns"])
|
|
56
56
|
.optional()
|
|
57
57
|
.describe(
|
|
58
|
-
"MUST be one of
|
|
59
|
-
"'cases' (default) = work records, bug fixes, architecture decisions
|
|
60
|
-
"'preferences' = user likes/dislikes, coding style
|
|
61
|
-
"'entities' = projects, tools, people, concepts
|
|
58
|
+
"Memory category. MUST be one of these exact values (lowercase): " +
|
|
59
|
+
"'cases' (default) = work records, bug fixes, architecture decisions; " +
|
|
60
|
+
"'preferences' = user likes/dislikes, coding style, tool choices; " +
|
|
61
|
+
"'entities' = projects, tools, people, concepts; " +
|
|
62
62
|
"'events' = time-bound milestones (deployments, releases, incidents); " +
|
|
63
63
|
"'profile' = user identity traits (role, skills, team membership); " +
|
|
64
|
-
"'patterns' = workflows, methodologies, best practices
|
|
65
|
-
"When in doubt,
|
|
64
|
+
"'patterns' = workflows, methodologies, best practices. " +
|
|
65
|
+
"When in doubt, omit this field (defaults to 'cases')."
|
|
66
66
|
),
|
|
67
67
|
},
|
|
68
68
|
async execute(args) {
|