import { v4 as uuidv4 } from 'uuid';
import { Networking } from '../../../../Network';
import { BaseTool } from './BaseTool';
import { Observation } from '../types/types';
import { ParametersType, ToolInfo } from '../types/tool_types';
const searchToolParams = [
    {
        name: 'queries',
        type: 'string[]',
        description:
            'The search query or queries to use for finding websites. Provide up to 3 search queries to find a broad range of websites. Should be in the form of a TypeScript array of strings (e.g. ["search term 1", "search term 2", "search term 3"]).',
        required: true,
        max_inputs: 3,
    },
] as const;
type SearchToolParamsType = typeof searchToolParams;
const searchToolInfo: ToolInfo = {
    name: 'searchTool',
    citationRules: 'No citation needed. Cannot cite search results for a response. Use web scraping tools to cite specific information.',
    parameterRules: searchToolParams,
    description: 'Search the web to find a wide range of websites related to a query or multiple queries. Returns a list of websites and their overviews based on the search queries.',
};
export class SearchTool extends BaseTool {
    private _addLinkedUrlDoc: (url: string, id: string) => void;
    private _max_results: number;
    constructor(addLinkedUrlDoc: (url: string, id: string) => void, max_results: number = 4) {
        super(searchToolInfo);
        this._addLinkedUrlDoc = addLinkedUrlDoc;
        this._max_results = max_results;
    }
    async execute(args: ParametersType): Promise {
        const queries = args.queries;
        console.log(`Searching the web for queries: ${queries[0]}`);
        // Create an array of promises, each one handling a search for a query
        const searchPromises = queries.map(async query => {
            try {
                const { results } = (await Networking.PostToServer('/getWebSearchResults', {
                    query,
                    max_results: this._max_results,
                })) as { results: { url: string; snippet: string }[] };
                const data = results.map((result: { url: string; snippet: string }) => {
                    const id = uuidv4();
                    this._addLinkedUrlDoc(result.url, id);
                    return {
                        type: 'text' as const,
                        text: `${result.url}${result.snippet}`,
                    };
                });
                return data;
            } catch (error) {
                console.log(error);
                return [
                    {
                        type: 'text' as const,
                        text: `An error occurred while performing the web search for query: ${query}`,
                    },
                ];
            }
        });
        const allResultsArrays = await Promise.all(searchPromises);
        return allResultsArrays.flat();
    }
}