"use strict";
/**
 * OrchestratedMissionExecutor — concrete MissionExecutor that bridges the
 * autonomous queue to the full OrchestrationLoop.
 *
 * Phase 1 (Daemon Wakeup) of the autonomous-agent milestone.
 *
 * The QueueScheduler owns the *queue* (pending → running → terminal) and
 * retry policy. This executor owns the *translation*: a queued MissionSpec
 * (id + goal + context) becomes a classified task and is run through the
 * OrchestrationLoop, which already wires governance, dynamic agent birth,
 * planning, review, and memory curation internally.
 *
 * Result mapping: OrchestrationLoop returns a MissionState whose terminal
 * `status` is 'completed' | 'failed' (set by the ReviewerAgent gate). The
 * judgeOutcome() policy converts that into the queue's
 * MissionExecutionResult, deciding what counts as success and what error
 * surfaces on failure.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.OrchestratedMissionExecutor = void 0;
const OrchestrationLoop_1 = require("./OrchestrationLoop");
const IntentClassifier_1 = require("./IntentClassifier");
const MissionGovernor_1 = require("./MissionGovernor");
class OrchestratedMissionExecutor {
    loop;
    classifier;
    governor;
    iterationBudget;
    constructor(opts) {
        this.loop = opts.loop || new OrchestrationLoop_1.OrchestrationLoop(opts.brain, opts.taskExecutor);
        this.classifier = opts.classifier || new IntentClassifier_1.IntentClassifier();
        this.governor = opts.governor || new MissionGovernor_1.MissionGovernor();
        this.iterationBudget = opts.iterationBudget ?? Number(process.env.OPENLIFE_STORY_MAX_ITERS || 10);
    }
    async execute(mission) {
        // Phase 3 — hard governance chokepoint BEFORE any orchestration/LLM spend.
        // A blocked mission is terminal (non-retryable): retrying would hit the
        // same wall, and a vortex-blocked op never self-authorizes.
        const auth = this.governor.authorize(mission);
        if (!auth.allowed) {
            return { status: 'failed', retryable: false, error: auth.reason };
        }
        let state;
        try {
            const task = await this.classifier.classify(mission.goal);
            const userId = mission.context?.userId || 'autonomous';
            const recentHistory = mission.context?.recentHistory || '';
            const origin = mission.source === 'telegram' ? 'telegram' : 'cli';
            const result = await this.loop.run(task, mission.goal, userId, recentHistory, {
                origin,
                goal: mission.goal,
            });
            state = result.state;
        }
        catch (err) {
            return {
                status: 'failed',
                error: `orchestration_threw: ${err instanceof Error ? err.message : String(err)}`,
            };
        }
        return this.judgeOutcome(state, mission);
    }
    /**
     * Decide whether a finished mission counts as success or failure for the
     * queue — which in turn governs the QueueScheduler's retry behavior
     * (a retryable 'failed' result is re-queued until maxAttempts).
     *
     * Policy: STRICT success + TERMINAL failure detection.
     *   - Success only when the ReviewerAgent approved (state.status ===
     *     'completed'). A near-miss does not silently ship.
     *   - A failure caused by a CRITICAL governance event (destructive action
     *     blocked, prompt injection, scope violation, executor blocked) is
     *     TERMINAL — retrying would hit the same wall every time, so we mark
     *     it non-retryable (`retryable: false`) and surface the blocking
     *     event. The QueueScheduler honors this and does not re-queue.
     *   - Any other failure is retryable (transient model/tool error, a
     *     refine loop that ran out of attempts, etc.).
     */
    judgeOutcome(state, _mission) {
        if (state.status === 'completed') {
            return { status: 'completed' };
        }
        const blocking = state.governanceEvents.find((e) => e.level === 'critical' &&
            (e.type === 'destructive_action_blocked' ||
                e.type === 'prompt_injection_detected' ||
                e.type === 'scope_violation' ||
                e.type === 'executor_blocked'));
        if (blocking) {
            return {
                status: 'failed',
                retryable: false,
                error: `governance_blocked: ${blocking.type} — ${blocking.summary}`,
            };
        }
        return {
            status: 'failed',
            error: `mission_not_completed: state=${state.status}`,
        };
    }
}
exports.OrchestratedMissionExecutor = OrchestratedMissionExecutor;
