import { getLogger } from "../../../../util/logger.js";
import { sendUserMessageChannel } from "../../../state-machine/helpers/peer.js";
import { getToolCallArguments, getToolOutput, } from "../../tool-message-utils.js";
import { SubagentType } from "../types.js";
import { buildCodingSubagentSystemPrompt } from "./prompt-builder.js";
/**
 * Run a single coding sub-agent to completion.
 *
 * The sub-agent is given a focused instruction blob from the main agent,
 * runs an isolated Clark `streamText` loop with tools filtered to
 * `SubagentType.CODING`, and exits when it stops producing tool calls or
 * hits `maxSteps`. Tool calls and tool results are forwarded to the UI so
 * the user can see progress; text/reasoning deltas are suppressed (the
 * main agent owns user-visible narration).
 *
 * Runs in parallel with sibling sub-agents — all shared mutable state
 * (e.g. the migration checklist JSON) must be serialized by the callees,
 * not here.
 */
export async function runCodingSubagent(args) {
    const logger = getLogger();
    const { clark, services, workerId, instructions } = args;
    const maxSteps = args.maxSteps ?? 80;
    const systemPrompt = buildCodingSubagentSystemPrompt({
        workerId,
        instructions,
    });
    const accessControl = clark.getAccessControl(services.features);
    const tools = await services.toolRegistry.getToolsRecord({
        ...accessControl,
        subagent: SubagentType.CODING,
    });
    const sendUserMessage = sendUserMessageChannel(clark, services.chatSessionStore);
    logger.info(`[CodingSubagent ${workerId}] Starting with ${Object.keys(tools).length} tools, maxSteps=${maxSteps}`);
    let steps = 0;
    try {
        const result = await clark.streamText(services, {
            system: systemPrompt,
            user: {
                role: "user",
                content: instructions,
            },
            tools,
            // Fresh context — sub-agents don't see the main agent's chat history.
            context: { messages: [] },
            maxSteps,
            // Stop as soon as a step produces no tool calls (the sub-agent has
            // nothing left to do).
            stopWhen: ({ steps }) => {
                const last = steps[steps.length - 1];
                const hasToolCalls = (last?.toolCalls?.length ?? 0) > 0;
                return !hasToolCalls;
            },
            logging: {
                conversationId: `coding-subagent-${workerId}-${Date.now()}`,
                metadata: { subagent: "coding", workerId },
            },
        });
        for await (const chunk of result.fullStream) {
            switch (chunk.type) {
                // Suppress narration — the main agent owns user-visible text.
                case "text-start":
                case "text-delta":
                case "text-end":
                case "reasoning-start":
                case "reasoning-delta":
                case "reasoning-end":
                    break;
                case "tool-call": {
                    const input = await getToolCallArguments(chunk.toolName, chunk.input, clark);
                    void sendUserMessage({
                        type: "tool",
                        tool: chunk.toolName,
                        toolCallId: chunk.toolCallId,
                        args: input,
                    });
                    break;
                }
                case "tool-result": {
                    const output = getToolOutput(chunk.toolName, chunk.output);
                    void sendUserMessage({
                        role: "assistant",
                        content: "",
                        type: "tool-result",
                        toolCallId: chunk.toolCallId,
                        toolName: chunk.toolName,
                        output,
                    });
                    break;
                }
                case "finish-step":
                    steps += 1;
                    break;
                default:
                    break;
            }
        }
        const stopped = steps >= maxSteps ? "max_steps" : "completed";
        logger.info(`[CodingSubagent ${workerId}] Finished (${stopped}, ${steps} steps)`);
        return { workerId, steps, stopped };
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        logger.error(`[CodingSubagent ${workerId}] Failed: ${message}`);
        return { workerId, steps, stopped: "error", error: message };
    }
}
//# sourceMappingURL=run-coding-subagent.js.map