import { createLogger } from "../../utils/logger/index.js";
import { init_logger } from "../../utils/logger.js";
import { isAssistantTurnAborted, isAssistantTurnFailed } from "../orchestration/llm-turn-retry.js";
import { resolveBackgroundReviewSettings } from "./settings.js";
import { runBackgroundReviewTurn } from "./run-background-review.js";
//#region src/agent/background-review/coordinator.ts
init_logger();
const log = createLogger("BackgroundReviewCoordinator");
var BackgroundReviewCoordinator = class {
	opts;
	states = /* @__PURE__ */ new Map();
	constructor(opts) {
		this.opts = opts;
	}
	/**
	* Called before the main `agent.prompt` for a user turn — bumps the memory
	* counter and arms `pendingMemoryReview` when the cadence interval is hit.
	*/
	beginUserTurn(sessionKey, registeredToolNames) {
		const cfg = resolveBackgroundReviewSettings(this.opts.getConfig());
		if (!cfg.enabled || cfg.memoryNudgeInterval <= 0) return;
		if (!registeredToolNames.includes("curated_memory")) return;
		const state = this.ensureState(sessionKey);
		state.turnsSinceMemory += 1;
		if (state.turnsSinceMemory >= cfg.memoryNudgeInterval) {
			state.pendingMemoryReview = true;
			state.turnsSinceMemory = 0;
		}
	}
	/**
	* Subscribe to the agent's events to update the skill counter as the
	* conversation progresses. Idempotent per session — the previous subscription
	* is torn down before installing the new one.
	*/
	attachToAgent(sessionKey, agent, registeredToolNames) {
		const state = this.ensureState(sessionKey);
		state.unsubscribe?.();
		state.unsubscribe = agent.subscribe((ev) => {
			const cfg = resolveBackgroundReviewSettings(this.opts.getConfig());
			if (!cfg.enabled || cfg.skillNudgeInterval <= 0) return;
			if (!registeredToolNames.includes("skill_manage")) return;
			if (ev.type === "turn_start") state.itersSinceSkill += 1;
			if (ev.type === "tool_execution_end") {
				const te = ev;
				if (!te.isError && typeof te.toolName === "string" && te.toolName.trim() === "skill_manage") state.itersSinceSkill = 0;
			}
		});
	}
	/**
	* Fire-and-forget review after the main user turn. Decides whether to run a
	* memory and/or skills sweep based on the counter state + last assistant text,
	* and delegates the actual review to {@link runBackgroundReviewTurn}.
	*/
	scheduleAfterUserTurn(ctx) {
		this.runReviewIfNeeded(ctx).catch((err) => {
			log.warn({
				err,
				sessionKey: ctx.sessionKey
			}, "Background review failed");
		});
	}
	/** Tear down state for a session (called by `AgentManager.removeAgent`). */
	forgetSession(sessionKey) {
		const state = this.states.get(sessionKey);
		if (!state) return;
		state.unsubscribe?.();
		this.states.delete(sessionKey);
	}
	/** Tear down every subscription (`AgentManager.dispose` / hot reload). */
	clear() {
		for (const state of this.states.values()) state.unsubscribe?.();
		this.states.clear();
	}
	ensureState(sessionKey) {
		const existing = this.states.get(sessionKey);
		if (existing) return existing;
		const state = {
			turnsSinceMemory: 0,
			itersSinceSkill: 0,
			pendingMemoryReview: false
		};
		this.states.set(sessionKey, state);
		return state;
	}
	async runReviewIfNeeded(ctx) {
		const state = this.states.get(ctx.sessionKey);
		if (!state) return;
		const settings = resolveBackgroundReviewSettings(this.opts.getConfig());
		if (!settings.enabled) return;
		if (isAssistantTurnAborted(ctx.agent) || isAssistantTurnFailed(ctx.agent)) return;
		if (!ctx.lastAssistantText?.trim()) return;
		const reviewMemory = state.pendingMemoryReview;
		state.pendingMemoryReview = false;
		let reviewSkills = false;
		if (settings.skillNudgeInterval > 0 && ctx.registeredToolNames.includes("skill_manage") && state.itersSinceSkill >= settings.skillNudgeInterval) {
			reviewSkills = true;
			state.itersSinceSkill = 0;
		}
		if (!reviewMemory && !reviewSkills) return;
		await runBackgroundReviewTurn({
			sessionKey: ctx.sessionKey,
			mainAgent: ctx.agent,
			settings,
			reviewMemory,
			reviewSkills,
			registeredToolNames: [...ctx.registeredToolNames],
			skillAllowlist: ctx.skillAllowlist ? [...ctx.skillAllowlist] : void 0,
			workspacePath: ctx.workspacePath,
			skillManager: ctx.workspaceRuntime.skillManager,
			builtinMemoryStore: ctx.workspaceRuntime.builtinMemoryStore,
			memoryManager: ctx.workspaceRuntime.memoryManager,
			getConfig: () => this.opts.getConfig(),
			onSkillsFilesystemMutate: this.opts.onSkillsFilesystemMutate
		});
	}
};
//#endregion
export { BackgroundReviewCoordinator };

//# sourceMappingURL=coordinator.js.map