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 { TaskError, ErrorCode } from "../../core/errors/index.js";
var AgentType = /* @__PURE__ */ ((AgentType2) => {
  AgentType2["FORMATTER"] = "formatter";
  AgentType2["SECURITY"] = "security";
  AgentType2["TESTING"] = "testing";
  AgentType2["PERFORMANCE"] = "performance";
  AgentType2["DOCUMENTATION"] = "documentation";
  AgentType2["REFACTORING"] = "refactoring";
  return AgentType2;
})(AgentType || {});
class AgentTaskManager {
  taskStore;
  frameManager;
  activeSessions = /* @__PURE__ */ new Map();
  sessionTimeouts = /* @__PURE__ */ new Map();
  agentRegistry = /* @__PURE__ */ new Map();
  // Spotify strategy constants
  MAX_TURNS_PER_SESSION = 10;
  MAX_SESSION_RETRIES = 3;
  SESSION_TIMEOUT_MS = 30 * 60 * 1e3;
  // 30 minutes
  CONTEXT_WINDOW_SIZE = 5;
  // Last 5 significant events
  constructor(taskStore, frameManager) {
    this.taskStore = taskStore;
    this.frameManager = frameManager;
  }
  /**
   * Start a new agent task session with Spotify's 10-turn limit
   */
  async startTaskSession(taskId, frameId) {
    const task = this.taskStore.getTask(taskId);
    if (!task) {
      throw new TaskError(
        `Task ${taskId} not found`,
        ErrorCode.TASK_NOT_FOUND,
        { taskId }
      );
    }
    if (this.needsBreakdown(task)) {
      const breakdown = await this.breakdownTask(task);
      return this.startMultiTaskSession(breakdown, frameId);
    }
    const sessionId = this.generateSessionId(taskId);
    const session = {
      id: sessionId,
      frameId,
      taskId,
      turnCount: 0,
      maxTurns: this.MAX_TURNS_PER_SESSION,
      status: "active",
      startedAt: /* @__PURE__ */ new Date(),
      verificationResults: [],
      contextWindow: [],
      feedbackLoop: []
    };
    this.activeSessions.set(sessionId, session);
    this.startSessionTimeout(sessionId);
    this.taskStore.updateTaskStatus(
      taskId,
      "in_progress",
      "Agent session started"
    );
    logger.info("Started agent task session", {
      sessionId,
      taskId,
      taskTitle: task.title,
      maxTurns: this.MAX_TURNS_PER_SESSION
    });
    return session;
  }
  /**
   * Execute a turn in the session with verification
   */
  async executeTurn(sessionId, action, context) {
    const session = this.activeSessions.get(sessionId);
    if (!session || session.status !== "active") {
      throw new TaskError(
        "Invalid or inactive session",
        ErrorCode.TASK_INVALID_STATE,
        { sessionId }
      );
    }
    session.turnCount++;
    if (session.turnCount >= session.maxTurns) {
      return this.handleTurnLimitReached(session);
    }
    const verificationResults = await this.runVerificationLoop(
      action,
      context,
      session
    );
    this.updateContextWindow(session, action, verificationResults);
    const feedback = this.generateFeedback(verificationResults);
    const success = verificationResults.every(
      (r) => r.passed || r.severity !== "error"
    );
    session.feedbackLoop.push({
      turn: session.turnCount,
      action,
      result: feedback,
      verificationPassed: success,
      contextAdjustment: this.suggestContextAdjustment(verificationResults) || void 0
    });
    const shouldContinue = success && session.turnCount < session.maxTurns;
    if (!shouldContinue && success) {
      await this.completeSession(session);
    }
    return {
      success,
      feedback,
      shouldContinue,
      verificationResults
    };
  }
  /**
   * Run Spotify-style verification loop
   */
  async runVerificationLoop(action, context, session) {
    const results = [];
    const verifiers = this.getApplicableVerifiers(context);
    for (const verifier of verifiers) {
      const result = await this.runVerifier(verifier, action, context);
      results.push(result);
      session.verificationResults.push(result);
      if (!result.passed && result.severity === "error") {
        logger.warn("Verification failed, stopping execution", {
          verifier: result.verifierId,
          message: result.message
        });
        break;
      }
    }
    return results;
  }
  /**
   * Get verifiers applicable to current context
   */
  getApplicableVerifiers(context) {
    const verifiers = [];
    if (context["codeChange"]) {
      verifiers.push("formatter", "linter", "type-checker");
    }
    if (context["testsPresent"]) {
      verifiers.push("test-runner");
    }
    if (context["hasDocumentation"]) {
      verifiers.push("doc-validator");
    }
    if (context["performanceCritical"]) {
      verifiers.push("performance-analyzer");
    }
    verifiers.push("semantic-validator");
    return verifiers;
  }
  /**
   * Run a single verifier
   */
  async runVerifier(verifierId, action, context) {
    const mockResults = {
      formatter: () => ({
        verifierId: "formatter",
        passed: Math.random() > 0.1,
        message: "Code formatting check",
        severity: "warning",
        timestamp: /* @__PURE__ */ new Date(),
        autoFix: "prettier --write"
      }),
      linter: () => ({
        verifierId: "linter",
        passed: Math.random() > 0.2,
        message: "Linting check",
        severity: "error",
        timestamp: /* @__PURE__ */ new Date()
      }),
      "test-runner": () => ({
        verifierId: "test-runner",
        passed: Math.random() > 0.3,
        message: "Test execution",
        severity: "error",
        timestamp: /* @__PURE__ */ new Date()
      }),
      "semantic-validator": () => ({
        verifierId: "semantic-validator",
        passed: Math.random() > 0.25,
        // ~75% pass rate like Spotify
        message: "Semantic validation against original requirements",
        severity: "error",
        timestamp: /* @__PURE__ */ new Date()
      })
    };
    const verifierFn = mockResults[verifierId] || (() => ({
      verifierId,
      passed: true,
      message: "Unknown verifier",
      severity: "info",
      timestamp: /* @__PURE__ */ new Date()
    }));
    return verifierFn();
  }
  /**
   * Check if task needs breakdown (Spotify strategy for complex tasks)
   */
  needsBreakdown(task) {
    const indicators = {
      hasMultipleComponents: (task.description?.match(/\band\b/gi)?.length || 0) > 2,
      longDescription: (task.description?.length || 0) > 500,
      highComplexityTags: task.tags.some(
        (tag) => ["refactor", "migration", "architecture", "redesign"].includes(
          tag.toLowerCase()
        )
      ),
      hasManydependencies: task.depends_on.length > 3
    };
    const complexityScore = Object.values(indicators).filter(Boolean).length;
    return complexityScore >= 2;
  }
  /**
   * Break down complex task into subtasks
   */
  async breakdownTask(task) {
    const subtasks = [
      {
        title: `Analyze requirements for ${task.title}`,
        description: "Understand and document requirements",
        acceptanceCriteria: [
          "Requirements documented",
          "Constraints identified"
        ],
        estimatedTurns: 2,
        verifiers: ["semantic-validator"]
      },
      {
        title: `Implement core functionality for ${task.title}`,
        description: "Build the main implementation",
        acceptanceCriteria: ["Core logic implemented", "Tests passing"],
        estimatedTurns: 5,
        verifiers: ["linter", "test-runner"]
      },
      {
        title: `Verify and refine ${task.title}`,
        description: "Final verification and improvements",
        acceptanceCriteria: ["All tests passing", "Documentation complete"],
        estimatedTurns: 3,
        verifiers: ["formatter", "linter", "test-runner", "semantic-validator"]
      }
    ];
    return {
      parentTaskId: task.id,
      subtasks,
      dependencies: /* @__PURE__ */ new Map([
        [subtasks[1].title, [subtasks[0].title]],
        [subtasks[2].title, [subtasks[1].title]]
      ]),
      estimatedTurns: subtasks.reduce((sum, st) => sum + st.estimatedTurns, 0)
    };
  }
  /**
   * Start multi-task session for complex tasks
   */
  async startMultiTaskSession(breakdown, frameId) {
    const subtaskIds = [];
    for (const subtask of breakdown.subtasks) {
      const subtaskId = this.taskStore.createTask({
        title: subtask.title,
        description: subtask.description,
        frameId,
        parentId: breakdown.parentTaskId,
        tags: ["agent-subtask", ...subtask.verifiers],
        estimatedEffort: subtask.estimatedTurns * 5
        // Rough conversion to minutes
      });
      subtaskIds.push(subtaskId);
    }
    const titleToId = new Map(
      breakdown.subtasks.map((st, i) => [st.title, subtaskIds[i]])
    );
    for (const [title, deps] of breakdown.dependencies) {
      const taskId = titleToId.get(title);
      if (taskId) {
        for (const dep of deps) {
          const depId = titleToId.get(dep);
          if (depId) {
            this.taskStore.addDependency(taskId, depId);
          }
        }
      }
    }
    return this.startTaskSession(subtaskIds[0], frameId);
  }
  /**
   * Update context window with significant events
   */
  updateContextWindow(session, action, verificationResults) {
    const significantEvent = {
      turn: session.turnCount,
      action: action.substring(0, 100),
      verificationSummary: verificationResults.map((r) => ({
        verifier: r.verifierId,
        passed: r.passed
      })),
      timestamp: (/* @__PURE__ */ new Date()).toISOString()
    };
    session.contextWindow.push(JSON.stringify(significantEvent));
    if (session.contextWindow.length > this.CONTEXT_WINDOW_SIZE) {
      session.contextWindow = session.contextWindow.slice(
        -this.CONTEXT_WINDOW_SIZE
      );
    }
  }
  /**
   * Generate feedback from verification results
   */
  generateFeedback(results) {
    const failed = results.filter((r) => !r.passed);
    const warnings = results.filter(
      (r) => !r.passed && r.severity === "warning"
    );
    const errors = results.filter((r) => !r.passed && r.severity === "error");
    if (errors.length > 0) {
      const errorMessages = errors.map((e) => `- ${e.message}`).join("\n");
      return `Verification failed with ${errors.length} error(s):
${errorMessages}`;
    }
    if (warnings.length > 0) {
      const warningMessages = warnings.map((w) => `- ${w.message}`).join("\n");
      return `Verification passed with ${warnings.length} warning(s):
${warningMessages}`;
    }
    return "All verifications passed successfully";
  }
  /**
   * Suggest context adjustment based on verification results
   */
  suggestContextAdjustment(results) {
    const failed = results.filter((r) => !r.passed && r.severity === "error");
    if (failed.length === 0) {
      return void 0;
    }
    const suggestions = [];
    if (failed.some((r) => r.verifierId === "test-runner")) {
      suggestions.push("Focus on fixing failing tests");
    }
    if (failed.some((r) => r.verifierId === "linter")) {
      suggestions.push("Address linting errors before proceeding");
    }
    if (failed.some((r) => r.verifierId === "semantic-validator")) {
      suggestions.push("Review original requirements and adjust approach");
    }
    return suggestions.length > 0 ? suggestions.join("; ") : void 0;
  }
  /**
   * Handle turn limit reached
   */
  async handleTurnLimitReached(session) {
    logger.warn("Session reached turn limit", {
      sessionId: session.id,
      taskId: session.taskId,
      turnCount: session.turnCount
    });
    const task = this.taskStore.getTask(session.taskId);
    const isComplete = this.assessTaskCompletion(session);
    if (isComplete) {
      await this.completeSession(session);
      return {
        success: true,
        feedback: "Task completed successfully within turn limit",
        shouldContinue: false,
        verificationResults: []
      };
    }
    session.status = "timeout";
    this.taskStore.updateTaskStatus(
      session.taskId,
      "blocked",
      "Session timeout - manual review needed"
    );
    return {
      success: false,
      feedback: `Session reached ${this.MAX_TURNS_PER_SESSION} turn limit. Task requires manual review or retry.`,
      shouldContinue: false,
      verificationResults: []
    };
  }
  /**
   * Assess if task is complete enough
   */
  assessTaskCompletion(session) {
    const recentResults = session.verificationResults.slice(-5);
    const recentPassRate = recentResults.filter((r) => r.passed).length / recentResults.length;
    const semanticPassed = recentResults.some(
      (r) => r.verifierId === "semantic-validator" && r.passed
    );
    return recentPassRate >= 0.8 && semanticPassed;
  }
  /**
   * Complete a session
   */
  async completeSession(session) {
    session.status = "completed";
    session.completedAt = /* @__PURE__ */ new Date();
    this.taskStore.updateTaskStatus(
      session.taskId,
      "completed",
      "Agent session completed"
    );
    const timeout = this.sessionTimeouts.get(session.id);
    if (timeout) {
      clearTimeout(timeout);
      this.sessionTimeouts.delete(session.id);
    }
    const summary = this.generateSessionSummary(session);
    this.frameManager.addEvent("observation", {
      type: "session_summary",
      frameId: session.frameId,
      summary
    });
    logger.info("Session completed", {
      sessionId: session.id,
      taskId: session.taskId,
      turnCount: session.turnCount,
      duration: session.completedAt.getTime() - session.startedAt.getTime()
    });
  }
  /**
   * Generate session summary for frame digest
   */
  generateSessionSummary(session) {
    const verificationStats = {
      total: session.verificationResults.length,
      passed: session.verificationResults.filter((r) => r.passed).length,
      failed: session.verificationResults.filter((r) => !r.passed).length
    };
    return {
      sessionId: session.id,
      taskId: session.taskId,
      status: session.status,
      turnCount: session.turnCount,
      duration: session.completedAt ? session.completedAt.getTime() - session.startedAt.getTime() : 0,
      verificationStats,
      feedbackLoop: session.feedbackLoop.slice(-3),
      // Last 3 feedback entries
      contextWindow: session.contextWindow.slice(-2)
      // Last 2 context entries
    };
  }
  /**
   * Start timeout for session
   */
  startSessionTimeout(sessionId) {
    const timeout = setTimeout(() => {
      const session = this.activeSessions.get(sessionId);
      if (session && session.status === "active") {
        session.status = "timeout";
        this.taskStore.updateTaskStatus(
          session.taskId,
          "blocked",
          "Session timeout - no activity"
        );
        logger.warn("Session timed out due to inactivity", { sessionId });
      }
    }, this.SESSION_TIMEOUT_MS);
    this.sessionTimeouts.set(sessionId, timeout);
  }
  /**
   * Generate unique session ID
   */
  generateSessionId(taskId) {
    return `session-${taskId}-${Date.now()}`;
  }
  /**
   * Get active sessions summary
   */
  getActiveSessions() {
    return Array.from(this.activeSessions.values()).map((session) => ({
      sessionId: session.id,
      taskId: session.taskId,
      turnCount: session.turnCount,
      status: session.status,
      startedAt: session.startedAt
    }));
  }
  /**
   * Retry a failed session (Spotify's 3-retry strategy)
   */
  async retrySession(sessionId) {
    const session = this.activeSessions.get(sessionId);
    if (!session || session.status === "active") {
      return null;
    }
    const retryCount = Array.from(this.activeSessions.values()).filter(
      (s) => s.taskId === session.taskId && s.status === "failed"
    ).length;
    if (retryCount >= this.MAX_SESSION_RETRIES) {
      logger.warn("Max retries reached for task", {
        taskId: session.taskId,
        retries: retryCount
      });
      return null;
    }
    const newSession = await this.startTaskSession(
      session.taskId,
      session.frameId
    );
    newSession.contextWindow = session.contextWindow.slice(-3);
    newSession.feedbackLoop = [
      {
        turn: 0,
        action: "Session retry with learned context",
        result: `Retrying after ${retryCount} previous attempts`,
        verificationPassed: true,
        contextAdjustment: session.feedbackLoop.filter((f) => f.contextAdjustment).map((f) => f.contextAdjustment).join("; ")
      }
    ];
    return newSession;
  }
}
export {
  AgentTaskManager,
  AgentType
};
//# sourceMappingURL=agent-task-manager.js.map
