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 { createCuratedMemoryTool } from "../tools/curated-memory-tool.js";
import { resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "../orchestration/run-agent-turn-with-timeout.js";
import { createSkillViewTool, createSkillsListTool } from "../tools/skills-tools.js";
import { createSkillManageTool } from "../tools/skill-manage-tool.js";
import { shouldRegisterCuratedMemoryTool } from "../memory/memory-config.js";
import { wrapToolsWithProtection } from "../tools/executor.js";
import { isAssistantTurnAborted, isAssistantTurnFailed } from "../orchestration/llm-turn-retry.js";
import { COMBINED_REVIEW_USER_PROMPT, MEMORY_REVIEW_USER_PROMPT, REVIEW_SYSTEM_PROMPT, SKILL_REVIEW_USER_PROMPT } from "./prompts.js";
import { Agent } from "@earendil-works/pi-agent-core";
//#region src/agent/background-review/run-background-review.ts
init_sync_provider_auth();
init_providers();
init_logger();
const log = createLogger("BackgroundReview");
function cloneMessageTail(messages, max) {
	const tail = messages.length <= max ? messages : messages.slice(-max);
	return JSON.parse(JSON.stringify(tail));
}
async function runBackgroundReviewTurn(params) {
	const { sessionKey, mainAgent, settings, reviewMemory, reviewSkills, registeredToolNames, skillAllowlist, workspacePath, skillManager, builtinMemoryStore, memoryManager, getConfig, onSkillsFilesystemMutate } = params;
	const userPrompt = reviewMemory && reviewSkills ? COMBINED_REVIEW_USER_PROMPT : reviewMemory ? MEMORY_REVIEW_USER_PROMPT : SKILL_REVIEW_USER_PROMPT;
	const rawTools = [];
	if (reviewMemory && shouldRegisterCuratedMemoryTool(getConfig())) rawTools.push(createCuratedMemoryTool(() => builtinMemoryStore, { onMemoryWrite: (action, target, content) => {
		memoryManager.onMemoryWrite(action, target, content);
	} }));
	if (reviewSkills) {
		const ctx = () => ({
			registeredToolNames,
			skillAllowlist
		});
		rawTools.push(createSkillsListTool({
			getSkillManager: () => skillManager,
			getSkillIndexingContext: ctx
		}), createSkillViewTool({
			getSkillManager: () => skillManager,
			getSkillIndexingContext: ctx
		}), createSkillManageTool({
			getSkillManager: () => skillManager,
			getWorkspace: () => workspacePath,
			onSkillsFilesystemMutate
		}));
	}
	if (rawTools.length === 0) {
		log.debug({ sessionKey }, "Background review skipped: no tools registered for selected channels");
		return;
	}
	const tools = wrapToolsWithProtection(rawTools, {});
	const model = mainAgent.state.model;
	let toolRounds = 0;
	let aborted = false;
	const reviewAgent = new Agent({
		initialState: {
			systemPrompt: REVIEW_SYSTEM_PROMPT,
			model,
			thinkingLevel: "off",
			tools,
			messages: []
		},
		streamFn: createExtensionAwareStreamFn(),
		getApiKey: (provider) => resolveProviderApiKeySync(provider) ?? getApiKeySync(provider) ?? "",
		beforeToolCall: async () => {
			if (aborted) return {
				block: true,
				reason: "Background review aborted."
			};
			if (toolRounds >= settings.maxToolRounds) return {
				block: true,
				reason: `Background review reached max tool rounds (${settings.maxToolRounds}).`
			};
		},
		afterToolCall: async () => {
			toolRounds += 1;
		}
	});
	reviewAgent.state.messages = cloneMessageTail(mainAgent.state.messages, settings.maxHistoryMessages);
	const timeoutMs = Math.min(settings.maxDurationMs, resolveAgentTurnTimeoutMs(getConfig()));
	try {
		await runAgentTurnWithTimeout(reviewAgent, async () => {
			await reviewAgent.prompt({
				role: "user",
				content: userPrompt,
				timestamp: Date.now()
			});
			await reviewAgent.waitForIdle();
		}, timeoutMs);
	} catch (err) {
		log.warn({
			err,
			sessionKey
		}, "Background review turn failed or timed out");
		aborted = true;
		reviewAgent.abort();
		await reviewAgent.waitForIdle().catch(() => {});
		return;
	}
	if (isAssistantTurnAborted(reviewAgent) || isAssistantTurnFailed(reviewAgent)) {
		log.debug({ sessionKey }, "Background review produced aborted/failed assistant turn");
		return;
	}
	const last = reviewAgent.state.messages;
	for (let i = last.length - 1; i >= 0; i--) {
		const msg = last[i];
		if (msg.role === "assistant") {
			const content = msg.content;
			const trimmed = (Array.isArray(content) ? extractTextContent(content) : String(content)).trim();
			if (trimmed && !/^nothing to save\.?$/i.test(trimmed)) log.info({
				sessionKey,
				preview: trimmed.slice(0, 120)
			}, "Background review completed");
			else log.debug({ sessionKey }, "Background review: nothing to save");
			return;
		}
	}
}
//#endregion
export { runBackgroundReviewTurn };

//# sourceMappingURL=run-background-review.js.map