/**
 * Handler for agent_message messages.
 * Sends a message to an existing OpenCode session.
 * If the session is busy, the message is queued (FIFO, max 50).
 *
 * Uses OpenCode API:
 * - POST /session/:id/prompt_async to send the prompt
 *
 * Events are streamed via SSE subscription (not from this handler).
 */
import { ErrorCode } from "@pocketcoder/shared/constants";
import { getProject } from "../db/repositories/projects.js";
import { proxyToOpenCode } from "../opencode/proxy.js";
import { initQueue, enqueueMessage, startDrain, getQueueSize, } from "../services/message-queue.js";
import { logger } from "../utils/logger.js";
export async function handleAgentMessage(message, send) {
    const msg = message;
    const { requestId, sessionId } = msg;
    const { agentSessionId, content } = msg.payload;
    const project = getProject(sessionId);
    if (!project) {
        send({
            type: "agent_message_response",
            requestId,
            error: {
                code: ErrorCode.INVALID_REQUEST,
                message: `Project not found: ${sessionId}`,
            },
        });
        return;
    }
    if (!content || typeof content !== "string" || content.trim().length === 0) {
        send({
            type: "agent_message_response",
            requestId,
            error: {
                code: ErrorCode.INVALID_REQUEST,
                message: "content is required for agent_message",
            },
        });
        return;
    }
    if (!agentSessionId || typeof agentSessionId !== "string") {
        send({
            type: "agent_message_response",
            requestId,
            error: {
                code: ErrorCode.INVALID_REQUEST,
                message: "agentSessionId is required for agent_message",
            },
        });
        return;
    }
    // Ensure the queue is initialized for this session
    initQueue(agentSessionId, async (queuedMsg) => {
        await processMessage(queuedMsg);
    });
    const queuedMsg = {
        projectPath: project.path,
        content,
        sessionId,
        requestId,
        agentSessionId,
    };
    const result = enqueueMessage(queuedMsg);
    if (result === "full") {
        const queueSize = getQueueSize(agentSessionId);
        send({
            type: "agent_message_response",
            requestId,
            error: {
                code: ErrorCode.DAEMON_BUSY,
                message: "Message queue is full",
                details: {
                    queueSize,
                    retryAfterMs: 5000,
                },
            },
        });
        return;
    }
    // Send response BEFORE starting the drain, so the client receives the
    // response before any streamed agent_event messages.
    send({
        type: "agent_message_response",
        requestId,
        payload: {
            ...(result === "started" ? { started: true } : { queued: true }),
        },
    });
    // If this message will start processing immediately, kick off the drain now
    if (result === "started") {
        startDrain(agentSessionId);
    }
}
/**
 * Process a single queued message by sending it to OpenCode.
 */
async function processMessage(msg) {
    const { agentSessionId, content } = msg;
    try {
        const response = await proxyToOpenCode({
            method: "POST",
            path: `/session/${agentSessionId}/prompt_async`,
            body: JSON.stringify({
                content,
            }),
        });
        if (response.status !== 200 && response.status !== 202) {
            logger.warn(`agent_message prompt failed: ${response.status} - session ${agentSessionId}`);
        }
    }
    catch (err) {
        const errorMessage = err instanceof Error ? err.message : String(err);
        logger.error(`agent_message error: ${errorMessage}`);
        // Events (including errors) come via SSE, so we don't send an error response here
    }
}
//# sourceMappingURL=agent-message.js.map