import { createLogger } from "../../utils/logger/index.js";
import { init_logger } from "../../utils/logger.js";
import { createDelegateChildHandle } from "../child-agent-factory.js";
import { DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS } from "../tools/delegate-tool.js";
import { STRUCTURED_OUTPUT_TOOL_NAME, createStructuredOutputTool } from "./structured-output-tool.js";
//#region src/agent/workflow/subagent-runner.ts
init_logger();
const log = createLogger("workflow-subagent-runner");
const DEFAULT_MAX_ITERATIONS = 30;
var DelegateSubagentRunner = class {
	constructor(deps) {
		this.deps = deps;
	}
	async run(prompt, opts) {
		if (opts.signal?.aborted) return null;
		const capture = {
			called: false,
			value: void 0
		};
		const wantStructured = Boolean(opts.schema);
		const allowed = resolveAllowedToolNames(opts.allowedToolNames, wantStructured);
		const model = opts.model ?? safeResolveDefaultModel(this.deps.getDefaultModel);
		if (!model) {
			log.warn({ label: opts.label }, "subagent run skipped: no primary model resolved");
			return null;
		}
		const fullPrompt = buildPrompt(prompt, opts, wantStructured);
		const streamMode = resolveSubagentStreamMode(this.deps.getConfig);
		const handle = createDelegateChildHandle({
			workspace: this.deps.workspace,
			goal: fullPrompt,
			allowedToolNames: allowed,
			maxIterations: opts.maxIterations ?? DEFAULT_MAX_ITERATIONS,
			model,
			bus: this.deps.bus,
			getConfig: this.deps.getConfig,
			toolExecutorConfig: this.deps.toolExecutorConfig,
			buildChildTools: (childOpts) => {
				const base = this.deps.buildChildTools(childOpts);
				if (!wantStructured || !opts.schema) return base;
				return [...base.filter((t) => t.name !== STRUCTURED_OUTPUT_TOOL_NAME), createStructuredOutputTool({
					schema: opts.schema,
					capture
				})];
			},
			progressHooks: opts.onProgress && streamMode !== "off" ? {
				mode: streamMode === "full" ? "full" : "steps",
				onProgress: (event) => {
					opts.onProgress?.(mapChildProgressEvent(event));
				}
			} : void 0
		});
		const onAbort = () => handle.abort();
		opts.signal?.addEventListener("abort", onAbort, { once: true });
		try {
			const { summary } = await handle.run();
			if (opts.signal?.aborted) return null;
			if (wantStructured) {
				if (!capture.called) {
					log.warn({ label: opts.label }, "subagent finished without calling structured_output");
					return null;
				}
				return capture.value;
			}
			return summary;
		} catch (e) {
			if (opts.rethrow) throw e;
			const msg = e instanceof Error ? e.message : String(e);
			log.warn({
				err: e,
				label: opts.label,
				errorMessage: msg
			}, `subagent run failed: ${msg}`);
			return null;
		} finally {
			opts.signal?.removeEventListener("abort", onAbort);
		}
	}
};
function resolveAllowedToolNames(requested, wantStructured) {
	const filtered = (requested && requested.length > 0 ? requested : [...DEFAULT_DELEGATE_TOOLS]).map((s) => String(s).trim()).filter((s) => s.length > 0).filter((s) => !DELEGATE_BLOCKED_TOOLS.has(s));
	if (wantStructured && !filtered.includes("structured_output")) filtered.push(STRUCTURED_OUTPUT_TOOL_NAME);
	return [...new Set(filtered)];
}
function buildPrompt(prompt, opts, structured) {
	const parts = [];
	if (opts.instructions?.trim()) parts.push(opts.instructions.trim());
	if (opts.label) parts.push(`Task label: ${opts.label}`);
	if (opts.phase) parts.push(`Workflow phase: ${opts.phase}`);
	parts.push(prompt);
	if (structured) parts.push([
		"Final output contract:",
		"- Your final action MUST be a structured_output tool call.",
		"- The structured_output arguments are the return value of this subagent.",
		"- Do not emit a prose final answer instead of structured_output.",
		"- If you need to inspect files or run commands first, do so, then call structured_output exactly once."
	].join("\n"));
	return parts.join("\n\n");
}
function safeResolveDefaultModel(get) {
	try {
		return get();
	} catch (e) {
		log.warn({ err: e }, "failed to resolve default subagent model");
		return null;
	}
}
function resolveSubagentStreamMode(getConfig) {
	const mode = getConfig()?.agents?.defaults?.workflow?.subagentStream;
	if (mode === "off" || mode === "steps" || mode === "full") return mode;
	return "steps";
}
function mapChildProgressEvent(event) {
	switch (event.type) {
		case "tool_start": return {
			type: "tool_start",
			toolCallId: event.toolCallId ?? "",
			toolName: event.toolName ?? "tool",
			args: event.args ?? {}
		};
		case "tool_end": return {
			type: "tool_end",
			toolCallId: event.toolCallId ?? "",
			toolName: event.toolName ?? "tool",
			isError: Boolean(event.isError)
		};
		case "iteration": return {
			type: "iteration",
			count: event.count ?? 0,
			max: event.max ?? 0
		};
		case "text_delta": return {
			type: "text_delta",
			delta: event.delta ?? ""
		};
		case "thinking_delta": return {
			type: "thinking_delta",
			delta: event.delta ?? ""
		};
		default: return {
			type: "text_delta",
			delta: ""
		};
	}
}
//#endregion
export { DelegateSubagentRunner };

//# sourceMappingURL=subagent-runner.js.map