import { dispatch } from "./dispatcher.js";
/**
 * Called from `session-registry.makeSubscribeHandler` for every
 * AgentSessionEvent that fires on a live session. We filter inside
 * for the 3 SDK events we care about — the rest are ignored.
 */
export function bridgeAgentSessionEvent(meta, event) {
    // `event` is the SDK's union; some fields are typed loose enough
    // that we cast through unknown to read them. That matches the
    // pattern session-registry.ts itself uses for the same union.
    const e = event;
    if (e.type === "agent_end") {
        // session.messages is post-turn; pull the final assistant
        // message for the payload's primary content. The SDK guarantees
        // session.errorMessage is the authoritative error field on
        // agent_end.
        const messages = meta.session.messages;
        const lastAssistant = findLastAssistant(messages);
        const errorMessage = meta.session.errorMessage ??
            lastAssistant?.errorMessage;
        void dispatch({
            event: "agent_end",
            sessionId: meta.sessionId,
            projectId: meta.projectId,
            data: {
                stopReason: lastAssistant?.stopReason ?? null,
                errorMessage: errorMessage ?? null,
                assistantText: lastAssistant?.text ?? null,
                usage: lastAssistant?.usage ?? null,
                provider: lastAssistant?.provider ?? null,
                model: lastAssistant?.model ?? null,
            },
        });
        return;
    }
    if (e.type === "auto_retry_end" && e.success === false) {
        void dispatch({
            event: "auto_retry_end",
            sessionId: meta.sessionId,
            projectId: meta.projectId,
            data: {
                attempt: e.attempt ?? null,
                maxAttempts: e.maxAttempts ?? null,
                finalError: e.finalError ?? null,
            },
        });
        return;
    }
    if (e.type === "compaction_end") {
        // Only fire on completed compactions (aborted ones aren't
        // useful for "your context just shrank" integrations).
        if (e.aborted === true)
            return;
        void dispatch({
            event: "compaction_end",
            sessionId: meta.sessionId,
            projectId: meta.projectId,
            data: {
                reason: e.reason ?? null,
                tokensBefore: e.tokensBefore ?? null,
            },
        });
        return;
    }
}
function findLastAssistant(messages) {
    for (let i = messages.length - 1; i >= 0; i--) {
        const m = messages[i];
        if (m?.role !== "assistant")
            continue;
        const a = m;
        const text = extractAssistantText(a.content);
        const result = {};
        if (a.stopReason !== undefined)
            result.stopReason = a.stopReason;
        if (a.errorMessage !== undefined)
            result.errorMessage = a.errorMessage;
        if (text !== undefined)
            result.text = text;
        if (a.usage !== undefined)
            result.usage = a.usage;
        if (a.provider !== undefined)
            result.provider = a.provider;
        if (a.model !== undefined)
            result.model = a.model;
        return result;
    }
    return undefined;
}
function extractAssistantText(content) {
    if (!Array.isArray(content))
        return undefined;
    const parts = [];
    for (const c of content) {
        const o = c;
        if (o.type === "text" && typeof o.text === "string")
            parts.push(o.text);
    }
    if (parts.length === 0)
        return undefined;
    return parts.join("\n");
}
/**
 * Called from a subscriber on the ask-user-question registry.
 * Fires the `ask_user_question` webhook when a NEW request lands;
 * cancellations aren't a webhook event (no obvious consumer use
 * case yet).
 */
export function bridgeAskUserQuestion(meta, questions, requestId) {
    void dispatch({
        event: "ask_user_question",
        sessionId: meta.sessionId,
        projectId: meta.projectId,
        data: {
            requestId,
            questions: questions.map((q) => ({
                header: q.header,
                question: q.question,
                multiSelect: q.multiSelect,
                options: q.options.map((o) => ({
                    label: o.label,
                    description: o.description,
                })),
            })),
        },
    });
}
// ---- processes ----
/**
 * Called from a subscriber on processManager. Fires the
 * `process_alert` webhook with the same trigger conditions the
 * agent-side alert uses (manager filters alertOn* flags before
 * emitting the manager event).
 */
export function bridgeProcessAlert(meta, info, reason) {
    void dispatch({
        event: "process_alert",
        sessionId: meta.sessionId,
        projectId: meta.projectId,
        data: {
            reason,
            processId: info.id,
            name: info.name,
            pid: info.pid,
            command: info.command,
            cwd: info.cwd,
            startTime: info.startTime,
            endTime: info.endTime,
            exitCode: info.exitCode,
            success: info.success,
        },
    });
}
// ---- session lifecycle ----
/**
 * Called from session-registry on session creation. Fires
 * `session_created` with enough metadata for an audit-log
 * consumer to record "session X was created in project Y at T."
 */
export function bridgeSessionCreated(meta) {
    void dispatch({
        event: "session_created",
        sessionId: meta.sessionId,
        projectId: meta.projectId,
        data: {
            workspacePath: meta.workspacePath,
        },
    });
}
/**
 * Called from session-registry on session deletion (cold delete
 * via the DELETE route). The wasLive flag distinguishes "we
 * disposed an active session" from "we removed a cold JSONL."
 */
export function bridgeSessionDeleted(meta) {
    void dispatch({
        event: "session_deleted",
        sessionId: meta.sessionId,
        ...(meta.projectId !== undefined ? { projectId: meta.projectId } : {}),
        data: {
            wasLive: meta.wasLive,
        },
    });
}
//# sourceMappingURL=event-bridge.js.map