import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { logger } from "../core/monitoring/logger.js";
import { ParallelExecutor } from "../core/execution/parallel-executor.js";
import { RecursiveContextManager } from "../core/context/recursive-context-manager.js";
import { ClaudeCodeSubagentClient } from "../integrations/claude-code/subagent-client.js";
class RecursiveAgentOrchestrator {
  frameManager;
  contextRetriever;
  taskStore;
  parallelExecutor;
  contextManager;
  subagentClient;
  // Subagent configurations
  subagentConfigs;
  // Execution tracking
  activeExecutions = /* @__PURE__ */ new Map();
  executionHistory = [];
  // Default options
  defaultOptions = {
    maxParallel: 5,
    maxRecursionDepth: 4,
    maxTokensPerAgent: 3e4,
    maxTotalCost: 50,
    // Quality over cost
    timeoutPerAgent: 300,
    retryFailedAgents: true,
    shareContextRealtime: true,
    testGenerationMode: "all",
    reviewStages: 3,
    // Multi-stage review
    qualityThreshold: 0.85,
    verboseLogging: true
    // Full transparency
  };
  constructor(frameManager, dualStackManager, contextRetriever, taskStore) {
    this.frameManager = frameManager;
    this.contextRetriever = contextRetriever;
    this.taskStore = taskStore;
    this.parallelExecutor = new ParallelExecutor(
      this.defaultOptions.maxParallel
    );
    this.contextManager = new RecursiveContextManager(
      dualStackManager,
      contextRetriever
    );
    this.subagentClient = new ClaudeCodeSubagentClient();
    this.subagentConfigs = this.initializeSubagentConfigs();
    logger.info("RLM Orchestrator initialized", {
      maxParallel: this.defaultOptions.maxParallel,
      maxRecursion: this.defaultOptions.maxRecursionDepth,
      reviewStages: this.defaultOptions.reviewStages
    });
  }
  /**
   * Initialize subagent configurations with specialized prompts
   */
  initializeSubagentConfigs() {
    const configs = /* @__PURE__ */ new Map();
    configs.set("planning", {
      type: "planning",
      model: "claude-3-5-sonnet-latest",
      maxTokens: 2e4,
      temperature: 0.3,
      systemPrompt: `You are a Planning Agent specializing in task decomposition.
        Analyze complex tasks and break them into parallel and sequential subtasks.
        Create detailed execution plans with clear dependencies.
        Consider edge cases and potential failures.
        Output structured task trees with agent assignments.`,
      capabilities: ["decompose", "analyze", "strategize", "prioritize"]
    });
    configs.set("code", {
      type: "code",
      model: "claude-3-5-sonnet-latest",
      maxTokens: 3e4,
      temperature: 0.2,
      systemPrompt: `You are a Code Agent specializing in implementation.
        Write clean, maintainable, production-ready code.
        Follow project conventions and best practices.
        Include comprehensive error handling.
        Document complex logic with clear comments.`,
      capabilities: ["implement", "refactor", "optimize", "document"]
    });
    configs.set("testing", {
      type: "testing",
      model: "claude-3-5-sonnet-latest",
      // High quality for test generation
      maxTokens: 25e3,
      temperature: 0.1,
      systemPrompt: `You are a Testing Agent specializing in test generation and validation.
        Generate comprehensive test suites including:
        - Unit tests for all functions/methods
        - Integration tests for API endpoints
        - E2E tests for critical user flows
        - Edge cases and error scenarios
        Ensure 100% code coverage where possible.
        Validate that all tests pass and are meaningful.`,
      capabilities: [
        "generate-tests",
        "validate",
        "coverage-analysis",
        "test-execution"
      ]
    });
    configs.set("linting", {
      type: "linting",
      model: "claude-3-5-haiku-latest",
      maxTokens: 15e3,
      temperature: 0,
      systemPrompt: `You are a Linting Agent specializing in code quality.
        Check for:
        - Syntax errors and type issues
        - Code formatting and style violations
        - Security vulnerabilities
        - Performance anti-patterns
        - Unused imports and dead code
        Provide actionable fixes for all issues found.`,
      capabilities: ["lint", "format", "type-check", "security-scan"]
    });
    configs.set("review", {
      type: "review",
      model: "claude-3-5-sonnet-latest",
      maxTokens: 25e3,
      temperature: 0.2,
      systemPrompt: `You are a Review Agent specializing in multi-stage code review.
        Perform thorough reviews focusing on:
        - Architecture and design patterns
        - Code quality and maintainability
        - Performance implications
        - Security considerations
        - Test coverage adequacy
        Suggest specific improvements with examples.
        Rate quality on a 0-1 scale.`,
      capabilities: [
        "review",
        "critique",
        "suggest-improvements",
        "quality-scoring"
      ]
    });
    configs.set("improve", {
      type: "improve",
      model: "claude-3-5-sonnet-latest",
      maxTokens: 3e4,
      temperature: 0.3,
      systemPrompt: `You are an Improvement Agent specializing in code enhancement.
        Take reviewed code and implement suggested improvements:
        - Refactor for better architecture
        - Optimize performance bottlenecks
        - Enhance error handling
        - Improve code clarity and documentation
        - Add missing test cases
        Ensure all improvements maintain backward compatibility.`,
      capabilities: ["enhance", "refactor", "optimize", "polish"]
    });
    configs.set("context", {
      type: "context",
      model: "claude-3-5-haiku-latest",
      maxTokens: 1e4,
      temperature: 0,
      systemPrompt: `You are a Context Agent specializing in information retrieval.
        Search and retrieve relevant context from:
        - Project codebase and documentation
        - Previous frame history
        - Similar implementations
        - Best practices and patterns
        Provide concise, relevant context for other agents.`,
      capabilities: ["search", "retrieve", "summarize", "contextualize"]
    });
    configs.set("publish", {
      type: "publish",
      model: "claude-3-5-haiku-latest",
      maxTokens: 15e3,
      temperature: 0,
      systemPrompt: `You are a Publish Agent specializing in release management.
        Handle:
        - NPM package publishing
        - GitHub releases and tagging
        - Documentation updates
        - Changelog generation
        - Deployment automation
        Ensure all release steps are properly sequenced.`,
      capabilities: ["publish-npm", "github-release", "deploy", "document"]
    });
    return configs;
  }
  /**
   * Execute a task with recursive decomposition
   */
  async execute(task, context, options) {
    const opts = { ...this.defaultOptions, ...options };
    const executionId = this.generateExecutionId();
    const startTime = Date.now();
    logger.info("Starting RLM execution", {
      executionId,
      task: task.slice(0, 100),
      options: opts
    });
    try {
      const rootFrameId = await this.createExecutionFrame(executionId, task);
      const rootNode = await this.planTask(task, context, opts);
      this.activeExecutions.set(executionId, rootNode);
      if (opts.verboseLogging) {
        this.logExecutionTree(rootNode);
      }
      await this.executeTaskTree(rootNode, context, opts, 0);
      const improvements = await this.performMultiStageReview(
        rootNode,
        opts.reviewStages,
        opts.qualityThreshold
      );
      const result = {
        success: rootNode.status === "completed",
        rootNode,
        totalTokens: this.calculateTotalTokens(rootNode),
        totalCost: this.calculateTotalCost(rootNode),
        duration: Date.now() - startTime,
        improvements,
        testsGenerated: this.countGeneratedTests(rootNode),
        issuesFound: this.countIssuesFound(rootNode),
        issuesFixed: this.countIssuesFixed(rootNode)
      };
      this.executionHistory.push(result);
      await this.updateExecutionFrame(rootFrameId, result);
      logger.info("RLM execution completed", {
        executionId,
        success: result.success,
        duration: result.duration,
        totalCost: result.totalCost,
        testsGenerated: result.testsGenerated,
        improvements: improvements.length
      });
      return result;
    } catch (error) {
      logger.error("RLM execution failed", { executionId, error });
      throw error;
    } finally {
      this.activeExecutions.delete(executionId);
    }
  }
  /**
   * Plan task decomposition
   */
  async planTask(task, context, options) {
    const response = await this.subagentClient.executeSubagent({
      type: "planning",
      task,
      context: {
        ...context,
        requirements: options
      }
    });
    const taskTree = this.parseTaskTree(JSON.stringify(response.result));
    this.injectTestGenerationNodes(taskTree, options.testGenerationMode);
    this.injectReviewStages(taskTree, options.reviewStages);
    return taskTree;
  }
  /**
   * Execute task tree recursively with parallelization
   */
  async executeTaskTree(node, context, options, depth) {
    if (depth >= options.maxRecursionDepth) {
      logger.warn("Max recursion depth reached", { nodeId: node.id, depth });
      node.status = "failed";
      node.error = new Error("Max recursion depth exceeded");
      return;
    }
    if (options.verboseLogging) {
      logger.info(`Executing node: ${node.description}`, {
        id: node.id,
        type: node.type,
        agent: node.agent,
        depth
      });
    }
    node.status = "running";
    node.startTime = /* @__PURE__ */ new Date();
    try {
      if (node.type === "parallel" && node.children) {
        await this.parallelExecutor.executeParallel(
          node.children,
          async (child) => {
            await this.executeTaskTree(child, context, options, depth + 1);
          }
        );
      } else if (node.type === "sequential" && node.children) {
        for (const child of node.children) {
          await this.executeTaskTree(child, context, options, depth + 1);
          if (child.result) {
            context[`${child.id}_result`] = child.result;
          }
        }
      } else {
        await this.executeLeafNode(node, context, options);
      }
      node.status = "completed";
    } catch (error) {
      logger.error(`Node execution failed: ${node.description}`, { error });
      if (options.retryFailedAgents && node.attempts < 3) {
        node.attempts++;
        logger.info(`Retrying node: ${node.description}`, {
          attempt: node.attempts
        });
        await this.executeTaskTree(node, context, options, depth);
      } else {
        node.status = "failed";
        node.error = error;
      }
    } finally {
      node.endTime = /* @__PURE__ */ new Date();
      if (options.verboseLogging) {
        const duration = node.endTime.getTime() - (node.startTime?.getTime() ?? 0);
        logger.info(`Completed node: ${node.description}`, {
          id: node.id,
          status: node.status,
          duration,
          tokens: node.tokens,
          cost: node.cost
        });
      }
    }
  }
  /**
   * Execute a leaf node with the appropriate agent
   */
  async executeLeafNode(node, context, options) {
    const agentConfig = this.subagentConfigs.get(node.agent);
    if (!agentConfig) {
      throw new Error(`Unknown agent type: ${node.agent}`);
    }
    const agentContext = await this.contextManager.prepareAgentContext(
      node.agent,
      context,
      options.maxTokensPerAgent
    );
    const taskDescription = this.buildAgentPrompt(node, agentContext);
    const response = await this.subagentClient.executeSubagent({
      type: node.agent,
      task: taskDescription,
      context: agentContext
    });
    node.result = response.result;
    node.tokens = response.tokens || this.estimateTokens(JSON.stringify(response));
    node.cost = this.calculateNodeCost(node.tokens, agentConfig.model);
    if (options.shareContextRealtime) {
      await this.shareAgentResults(node);
    }
  }
  /**
   * Perform multi-stage review and improvement
   */
  async performMultiStageReview(rootNode, stages, qualityThreshold) {
    const improvements = [];
    let currentQuality = 0;
    for (let stage = 1; stage <= stages; stage++) {
      logger.info(`Starting review stage ${stage}/${stages}`);
      const reviewNode = {
        id: `review-stage-${stage}`,
        type: "task",
        description: `Review stage ${stage}`,
        agent: "review",
        dependencies: [],
        context: { rootNode, stage },
        status: "pending",
        attempts: 0
      };
      const reviewResponse = await this.subagentClient.executeSubagent({
        type: "review",
        task: `Review stage ${stage}: Analyze code quality and suggest improvements`,
        context: { rootNode, stage }
      });
      reviewNode.result = reviewResponse.result;
      reviewNode.status = reviewResponse.success ? "completed" : "failed";
      const reviewResult = reviewResponse.result;
      currentQuality = reviewResult.quality || 0.5;
      if (reviewResult.suggestions && Array.isArray(reviewResult.suggestions)) {
        improvements.push(...reviewResult.suggestions);
      } else {
        improvements.push(
          `Stage ${stage}: Review completed with quality ${currentQuality}`
        );
      }
      logger.info(`Review stage ${stage} complete`, {
        quality: currentQuality,
        issues: reviewResult.issues?.length || 0,
        suggestions: reviewResult.suggestions?.length || 0
      });
      if (currentQuality >= qualityThreshold) {
        logger.info(
          `Quality threshold met: ${currentQuality} >= ${qualityThreshold}`
        );
        break;
      }
      if (stage < stages) {
        const improveNode = {
          id: `improve-stage-${stage}`,
          type: "task",
          description: `Improvement stage ${stage}`,
          agent: "improve",
          dependencies: [reviewNode.id],
          context: { reviewResult, rootNode },
          status: "pending",
          attempts: 0
        };
        const improveResponse = await this.subagentClient.executeSubagent({
          type: "improve",
          task: `Improvement stage ${stage}: Implement suggested improvements`,
          context: { reviewResult, rootNode }
        });
        improveNode.result = improveResponse.result;
        improveNode.status = improveResponse.success ? "completed" : "failed";
        this.applyImprovements(rootNode, improveNode.result);
      }
    }
    return improvements;
  }
  /**
   * Helper methods
   */
  generateExecutionId() {
    return `rlm-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
  }
  async createExecutionFrame(executionId, task) {
    return this.frameManager.createFrame({
      name: `RLM: ${task.slice(0, 50)}`,
      type: "task",
      inputs: { executionId, task, type: "rlm-execution" }
    });
  }
  async updateExecutionFrame(frameId, result) {
    this.frameManager.closeFrame(frameId, {
      type: "rlm-result",
      content: JSON.stringify(result, null, 2),
      success: result.success,
      duration: result.duration,
      totalTokens: result.totalTokens,
      totalCost: result.totalCost
    });
  }
  logExecutionTree(node, depth = 0) {
    const indent = "  ".repeat(depth);
    const status = node.status === "completed" ? "\u2713" : node.status === "failed" ? "\u2717" : node.status === "running" ? "\u27F3" : "\u25CB";
    console.log(`${indent}${status} ${node.description} [${node.agent}]`);
    if (node.children) {
      for (const child of node.children) {
        this.logExecutionTree(child, depth + 1);
      }
    }
  }
  parseTaskTree(_response) {
    return {
      id: "root",
      type: "sequential",
      description: "Root task",
      agent: "planning",
      dependencies: [],
      context: {},
      status: "pending",
      attempts: 0,
      children: []
    };
  }
  injectTestGenerationNodes(node, _mode) {
    if (!node.children) {
      node.children = [];
    }
    const testNode = {
      id: `${node.id}-test`,
      type: "task",
      description: `Generate ${_mode} tests for ${node.description}`,
      agent: "testing",
      dependencies: [node.id],
      context: { testMode: _mode },
      status: "pending",
      attempts: 0
    };
    node.children.push(testNode);
  }
  injectReviewStages(_node, _stages) {
  }
  buildAgentPrompt(node, context) {
    return `
      Task: ${node.description}
      
      Context:
      ${JSON.stringify(context, null, 2)}
      
      Previous Results:
      ${JSON.stringify(
      node.dependencies.map((id) => this.activeExecutions.get(id)?.result),
      null,
      2
    )}
      
      Please complete this task following your specialized role.
    `;
  }
  estimateTokens(text) {
    return Math.ceil(text.length / 4);
  }
  async shareAgentResults(_node) {
    logger.debug("Sharing agent results", { nodeId: _node.id });
  }
  applyImprovements(_rootNode, improvements) {
    logger.debug("Applying improvements", { improvements });
  }
  calculateTotalTokens(node) {
    let total = node.tokens || 0;
    if (node.children) {
      for (const child of node.children) {
        total += this.calculateTotalTokens(child);
      }
    }
    return total;
  }
  calculateTotalCost(node) {
    let total = node.cost || 0;
    if (node.children) {
      for (const child of node.children) {
        total += this.calculateTotalCost(child);
      }
    }
    return total;
  }
  calculateNodeCost(tokens, model) {
    const pricing = {
      "claude-3-5-sonnet-latest": 15,
      "claude-3-5-haiku-latest": 1,
      "claude-3-opus-latest": 75
    };
    return tokens / 1e6 * (pricing[model] || 10);
  }
  countGeneratedTests(node) {
    let count = 0;
    if (node.agent === "testing" && node.result?.tests) {
      count += node.result.tests.length;
    }
    if (node.children) {
      for (const child of node.children) {
        count += this.countGeneratedTests(child);
      }
    }
    return count;
  }
  countIssuesFound(node) {
    let count = 0;
    if ((node.agent === "review" || node.agent === "linting") && node.result?.issues) {
      count += node.result.issues.length;
    }
    if (node.children) {
      for (const child of node.children) {
        count += this.countIssuesFound(child);
      }
    }
    return count;
  }
  countIssuesFixed(node) {
    let count = 0;
    if (node.agent === "improve" && node.result?.fixed) {
      count += node.result.fixed.length;
    }
    if (node.children) {
      for (const child of node.children) {
        count += this.countIssuesFixed(child);
      }
    }
    return count;
  }
}
export {
  RecursiveAgentOrchestrator
};
//# sourceMappingURL=recursive-agent-orchestrator.js.map
