diff --git a/hindsight-integrations/openclaw/src/index.ts b/hindsight-integrations/openclaw/src/index.ts index feafb5fc..a05a0730 100644 --- a/hindsight-integrations/openclaw/src/index.ts +++ b/hindsight-integrations/openclaw/src/index.ts @@ -554,17 +554,40 @@ export default function (api: MoltbotPluginAPI) { console.log(`[Hindsight] before_agent_start - bank: ${bankId}, channel: ${ctx?.messageProvider}/${ctx?.channelId}`); // Get the user's latest message for recall - let prompt = event.prompt; + // Prefer rawMessage (clean user text) over prompt (envelope-formatted) + let prompt = event.rawMessage ?? event.prompt; if (!prompt || typeof prompt !== 'string' || prompt.length < 5) { return; // Skip very short messages } - // Extract actual message from Telegram format: [Telegram ... GMT+1] actual message - const telegramMatch = prompt.match(/\[Telegram[^\]]+\]\s*(.+)$/); - if (telegramMatch) { - prompt = telegramMatch[1].trim(); + // Strip envelope-formatted prompts from any channel + // The prompt may contain: System: lines, abort hints, [Channel ...] header, [from: ...] suffix + let cleaned = prompt; + + // Remove leading "System: ..." lines (from prependSystemEvents) + cleaned = cleaned.replace(/^(?:System:.*\n)+\n?/, ''); + + // Remove session abort hint + cleaned = cleaned.replace( + /^Note: The previous agent run was aborted[^\n]*\n\n/, + '', + ); + + // Extract message after [ChannelName ...] envelope header + // Handles any channel: Telegram, Slack, Discord, WhatsApp, Signal, etc. + // Uses [\s\S]+ instead of .+ to support multiline messages + const envelopeMatch = cleaned.match( + /\[[A-Z][A-Za-z]*(?:\s[^\]]+)?\]\s*([\s\S]+)$/, + ); + if (envelopeMatch) { + cleaned = envelopeMatch[1]; } + // Remove trailing [from: SenderName] metadata (group chats) + cleaned = cleaned.replace(/\n\[from:[^\]]*\]\s*$/, ''); + + prompt = cleaned.trim() || prompt; + if (prompt.length < 5) { return; // Skip very short messages after extraction } @@ -587,10 +610,10 @@ export default function (api: MoltbotPluginAPI) { console.log(`[Hindsight] Auto-recall for bank ${bankId}, prompt: ${prompt.substring(0, 50)}`); - // Recall relevant memories (up to 512 tokens) + // Recall relevant memories const response = await client.recall({ query: prompt, - max_tokens: 512, + max_tokens: 2048, }); if (!response.results || response.results.length === 0) { @@ -675,8 +698,9 @@ User message: ${prompt} return; } - // Use session key as document ID (prefer context over captured value) - const documentId = effectiveCtx?.sessionKey || currentSessionKey || 'default-session'; + // Use unique document ID per conversation (sessionKey + timestamp) + // Static sessionKey (e.g. "agent:main:main") causes CASCADE delete of old memories + const documentId = `${effectiveCtx?.sessionKey || currentSessionKey || 'session'}-${Date.now()}`; // Retain to Hindsight await client.retain({