@mingxy/cerebro 1.11.9 โ 1.11.10
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 +103 -0
- package/src/index.ts +2 -1
package/package.json
CHANGED
package/src/hooks.ts
CHANGED
|
@@ -653,6 +653,109 @@ export function compactingHook(client: CerebroClient, containerTags: string[], t
|
|
|
653
653
|
};
|
|
654
654
|
}
|
|
655
655
|
|
|
656
|
+
export function autocontinueHook(
|
|
657
|
+
client: CerebroClient,
|
|
658
|
+
containerTags: string[],
|
|
659
|
+
tui: any,
|
|
660
|
+
ingestMode: "smart" | "raw" = "smart",
|
|
661
|
+
isAutoStoreEnabled?: (sessionId: string | undefined) => boolean,
|
|
662
|
+
getMainSessionId?: () => string | undefined,
|
|
663
|
+
sdkClient?: any,
|
|
664
|
+
config: Partial<OmemPluginConfig> = {},
|
|
665
|
+
agentId?: string,
|
|
666
|
+
) {
|
|
667
|
+
const effectiveAgentId = agentId || process.env.OMEM_AGENT_ID || "opencode";
|
|
668
|
+
return async (
|
|
669
|
+
input: {
|
|
670
|
+
sessionID: string;
|
|
671
|
+
agent: string;
|
|
672
|
+
model: Model;
|
|
673
|
+
message: UserMessage;
|
|
674
|
+
overflow: boolean;
|
|
675
|
+
},
|
|
676
|
+
_output: { enabled: boolean },
|
|
677
|
+
) => {
|
|
678
|
+
try {
|
|
679
|
+
const policy = resolveAgentPolicy(effectiveAgentId, config);
|
|
680
|
+
if (policy !== "readwrite") {
|
|
681
|
+
logInfo("autocontinueHook blocked by policy", { agentId: effectiveAgentId, policy });
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
if (isAutoStoreEnabled && !isAutoStoreEnabled(input.sessionID)) {
|
|
686
|
+
logInfo("autocontinueHook skipped: auto-store disabled", { sessionId: input.sessionID });
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
const effectiveSessionId = getMainSessionId?.() || input.sessionID;
|
|
691
|
+
|
|
692
|
+
if (!sdkClient) {
|
|
693
|
+
logInfo("autocontinueHook skipped: no sdkClient", { sessionId: input.sessionID });
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
let summaryText: string | undefined;
|
|
698
|
+
try {
|
|
699
|
+
const response = await sdkClient.session.messages({ path: { id: input.sessionID } });
|
|
700
|
+
if (response?.data) {
|
|
701
|
+
const targetMsg = response.data.find(
|
|
702
|
+
(msg: any) => msg.info?.id === input.message.id,
|
|
703
|
+
);
|
|
704
|
+
if (targetMsg?.parts) {
|
|
705
|
+
const textParts = (targetMsg.parts as any[])
|
|
706
|
+
.filter((p: any) => p.type === "text" && p.text)
|
|
707
|
+
.map((p: any) => p.text);
|
|
708
|
+
summaryText = textParts.join("\n").trim();
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
} catch (e) {
|
|
712
|
+
logErr("autocontinueHook failed to fetch message parts", { error: String(e) });
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
if (!summaryText) {
|
|
716
|
+
logInfo("autocontinueHook skipped: no summary text found", { sessionId: input.sessionID, messageId: input.message.id });
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
let projectName: string | undefined;
|
|
721
|
+
try {
|
|
722
|
+
const sessionInfo = await sdkClient.session.get({ path: { id: input.sessionID } });
|
|
723
|
+
projectName = sessionInfo?.data?.directory
|
|
724
|
+
? await detectProjectName(sessionInfo.data.directory)
|
|
725
|
+
: undefined;
|
|
726
|
+
} catch (e) {
|
|
727
|
+
logErr("autocontinueHook detectProjectName failed", { error: String(e) });
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
const messages = [{ role: "user" as const, content: summaryText }];
|
|
731
|
+
logInfo("autocontinueHook storing compact summary", {
|
|
732
|
+
summaryLen: summaryText.length,
|
|
733
|
+
sessionId: effectiveSessionId,
|
|
734
|
+
agentId: effectiveAgentId,
|
|
735
|
+
overflow: input.overflow,
|
|
736
|
+
projectName,
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
const result = await client.ingestMessages(messages, {
|
|
740
|
+
mode: ingestMode,
|
|
741
|
+
tags: [...containerTags, "auto-capture", "compact-summary"],
|
|
742
|
+
sessionId: effectiveSessionId,
|
|
743
|
+
projectName: projectName,
|
|
744
|
+
agentId: effectiveAgentId,
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
logInfo("autocontinueHook store result", { result: result === null ? "null(blocked)" : "ok" });
|
|
748
|
+
if (result === null) {
|
|
749
|
+
showToast(tui, "๐ด Compact Summary Failed", "Storage blocked ยท check server status", "error");
|
|
750
|
+
} else {
|
|
751
|
+
showToast(tui, "๐ฆ Compact Summary Stored", "Session summary archived to memory", "success");
|
|
752
|
+
}
|
|
753
|
+
} catch (e) {
|
|
754
|
+
logErr("autocontinueHook failed", { error: String(e) });
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
|
|
656
759
|
const processedMessageIds = new Set<string>();
|
|
657
760
|
const pluginStartTime = Date.now();
|
|
658
761
|
|
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, compactingHook, keywordDetectionHook, sessionIdleHook } from "./hooks.js";
|
|
7
|
+
import { autoRecallHook, autocontinueHook, compactingHook, keywordDetectionHook, sessionIdleHook } 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";
|
|
@@ -140,6 +140,7 @@ const OmemPlugin: Plugin = async (input) => {
|
|
|
140
140
|
},
|
|
141
141
|
"chat.message": keywordDetectionHook(cerebroClient, containerTags, config.ingest.autoCaptureThreshold, tui, config.ingest.ingestMode, config, agentId),
|
|
142
142
|
"experimental.session.compacting": compactingHook(cerebroClient, containerTags, tui, config.ingest.ingestMode, isAutoStoreEnabled, () => mainSessionId, client, config, agentId),
|
|
143
|
+
"experimental.compaction.autocontinue": autocontinueHook(cerebroClient, containerTags, tui, config.ingest.ingestMode, isAutoStoreEnabled, () => mainSessionId, client, config, agentId),
|
|
143
144
|
tool: buildTools(cerebroClient, containerTags, { agentId, getSessionId: () => mainSessionId, getAgentName: () => cachedAgentName || agentId }),
|
|
144
145
|
event: sessionIdleHook(cerebroClient, containerTags, tui, client, config.ingest.ingestMode, config.ingest.autoCaptureThreshold, () => mainSessionId, isAutoStoreEnabled, agentId, config, (name: string) => { cachedAgentName = name; }),
|
|
145
146
|
"shell.env": async (_input: any, output: any) => {
|