Spaces:
Sleeping
Sleeping
File size: 2,752 Bytes
0bcc252 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
import https from 'https';
import { TokenTracker } from "../utils/token-tracker";
import { SearchResponse } from '../types';
import { JINA_API_KEY } from "../config";
export function search(query: string, tracker?: TokenTracker): Promise<{ response: SearchResponse}> {
return new Promise((resolve, reject) => {
if (!query.trim()) {
reject(new Error('Query cannot be empty'));
return;
}
const options = {
hostname: 's.jina.ai',
port: 443,
path: `/${encodeURIComponent(query)}?count=0`,
method: 'GET',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${JINA_API_KEY}`,
'X-Retain-Images': 'none'
}
};
const req = https.request(options, (res) => {
let responseData = '';
res.on('data', (chunk) => responseData += chunk);
res.on('end', () => {
// Check HTTP status code first
if (res.statusCode && res.statusCode >= 400) {
try {
// Try to parse error message from response if available
const errorResponse = JSON.parse(responseData);
if (res.statusCode === 402) {
reject(new Error(errorResponse.readableMessage || 'Insufficient balance'));
return;
}
reject(new Error(errorResponse.readableMessage || `HTTP Error ${res.statusCode}`));
} catch {
// If parsing fails, just return the status code
reject(new Error(`HTTP Error ${res.statusCode}`));
}
return;
}
// Only parse JSON for successful responses
let response: SearchResponse;
try {
response = JSON.parse(responseData) as SearchResponse;
} catch (error: unknown) {
reject(new Error(`Failed to parse response: ${error instanceof Error ? error.message : 'Unknown error'}`));
return;
}
if (!response.data || !Array.isArray(response.data)) {
reject(new Error('Invalid response format'));
return;
}
const totalTokens = response.data.reduce((sum, item) => sum + (item.usage?.tokens || 0), 0);
console.log('Total URLs:', response.data.length);
const tokenTracker = tracker || new TokenTracker();
tokenTracker.trackUsage('search', {
totalTokens,
promptTokens: query.length,
completionTokens: totalTokens
});
resolve({ response });
});
});
// Add timeout handling
req.setTimeout(30000, () => {
req.destroy();
reject(new Error('Request timed out'));
});
req.on('error', (error) => {
reject(new Error(`Request failed: ${error.message}`));
});
req.end();
});
} |