import { t as textSimilarity } from "./text-similarity-DIRFELa3.js";
//#region src/cognitive/evolution/skill-lifecycle.ts
function levenshtein(a, b) {
	const m = a.length;
	const n = b.length;
	const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
	for (let i = 0; i <= m; i++) dp[i][0] = i;
	for (let j = 0; j <= n; j++) dp[0][j] = j;
	for (let i = 1; i <= m; i++) for (let j = 1; j <= n; j++) dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
	return dp[m][n];
}
var SkillLifecycleManager = class {
	constructor(writer) {
		this.writer = writer;
	}
	async listSkills() {
		const names = await this.writer.listSkillNames();
		const metas = [];
		for (const name of names) {
			const meta = await this.writer.readSkillMeta(name);
			if (meta) metas.push(meta);
		}
		return metas;
	}
	async findSimilar(name, description) {
		const allMeta = await this.listSkills();
		const results = [];
		for (const existing of allMeta) {
			const maxLen = Math.max(name.length, existing.name.length);
			const nameSim = maxLen === 0 ? 1 : 1 - levenshtein(name, existing.name) / maxLen;
			const descSim = textSimilarity(description, existing.description);
			if (.4 * nameSim + .6 * descSim > .5) results.push(existing.name);
		}
		return results;
	}
	async checkDuplicate(name, description) {
		const similar = await this.findSimilar(name, description);
		if (similar.length > 0) {
			const match = (await this.listSkills()).find((m) => m.name === similar[0]);
			const maxLen = Math.max(name.length, similar[0].length);
			const nameSim = maxLen === 0 ? 1 : 1 - levenshtein(name, similar[0]) / maxLen;
			const descSim = match ? textSimilarity(description, match.description) : 0;
			const similarity = .4 * nameSim + .6 * descSim;
			return {
				duplicate: true,
				existingName: similar[0],
				similarity
			};
		}
		return { duplicate: false };
	}
	async checkSemanticDuplicate(taskSummary, candidateDescription, existingSkills, deps) {
		if (!deps?.generateText) return this.checkDuplicate(taskSummary, candidateDescription);
		if (existingSkills.length === 0) return { duplicate: false };
		const prompt = `You are a skill deduplication assistant. Determine if the following task pattern is semantically equivalent to any existing skill.

Task pattern: ${taskSummary}
Candidate skill description: ${candidateDescription}

Existing skills:
${existingSkills.map((s, i) => `${i + 1}. ${s.name}: ${s.description}`).join("\n")}

Respond with ONLY a JSON object (no markdown fences):
- If semantically equivalent to an existing skill: {"duplicate": true, "skillName": "<exact name>", "confidence": 0.0-1.0}
- If not equivalent: {"duplicate": false, "confidence": 0.0-1.0}

Consider two skills duplicates if they solve the same class of problems, even if wording differs. Different tools or different domains = not duplicates.`;
		try {
			const cleaned = (await deps.generateText(prompt)).trim().replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "");
			const parsed = JSON.parse(cleaned);
			if (parsed.duplicate === true && typeof parsed.skillName === "string" && (parsed.confidence ?? 0) > .7) {
				const match = existingSkills.find((s) => s.name === parsed.skillName);
				if (match) {
					const maxLen = Math.max(taskSummary.length, match.name.length);
					const nameSim = maxLen === 0 ? 1 : 1 - levenshtein(taskSummary, match.name) / maxLen;
					const descSim = textSimilarity(candidateDescription, match.description);
					const similarity = .4 * nameSim + .6 * descSim;
					return {
						duplicate: true,
						existingName: match.name,
						similarity
					};
				}
			}
			return { duplicate: false };
		} catch {
			return this.checkDuplicate(taskSummary, candidateDescription);
		}
	}
	async removeStale(olderThanDays) {
		const allMeta = await this.listSkills();
		const threshold = Date.now() - olderThanDays * 864e5;
		let archived = 0;
		for (const meta of allMeta) {
			if (meta.provenance !== "agent") continue;
			if (meta.lastUsedAt < threshold && meta.usageCount === 0) {
				await this.writer.archiveSkill(meta.name);
				archived++;
			}
		}
		return archived;
	}
};
//#endregion
export { SkillLifecycleManager };
