"use strict";
/**
 * Operations API surface for the built-in agent (#626).
 *
 * Six handlers, all super_user-only — the auth check is inline because none
 * of these ops are registered in `utility/operation_authorization.ts`'s
 * `requiredPermissions` map. Without the inline gate, a non-SU request would
 * fall through the standard flow and be allowed.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildOperations = buildOperations;
const hdbTerms_ts_1 = require("../utility/hdbTerms.js");
const hdbError_ts_1 = require("../utility/errors/hdbError.js");
const session_ts_1 = require("./session.js");
function buildOperations(deps) {
    return [
        {
            name: hdbTerms_ts_1.OPERATIONS_ENUM.AGENT_PROMPT,
            execute: async (op) => agentPrompt(op, deps),
        },
        {
            name: hdbTerms_ts_1.OPERATIONS_ENUM.GET_AGENT_SESSION,
            execute: async (op) => getAgentSession(op),
        },
        {
            name: hdbTerms_ts_1.OPERATIONS_ENUM.LIST_AGENT_SESSIONS,
            execute: async (op) => listAgentSessions(op),
        },
        {
            name: hdbTerms_ts_1.OPERATIONS_ENUM.CANCEL_AGENT_RUN,
            execute: async (op) => cancelAgentRun(op, deps),
        },
        {
            name: hdbTerms_ts_1.OPERATIONS_ENUM.APPROVE_AGENT_ACTION,
            execute: async (op) => approveAgentAction(op, deps),
        },
        {
            name: hdbTerms_ts_1.OPERATIONS_ENUM.SET_AGENT_CONFIG,
            execute: async (op) => setAgentConfig(op, deps),
        },
    ];
}
function requireSuperUser(op) {
    if (!op?.hdb_user?.role?.permission?.super_user) {
        throw new hdbError_ts_1.ClientError('Agent operations require super_user', 403);
    }
}
async function agentPrompt(op, deps) {
    requireSuperUser(op);
    const config = deps.getConfig();
    if (!config.enabled) {
        throw new hdbError_ts_1.ClientError('Agent component is disabled (agent.enabled=false)', 409);
    }
    const message = String(op?.message ?? '').trim();
    if (!message)
        throw new hdbError_ts_1.ClientError('message is required', 400);
    let sessionId = op?.session_id;
    if (sessionId) {
        const existing = await (0, session_ts_1.getSession)(sessionId);
        if (!existing)
            throw new hdbError_ts_1.ClientError(`Unknown session ${sessionId}`, 404);
        if (existing.status === 'running' || existing.status === 'awaiting_approval') {
            throw new hdbError_ts_1.ClientError(`Session ${sessionId} is ${existing.status}; resolve or cancel before sending another prompt`, 409);
        }
        await (0, session_ts_1.appendMessage)(sessionId, asUserMessage(message));
    }
    else {
        const created = await (0, session_ts_1.createSession)({
            user: op?.hdb_user?.username ?? config.user,
            model: config.model,
            provider: config.provider,
            initialMessage: asUserMessage(message),
        });
        sessionId = created.session_id;
    }
    deps.startRun(sessionId);
    return { session_id: sessionId, status: 'running' };
}
async function getAgentSession(op) {
    requireSuperUser(op);
    const sessionId = String(op?.session_id ?? '');
    if (!sessionId)
        throw new hdbError_ts_1.ClientError('session_id is required', 400);
    const session = await (0, session_ts_1.getSession)(sessionId);
    if (!session)
        throw new hdbError_ts_1.ClientError(`Unknown session ${sessionId}`, 404);
    return session;
}
async function listAgentSessions(op) {
    requireSuperUser(op);
    const limit = Number.isFinite(op?.limit) ? Number(op.limit) : undefined;
    return { sessions: await (0, session_ts_1.listSessions)({ limit }) };
}
async function cancelAgentRun(op, deps) {
    requireSuperUser(op);
    const sessionId = String(op?.session_id ?? '');
    if (!sessionId)
        throw new hdbError_ts_1.ClientError('session_id is required', 400);
    const session = await (0, session_ts_1.getSession)(sessionId);
    if (!session)
        throw new hdbError_ts_1.ClientError(`Unknown session ${sessionId}`, 404);
    // Abort any active controller (best-effort — there may not be one if the loop is paused
    // in `awaiting_approval` or sitting `idle` between turns). Always update the persisted
    // status so a paused session can still be terminated by the operator.
    const signalledLiveRun = deps.cancelRun(sessionId);
    const wasTerminal = session.status === 'completed' || session.status === 'aborted' || session.status === 'error';
    if (!wasTerminal)
        await (0, session_ts_1.setStatus)(sessionId, 'aborted', 'Cancelled by operator');
    return { cancelled: !wasTerminal, signalledLiveRun };
}
async function approveAgentAction(op, deps) {
    requireSuperUser(op);
    const sessionId = String(op?.session_id ?? '');
    const approvalId = String(op?.approval_id ?? '');
    if (!sessionId || !approvalId) {
        throw new hdbError_ts_1.ClientError('session_id and approval_id are required', 400);
    }
    const approved = op?.approved !== false;
    const resolved = await (0, session_ts_1.resolveApproval)(sessionId, approvalId, approved);
    // Either decision should resume the loop: an approval means execute the saved tool call;
    // a denial means hand the operator-rejection observation back to the model so it can adjust.
    deps.startRun(sessionId);
    return resolved;
}
async function setAgentConfig(op, deps) {
    requireSuperUser(op);
    const patch = {};
    for (const key of ['enabled', 'provider', 'model', 'maxTurns', 'maxCostUsd', 'autoApprove', 'allowDestructive']) {
        if (op?.[key] !== undefined)
            patch[key] = op[key];
    }
    return deps.setConfig(patch);
}
function asUserMessage(content) {
    return { role: 'user', content, createdAt: Date.now() };
}
//# sourceMappingURL=operations.js.map