fix(openclaw): prevent memory wipe on every session (#323)
Use unique document_id per conversation (sessionKey + timestamp) instead of static sessionKey. The backend CASCADE-deletes old memories when the same document_id is reused, causing all prior facts to be lost. Also: - Universal envelope stripping for all channels (was Telegram-only) - Prefer rawMessage over prompt for cleaner recall queries - Increase recall max_tokens from 512 to 2048 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d90588b3e1
commit
981cf6057f
1 changed files with 33 additions and 9 deletions
|
|
@ -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({
|
||||
|
|
|
|||
Loading…
Reference in a new issue