From 39956087a5b9e100f840a4dbf6157ebbecaece9f Mon Sep 17 00:00:00 2001 From: TarakNathJana Date: Tue, 27 Jan 2026 15:50:04 +0530 Subject: [PATCH] feat(hooks): Make session-memory message count configurable (#2681) --- src/hooks/bundled/session-memory/HOOK.md | 7 +++- src/hooks/bundled/session-memory/handler.ts | 46 ++++++++++++++++----- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/hooks/bundled/session-memory/HOOK.md b/src/hooks/bundled/session-memory/HOOK.md index cc3eab0a2..59b7000a5 100644 --- a/src/hooks/bundled/session-memory/HOOK.md +++ b/src/hooks/bundled/session-memory/HOOK.md @@ -74,13 +74,18 @@ clawdbot hooks disable session-memory Or remove it from your config: ```json + { "hooks": { "internal": { "entries": { - "session-memory": { "enabled": false } + "session-memory": { + "enabled": true, + "messages": 100 + } } } } } + ``` diff --git a/src/hooks/bundled/session-memory/handler.ts b/src/hooks/bundled/session-memory/handler.ts index 14b486fcc..1a70e737d 100644 --- a/src/hooks/bundled/session-memory/handler.ts +++ b/src/hooks/bundled/session-memory/handler.ts @@ -13,20 +13,28 @@ import { resolveAgentWorkspaceDir } from "../../../agents/agent-scope.js"; import { resolveAgentIdFromSessionKey } from "../../../routing/session-key.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 */ -async function getRecentSessionContent(sessionFilePath: string): Promise { +async function getRecentSessionContent( + sessionFilePath: string, + messageCount: number, +): Promise { try { 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 recentLines = lines.slice(-15); + const lines = content.split("\n"); - // Parse JSONL and extract messages - const messages: string[] = []; - for (const line of recentLines) { + // Parse JSONL and extract ONLY user and assistant messages FIRST + const conversationMessages: string[] = []; + + for (const line of lines) { try { const entry = JSON.parse(line); // Session files have entries with type="message" containing a nested message object @@ -39,7 +47,7 @@ async function getRecentSessionContent(sessionFilePath: string): Promise c.type === "text")?.text : msg.content; if (text && !text.startsWith("/")) { - messages.push(`${role}: ${text}`); + conversationMessages.push(`${role}: ${text}`); } } } @@ -48,7 +56,10 @@ async function getRecentSessionContent(sessionFilePath: string): Promise { let sessionContent: string | null = null; if (sessionFile) { - // Get recent conversation content - sessionContent = await getRecentSessionContent(sessionFile); + // Read hook config for message count + 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); if (sessionContent && cfg) {