import type { ArxivSearchParams, ArxivSearchResponse } from '@/tools/arxiv/types' import { extractTotalResults, parseArxivXML } from '@/tools/arxiv/utils' import type { ToolConfig } from '@/tools/types' export const searchTool: ToolConfig = { id: 'arxiv_search', name: 'ArXiv Search', description: 'Search for academic papers on ArXiv by keywords, authors, titles, or other fields.', version: '1.0.0', params: { searchQuery: { type: 'string', required: true, visibility: 'user-or-llm', description: 'The search query to execute', }, searchField: { type: 'string', required: false, visibility: 'user-only', description: 'Field to search in: all, ti (title), au (author), abs (abstract), co (comment), jr (journal), cat (category), rn (report number)', }, maxResults: { type: 'number', required: false, visibility: 'user-only', description: 'Maximum number of results to return (default: 10, max: 2000)', }, sortBy: { type: 'string', required: false, visibility: 'user-only', description: 'Sort by: relevance, lastUpdatedDate, submittedDate (default: relevance)', }, sortOrder: { type: 'string', required: false, visibility: 'user-only', description: 'Sort order: ascending, descending (default: descending)', }, }, request: { url: (params: ArxivSearchParams) => { const baseUrl = 'https://export.arxiv.org/api/query' const searchParams = new URLSearchParams() // Build search query let searchQuery = params.searchQuery if (params.searchField && params.searchField !== 'all') { searchQuery = `${params.searchField}:${params.searchQuery}` } searchParams.append('search_query', searchQuery) // Add optional parameters if (params.maxResults) { searchParams.append('max_results', Math.min(Number(params.maxResults), 2000).toString()) } else { searchParams.append('max_results', '10') } if (params.sortBy) { searchParams.append('sortBy', params.sortBy) } if (params.sortOrder) { searchParams.append('sortOrder', params.sortOrder) } return `${baseUrl}?${searchParams.toString()}` }, method: 'GET', headers: () => ({ 'Content-Type': 'application/xml', }), }, transformResponse: async (response: Response) => { const xmlText = await response.text() // Parse XML response const papers = parseArxivXML(xmlText) const totalResults = extractTotalResults(xmlText) return { success: true, output: { papers, totalResults, query: '', // Will be filled by the calling code }, } }, outputs: { papers: { type: 'json', description: 'Array of papers matching the search query', items: { type: 'object', properties: { id: { type: 'string' }, title: { type: 'string' }, summary: { type: 'string' }, authors: { type: 'string' }, published: { type: 'string' }, updated: { type: 'string' }, link: { type: 'string' }, pdfLink: { type: 'string' }, categories: { type: 'string' }, primaryCategory: { type: 'string' }, comment: { type: 'string' }, journalRef: { type: 'string' }, doi: { type: 'string' }, }, }, }, totalResults: { type: 'number', description: 'Total number of results found for the search query', }, }, }