/**
 * Web search tool — searches the web through the shared Shortcut product API.
 *
 * The runtime sends only Shortcut auth to `api-server-v1`.
 * Provider selection and third-party API keys stay entirely server-side.
 */
import { Type } from '@sinclair/typebox';
import { APP_NAME } from '../../config.js';
import { SHORTCUT_API_URL } from '../../constants.js';
import { SHORTCUT_API_ENDPOINTS } from '../../endpoints.js';
import { SHORTCUT_PROVIDER_ID } from '../../model-ids.js';
import { WEB_SEARCH } from '../../tool-names.js';
const TIMEOUT_MS = 90_000;
const currentDate = () => new Date().toISOString().slice(0, 10);
const TOOL_DESCRIPTION = `\
Search the web for real-time information.

CURRENT DATE: ${currentDate()}

WHEN TO USE:
- Current data, market info, company details, product specs, trends, or ANY external data that could enhance accuracy
- Essential for ensuring quantitative data is up to date

IMPORTANT:
- Your query must be completely self-contained
- Include all necessary context, instructions, and specific details about what information to find`;
export const WEB_SEARCH_TOOL_SUMMARY = 'Search the web for current or external information with numbered references';
const schema = Type.Object({
    description: Type.String({
        description: "A short one-sentence summary starting with 'Searching for...' or 'Looking for...'",
        minLength: 1
    }),
    query: Type.String({
        description: 'The search query to execute. Must be self-contained with all necessary context.',
        minLength: 1
    })
});
const defaultOperations = {
    fetch: globalThis.fetch.bind(globalThis)
};
export function createWebSearchTool(baseUrl = SHORTCUT_API_URL, options) {
    const ops = options?.operations ?? defaultOperations;
    return {
        name: WEB_SEARCH,
        label: 'Web Search',
        description: TOOL_DESCRIPTION,
        parameters: schema,
        async execute(toolCallId, { description: _description, query }, signal, _onUpdate, ctx) {
            // Resolve API key from model registry
            const extCtx = ctx;
            const apiKey = extCtx?.modelRegistry
                ? await extCtx.modelRegistry.getApiKeyForProvider(SHORTCUT_PROVIDER_ID)
                : undefined;
            if (!apiKey) {
                throw new Error('Not authenticated. Please log in first.');
            }
            let response;
            try {
                response = await ops.fetch(`${baseUrl}${SHORTCUT_API_ENDPOINTS.webSearch}`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        Authorization: `Bearer ${apiKey}`,
                        'User-AgentController': `Mozilla/5.0 (compatible; ${APP_NAME}-coding-agent/1.0)`
                    },
                    body: JSON.stringify({ query }),
                    signal: signal
                        ? AbortSignal.any([signal, AbortSignal.timeout(TIMEOUT_MS)])
                        : AbortSignal.timeout(TIMEOUT_MS)
                });
            }
            catch (e) {
                const msg = e instanceof Error ? e.message : String(e);
                throw new Error(`Web search failed to connect: ${msg}`);
            }
            if (!response.ok) {
                const raw = await response.text();
                const text = raw.split('\n').slice(0, 10).join('\n');
                throw new Error(`Web search API error ${response.status}: ${text}`);
            }
            const data = (await response.json());
            const text = typeof data.text === 'string' && data.text.length > 0
                ? data.text
                : 'No search results found.';
            return {
                content: [{ type: 'text', text }],
                details: { provider: data.provider ?? 'anthropic', query }
            };
        }
    };
}
//# sourceMappingURL=web-search.js.map