import { ReadDirectoryFunction } from './ReadDirectory.js';
import { ReadAndAnalyzeFileFunction } from './ReadAndAnalyzeFile.js';
import { AnalyzeSoftwareRequirementsFunction } from './AnalyzeSoftwareRequirements.js';
import { PlanSoftwareRoadmapFunction } from './PlanSoftwareRoadmap.js';
import { AgentFunctionBase } from './utils/index.js';
import { ChatMessageBuilder } from '../agent-core/index.js';
export class PlanDevelopmentFunction extends AgentFunctionBase {
    name = 'planDevelopment';
    description = 'Plan software development tasks to achieve a user goal';
    parameters = {
        type: 'object',
        properties: {
            goal: {
                type: 'string',
                description: "The user's goal",
            },
        },
        required: ['goal'],
        additionalProperties: false,
    };
    buildExecutor(agent) {
        return async (params, rawParams) => {
            const readDirectory = new ReadDirectoryFunction().buildExecutor(agent);
            const analyzeRequirements = new AnalyzeSoftwareRequirementsFunction(agent.context.llm, agent.context.chat.tokenizer).buildExecutor(agent);
            const planRoadmap = new PlanSoftwareRoadmapFunction(agent.context.llm, agent.context.chat.tokenizer).buildExecutor(agent);
            const plan = Promise.all([analyzeRequirements({ goal: params.goal }), planRoadmap({ goal: params.goal })]);
            const understand = await Promise.all([
                readDirectory({ path: './' }),
                ...(await this.readAndAnalyzeFiles(agent, params.goal)),
            ]);
            const results = [...(await plan), ...(await understand)];
            return {
                outputs: results.flatMap(x => x.outputs),
                messages: [
                    ChatMessageBuilder.functionCall(this.name, params),
                    ChatMessageBuilder.functionCallResult(this.name, 'Understanding data...'),
                    ...results.flatMap(x => x.messages),
                ],
            };
        };
    }
    async readAndAnalyzeFiles(agent, goal) {
        const workspace = agent.context.workspace;
        const files = (await workspace.readdir('./')).filter(x => x.type === 'file');
        const readAndAnalyzeFile = new ReadAndAnalyzeFileFunction().buildExecutor(agent);
        const analyzes = await Promise.all(files.map(file => readAndAnalyzeFile({
            path: file.name,
            question: goal,
        })));
        return [...analyzes];
    }
}
