Fix CF-271: Add fallback text search to archive_search
When LiteLLM embedding service is unavailable, archive_search now gracefully falls back to PostgreSQL text search (ILIKE) instead of returning an error. Also adds dotenv support for proper credential loading. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -125,10 +125,54 @@ export async function archiveSearch(args: ArchiveSearchArgs): Promise<string> {
|
||||
// Generate embedding for search
|
||||
const embedding = await getEmbedding(searchQuery);
|
||||
|
||||
// Fallback to text search if embeddings unavailable
|
||||
if (!embedding) {
|
||||
return 'Error: Could not generate embedding for search';
|
||||
console.warn('Embeddings unavailable, falling back to text search');
|
||||
|
||||
let whereClause = '(title ILIKE $1 OR content ILIKE $1)';
|
||||
const params: unknown[] = [`%${searchQuery}%`];
|
||||
let paramIndex = 2;
|
||||
|
||||
if (project) {
|
||||
whereClause += ` AND project_key = $${paramIndex++}`;
|
||||
params.push(project);
|
||||
}
|
||||
if (archive_type) {
|
||||
whereClause += ` AND archive_type = $${paramIndex++}`;
|
||||
params.push(archive_type);
|
||||
}
|
||||
|
||||
params.push(limit);
|
||||
|
||||
const archives = await query<Archive>(
|
||||
`SELECT id, archive_type, title, original_path, file_size,
|
||||
to_char(archived_at, 'YYYY-MM-DD') as archived_at
|
||||
FROM project_archives
|
||||
WHERE ${whereClause}
|
||||
ORDER BY archived_at DESC
|
||||
LIMIT $${paramIndex}`,
|
||||
params
|
||||
);
|
||||
|
||||
if (archives.length === 0) {
|
||||
return 'No relevant archives found';
|
||||
}
|
||||
|
||||
const lines = ['Relevant archives (text search - embeddings unavailable):\n'];
|
||||
for (const a of archives) {
|
||||
const sizeStr = a.file_size ? ` (${Math.round(a.file_size / 1024)}KB)` : '';
|
||||
lines.push(`**[${a.archive_type}]** ${a.title}`);
|
||||
lines.push(` Archived: ${a.archived_at}${sizeStr}`);
|
||||
if (a.original_path) {
|
||||
lines.push(` Path: ${a.original_path}`);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
// Semantic search with embeddings
|
||||
const embeddingStr = formatEmbedding(embedding);
|
||||
|
||||
let whereClause = 'WHERE embedding IS NOT NULL';
|
||||
|
||||
Reference in New Issue
Block a user