import { createLogger } from "../utils/logger/index.js";
import { init_logger } from "../utils/logger.js";
import { init_sync_provider_auth, resolveProviderApiKeySync } from "../auth/sync-provider-auth.js";
import { getApiKeySync, init_providers } from "../providers/index.js";
import { createExtensionAwareStreamFn } from "../providers/extension-stream-bridge.js";
import { extractTextContent } from "./context/workspace.js";
import { resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "./orchestration/run-agent-turn-with-timeout.js";
import { Agent } from "@earendil-works/pi-agent-core";
//#region src/agent/child-agent-factory.ts
init_sync_provider_auth();
init_providers();
init_logger();
const log = createLogger("delegate-child");
function buildChildSystemPrompt(goal, context, workspace) {
	const parts = [
		"You are a focused sub-agent working on a specific delegated task.",
		"",
		`YOUR TASK:\n${goal}`
	];
	if (context?.trim()) parts.push(`\nCONTEXT:\n${context.trim()}`);
	if (workspace?.trim()) parts.push(`\nWORKSPACE: ${workspace.trim()}`);
	parts.push("\nComplete this task using only the tools available to you. When finished, reply with a clear, concise summary covering:\n- What you did\n- What you found or accomplished\n- Files created or modified\n- Issues encountered\n\nYour final reply is returned to the parent agent — be thorough but compact.");
	return parts.join("\n");
}
/**
* Build an isolated tool factory (no extensions, no session memory hooks) and a child {@link Agent}.
*/
function createDelegateChildHandle(options) {
	const allTools = options.buildChildTools({
		workspace: options.workspace,
		bus: options.bus,
		model: options.model,
		getConfig: options.getConfig,
		toolExecutorConfig: options.toolExecutorConfig
	});
	const allow = new Set(options.allowedToolNames);
	const filteredTools = allTools.filter((t) => allow.has(t.name));
	if (filteredTools.length === 0) return {
		async run() {
			return {
				summary: "No tools matched the allowlist after factory registration.",
				toolIterations: 0
			};
		},
		abort() {}
	};
	let toolIterations = 0;
	let aborted = false;
	const progress = options.progressHooks;
	const agent = new Agent({
		initialState: {
			systemPrompt: buildChildSystemPrompt(options.goal, options.context, options.workspace),
			model: options.model,
			thinkingLevel: "low",
			tools: filteredTools,
			messages: []
		},
		streamFn: createExtensionAwareStreamFn(),
		getApiKey: (provider) => resolveProviderApiKeySync(provider) ?? getApiKeySync(provider) ?? "",
		beforeToolCall: async ({ toolCall, args }) => {
			if (aborted) return {
				block: true,
				reason: "Sub-agent aborted."
			};
			if (toolIterations >= options.maxIterations) return {
				block: true,
				reason: `Sub-agent reached max tool iterations (${options.maxIterations}).`
			};
			progress?.onProgress({
				type: "tool_start",
				toolCallId: toolCall.id,
				toolName: toolCall.name,
				args: args ?? {}
			});
		},
		afterToolCall: async ({ toolCall, isError }) => {
			toolIterations += 1;
			progress?.onProgress({
				type: "iteration",
				count: toolIterations,
				max: options.maxIterations
			});
			progress?.onProgress({
				type: "tool_end",
				toolCallId: toolCall.id,
				toolName: toolCall.name,
				isError: Boolean(isError)
			});
		}
	});
	const userText = options.context?.trim() ? `${options.goal}\n\nAdditional context:\n${options.context.trim()}` : options.goal;
	return {
		async run() {
			toolIterations = 0;
			aborted = false;
			const unsub = progress?.mode === "full" ? agent.subscribe((ev) => {
				if (ev.type === "message_update") {
					const delta = ev.assistantMessageEvent;
					if (delta?.type === "text_delta" && typeof delta.delta === "string" && delta.delta) progress.onProgress({
						type: "text_delta",
						delta: delta.delta
					});
					if (delta?.type === "thinking_delta" && typeof delta.delta === "string" && delta.delta) progress.onProgress({
						type: "thinking_delta",
						delta: delta.delta
					});
				}
			}) : void 0;
			try {
				await runAgentTurnWithTimeout(agent, async () => {
					await agent.prompt(userText);
					await agent.waitForIdle();
				}, resolveAgentTurnTimeoutMs(options.getConfig()));
				const messages = agent.state.messages;
				for (let i = messages.length - 1; i >= 0; i--) {
					const msg = messages[i];
					if (msg.role === "assistant") {
						const content = msg.content;
						if (typeof content === "string") return {
							summary: content.trim() || "(empty assistant message)",
							toolIterations
						};
						if (Array.isArray(content)) return {
							summary: extractTextContent(content).trim() || "(empty assistant message)",
							toolIterations
						};
					}
				}
				return {
					summary: aborted ? "Sub-agent was aborted before producing a result." : "Sub-agent completed but produced no assistant text.",
					toolIterations
				};
			} catch (e) {
				const msg = e instanceof Error ? e.message : String(e);
				const m = options.model;
				const modelId = m?.model ?? m?.id;
				log.warn({
					err: e,
					errorMessage: msg,
					goalPreview: options.goal.slice(0, 120),
					maxIterations: options.maxIterations,
					allowedToolCount: options.allowedToolNames.length,
					modelId
				}, `Delegate child run failed: ${msg}`);
				return {
					summary: `Sub-agent error: ${msg}`,
					toolIterations
				};
			} finally {
				unsub?.();
			}
		},
		abort() {
			aborted = true;
			agent.abort();
		}
	};
}
//#endregion
export { buildChildSystemPrompt, createDelegateChildHandle };

//# sourceMappingURL=child-agent-factory.js.map