// src/pages/api/search/semantic.ts import type { APIRoute } from 'astro'; import { getToolsData } from '../../../utils/dataService.js'; import { configDotenv } from 'dotenv'; configDotenv(); const DEFAULT_MAX_RESULTS = (() => { const raw = process.env.AI_EMBEDDING_CANDIDATES; const n = Number.parseInt(raw ?? '', 10); return Number.isFinite(n) && n > 0 ? n : 50; })(); const DEFAULT_THRESHOLD = (() => { const raw = process.env.AI_SIMILARITY_THRESHOLD; const n = Number.parseFloat(raw ?? ''); return Number.isFinite(n) && n >= 0 && n <= 1 ? n : 0.45; })(); export const prerender = false; export const POST: APIRoute = async ({ request }) => { try { const { query, maxResults = DEFAULT_MAX_RESULTS, threshold = DEFAULT_THRESHOLD } = await request.json(); if (!query || typeof query !== 'string') { return new Response( JSON.stringify({ success: false, error: 'Query is required' }), { status: 400, headers: { 'Content-Type': 'application/json' } } ); } /* --- (rest of the handler unchanged) -------------------------- */ const { embeddingsService } = await import('../../../utils/embeddings.js'); if (!embeddingsService.isEnabled()) { return new Response( JSON.stringify({ success: false, error: 'Semantic search not available' }), { status: 400, headers: { 'Content-Type': 'application/json' } } ); } await embeddingsService.waitForInitialization(); const similarItems = await embeddingsService.findSimilar( query.trim(), maxResults, threshold ); const toolsData = await getToolsData(); const rankedTools = similarItems .map((s, i) => { const tool = toolsData.tools.find(t => t.name === s.name); return tool ? { ...tool, _semanticSimilarity: s.similarity, _semanticRank: i + 1 } : null; }) .filter(Boolean); return new Response( JSON.stringify({ success: true, query: query.trim(), results: rankedTools, totalFound: rankedTools.length, semanticSearch: true, threshold, maxSimilarity: rankedTools[0]?._semanticSimilarity ?? 0 }), { status: 200, headers: { 'Content-Type': 'application/json' } } ); } catch (error) { console.error('Semantic search error:', error); return new Response( JSON.stringify({ success: false, error: 'Semantic search failed' }), { status: 500, headers: { 'Content-Type': 'application/json' } } ); } };