diff --git a/packages/memory-service/src/index.js b/packages/memory-service/src/index.js index 43e48e7..f011962 100644 --- a/packages/memory-service/src/index.js +++ b/packages/memory-service/src/index.js @@ -112,6 +112,29 @@ app.post('/episodes', async (req, res) => { res.status(201).json(episode); }); +app.get('/episodes', (req, res) => { + const { limit = 50, offset = 0, sessionId, q } = req.query; + + if (q) { + const results = episodic.searchEpisodes(q, Number(limit)); + return res.json({ episodes: results, total: results.length }); + } + + const db = getDB(); + let episodes; + + if (sessionId) { + episodes = episodic.getEpisodesBySession(Number(sessionId), Number(limit), Number(offset)); + } else { + episodes = db.prepare( + `SELECT * FROM episodes ORDER BY created_at DESC LIMIT ? OFFSET ?` + ).all(Number(limit), Number(offset)).map(row => require('@nexusai/shared').parseRow(row)); + } + + const total = db.prepare(`SELECT COUNT(*) as count FROM episodes`).get().count; + res.json({ episodes, total }); +}); + // Search MUST come before /:id — otherwise 'search' gets captured as an id app.get('/episodes/search', (req, res) => { const { q, limit = EPISODIC.DEFAULT_PAGE_SIZE } = req.query; @@ -138,7 +161,12 @@ app.get('/sessions/:id/episodes', (req, res) => { }); app.delete('/episodes/:id', (req, res) => { - episodic.deleteEpisode(req.params.id); + const id = Number(req.params.id); + episodic.deleteEpisode(id); + + semantic.deleteEpisode(id) // fire-and-forget + .catch(err => console.error(`[Memory] Qdrant delete failed for episode ${id}:`, err.message)); + res.status(204).send(); }); diff --git a/packages/memory-service/src/semantic/index.js b/packages/memory-service/src/semantic/index.js index 49c0b63..8f1f5f4 100644 --- a/packages/memory-service/src/semantic/index.js +++ b/packages/memory-service/src/semantic/index.js @@ -95,6 +95,11 @@ async function deleteVector(collection, id) { }); } +async function deleteEpisode(id) { + return deleteVector(COLLECTIONS.EPISODES, id); +} + + module.exports = { initCollections, upsertEpisode, @@ -103,5 +108,6 @@ module.exports = { searchEpisodes, searchEntities, searchSummaries, - deleteVector + deleteVector, + deleteEpisode }; \ No newline at end of file diff --git a/packages/source.zip b/packages/source.zip new file mode 100644 index 0000000..b4b02de Binary files /dev/null and b/packages/source.zip differ