semanticsearch
This commit is contained in:
37
src/pages/api/ai/embeddings-status.ts
Normal file
37
src/pages/api/ai/embeddings-status.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
// src/pages/api/ai/embeddings-status.ts
|
||||
import type { APIRoute } from 'astro';
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
export const GET: APIRoute = async () => {
|
||||
try {
|
||||
const { embeddingsService } = await import('../../../utils/embeddings.js');
|
||||
await embeddingsService.waitForInitialization();
|
||||
|
||||
const stats = embeddingsService.getStats();
|
||||
const status = stats.enabled && stats.initialized ? 'ready' :
|
||||
stats.enabled && !stats.initialized ? 'initializing' : 'disabled';
|
||||
|
||||
return new Response(JSON.stringify({
|
||||
success: true,
|
||||
embeddings: stats,
|
||||
timestamp: new Date().toISOString(),
|
||||
status: status
|
||||
}), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
return new Response(JSON.stringify({
|
||||
success: false,
|
||||
embeddings: { enabled: false, initialized: false, count: 0 },
|
||||
timestamp: new Date().toISOString(),
|
||||
status: 'disabled',
|
||||
error: error.message
|
||||
}), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
// src/pages/api/ai/embeddings-status.ts
|
||||
import type { APIRoute } from 'astro';
|
||||
import { embeddingsService } from '../../../utils/embeddings.js';
|
||||
import { apiResponse, apiServerError } from '../../../utils/api.js';
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
export const GET: APIRoute = async () => {
|
||||
try {
|
||||
const stats = embeddingsService.getStats();
|
||||
|
||||
return apiResponse.success({
|
||||
embeddings: stats,
|
||||
timestamp: new Date().toISOString(),
|
||||
status: stats.enabled && stats.initialized ? 'ready' :
|
||||
stats.enabled && !stats.initialized ? 'initializing' : 'disabled'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Embeddings status error:', error);
|
||||
return apiServerError.internal('Failed to get embeddings status');
|
||||
}
|
||||
};
|
||||
42
src/pages/api/debug-env.ts
Normal file
42
src/pages/api/debug-env.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
// src/pages/api/debug-env.ts
|
||||
import type { APIRoute } from 'astro';
|
||||
import { debugEmbeddings } from '../../utils/embeddings.js';
|
||||
|
||||
export const GET: APIRoute = async () => {
|
||||
const embeddingVars = Object.keys(process.env)
|
||||
.filter(key => key.includes('EMBEDDINGS'))
|
||||
.reduce((obj: Record<string, string>, key) => {
|
||||
obj[key] = process.env[key] || 'undefined';
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
const aiVars = Object.keys(process.env)
|
||||
.filter(key => key.includes('AI_'))
|
||||
.reduce((obj: Record<string, string>, key) => {
|
||||
// Mask sensitive values
|
||||
const value = process.env[key] || 'undefined';
|
||||
obj[key] = key.includes('KEY') || key.includes('SECRET') ?
|
||||
(value.length > 10 ? `${value.slice(0, 6)}...${value.slice(-4)}` : value) :
|
||||
value;
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
// Force recheck embeddings environment
|
||||
await debugEmbeddings.recheckEnvironment();
|
||||
const embeddingsStatus = debugEmbeddings.getStatus();
|
||||
|
||||
return new Response(JSON.stringify({
|
||||
timestamp: new Date().toISOString(),
|
||||
embeddingVars,
|
||||
allAiVars: aiVars,
|
||||
totalEnvVars: Object.keys(process.env).length,
|
||||
embeddingsStatus,
|
||||
nodeEnv: process.env.NODE_ENV,
|
||||
platform: process.platform
|
||||
}, null, 2), {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
};
|
||||
83
src/pages/api/search/semantic.ts
Normal file
83
src/pages/api/search/semantic.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
// src/pages/api/search/semantic.ts
|
||||
import type { APIRoute } from 'astro';
|
||||
import { getToolsData } from '../../../utils/dataService.js';
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
export const POST: APIRoute = async ({ request }) => {
|
||||
try {
|
||||
const { query, maxResults = 50, threshold = 0.15 } = 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' }
|
||||
});
|
||||
}
|
||||
|
||||
// Import embeddings service dynamically
|
||||
const { embeddingsService } = await import('../../../utils/embeddings.js');
|
||||
|
||||
// Check if embeddings are available
|
||||
if (!embeddingsService.isEnabled()) {
|
||||
return new Response(JSON.stringify({
|
||||
success: false,
|
||||
error: 'Semantic search not available'
|
||||
}), {
|
||||
status: 400,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
}
|
||||
|
||||
// Wait for embeddings initialization if needed
|
||||
await embeddingsService.waitForInitialization();
|
||||
|
||||
// Get similar items using embeddings
|
||||
const similarItems = await embeddingsService.findSimilar(
|
||||
query.trim(),
|
||||
maxResults,
|
||||
threshold
|
||||
);
|
||||
|
||||
// Get current tools data
|
||||
const toolsData = await getToolsData();
|
||||
|
||||
// Map similarity results back to full tool objects, preserving similarity ranking
|
||||
const rankedTools = similarItems
|
||||
.map(similarItem => {
|
||||
const tool = toolsData.tools.find(t => t.name === similarItem.name);
|
||||
return tool ? {
|
||||
...tool,
|
||||
_semanticSimilarity: similarItem.similarity,
|
||||
_semanticRank: similarItems.indexOf(similarItem) + 1
|
||||
} : null;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
return new Response(JSON.stringify({
|
||||
success: true,
|
||||
query: query.trim(),
|
||||
results: rankedTools,
|
||||
totalFound: rankedTools.length,
|
||||
semanticSearch: true,
|
||||
threshold,
|
||||
maxSimilarity: rankedTools.length > 0 ? 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' }
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user