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:
```json
{
"hooks": {
"internal": {
"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 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<string | null> {
async function getRecentSessionContent(
sessionFilePath: string,
messageCount: number,
): Promise<string | null> {
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<string
? msg.content.find((c: any) => 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<string
}
}
return messages.join("\n");
// THEN take the last N conversation messages
const selectedMessages = conversationMessages.slice(-messageCount);
return selectedMessages.join("\n");
} catch {
return null;
}
@ -97,8 +108,21 @@ const saveSessionToMemory: HookHandler = async (event) => {
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) {