Files
TORCH/scripts/memory/retrieve.mjs
T
thePR0M3TH3ANandClaude Sonnet 4.6 8a9080e7c3 fix(memory): close the content gap so agents can actually write and retrieve learnings
- run-selected-prompt.mjs: set SCHEDULER_MEMORY_FILE env var before spawning each agent so
  store.mjs has a well-known path to read from (memory-updates/<ts>__<agent>.md)
- retrieve.mjs: format memories.md using m.summary + date/tags in readable markdown sections
  instead of raw m.content blobs; agents can now scan injected context at a glance
- store.mjs: remove semantically-empty fallback placeholder events that polluted the store
  and degraded retrieval quality; also fix default cadence 'weekly' -> 'daily' to match retrieve
- scheduler-flow.md: replace vague "write insights" instruction with a concrete three-section
  template (Key findings / Patterns / Warnings) and clarify that $SCHEDULER_MEMORY_FILE is
  set by the scheduler automatically

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-02-20 10:51:03 -05:00

105 lines
3.9 KiB
JavaScript

import { ingestEvents, getRelevantMemories } from '../../src/services/memory/index.js';
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import path from 'node:path';
// Parse environment variables
const fallbackCadence = 'daily';
const cadence = process.env.SCHEDULER_CADENCE || fallbackCadence;
const agentId = process.env.SCHEDULER_AGENT || `scheduler-memory-${cadence}`;
const promptPath = process.env.SCHEDULER_PROMPT_PATH || '';
const runId = process.env.SCHEDULER_RUN_ID ||
process.env.SCHEDULER_SESSION_ID ||
process.env.RUN_ID ||
`session-${Date.now().toString(36)}`;
// Extract prompt intent
let promptIntent = `scheduler memory retrieval`;
if (promptPath) {
try {
const promptRaw = readFileSync(promptPath, 'utf8');
const promptLines = promptRaw.split(/\r?\n/).map(line => line.trim()).filter(Boolean);
const intentLine = promptLines.find(line => line.startsWith('#') || line.toLowerCase().startsWith('goal'));
if (intentLine) {
promptIntent = intentLine.replace(/^#+\s*/, '');
} else if (promptLines.length > 0) {
promptIntent = promptLines[0];
}
} catch (err) {
console.warn(`Could not read prompt file: ${promptPath}`, err.message);
}
}
// Construct query
const query = ['scheduler', cadence, 'agent', agentId, 'intent', promptIntent].join(' | ');
const timestamp = Date.now();
// Create retrieval seed event
const events = [{
agent_id: agentId,
content: `Memory retrieval seed for ${cadence} :: ${promptIntent}`,
timestamp,
tags: ['scheduler', cadence, 'retrieve'],
metadata: {
session_id: runId,
source: 'scheduler-retrieve',
importance: 0.4,
prompt_path: promptPath
}
}];
try {
// 1. Ingest seed event
const ingested = await ingestEvents(events, { agent_id: agentId });
// 2. Retrieve memories
const retrieved = await getRelevantMemories({ agent_id: agentId, query, k: 5 });
// 3. Prepare artifacts
const sessionDir = path.join('.scheduler-memory', runId);
const latestDir = path.join('.scheduler-memory', 'latest', cadence);
mkdirSync(sessionDir, { recursive: true });
mkdirSync(latestDir, { recursive: true });
const artifact = {
cadence,
operation: 'retrieve',
runId,
servicePath: 'src/services/memory/index.js#getRelevantMemories',
inputs: {
agentId,
promptPath,
promptIntent,
query,
events: events.length
},
outputs: {
ingestedCount: ingested.length,
retrievedCount: retrieved.length
},
status: 'ok'
};
// 4. Write artifacts
writeFileSync(path.join(sessionDir, 'retrieve.json'), JSON.stringify(artifact, null, 2));
writeFileSync(path.join(sessionDir, 'retrieve.ok'), 'MEMORY_RETRIEVED\n');
writeFileSync(path.join(latestDir, 'retrieve.ok'), 'MEMORY_RETRIEVED\n');
// Format retrieved memories as readable markdown sections.
// Prefer m.summary (compact excerpt) over m.content (full blob) for prompt injection.
const memoriesMarkdown = retrieved.length > 0
? retrieved.map((m, i) => {
const date = new Date(m.created_at || m.last_seen || Date.now()).toISOString().split('T')[0];
const tagStr = Array.isArray(m.tags) && m.tags.length > 0 ? m.tags.join(', ') : '';
const text = (m.summary || m.content || '').trim();
return `### ${i + 1}. [${date}]${tagStr ? ` (${tagStr})` : ''}\n\n${text}`;
}).join('\n\n---\n\n')
: '_No memories found for this agent. This may be the first run or the memory store is empty._';
writeFileSync(path.join(latestDir, 'memories.md'), memoriesMarkdown);
// 5. Output success marker to stdout (for scheduler verification)
console.log('MEMORY_RETRIEVED');
} catch (error) {
console.error('Memory retrieval failed:', error);
process.exit(1);
}