devin-ai-integration[bot] 76f8cd242a
feat: merge types and add tests (#10)
* feat: merge types and add tests

- Merged types.ts and tracker.ts
- Added Jest configuration and setup
- Added comprehensive tests for tools and agent
- Updated package.json with test scripts

Co-Authored-By: Han Xiao <han.xiao@jina.ai>

* chore: remove tracker.ts after merging into types.ts

Co-Authored-By: Han Xiao <han.xiao@jina.ai>

* fix: remove sensitive API keys from jest.setup.js

Co-Authored-By: Han Xiao <han.xiao@jina.ai>

* fix: improve error handling and test timeouts

Co-Authored-By: Han Xiao <han.xiao@jina.ai>

* feat: add token budget enforcement to TokenTracker

Co-Authored-By: Han Xiao <han.xiao@jina.ai>

* feat: add github actions workflow for CI and fix remaining issues

Co-Authored-By: Han Xiao <han.xiao@jina.ai>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Han Xiao <han.xiao@jina.ai>
2025-02-03 18:01:59 +08:00

62 lines
1.8 KiB
TypeScript

import https from 'https';
import { TokenTracker } from "../utils/token-tracker";
import { SearchResponse } from '../types';
export function search(query: string, token: string, tracker?: TokenTracker): Promise<{ response: SearchResponse, tokens: number }> {
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)}`,
method: 'GET',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${token}`,
'X-Retain-Images': 'none'
}
};
const req = https.request(options, (res) => {
let responseData = '';
res.on('data', (chunk) => responseData += chunk);
res.on('end', () => {
const response = JSON.parse(responseData) as SearchResponse;
console.log('Raw response:', response);
if (!query.trim()) {
reject(new Error('Query cannot be empty'));
return;
}
if (response.code === 402) {
reject(new Error(response.readableMessage || 'Insufficient balance'));
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('Search:', response.data.map(item => ({
title: item.title,
url: item.url,
tokens: item.usage?.tokens || 0
})));
(tracker || new TokenTracker()).trackUsage('search', totalTokens);
resolve({ response, tokens: totalTokens });
});
});
req.on('error', reject);
req.end();
});
}