retrieval fusion

This commit is contained in:
Storme-bit
2026-04-27 05:21:43 -07:00
parent 9c6c5c9a42
commit 49982a85de
4 changed files with 29 additions and 10 deletions

View File

@@ -168,17 +168,26 @@ function getRecentEpisodes(sessionId, limit = EPISODIC.DEFAULT_RECENT_LIMIT) {
// Searches episodes using FTS5 full-text search, ordered by relevance, with a limit
function searchEpisodes(query, limit = EPISODIC.DEFAULT_SEARCH_LIMIT) {
// FTS5 full-text search across all episodes
function searchEpisodes(query, limit = EPISODIC.DEFAULT_SEARCH_LIMIT, sessionIds = null) {
const db = getDB();
const stmt = db.prepare(`
if (sessionIds && sessionIds.length > 0) {
const ph = sessionIds.map(() => '?').join(',');
return db.prepare(`
SELECT e.* FROM episodes e
JOIN episodes_fts fts ON e.id = fts.rowid
WHERE episodes_fts MATCH ?
AND e.session_id IN (${ph})
ORDER BY rank
LIMIT ?
`).all(query, ...sessionIds, limit).map(parseRow);
}
return db.prepare(`
SELECT e.* FROM episodes e
JOIN episodes_fts fts ON e.id = fts.rowid
WHERE episodes_fts MATCH ?
ORDER BY rank
LIMIT ?
`);
return stmt.all(query, limit).map(parseRow);
`).all(query, limit).map(parseRow);
}
// Deletes an episode by its ID

View File

@@ -131,10 +131,12 @@ app.get('/episodes', (req, res) => {
// 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;
const { q, limit = EPISODIC.DEFAULT_PAGE_SIZE, sessionIds } = req.query;
if (!q) return res.status(400).json({ error: 'q (query) parameter is required' });
const results = episodic.searchEpisodes(q, Number(limit));
res.json(results);
const parsedSessionIds = sessionIds
? sessionIds.split(',').map(Number).filter(Boolean)
: null;
res.json(episodic.searchEpisodes(q, Number(limit), parsedSessionIds));
});
app.get('/episodes/:id', (req, res) => {