Initial commit: OpenClaw Memory System MVP

This commit is contained in:
daotong
2026-04-04 11:15:57 +00:00
commit f18f4daea5
14 changed files with 1389 additions and 0 deletions

199
src/routes/memories.ts Normal file
View File

@@ -0,0 +1,199 @@
import { Request, Response } from 'express';
import memoryService from '../services/memory.service';
import { CreateMemoryInput, UpdateMemoryInput, SearchOptions } from '../models/memory.model';
// POST /api/memories - Create a new memory
export async function createMemory(req: Request, res: Response): Promise<void> {
try {
const input: CreateMemoryInput = req.body;
const memory = await memoryService.create(input);
res.status(201).json({ success: true, data: memory });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// GET /api/memories/:id - Get a memory by ID
export async function getMemory(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params;
const memory = await memoryService.getById(id);
if (!memory) {
res.status(404).json({ success: false, error: 'Memory not found' });
return;
}
// Log access
await memoryService.logAccess(
id,
req.query.context as string,
req.query.session as string
);
res.json({ success: true, data: memory });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// PUT /api/memories/:id - Update a memory
export async function updateMemory(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params;
const input: UpdateMemoryInput = req.body;
const memory = await memoryService.update(id, input);
if (!memory) {
res.status(404).json({ success: false, error: 'Memory not found' });
return;
}
res.json({ success: true, data: memory });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// DELETE /api/memories/:id - Archive a memory
export async function deleteMemory(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params;
const reason = req.body.reason || 'Deleted via API';
const memory = await memoryService.archive(id, reason);
if (!memory) {
res.status(404).json({ success: false, error: 'Memory not found' });
return;
}
res.json({ success: true, data: memory });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// GET /api/memories/search - Search memories
export async function searchMemories(req: Request, res: Response): Promise<void> {
try {
const options: SearchOptions = {
query: req.query.query as string,
type: req.query.type ? (req.query.type as string).split(',') : undefined,
category: req.query.category ? (req.query.category as string).split(',') : undefined,
priority: req.query.priority ? parseInt(req.query.priority as string) : undefined,
priority_min: req.query.priority_min ? parseInt(req.query.priority_min as string) : undefined,
priority_max: req.query.priority_max ? parseInt(req.query.priority_max as string) : undefined,
status: req.query.status ? (req.query.status as string).split(',') : ['active'],
tags: req.query.tags ? (req.query.tags as string).split(',') : undefined,
limit: req.query.limit ? parseInt(req.query.limit as string) : 20,
offset: req.query.offset ? parseInt(req.query.offset as string) : 0,
};
const result = await memoryService.search(options);
res.json({ success: true, ...result });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// GET /api/memories/context - Get context memories for a session
export async function getContext(req: Request, res: Response): Promise<void> {
try {
const session = req.query.session as string;
const limit = req.query.limit ? parseInt(req.query.limit as string) : 5;
if (!session) {
res.status(400).json({ success: false, error: 'Session parameter is required' });
return;
}
const memories = await memoryService.getContext(session, limit);
res.json({ success: true, data: memories });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// GET /api/memories/:id/related - Get related memories
export async function getRelated(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params;
const limit = req.query.limit ? parseInt(req.query.limit as string) : 10;
const memories = await memoryService.getRelated(id, limit);
res.json({ success: true, data: memories });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// POST /api/memories/:id/merge - Merge memories
export async function mergeMemories(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params;
const { target_id, reason } = req.body;
if (!target_id || !reason) {
res.status(400).json({ success: false, error: 'target_id and reason are required' });
return;
}
const memory = await memoryService.merge(id, target_id, reason);
if (!memory) {
res.status(404).json({ success: false, error: 'Memory not found' });
return;
}
res.json({ success: true, data: memory });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// POST /api/memories/:id/archive - Archive a memory
export async function archiveMemory(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params;
const reason = req.body.reason || 'Archived via API';
const memory = await memoryService.archive(id, reason);
if (!memory) {
res.status(404).json({ success: false, error: 'Memory not found' });
return;
}
res.json({ success: true, data: memory });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// POST /api/memories/:id/forget - Forget a memory
export async function forgetMemory(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params;
const reason = req.body.reason || 'Forgotten via API';
const memory = await memoryService.forget(id, reason);
if (!memory) {
res.status(404).json({ success: false, error: 'Memory not found' });
return;
}
res.json({ success: true, data: memory });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}
// GET /api/memories/analytics - Get analytics
export async function getAnalytics(req: Request, res: Response): Promise<void> {
try {
const analytics = await memoryService.getAnalytics();
res.json({ success: true, data: analytics });
} catch (error: any) {
res.status(500).json({ success: false, error: error.message });
}
}