import type { LangSearchConfig, SemanticRerankParams, SemanticRerankResponse, ToolResult } from '../types.js';
/**
* Semantic Rerank Tool Implementation
*
* Reranks documents based on semantic relevance to a query using
* LangSearch's Semantic Rerank API.
*/
export async function semanticRerankTool(
params: SemanticRerankParams,
config: LangSearchConfig
): Promise<ToolResult> {
try {
// Validate inputs
if (params.documents.length === 0) {
throw new Error('At least one document is required for reranking');
}
// Build request body with defaults
const requestBody = {
model: 'langsearch-reranker-v1',
query: params.query,
documents: params.documents,
top_n: params.top_n,
return_documents: params.return_documents !== undefined ? params.return_documents : true
};
// Make API request
const response = await fetch(`${config.baseUrl}/v1/rerank`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`LangSearch API error (${response.status}): ${errorText}`);
}
const result = await response.json() as SemanticRerankResponse;
// Check for API-level errors
if (result.code !== 200) {
throw new Error(`LangSearch API returned error code ${result.code}: ${result.msg || 'Unknown error'}`);
}
// Format results for display
const formattedResults = result.results.map((item, idx) => {
let text = `${idx + 1}. Document Index: ${item.index}\n`;
text += ` Relevance Score: ${item.relevance_score.toFixed(4)}\n`;
if (item.document?.text) {
// Truncate long documents for display
const displayText = item.document.text.length > 200
? item.document.text.substring(0, 200) + '...'
: item.document.text;
text += ` Text: ${displayText}\n`;
}
return text;
}).join('\n');
const displayText = `Semantic Rerank Results for "${params.query}"\n` +
`Model: ${result.model}\n` +
`Reranked ${result.results.length} document(s)\n\n` +
formattedResults;
return {
content: [{
type: 'text',
text: displayText
}],
structuredContent: {
model: result.model,
results: result.results
}
};
} catch (error: unknown) {
const err = error as Error;
const errorMessage = `Semantic rerank failed: ${err.message}`;
return {
content: [{
type: 'text',
text: errorMessage
}],
isError: true
};
}
}