import { allChecklistTerminal, checklistCounts } from "./checklist-types.js";
import { applyJudgeChecklistUpdates, mergeDecomposedChecklistItems, renderChecklistNumbered } from "./state.js";
import { CONTINUATION_PROMPT_TEMPLATE_EN, CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE_EN, buildContinuationPromptFromState, checklistProgressSuffix, goalEvaluateUserCopy, resolveGoalUiLocale } from "./goal-locale.js";
import { judgeGoalHermesStyle } from "./judge.js";
import { decomposeGoalChecklist, evaluateGoalChecklistJudge } from "./checklist-judge.js";
//#region src/agent/goals/evaluate-turn.ts
/** Hermes `CONTINUATION_PROMPT_TEMPLATE` (English; parity / tests). */
const CONTINUATION_PROMPT_TEMPLATE = CONTINUATION_PROMPT_TEMPLATE_EN;
/** Hermes `CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE` (English; parity / tests). */
const CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE = CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE_EN;
function cloneState(s) {
	return {
		...s,
		checklist: s.checklist?.map((it) => ({ ...it }))
	};
}
/**
* Hermes `GoalManager.evaluate_after_turn` equivalent (minus SessionDB I/O).
*/
async function evaluateAfterTurnHermesLike(state, lastResponse, judgeModelRef, signal, opts) {
	const locale = opts?.uiLocale ?? resolveGoalUiLocale(state);
	const copy = goalEvaluateUserCopy(locale);
	if (state.status !== "active") return {
		newState: state,
		shouldContinue: false,
		continuationPrompt: null,
		verdict: "inactive",
		reason: "no active goal",
		message: ""
	};
	const slice = opts?.goalsSlice;
	const checklistMode = slice?.checklistMode !== false;
	const maxParseFailures = slice?.maxConsecutiveParseFailures ?? 3;
	const judgeTimeoutMs = slice?.judgeTimeoutMs;
	const next = cloneState(state);
	next.turnsUsed += 1;
	next.lastTurnAt = Date.now();
	const bumpParse = () => {
		next.consecutiveParseFailures = (next.consecutiveParseFailures ?? 0) + 1;
	};
	const resetParse = () => {
		next.consecutiveParseFailures = 0;
	};
	const pauseIfParseStorm = (reason) => {
		const n = next.consecutiveParseFailures ?? 0;
		if (n < maxParseFailures) return null;
		next.status = "paused";
		next.pausedReason = `judge parse failures (${n} consecutive)`;
		return {
			newState: next,
			shouldContinue: false,
			continuationPrompt: null,
			verdict: "continue",
			reason,
			message: copy.pauseParse(n)
		};
	};
	const pauseIfBudget = (reason) => {
		if (next.turnsUsed < next.maxTurns) return null;
		next.status = "paused";
		next.pausedReason = `turn budget exhausted (${next.turnsUsed}/${next.maxTurns})`;
		return {
			newState: next,
			shouldContinue: false,
			continuationPrompt: null,
			verdict: "continue",
			reason,
			message: copy.pauseBudget(next.turnsUsed, next.maxTurns)
		};
	};
	if (checklistMode && !next.decomposed) {
		const dec = await decomposeGoalChecklist({
			goal: next.goal,
			judgeModelRef,
			signal,
			judgeTimeoutMs,
			uiLocale: locale
		});
		next.decomposed = true;
		if (!dec.parseFailed && dec.items.length > 0) {
			next.checklist = mergeDecomposedChecklistItems(next.checklist ?? [], dec.items);
			const mergedCount = next.checklist.length;
			next.lastVerdict = "decompose";
			next.lastReason = copy.decomposedReason(mergedCount);
			resetParse();
			const budgetEarly = pauseIfBudget(next.lastReason);
			if (budgetEarly) return budgetEarly;
			return {
				newState: next,
				shouldContinue: true,
				continuationPrompt: buildContinuationPromptFromState(next, locale),
				verdict: "decompose",
				reason: next.lastReason ?? "",
				message: copy.checklistReady(mergedCount)
			};
		}
		next.lastReason = dec.errorReason ? copy.decomposeFallbackReason(dec.errorReason) : copy.noChecklistFallback();
	}
	const checklist = next.checklist ?? [];
	if (checklist.length > 0) {
		const evalResult = await evaluateGoalChecklistJudge({
			goal: next.goal,
			numberedChecklist: renderChecklistNumbered(checklist),
			lastResponse,
			historyExcerpt: opts?.historyExcerpt ?? "",
			judgeModelRef,
			signal,
			judgeTimeoutMs,
			uiLocale: locale
		});
		if (evalResult.parseFailed) bumpParse();
		else {
			resetParse();
			next.checklist = applyJudgeChecklistUpdates(checklist, {
				updates: evalResult.parsed.updates,
				newItems: evalResult.parsed.newItems
			});
		}
		next.lastVerdict = "continue";
		next.lastReason = evalResult.parsed.reason;
		if (!evalResult.parseFailed && allChecklistTerminal(next.checklist ?? [])) {
			next.status = "done";
			next.lastVerdict = "done";
			return {
				newState: next,
				shouldContinue: false,
				continuationPrompt: null,
				verdict: "done",
				reason: evalResult.parsed.reason,
				message: copy.goalAchieved(evalResult.parsed.reason)
			};
		}
		const parseStorm = pauseIfParseStorm(evalResult.parsed.reason);
		if (parseStorm) return parseStorm;
		const budget = pauseIfBudget(evalResult.parsed.reason);
		if (budget) return budget;
		const { total, completed, impossible } = checklistCounts(next.checklist ?? []);
		const progressSuffix = checklistProgressSuffix(completed + impossible, total, locale);
		return {
			newState: next,
			shouldContinue: true,
			continuationPrompt: buildContinuationPromptFromState(next, locale),
			verdict: "continue",
			reason: evalResult.parsed.reason,
			message: copy.continuingWithProgress(next.turnsUsed, next.maxTurns, progressSuffix, evalResult.parsed.reason)
		};
	}
	const j = await judgeGoalHermesStyle(state.goal, lastResponse, judgeModelRef, signal, {
		judgeTimeoutMs,
		uiLocale: locale
	});
	next.lastVerdict = j.verdict === "skipped" ? "skipped" : j.verdict;
	next.lastReason = j.reason;
	if (j.parseFailed) bumpParse();
	else resetParse();
	if (j.verdict === "done") {
		next.status = "done";
		return {
			newState: next,
			shouldContinue: false,
			continuationPrompt: null,
			verdict: "done",
			reason: j.reason,
			message: copy.goalAchieved(j.reason)
		};
	}
	const parseStorm = pauseIfParseStorm(j.reason);
	if (parseStorm) return parseStorm;
	const budget = pauseIfBudget(j.reason);
	if (budget) return budget;
	return {
		newState: next,
		shouldContinue: true,
		continuationPrompt: buildContinuationPromptFromState(next, locale),
		verdict: "continue",
		reason: j.reason,
		message: copy.continuing(next.turnsUsed, next.maxTurns, j.reason)
	};
}
//#endregion
export { CONTINUATION_PROMPT_TEMPLATE, CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE, evaluateAfterTurnHermesLike };

//# sourceMappingURL=evaluate-turn.js.map