feat(hooks): Make session-memory message count configurable (#2681)

This commit is contained in:
TarakNathJana 2026-01-27 15:50:04 +05:30
parent 2ad550abe8
commit 39956087a5
2 changed files with 41 additions and 12 deletions

View File

@ -74,13 +74,18 @@ clawdbot hooks disable session-memory
Or remove it from your config: Or remove it from your config:
```json ```json
{ {
"hooks": { "hooks": {
"internal": { "internal": {
"entries": { "entries": {
"session-memory": { "enabled": false } "session-memory": {
"enabled": true,
"messages": 100
}
} }
} }
} }
} }
``` ```

View File

@ -13,20 +13,28 @@ import { resolveAgentWorkspaceDir } from "../../../agents/agent-scope.js";
import { resolveAgentIdFromSessionKey } from "../../../routing/session-key.js"; import { resolveAgentIdFromSessionKey } from "../../../routing/session-key.js";
import type { HookHandler } from "../../hooks.js"; import type { HookHandler } from "../../hooks.js";
/**
* Default number of conversation messages to capture
*/
const DEFAULT_MESSAGE_COUNT = 15;
/** /**
* Read recent messages from session file for slug generation * Read recent messages from session file for slug generation
*/ */
async function getRecentSessionContent(sessionFilePath: string): Promise<string | null> { async function getRecentSessionContent(
sessionFilePath: string,
messageCount: number,
): Promise<string | null> {
try { try {
const content = await fs.readFile(sessionFilePath, "utf-8"); const content = await fs.readFile(sessionFilePath, "utf-8");
const lines = content.trim().split("\n"); if (!content.trim()) return null;
// Get last 15 lines (recent conversation) const lines = content.split("\n");
const recentLines = lines.slice(-15);
// Parse JSONL and extract messages // Parse JSONL and extract ONLY user and assistant messages FIRST
const messages: string[] = []; const conversationMessages: string[] = [];
for (const line of recentLines) {
for (const line of lines) {
try { try {
const entry = JSON.parse(line); const entry = JSON.parse(line);
// Session files have entries with type="message" containing a nested message object // Session files have entries with type="message" containing a nested message object
@ -39,7 +47,7 @@ async function getRecentSessionContent(sessionFilePath: string): Promise<string
? msg.content.find((c: any) => c.type === "text")?.text ? msg.content.find((c: any) => c.type === "text")?.text
: msg.content; : msg.content;
if (text && !text.startsWith("/")) { if (text && !text.startsWith("/")) {
messages.push(`${role}: ${text}`); conversationMessages.push(`${role}: ${text}`);
} }
} }
} }
@ -48,7 +56,10 @@ async function getRecentSessionContent(sessionFilePath: string): Promise<string
} }
} }
return messages.join("\n"); // THEN take the last N conversation messages
const selectedMessages = conversationMessages.slice(-messageCount);
return selectedMessages.join("\n");
} catch { } catch {
return null; return null;
} }
@ -97,8 +108,21 @@ const saveSessionToMemory: HookHandler = async (event) => {
let sessionContent: string | null = null; let sessionContent: string | null = null;
if (sessionFile) { if (sessionFile) {
// Get recent conversation content // Read hook config for message count
sessionContent = await getRecentSessionContent(sessionFile); const hookConfig = (context.hooks as any)?.internal?.entries?.["session-memory"] as
| { messages?: number }
| undefined;
let messageCount = hookConfig?.messages ?? DEFAULT_MESSAGE_COUNT;
if (!Number.isInteger(messageCount) || messageCount < 1 || messageCount > 1000) {
console.warn(
`[session-memory] Invalid messages config (${messageCount}), using default ${DEFAULT_MESSAGE_COUNT}`,
);
messageCount = DEFAULT_MESSAGE_COUNT;
}
// Get recent conversation content (correct filtering order)
sessionContent = await getRecentSessionContent(sessionFile, messageCount);
console.log("[session-memory] sessionContent length:", sessionContent?.length || 0); console.log("[session-memory] sessionContent length:", sessionContent?.length || 0);
if (sessionContent && cfg) { if (sessionContent && cfg) {