import { createLogger } from "../../utils/logger/index.js";
import { init_logger } from "../../utils/logger.js";
//#region src/agent/lifecycle/progress.ts
init_logger();
const log = createLogger("ProgressFeedback");
const DEFAULT_CONFIG = {
	level: "normal",
	showThinking: true,
	streamToolProgress: true,
	heartbeatEnabled: true,
	heartbeatIntervalMs: 2e4,
	longTaskThresholdMs: 3e4,
	showErrorAccumulation: true,
	showRequestLimitWarning: true
};
const TOOL_STAGE_MAP = {
	"read": "reading",
	"read_file": "reading",
	"read_multiple": "reading",
	"glob": "reading",
	"find": "reading",
	"list_dir": "reading",
	"ls": "reading",
	"memory_get": "reading",
	"curated_memory": "writing",
	"grep": "searching",
	"web_search": "searching",
	"search": "searching",
	"memory_search": "searching",
	"session_search": "searching",
	"find_files": "searching",
	"web_fetch": "reading",
	"fetch": "reading",
	"curl": "reading",
	"wget": "reading",
	"write": "writing",
	"write_file": "writing",
	"write_multiple": "writing",
	"edit": "writing",
	"patch": "writing",
	"create": "writing",
	"mkdir": "writing",
	"delete": "writing",
	"remove": "writing",
	"bash": "executing",
	"shell": "executing",
	"exec": "executing",
	"run": "executing",
	"command": "executing",
	"node": "executing",
	"python": "executing",
	"npm": "executing",
	"pnpm": "executing",
	"git": "executing",
	"docker": "executing",
	"kubectl": "executing",
	"message": "idle",
	"send": "idle",
	"reply": "idle",
	"analyze": "analyzing",
	"compare": "analyzing",
	"diff": "analyzing",
	"summarize": "analyzing"
};
const STAGE_EMOJI = {
	"thinking": "🤔",
	"searching": "🔍",
	"reading": "📖",
	"writing": "✍️",
	"executing": "⚙️",
	"analyzing": "📊",
	"idle": "💬"
};
const STAGE_LABEL = {
	"thinking": "Thinking",
	"searching": "Searching",
	"reading": "Reading",
	"writing": "Writing",
	"executing": "Executing",
	"analyzing": "Analyzing",
	"idle": "Ready"
};
var ProgressFeedbackManager = class {
	config;
	callbacks = {};
	currentStage = "idle";
	currentTool = null;
	taskStartTime = 0;
	lastHeartbeatTime = 0;
	heartbeatTimer;
	streamActive = false;
	constructor(config = {}) {
		this.config = {
			...DEFAULT_CONFIG,
			...config
		};
	}
	setCallbacks(callbacks) {
		this.callbacks = {
			...this.callbacks,
			...callbacks
		};
	}
	startTask() {
		this.taskStartTime = Date.now();
		this.lastHeartbeatTime = Date.now();
		if (this.config.heartbeatEnabled) this.startHeartbeat();
	}
	endTask() {
		this.stopHeartbeat();
		this.currentStage = "idle";
		this.currentTool = null;
		this.taskStartTime = 0;
		this.streamActive = false;
	}
	startHeartbeat() {
		this.stopHeartbeat();
		this.heartbeatTimer = setInterval(() => {
			const elapsed = Date.now() - this.taskStartTime;
			if (elapsed >= this.config.longTaskThresholdMs) {
				this.callbacks.onHeartbeat?.(elapsed, this.currentStage);
				this.lastHeartbeatTime = Date.now();
			}
		}, this.config.heartbeatIntervalMs);
	}
	stopHeartbeat() {
		if (this.heartbeatTimer) {
			clearInterval(this.heartbeatTimer);
			this.heartbeatTimer = void 0;
		}
	}
	mapToolToStage(toolName) {
		const normalizedName = toolName.toLowerCase();
		const toCheck = [normalizedName, normalizedName.replace(/_/g, "")];
		const sortedKeys = Object.keys(TOOL_STAGE_MAP).sort((a, b) => b.length - a.length);
		for (const name of toCheck) for (const key of sortedKeys) if (name.includes(key)) return TOOL_STAGE_MAP[key];
		return "executing";
	}
	formatToolName(toolName) {
		return toolName.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
	}
	onToolStart(toolName, toolArgs = {}) {
		if (this.config.level === "minimal") return;
		this.currentTool = toolName;
		this.currentStage = this.mapToolToStage(toolName);
		this.streamActive = true;
		const formattedName = this.formatToolName(toolName);
		const emoji = STAGE_EMOJI[this.currentStage];
		const label = STAGE_LABEL[this.currentStage];
		let detail = "";
		if (toolArgs.path) detail = `📁 ${toolArgs.path}`;
		else if (toolArgs.query) detail = `🔎 ${toolArgs.query}`;
		else if (toolArgs.command) {
			const cmd = String(toolArgs.command);
			detail = `⚡ ${cmd.length > 50 ? cmd.slice(0, 50) + "..." : cmd}`;
		}
		const message = {
			type: "start",
			stage: this.currentStage,
			message: `${emoji} ${label}: ${formattedName}`,
			detail: detail || void 0,
			toolName,
			toolArgs
		};
		if (this.config.level === "verbose" || this.config.streamToolProgress) this.callbacks.onProgress?.(message);
		this.callbacks.onStreamStart?.(toolName, toolArgs);
		log.debug({
			toolName,
			stage: this.currentStage
		}, "Tool execution started");
	}
	onToolUpdate(toolName, partialResult) {
		if (this.config.level === "minimal") return;
		if (!this.streamActive || !this.config.streamToolProgress) return;
		let displayResult = "";
		if (typeof partialResult === "string") displayResult = partialResult.slice(0, 200);
		else if (partialResult && typeof partialResult === "object") {
			const result = partialResult;
			if (result.output) displayResult = String(result.output).slice(0, 200);
			else if (result.content) displayResult = String(result.content).slice(0, 200);
			else if (result.text) displayResult = String(result.text).slice(0, 200);
		}
		this.callbacks.onStreamUpdate?.(toolName, displayResult);
	}
	onToolEnd(toolName, result, isError = false) {
		if (this.config.level === "minimal" && !isError) return;
		const wasActive = this.streamActive;
		this.streamActive = false;
		let resultSummary = "";
		if (result && typeof result === "object") {
			const res = result;
			if (res.content && Array.isArray(res.content)) {
				const textContent = res.content.find((c) => typeof c === "object" && c !== null && c.type === "text");
				if (textContent) resultSummary = String(textContent.text || "").slice(0, 100);
			}
		}
		const message = {
			type: isError ? "error" : "complete",
			stage: this.currentStage,
			message: isError ? `❌ Tool failed: ${this.formatToolName(toolName)}` : `✅ Done: ${this.formatToolName(toolName)}`,
			toolName
		};
		if (wasActive) this.callbacks.onStreamEnd?.(toolName, resultSummary, isError);
		if (isError || this.config.level !== "minimal") this.callbacks.onProgress?.(message);
		if (this.currentTool === toolName) {
			this.currentTool = null;
			this.currentStage = "idle";
		}
		log.debug({
			toolName,
			isError
		}, "Tool execution ended");
	}
	onThinking(thinking) {
		if (!this.config.showThinking || this.config.level === "minimal") return;
		const displayThinking = thinking.length > 100 ? thinking.slice(0, 100) + "..." : thinking;
		this.callbacks.onThinking?.(displayThinking);
	}
	onTurnStart() {
		if (this.config.level === "minimal") return;
		this.currentStage = "thinking";
		this.taskStartTime = Date.now();
		if (this.config.heartbeatEnabled && !this.heartbeatTimer) this.startHeartbeat();
	}
	onMessageStart() {}
	onMessageUpdate(_content) {}
	onAgentEnd() {
		this.endTask();
	}
	getCurrentState() {
		return {
			stage: this.currentStage,
			tool: this.currentTool,
			elapsedMs: this.taskStartTime ? Date.now() - this.taskStartTime : 0
		};
	}
	setConfig(config) {
		this.config = {
			...this.config,
			...config
		};
	}
	getStageEmoji(stage) {
		return STAGE_EMOJI[stage] || "💬";
	}
	getStageLabel(stage) {
		return STAGE_LABEL[stage] || "Unknown";
	}
	/**
	* Notify about accumulated tool errors
	* Enhanced feedback for tool failures
	*/
	onToolErrorAccumulated(toolName, failureCount, maxFailures, remainingAttempts) {
		if (!this.config.showErrorAccumulation) return;
		if (this.config.level === "minimal") return;
		const remaining = remainingAttempts ?? maxFailures - failureCount;
		const percentage = failureCount / maxFailures * 100;
		let message;
		let type = percentage >= 100 ? "error" : "warning";
		if (percentage >= 100) message = `❌ ${this.formatToolName(toolName)} has reached maximum failures (${maxFailures}/${maxFailures})`;
		else if (percentage >= 50) message = `⚠️ ${this.formatToolName(toolName)} failed ${failureCount}/${maxFailures} times`;
		else message = `⚠️ ${this.formatToolName(toolName)} failed ${failureCount} time${failureCount > 1 ? "s" : ""}`;
		const progressMsg = {
			type,
			stage: "executing",
			message,
			detail: remaining > 0 ? `Remaining attempts: ${remaining}` : "Stopping tool execution",
			toolName
		};
		this.callbacks.onProgress?.(progressMsg);
		const atCap = maxFailures > 0 && failureCount >= maxFailures;
		const summary = atCap ? `Tool "${toolName}" reached max failures (${failureCount}/${maxFailures})` : `Tool "${toolName}" failures ${failureCount}/${maxFailures} (${remaining} attempt(s) left)`;
		if (atCap) log.error({
			toolName,
			failureCount,
			maxFailures,
			remaining
		}, summary);
		else log.warn({
			toolName,
			failureCount,
			maxFailures,
			remaining
		}, summary);
	}
	/**
	* Notify about request limit status
	* Enhanced feedback for approaching/ reaching request limits
	*/
	onRequestLimitStatus(count, limit, remaining, isWarning, shouldStop) {
		if (!this.config.showRequestLimitWarning) return;
		if (this.config.level === "minimal") return;
		if (!isWarning && !shouldStop) return;
		const percentage = count / limit * 100;
		let message;
		let type = shouldStop ? "error" : "warning";
		if (shouldStop) message = `❌ Request limit reached (${count}/${limit})`;
		else if (percentage >= 90) message = `⚠️ Request limit warning (${count}/${limit})`;
		else message = `⚠️ Approaching request limit (${count}/${limit})`;
		const progressMsg = {
			type,
			stage: "thinking",
			message,
			detail: remaining > 0 ? `Remaining requests: ${remaining}` : "Stopping execution"
		};
		this.callbacks.onProgress?.(progressMsg);
		const summary = shouldStop ? `LLM request limit reached (${count}/${limit}); stopping turn` : `LLM request budget ${count}/${limit} (${remaining} left)`;
		if (shouldStop) log.error({
			count,
			limit,
			remaining,
			shouldStop
		}, summary);
		else log.warn({
			count,
			limit,
			remaining,
			shouldStop
		}, summary);
	}
};
const progressFeedbackManager = new ProgressFeedbackManager();
function formatProgressMessage(msg, parseMode = "HTML") {
	const emoji = STAGE_EMOJI[msg.stage];
	if (parseMode === "HTML") {
		let html = `<b>${emoji} ${msg.message}</b>`;
		if (msg.detail) html += `\n${msg.detail}`;
		return html;
	} else {
		let md = `**${emoji} ${msg.message}**`;
		if (msg.detail) md += `\n${msg.detail}`;
		return md;
	}
}
function formatHeartbeatMessage(elapsedMs, stage, detail) {
	const seconds = Math.floor(elapsedMs / 1e3);
	let message = `${STAGE_EMOJI[stage]} Still ${STAGE_LABEL[stage].toLowerCase()}...`;
	if (detail) message += `\n${detail}`;
	message += `\n⏱️ ${seconds}s elapsed`;
	return message;
}
//#endregion
export { ProgressFeedbackManager, formatHeartbeatMessage, formatProgressMessage, progressFeedbackManager };

//# sourceMappingURL=progress.js.map