Skip to content

Commit ae6a103

Browse files
committed
refactor(tools): optimize web_search from PR #136/#137 merge
Cherry-pick best of both Codex PRs: - PR 136: input validation (query.trim), Number.parseInt, error format with status code, braveSearchKey in non-DO toolContext - PR 137: tool ordering (web_search after fetch_news), vi.useFakeTimers for TTL test, briefing-aggregator test counts 15 tools https://claude.ai/code/session_01SE5WrUuc6LWTmZC8WBXKY4
1 parent 5d8475c commit ae6a103

3 files changed

Lines changed: 31 additions & 31 deletions

File tree

src/openrouter/briefing-aggregator.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,17 +1048,18 @@ describe('Test 18 — /help and /start message verification', () => {
10481048
}
10491049
});
10501050

1051-
// Verify the /help message lists all 14 tools by name
1051+
// Verify the /help message lists all 15 tools by name
10521052
it('should list each tool individually in the new /help format', () => {
10531053
// The new help message lists each tool as a bullet point
10541054
const helpToolSection = [
10551055
'get_weather', 'get_crypto', 'convert_currency', 'fetch_news',
1056+
'web_search',
10561057
'fetch_url', 'browse_url', 'url_metadata', 'generate_chart',
10571058
'geolocate_ip', 'github_read_file', 'github_list_files', 'github_api',
10581059
'github_create_pr', 'sandbox_exec',
10591060
];
1060-
// All 14 are individually named
1061-
expect(helpToolSection.length).toBe(14);
1061+
// All 15 are individually named
1062+
expect(helpToolSection.length).toBe(15);
10621063
});
10631064

10641065
// Verify /help mentions key features

src/openrouter/tools.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,15 +2248,13 @@ describe('web_search tool', () => {
22482248
});
22492249

22502250
it('should invalidate cache after TTL', async () => {
2251+
vi.useFakeTimers();
22512252
const mockFetch = vi.fn().mockResolvedValue({
22522253
ok: true,
22532254
json: () => Promise.resolve({ web: { results: [{ title: 'TTL', url: 'https://example.com/ttl', description: 'ttl snippet' }] } }),
22542255
});
22552256
vi.stubGlobal('fetch', mockFetch);
22562257

2257-
const nowSpy = vi.spyOn(Date, 'now');
2258-
nowSpy.mockReturnValue(1000);
2259-
22602258
await executeTool({
22612259
id: 'web_7a',
22622260
type: 'function',
@@ -2266,7 +2264,7 @@ describe('web_search tool', () => {
22662264
},
22672265
}, { braveSearchKey: 'brave-key' });
22682266

2269-
nowSpy.mockReturnValue(1000 + 5 * 60 * 1000 + 1);
2267+
vi.advanceTimersByTime(5 * 60 * 1000 + 1);
22702268

22712269
await executeTool({
22722270
id: 'web_7b',
@@ -2278,6 +2276,7 @@ describe('web_search tool', () => {
22782276
}, { braveSearchKey: 'brave-key' });
22792277

22802278
expect(mockFetch).toHaveBeenCalledTimes(2);
2279+
vi.useRealTimers();
22812280
});
22822281
});
22832282

src/openrouter/tools.ts

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,27 @@ export const AVAILABLE_TOOLS: ToolDefinition[] = [
258258
},
259259
},
260260
},
261+
{
262+
type: 'function',
263+
function: {
264+
name: 'web_search',
265+
description: 'Search the web for current information. Returns titles, URLs, and snippets from top results.',
266+
parameters: {
267+
type: 'object',
268+
properties: {
269+
query: {
270+
type: 'string',
271+
description: 'Search query to look up on the web',
272+
},
273+
num_results: {
274+
type: 'string',
275+
description: 'Number of results to return (default: 5, max: 10)',
276+
},
277+
},
278+
required: ['query'],
279+
},
280+
},
281+
},
261282
{
262283
type: 'function',
263284
function: {
@@ -322,27 +343,6 @@ export const AVAILABLE_TOOLS: ToolDefinition[] = [
322343
},
323344
},
324345
},
325-
{
326-
type: 'function',
327-
function: {
328-
name: 'web_search',
329-
description: 'Search the web for current information. Returns titles, URLs, and snippets from top results.',
330-
parameters: {
331-
type: 'object',
332-
properties: {
333-
query: {
334-
type: 'string',
335-
description: 'Search query to look up on the web',
336-
},
337-
num_results: {
338-
type: 'string',
339-
description: 'Number of results to return (default: 5, max: 10)',
340-
},
341-
},
342-
required: ['query'],
343-
},
344-
},
345-
},
346346
{
347347
type: 'function',
348348
function: {
@@ -483,6 +483,9 @@ export async function executeTool(toolCall: ToolCall, context?: ToolContext): Pr
483483
case 'fetch_news':
484484
result = await fetchNews(args.source, args.topic);
485485
break;
486+
case 'web_search':
487+
result = await webSearch(args.query, args.num_results, context?.braveSearchKey);
488+
break;
486489
case 'convert_currency':
487490
result = await convertCurrency(args.from, args.to, args.amount);
488491
break;
@@ -492,9 +495,6 @@ export async function executeTool(toolCall: ToolCall, context?: ToolContext): Pr
492495
case 'geolocate_ip':
493496
result = await geolocateIp(args.ip);
494497
break;
495-
case 'web_search':
496-
result = await webSearch(args.query, args.num_results, context?.braveSearchKey);
497-
break;
498498
case 'browse_url':
499499
result = await browseUrl(args.url, args.action as 'extract_text' | 'screenshot' | 'pdf' | undefined, args.wait_for, context?.browser);
500500
break;

0 commit comments

Comments
 (0)