import { a7 as agentInstances, a8 as agentErrorLog } from './conduit-Ca_OFWR_.js';
import { a as getDb } from './sqlite-Dsbe0wec.js';
import 'node:crypto';
import { e as eq, i as inArray, a as and, j as lt } from './logger-ChCwlV5k.js';

//#region ../core/dist/agents/registry.js
/**
* Update agent status with optional error tracking.
* When status is 'error' or 'crashed', increments the error count
* and logs the error to the agent_error_log table.
*/
async function updateAgentStatus(id, opts, cwd) {
	const db = await getDb(cwd);
	const existing = await db.select().from(agentInstances).where(eq(agentInstances.id, id)).get();
	if (!existing) return null;
	const updates = { status: opts.status };
	if (opts.taskId !== void 0) updates.taskId = opts.taskId;
	if (opts.status === "active") updates.lastHeartbeat = (/* @__PURE__ */ new Date()).toISOString();
	if (opts.status === "error" || opts.status === "crashed") {
		updates.errorCount = existing.errorCount + 1;
		if (opts.error) {
			const errorType = classifyError(new Error(opts.error));
			await db.insert(agentErrorLog).values({
				agentId: id,
				errorType,
				message: opts.error,
				occurredAt: (/* @__PURE__ */ new Date()).toISOString()
			});
		}
	}
	if (opts.status === "stopped") updates.stoppedAt = (/* @__PURE__ */ new Date()).toISOString();
	await db.update(agentInstances).set(updates).where(eq(agentInstances.id, id));
	return {
		...existing,
		...updates
	};
}
/**
* List agent instances with optional filters.
*/
async function listAgentInstances(filters, cwd) {
	const db = await getDb(cwd);
	const conditions = [];
	if (filters?.status) {
		const statuses = Array.isArray(filters.status) ? filters.status : [filters.status];
		conditions.push(inArray(agentInstances.status, statuses));
	}
	if (filters?.agentType) {
		const types = Array.isArray(filters.agentType) ? filters.agentType : [filters.agentType];
		conditions.push(inArray(agentInstances.agentType, types));
	}
	if (filters?.sessionId) conditions.push(eq(agentInstances.sessionId, filters.sessionId));
	if (filters?.parentAgentId) conditions.push(eq(agentInstances.parentAgentId, filters.parentAgentId));
	if (conditions.length === 0) return db.select().from(agentInstances).all();
	return db.select().from(agentInstances).where(and(...conditions)).all();
}
/**
* Get a single agent instance by ID.
*/
async function getAgentInstance(id, cwd) {
	return await (await getDb(cwd)).select().from(agentInstances).where(eq(agentInstances.id, id)).get() ?? null;
}
/** Patterns indicating retriable errors. */
var RETRIABLE_PATTERNS = [
	/timeout/i,
	/ECONNREFUSED/,
	/ECONNRESET/,
	/EPIPE/,
	/ETIMEDOUT/,
	/rate.?limit/i,
	/429/,
	/503/,
	/502/,
	/SQLITE_BUSY/i,
	/database is locked/i,
	/temporarily unavailable/i,
	/too many requests/i,
	/network/i,
	/socket hang up/i
];
/** Patterns indicating permanent (non-retriable) errors. */
var PERMANENT_PATTERNS = [
	/permission denied/i,
	/EACCES/,
	/authentication/i,
	/unauthorized/i,
	/401/,
	/403/,
	/404/,
	/not found/i,
	/invalid.*token/i,
	/SQLITE_CONSTRAINT/i,
	/syntax error/i,
	/type error/i,
	/reference error/i
];
/**
* Classify an error as retriable, permanent, or unknown.
*
* Retriable errors are transient conditions (network, rate limits, locks)
* where a retry may succeed. Permanent errors are structural (auth,
* not found, constraint violations) where retrying is pointless.
*/
function classifyError(error) {
	const message = error instanceof Error ? error.message : String(error);
	for (const pattern of RETRIABLE_PATTERNS) if (pattern.test(message)) return "retriable";
	for (const pattern of PERMANENT_PATTERNS) if (pattern.test(message)) return "permanent";
	return "unknown";
}
/**
* Get the error history for a specific agent.
*/
async function getAgentErrorHistory(agentId, cwd) {
	return (await getDb(cwd)).select().from(agentErrorLog).where(eq(agentErrorLog.agentId, agentId)).all();
}
/**
* Check agent health by finding instances whose last heartbeat exceeds the threshold.
* Default threshold: 30000ms (30 seconds) as specified by the BRAIN spec.
*
* Returns agents that appear to have crashed (stale heartbeat).
*/
async function checkAgentHealth(thresholdMs = 3e4, cwd) {
	const db = await getDb(cwd);
	const cutoff = new Date(Date.now() - thresholdMs).toISOString();
	return db.select().from(agentInstances).where(and(inArray(agentInstances.status, [
		"active",
		"idle",
		"starting"
	]), lt(agentInstances.lastHeartbeat, cutoff))).all();
}
/**
* Mark an agent instance as crashed.
* Increments error count and sets status to 'crashed'.
*/
async function markCrashed(id, reason, cwd) {
	return updateAgentStatus(id, {
		status: "crashed",
		error: reason ?? "Heartbeat timeout — agent presumed crashed"
	}, cwd);
}

export { getAgentErrorHistory as a, checkAgentHealth as c, getAgentInstance as g, listAgentInstances as l, markCrashed as m, updateAgentStatus as u };
//# sourceMappingURL=registry4-DHPSIQiW.js.map
