import { agentLabel } from "../../agents/shared/agent.js";
import { friendlyErrorText } from "../../core/error-messages.js";
import { evaluateWorkspacePolicy } from "../../core/workspace-policy.js";
import { capabilitiesOf, renderPromptFailure } from "./bot-rendering.js";
import { createChannelPromptEngine } from "./channel-prompt-engine.js";
export async function runChannelLocalPrompt(options) {
    const { request, session, envelope, busyState, promptStore, turnProgress, config, } = options;
    busyState.processing = true;
    let turnInfo = null;
    const currentTurnInfo = () => turnInfo ?? session.getInfo();
    const engine = createChannelPromptEngine({
        runtime: options.runtime,
        context: request.context,
        contextKey: request.contextKey,
        promptDescription: envelope.description,
        abortAction: `${options.abortActionPrefix}_abort:${request.contextKey}`,
        trimMessage: options.trimMessage,
        splitMessage: options.splitMessage,
        editDebounceMs: options.editDebounceMs,
        typingIntervalMs: options.typingIntervalMs,
        toolVerbosity: config.toolVerbosity,
        logPrefix: options.label,
        onResponseMessage: options.onResponseMessage,
        onToolStart: (toolName) => {
            const info = currentTurnInfo();
            return options.appendActivity(request, {
                status: "running",
                type: "tool_started",
                prompt: envelope.description,
                detail: toolName,
                threadId: info.threadId,
                workspace: info.workspace,
                agentId: info.agentId,
            });
        },
        onToolEnd: (isError) => {
            const info = currentTurnInfo();
            return options.appendActivity(request, {
                status: isError ? "failed" : "completed",
                type: isError ? "tool_failed" : "tool_completed",
                prompt: envelope.description,
                detail: "tool",
                threadId: info.threadId,
                workspace: info.workspace,
                agentId: info.agentId,
            });
        },
    });
    const progress = engine.progress;
    turnProgress.set(request.contextKey, progress);
    engine.start();
    try {
        const info = session.getInfo();
        if ((info.capabilities ?? capabilitiesOf(info)).auth) {
            const auth = await options.checkAgentAuthStatus(info);
            if (!auth.authenticated) {
                throw new Error(`${agentLabel(info.agentId)} is not authenticated: ${auth.detail}`);
            }
        }
        await options.ensureActiveThread(request, session);
        const currentInfo = session.getInfo();
        turnInfo = currentInfo;
        const workspacePolicy = evaluateWorkspacePolicy(currentInfo.workspace, config);
        if (!workspacePolicy.allowed) {
            throw new Error(workspacePolicy.warning ?? "Current workspace is blocked by policy.");
        }
        promptStore.setLastPrompt(request.contextKey, envelope);
        options.appendActivity(request, promptActivity("running", "prompt_started", envelope, currentInfo));
        options.audit(request, promptAudit("prompt_started", "ok", envelope, currentInfo));
        await session.prompt(envelope.input, engine.callbacks);
        options.updateSession(request, session);
        progress.status = "completed";
        progress.completedAt = Date.now();
        progress.updatedAt = progress.completedAt;
        await engine.finalize();
        await options.artifactService.persistWorkspaceArtifactsForTurn(currentInfo.workspace, engine.turnId, new Date(engine.startedAt), {
            source: options.source,
            agentId: currentInfo.agentId,
            threadId: currentInfo.threadId,
            workspace: currentInfo.workspace,
            contextKey: request.contextKey,
            correlationId: envelope.correlationId,
            prompt: envelope.description,
            actor: options.actor,
            turnStartedAt: new Date(engine.startedAt).toISOString(),
        });
        if (config.artifactsEnabled) {
            await options.sendRecentArtifacts(new Date(engine.startedAt), engine.turnId);
        }
        options.appendActivity(request, {
            ...promptActivity("completed", "prompt_completed", envelope, currentInfo),
            durationMs: Date.now() - engine.startedAt,
        });
        options.audit(request, promptAudit("prompt_completed", "ok", envelope, currentInfo));
    }
    catch (error) {
        const failedInfo = turnInfo ?? session.getInfo();
        progress.status = "failed";
        progress.completedAt = Date.now();
        progress.updatedAt = progress.completedAt;
        progress.error = friendlyErrorText(error);
        await engine.fail(renderPromptFailure(engine.accumulatedText(), error));
        options.appendActivity(request, {
            ...promptActivity("failed", "prompt_failed", envelope, failedInfo),
            detail: friendlyErrorText(error),
            durationMs: Date.now() - engine.startedAt,
        });
        options.audit(request, {
            ...promptAudit("prompt_failed", "failed", envelope, failedInfo),
            detail: friendlyErrorText(error),
        });
    }
    finally {
        engine.stop();
        busyState.processing = false;
        await options.drainQueue().catch((error) => console.error(`Failed to drain ${options.label} queue:`, error));
    }
}
function promptActivity(status, type, envelope, info) {
    return {
        status,
        type,
        prompt: envelope.description,
        threadId: info.threadId,
        workspace: info.workspace,
        agentId: info.agentId,
    };
}
function promptAudit(action, status, envelope, info) {
    return {
        action,
        status,
        agentId: info.agentId,
        threadId: info.threadId,
        workspace: info.workspace,
        description: envelope.description,
    };
}
