import { AgentOutputType, ChatMessageBuilder, trimText } from '../agent-core/index.js';
import { FUNCTION_CALL_FAILED, FUNCTION_CALL_SUCCESS_CONTENT } from '../agents/Scripter/utils.js';
import { LlmAgentFunctionBase } from './utils/index.js';
export class PlanWebResearchFunction extends LlmAgentFunctionBase {
    constructor(llm, tokenizer) {
        super(llm, tokenizer);
    }
    name = 'plan_webResearch';
    description = 'Plans how to research on the internet for a given user goal.';
    parameters = {
        type: 'object',
        properties: {
            goal: {
                type: 'string',
                description: "The user's goal",
            },
        },
        required: ['goal'],
        additionalProperties: false,
    };
    buildExecutor({ context }) {
        return async (params, rawParams) => {
            try {
                const getPlan = this.askLlm(this.getPlanningPrompt(params.goal), { model: 'gpt-3.5-turbo-16k', maxResponseTokens: 200 });
                const getFormatting = this.askLlm(this.getFormattingPrompt(params.goal), { model: 'gpt-3.5-turbo-16k', maxResponseTokens: 200 });
                const [plan, formatting] = await Promise.all([getPlan, getFormatting]);
                return this.onSuccess(params, plan, formatting, rawParams, context.variables);
            }
            catch (err) {
                return this.onError(params, err.toString(), rawParams, context.variables);
            }
        };
    }
    onSuccess(params, plan, formatting, rawParams, variables) {
        return {
            outputs: [
                {
                    type: AgentOutputType.Success,
                    title: `Plan research for '${params.goal}'`,
                    content: FUNCTION_CALL_SUCCESS_CONTENT(this.name, params, 'Research Plan:' +
                        `\n--------------\n${plan}\n--------------\n` +
                        'Formatting Requirements:' +
                        `\n--------------\n${formatting}\n--------------\n`),
                },
            ],
            messages: [
                ChatMessageBuilder.functionCall(this.name, rawParams),
                ChatMessageBuilder.functionCallResult(this.name, `Research Plan:\n\`\`\`\n${plan}\n\`\`\`\nFormatting Requirements:\n\`\`\`\n${formatting}\n\`\`\`\n`),
                ChatMessageBuilder.functionCallResult(this.name, `Formatting Requirements:\n\`\`\`\n${formatting}\n\`\`\`\n`),
            ],
        };
    }
    onError(params, error, rawParams, variables) {
        return {
            outputs: [
                {
                    type: AgentOutputType.Error,
                    title: `Plan research for '${params.goal}'`,
                    content: FUNCTION_CALL_FAILED(params, this.name, error),
                },
            ],
            messages: [
                ChatMessageBuilder.functionCall(this.name, rawParams),
                ChatMessageBuilder.functionCallResult(this.name, `Error planning research for '${params.goal}'\n\`\`\`
${trimText(error, 300)}\n\`\`\``),
            ],
        };
    }
    getPlanningPrompt(goal) {
        return `1. **Break Down the Question**:
       - Divide big questions into smaller, related parts.
       - Example: Instead of "Votes of last US presidential winner?", ask:
         a. "When was the last US presidential election?"
         b. "Who won that election?"
         c. "How many votes did the winner get?"
       - If one search is enough, leave the question as is.

    2. **Keep Important Details**:
       - When asking follow-up questions, always include important details from previous questions.
       - Example: For "Email of CTO of 'XYZ Tech'?", ask:
         a. "Who's the CTO of 'XYZ Tech'?"
         b. "What's {CTO}'s email at 'XYZ Tech'?"

    3. **Avoid Year-by-Year Searches**:
       - Don't search for each year individually. Look for grouped data.
       - Instead of searching "US births 2019", "US births 2020", etc., ask for "US births from 2019 to 2021".

    4. **Use Current Year**:
       - If you need the current year in a search, use ${new Date().getFullYear()}.

    5. **Explain Your Steps**:
       - Tell us how you came up with your plan.

    6. **Be Clear and Brief**:
       - Aim for accuracy and keep it short.

    Here's the query you need to plan: ${goal}`;
    }
    getFormattingPrompt(goal) {
        return `Given the following user goal, please identify any formatting requirements: ${goal}`;
    }
}
