import { c as defaultRuntime, h as DEFAULT_CHAT_CHANNEL } from "./subsystem-D4e4nOE7.js";
import { $t as hasNonzeroUsage, B as applyVerboseOverride, C as resolveSendPolicy, Gt as shouldContinueTask, L as getSkillsSnapshotVersion, Lt as getActiveTask, Mt as advanceToNextRunnableTask, Wt as setActiveTask, Zn as logSessionStateChange, b as setCliSessionId, bt as loadModelCatalog, cn as resolveOutboundTarget, en as lookupContextTokens, ln as resolveSessionDeliveryTarget, lt as runEmbeddedPiAgent, mn as runWithModelFallback, or as clearAgentRunContext, ot as resolveAgentTimeoutMs, sr as emitAgentEvent, ur as registerAgentRunContext, v as runCliAgent, w as getRemoteSkillEligibility, xt as applyModelOverrideToSessionEntry, y as getCliSessionId, yt as AGENT_LANE_NESTED, z as clearSessionAuthProfileOverride } from "./loader-nlcizznp.js";
import { r as loadConfig } from "./config-C9wUwpYY.js";
import { F as resolveAgentIdFromSessionKey, N as normalizeAgentId, P as normalizeMainKey, a as resolveAgentModelPrimary, i as resolveAgentModelFallbacksOverride, o as resolveAgentSkillsFilter, r as resolveAgentDir, s as resolveAgentWorkspaceDir, t as listAgentIds, x as ensureAgentWorkspace } from "./agent-scope-BcV171ci.js";
import { a as modelKey, dt as DEFAULT_CONTEXT_TOKENS, ft as DEFAULT_MODEL, i as isCliProvider, l as resolveConfiguredModelRef, p as resolveThinkingDefault, pt as DEFAULT_PROVIDER, t as buildAllowedModelSet, tt as ensureAuthProfileStore } from "./model-selection-ChysOie6.js";
import { t as formatCliCommand } from "./command-format-XQlUKdf6.js";
import { a as isInternalMessageChannel, d as resolveMessageChannel, i as isGatewayMessageChannel, l as normalizeMessageChannel, n as isDeliverableMessageChannel, t as INTERNAL_MESSAGE_CHANNEL } from "./message-channel-eeeqF-J8.js";
import { C as resolveSessionResetPolicy, S as resolveChannelResetConfig, b as resolveSessionKey, d as loadSessionStore, g as updateSessionStore, k as resolveExplicitAgentSessionKey, lt as normalizeAccountId, w as resolveSessionResetType, x as evaluateSessionFreshness } from "./sandbox-B_7wnPz0.js";
import { i as normalizeOutboundPayloadsForJson, n as formatOutboundPayloadLog, r as normalizeOutboundPayloads, t as deliverOutboundPayloads } from "./deliver-Ce4muAXi.js";
import { r as normalizeChannelId, t as getChannelPlugin } from "./plugins-D_f06tiR.js";
import { a as formatXHighModelHint, f as normalizeVerboseLevel, i as formatThinkingLevels, m as supportsXHighThinking, u as normalizeThinkLevel } from "./pi-embedded-helpers-Hus0BP0L.js";
import { r as buildWorkspaceSkillSnapshot } from "./skills-B9WXNmn5.js";
import { n as resolveSessionFilePath, o as resolveStorePath } from "./paths-1OcM9YBo.js";
import { t as createDefaultDeps } from "./deps-BygaPoRm.js";
import crypto, { randomUUID } from "node:crypto";

//#region ../../src/commands/agent/auto-continue.ts
const DONE_RE = /\b(done|completed|complete|finished|all set|resolved)\b/i;
const BLOCKED_RE = /\b(blocked|can't continue|cannot continue|stuck|hard blocker)\b/i;
const NEEDS_USER_RE = /\b(need your input|need you to|waiting on you|please (confirm|approve|provide)|can you|could you)\b/i;
const AUTO_CONTINUE_PROMPT = "Continue the active task. If done, summarize completion. If blocked or you need user input, report that instead of continuing.";
function resolveAutoContinueState(state) {
	return {
		enabled: state?.enabled === true,
		maxIterations: Math.max(1, Math.min(100, state?.maxIterations ?? 8)),
		delayMs: Math.max(0, Math.min(36e5, state?.delayMs ?? 1e3)),
		iterationCount: Math.max(0, state?.iterationCount ?? 0),
		active: state?.active === true,
		lastStopReason: state?.lastStopReason,
		lastRunAt: state?.lastRunAt
	};
}
function classifyAutoContinueStopReason(text) {
	const cleaned = text.trim();
	if (!cleaned) return "continue";
	if (BLOCKED_RE.test(cleaned)) return "blocked";
	if (NEEDS_USER_RE.test(cleaned)) return "needs_user";
	if (DONE_RE.test(cleaned)) return "done";
	return "continue";
}
function getAutoContinueText(payloads) {
	return (payloads ?? []).map((payload) => typeof payload?.text === "string" ? payload.text : "").filter(Boolean).join("\n").trim();
}
function nextAutoContinueState(params) {
	const current = resolveAutoContinueState(params.state);
	const nextCount = current.iterationCount + 1;
	return {
		enabled: current.enabled,
		maxIterations: current.maxIterations,
		delayMs: current.delayMs,
		iterationCount: nextCount,
		active: params.stopReason === "continue" && nextCount < current.maxIterations,
		lastStopReason: params.stopReason === "continue" && nextCount >= current.maxIterations ? "max_iterations" : params.stopReason,
		lastRunAt: params.ranAt ?? Date.now()
	};
}
function resolveTaskState(state) {
	return {
		id: state?.id,
		goal: state?.goal,
		definitionOfDone: state?.definitionOfDone,
		status: state?.status,
		autoContinueEnabled: state?.autoContinueEnabled === true,
		maxIterations: Math.max(1, Math.min(100, state?.maxIterations ?? 8)),
		delayMs: Math.max(0, Math.min(36e5, state?.delayMs ?? 1e3)),
		iterationCount: Math.max(0, state?.iterationCount ?? 0),
		active: state?.active === true,
		lastStopReason: state?.lastStopReason,
		lastRunAt: state?.lastRunAt,
		criteria: Array.isArray(state?.criteria) ? state.criteria.filter((item) => typeof item === "string" && item.trim().length > 0) : [],
		completedCriteria: Array.isArray(state?.completedCriteria) ? state.completedCriteria.filter((item) => typeof item === "string" && item.trim().length > 0) : [],
		blockedReason: state?.blockedReason,
		needsUserReason: state?.needsUserReason,
		lastEvaluationReason: state?.lastEvaluationReason
	};
}
function mapStopReasonToTaskStatus(reason) {
	if (reason === "done") return "done";
	if (reason === "blocked") return "blocked";
	if (reason === "needs_user") return "needs_user";
	return "active";
}
function buildTaskContinuationPrompt(task) {
	const resolved = resolveTaskState(task);
	const remaining = getRemainingTaskCriteria(resolved);
	return [
		"Continue the active task.",
		resolved.goal ? `TASK_GOAL: ${resolved.goal}` : void 0,
		resolved.definitionOfDone ? `TASK_DEFINITION_OF_DONE: ${resolved.definitionOfDone}` : void 0,
		resolved.criteria.length > 0 ? `TASK_CRITERIA_TOTAL: ${resolved.criteria.length}` : void 0,
		remaining.length > 0 ? `TASK_CRITERIA_REMAINING: ${remaining.join(" | ")}` : void 0,
		"Update the task state deterministically via session metadata as criteria are completed or blocked."
	].filter(Boolean).join("\n");
}
function getRemainingTaskCriteria(task) {
	const resolved = resolveTaskState(task);
	const completed = new Set(resolved.completedCriteria.map((item) => item.trim()));
	return resolved.criteria.filter((item) => !completed.has(item.trim()));
}
function evaluateTaskState(task) {
	const resolved = resolveTaskState(task);
	if (resolved.blockedReason?.trim()) return {
		stopReason: "blocked",
		reason: resolved.blockedReason.trim(),
		status: "blocked"
	};
	if (resolved.needsUserReason?.trim()) return {
		stopReason: "needs_user",
		reason: resolved.needsUserReason.trim(),
		status: "needs_user"
	};
	const remaining = getRemainingTaskCriteria(resolved);
	if (remaining.length === 0) return {
		stopReason: "done",
		reason: resolved.definitionOfDone?.trim() || resolved.goal?.trim() || "All task criteria have been completed.",
		status: "done"
	};
	return {
		stopReason: "continue",
		reason: `Remaining criteria: ${remaining.join("; ")}`,
		status: "active"
	};
}
function nextTaskState(params) {
	const current = resolveTaskState(params.state);
	const nextCount = current.iterationCount + 1;
	const hitMax = params.stopReason === "continue" && nextCount >= current.maxIterations;
	return {
		id: current.id,
		goal: current.goal,
		definitionOfDone: current.definitionOfDone,
		criteria: current.criteria,
		completedCriteria: current.completedCriteria,
		blockedReason: current.blockedReason,
		needsUserReason: current.needsUserReason,
		lastEvaluationReason: params.evaluationReason,
		status: hitMax ? "blocked" : mapStopReasonToTaskStatus(params.stopReason),
		autoContinueEnabled: current.autoContinueEnabled,
		maxIterations: current.maxIterations,
		delayMs: current.delayMs,
		iterationCount: nextCount,
		active: params.stopReason === "continue" && !hitMax,
		lastStopReason: hitMax ? "max_iterations" : params.stopReason,
		lastRunAt: params.ranAt ?? Date.now()
	};
}

//#endregion
//#region ../../src/cli/outbound-send-deps.ts
function createOutboundSendDeps(deps) {
	return {
		sendWhatsApp: deps.sendMessageWhatsApp,
		sendTelegram: deps.sendMessageTelegram,
		sendDiscord: deps.sendMessageDiscord,
		sendSlack: deps.sendMessageSlack,
		sendSignal: deps.sendMessageSignal,
		sendIMessage: deps.sendMessageIMessage
	};
}

//#endregion
//#region ../../src/infra/outbound/agent-delivery.ts
function resolveAgentDeliveryPlan(params) {
	const requestedRaw = typeof params.requestedChannel === "string" ? params.requestedChannel.trim() : "";
	const requestedChannel = (requestedRaw ? normalizeMessageChannel(requestedRaw) : void 0) || "last";
	const explicitTo = typeof params.explicitTo === "string" && params.explicitTo.trim() ? params.explicitTo.trim() : void 0;
	const baseDelivery = resolveSessionDeliveryTarget({
		entry: params.sessionEntry,
		requestedChannel: requestedChannel === INTERNAL_MESSAGE_CHANNEL ? "last" : requestedChannel,
		explicitTo,
		explicitThreadId: params.explicitThreadId
	});
	const resolvedChannel = (() => {
		if (requestedChannel === INTERNAL_MESSAGE_CHANNEL) return INTERNAL_MESSAGE_CHANNEL;
		if (requestedChannel === "last") {
			if (baseDelivery.channel && baseDelivery.channel !== INTERNAL_MESSAGE_CHANNEL) return baseDelivery.channel;
			return params.wantsDelivery ? DEFAULT_CHAT_CHANNEL : INTERNAL_MESSAGE_CHANNEL;
		}
		if (isGatewayMessageChannel(requestedChannel)) return requestedChannel;
		if (baseDelivery.channel && baseDelivery.channel !== INTERNAL_MESSAGE_CHANNEL) return baseDelivery.channel;
		return params.wantsDelivery ? DEFAULT_CHAT_CHANNEL : INTERNAL_MESSAGE_CHANNEL;
	})();
	const deliveryTargetMode = explicitTo ? "explicit" : isDeliverableMessageChannel(resolvedChannel) ? "implicit" : void 0;
	const resolvedAccountId = normalizeAccountId(params.accountId) ?? (deliveryTargetMode === "implicit" ? baseDelivery.accountId : void 0);
	let resolvedTo = explicitTo;
	if (!resolvedTo && isDeliverableMessageChannel(resolvedChannel) && resolvedChannel === baseDelivery.lastChannel) resolvedTo = baseDelivery.lastTo;
	return {
		baseDelivery,
		resolvedChannel,
		resolvedTo,
		resolvedAccountId,
		resolvedThreadId: baseDelivery.threadId,
		deliveryTargetMode
	};
}
function resolveAgentOutboundTarget(params) {
	const targetMode = params.targetMode ?? params.plan.deliveryTargetMode ?? (params.plan.resolvedTo ? "explicit" : "implicit");
	if (!isDeliverableMessageChannel(params.plan.resolvedChannel)) return {
		resolvedTarget: null,
		resolvedTo: params.plan.resolvedTo,
		targetMode
	};
	if (params.validateExplicitTarget !== true && params.plan.resolvedTo) return {
		resolvedTarget: null,
		resolvedTo: params.plan.resolvedTo,
		targetMode
	};
	const resolvedTarget = resolveOutboundTarget({
		channel: params.plan.resolvedChannel,
		to: params.plan.resolvedTo,
		cfg: params.cfg,
		accountId: params.plan.resolvedAccountId,
		mode: targetMode
	});
	return {
		resolvedTarget,
		resolvedTo: resolvedTarget.ok ? resolvedTarget.to : params.plan.resolvedTo,
		targetMode
	};
}

//#endregion
//#region ../../src/infra/outbound/envelope.ts
const isOutboundPayloadJson = (payload) => "mediaUrl" in payload;
function buildOutboundResultEnvelope(params) {
	const hasPayloads = params.payloads !== void 0;
	const payloads = params.payloads === void 0 ? void 0 : params.payloads.length === 0 ? [] : isOutboundPayloadJson(params.payloads[0]) ? params.payloads : normalizeOutboundPayloadsForJson(params.payloads);
	if (params.flattenDelivery !== false && params.delivery && !params.meta && !hasPayloads) return params.delivery;
	return {
		...hasPayloads ? { payloads } : {},
		...params.meta ? { meta: params.meta } : {},
		...params.delivery ? { delivery: params.delivery } : {}
	};
}

//#endregion
//#region ../../src/commands/agent/delivery.ts
const NESTED_LOG_PREFIX = "[agent:nested]";
function formatNestedLogPrefix(opts) {
	const parts = [NESTED_LOG_PREFIX];
	const session = opts.sessionKey ?? opts.sessionId;
	if (session) parts.push(`session=${session}`);
	if (opts.runId) parts.push(`run=${opts.runId}`);
	const channel = opts.messageChannel ?? opts.channel;
	if (channel) parts.push(`channel=${channel}`);
	if (opts.to) parts.push(`to=${opts.to}`);
	if (opts.accountId) parts.push(`account=${opts.accountId}`);
	return parts.join(" ");
}
function logNestedOutput(runtime, opts, output) {
	const prefix = formatNestedLogPrefix(opts);
	for (const line of output.split(/\r?\n/)) {
		if (!line) continue;
		runtime.log(`${prefix} ${line}`);
	}
}
async function deliverAgentCommandResult(params) {
	const { cfg, deps, runtime, opts, sessionEntry, payloads, result } = params;
	const deliver = opts.deliver === true;
	const bestEffortDeliver = opts.bestEffortDeliver === true;
	const deliveryPlan = resolveAgentDeliveryPlan({
		sessionEntry,
		requestedChannel: opts.replyChannel ?? opts.channel,
		explicitTo: opts.replyTo ?? opts.to,
		explicitThreadId: opts.threadId,
		accountId: opts.replyAccountId ?? opts.accountId,
		wantsDelivery: deliver
	});
	const deliveryChannel = deliveryPlan.resolvedChannel;
	const deliveryPlugin = !isInternalMessageChannel(deliveryChannel) ? getChannelPlugin(normalizeChannelId(deliveryChannel) ?? deliveryChannel) : void 0;
	const isDeliveryChannelKnown = isInternalMessageChannel(deliveryChannel) || Boolean(deliveryPlugin);
	const targetMode = opts.deliveryTargetMode ?? deliveryPlan.deliveryTargetMode ?? (opts.to ? "explicit" : "implicit");
	const resolvedAccountId = deliveryPlan.resolvedAccountId;
	const resolved = deliver && isDeliveryChannelKnown && deliveryChannel ? resolveAgentOutboundTarget({
		cfg,
		plan: deliveryPlan,
		targetMode,
		validateExplicitTarget: true
	}) : {
		resolvedTarget: null,
		resolvedTo: deliveryPlan.resolvedTo,
		targetMode
	};
	const resolvedTarget = resolved.resolvedTarget;
	const deliveryTarget = resolved.resolvedTo;
	const resolvedThreadId = deliveryPlan.resolvedThreadId ?? opts.threadId;
	const resolvedReplyToId = deliveryChannel === "slack" && resolvedThreadId != null ? String(resolvedThreadId) : void 0;
	const resolvedThreadTarget = deliveryChannel === "slack" ? void 0 : resolvedThreadId;
	const logDeliveryError = (err) => {
		const message = `Delivery failed (${deliveryChannel}${deliveryTarget ? ` to ${deliveryTarget}` : ""}): ${String(err)}`;
		runtime.error?.(message);
		if (!runtime.error) runtime.log(message);
	};
	if (deliver) {
		if (!isDeliveryChannelKnown) {
			const err = /* @__PURE__ */ new Error(`Unknown channel: ${deliveryChannel}`);
			if (!bestEffortDeliver) throw err;
			logDeliveryError(err);
		} else if (resolvedTarget && !resolvedTarget.ok) {
			if (!bestEffortDeliver) throw resolvedTarget.error;
			logDeliveryError(resolvedTarget.error);
		}
	}
	const normalizedPayloads = normalizeOutboundPayloadsForJson(payloads ?? []);
	if (opts.json) {
		runtime.log(JSON.stringify(buildOutboundResultEnvelope({
			payloads: normalizedPayloads,
			meta: result.meta
		}), null, 2));
		if (!deliver) return {
			payloads: normalizedPayloads,
			meta: result.meta
		};
	}
	if (!payloads || payloads.length === 0) {
		runtime.log("No reply from agent.");
		return {
			payloads: [],
			meta: result.meta
		};
	}
	const deliveryPayloads = normalizeOutboundPayloads(payloads);
	const logPayload = (payload) => {
		if (opts.json) return;
		const output = formatOutboundPayloadLog(payload);
		if (!output) return;
		if (opts.lane === AGENT_LANE_NESTED) {
			logNestedOutput(runtime, opts, output);
			return;
		}
		runtime.log(output);
	};
	if (!deliver) for (const payload of deliveryPayloads) logPayload(payload);
	if (deliver && deliveryChannel && !isInternalMessageChannel(deliveryChannel)) {
		if (deliveryTarget) await deliverOutboundPayloads({
			cfg,
			channel: deliveryChannel,
			to: deliveryTarget,
			accountId: resolvedAccountId,
			payloads: deliveryPayloads,
			replyToId: resolvedReplyToId ?? null,
			threadId: resolvedThreadTarget ?? null,
			bestEffort: bestEffortDeliver,
			onError: (err) => logDeliveryError(err),
			onPayload: logPayload,
			deps: createOutboundSendDeps(deps)
		});
	}
	return {
		payloads: normalizedPayloads,
		meta: result.meta
	};
}

//#endregion
//#region ../../src/commands/agent/run-context.ts
function resolveAgentRunContext(opts) {
	const merged = opts.runContext ? { ...opts.runContext } : {};
	const normalizedChannel = resolveMessageChannel(merged.messageChannel ?? opts.messageChannel, opts.replyChannel ?? opts.channel);
	if (normalizedChannel) merged.messageChannel = normalizedChannel;
	const normalizedAccountId = normalizeAccountId(merged.accountId ?? opts.accountId);
	if (normalizedAccountId) merged.accountId = normalizedAccountId;
	const groupId = (merged.groupId ?? opts.groupId)?.toString().trim();
	if (groupId) merged.groupId = groupId;
	const groupChannel = (merged.groupChannel ?? opts.groupChannel)?.toString().trim();
	if (groupChannel) merged.groupChannel = groupChannel;
	const groupSpace = (merged.groupSpace ?? opts.groupSpace)?.toString().trim();
	if (groupSpace) merged.groupSpace = groupSpace;
	if (merged.currentThreadTs == null && opts.threadId != null && opts.threadId !== "" && opts.threadId !== null) merged.currentThreadTs = String(opts.threadId);
	return merged;
}

//#endregion
//#region ../../src/commands/agent/session-store.ts
async function updateSessionStoreAfterAgentRun(params) {
	const { cfg, sessionId, sessionKey, storePath, sessionStore, defaultProvider, defaultModel, fallbackProvider, fallbackModel, result } = params;
	const usage = result.meta.agentMeta?.usage;
	const modelUsed = result.meta.agentMeta?.model ?? fallbackModel ?? defaultModel;
	const providerUsed = result.meta.agentMeta?.provider ?? fallbackProvider ?? defaultProvider;
	const contextTokens = params.contextTokensOverride ?? lookupContextTokens(modelUsed) ?? DEFAULT_CONTEXT_TOKENS;
	const staleEntry = sessionStore[sessionKey] ?? {
		sessionId,
		updatedAt: Date.now()
	};
	const next = await updateSessionStore(storePath, (store) => {
		const merged = {
			...store[sessionKey] ?? staleEntry,
			sessionId,
			updatedAt: Date.now(),
			modelProvider: providerUsed,
			model: modelUsed,
			contextTokens
		};
		if (isCliProvider(providerUsed, cfg)) {
			const cliSessionId = result.meta.agentMeta?.sessionId?.trim();
			if (cliSessionId) setCliSessionId(merged, providerUsed, cliSessionId);
		}
		merged.abortedLastRun = result.meta.aborted ?? false;
		if (hasNonzeroUsage(usage)) {
			const input = usage.input ?? 0;
			const output = usage.output ?? 0;
			const promptTokens = input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
			merged.inputTokens = input;
			merged.outputTokens = output;
			merged.totalTokens = promptTokens > 0 ? promptTokens : usage.total ?? input;
		}
		store[sessionKey] = merged;
		return merged;
	});
	sessionStore[sessionKey] = next;
	return next;
}

//#endregion
//#region ../../src/commands/agent/session.ts
function resolveSessionKeyForRequest(opts) {
	const sessionCfg = opts.cfg.session;
	const scope = sessionCfg?.scope ?? "per-sender";
	const mainKey = normalizeMainKey(sessionCfg?.mainKey);
	const explicitSessionKey = opts.sessionKey?.trim() || resolveExplicitAgentSessionKey({
		cfg: opts.cfg,
		agentId: opts.agentId
	});
	const storeAgentId = resolveAgentIdFromSessionKey(explicitSessionKey);
	const storePath = resolveStorePath(sessionCfg?.store, { agentId: storeAgentId });
	const sessionStore = loadSessionStore(storePath);
	const ctx = opts.to?.trim() ? { From: opts.to } : void 0;
	let sessionKey = explicitSessionKey ?? (ctx ? resolveSessionKey(scope, ctx, mainKey) : void 0);
	if (!explicitSessionKey && opts.sessionId && (!sessionKey || sessionStore[sessionKey]?.sessionId !== opts.sessionId)) {
		const foundKey = Object.keys(sessionStore).find((key) => sessionStore[key]?.sessionId === opts.sessionId);
		if (foundKey) sessionKey = foundKey;
	}
	return {
		sessionKey,
		sessionStore,
		storePath
	};
}
function resolveSession(opts) {
	const sessionCfg = opts.cfg.session;
	const { sessionKey, sessionStore, storePath } = resolveSessionKeyForRequest({
		cfg: opts.cfg,
		to: opts.to,
		sessionId: opts.sessionId,
		sessionKey: opts.sessionKey,
		agentId: opts.agentId
	});
	const now = Date.now();
	const sessionEntry = sessionKey ? sessionStore[sessionKey] : void 0;
	const resetPolicy = resolveSessionResetPolicy({
		sessionCfg,
		resetType: resolveSessionResetType({ sessionKey }),
		resetOverride: resolveChannelResetConfig({
			sessionCfg,
			channel: sessionEntry?.lastChannel ?? sessionEntry?.channel
		})
	});
	const fresh = sessionEntry ? evaluateSessionFreshness({
		updatedAt: sessionEntry.updatedAt,
		now,
		policy: resetPolicy
	}).fresh : false;
	return {
		sessionId: opts.sessionId?.trim() || (fresh ? sessionEntry?.sessionId : void 0) || crypto.randomUUID(),
		sessionKey,
		sessionEntry,
		sessionStore,
		storePath,
		isNewSession: !fresh && !opts.sessionId,
		persistedThinking: fresh && sessionEntry?.thinkingLevel ? normalizeThinkLevel(sessionEntry.thinkingLevel) : void 0,
		persistedVerbose: fresh && sessionEntry?.verboseLevel ? normalizeVerboseLevel(sessionEntry.verboseLevel) : void 0
	};
}

//#endregion
//#region ../../src/commands/agent.ts
async function agentCommand(opts, runtime = defaultRuntime, deps = createDefaultDeps()) {
	const body = (opts.message ?? "").trim();
	if (!body) throw new Error("Message (--message) is required");
	if (!opts.to && !opts.sessionId && !opts.sessionKey && !opts.agentId) throw new Error("Pass --to <E.164>, --session-id, or --agent to choose a session");
	const cfg = loadConfig();
	const agentIdOverrideRaw = opts.agentId?.trim();
	const agentIdOverride = agentIdOverrideRaw ? normalizeAgentId(agentIdOverrideRaw) : void 0;
	if (agentIdOverride) {
		if (!listAgentIds(cfg).includes(agentIdOverride)) throw new Error(`Unknown agent id "${agentIdOverrideRaw}". Use "${formatCliCommand("edwinpai agents list")}" to see configured agents.`);
	}
	if (agentIdOverride && opts.sessionKey) {
		const sessionAgentId = resolveAgentIdFromSessionKey(opts.sessionKey);
		if (sessionAgentId !== agentIdOverride) throw new Error(`Agent id "${agentIdOverrideRaw}" does not match session key agent "${sessionAgentId}".`);
	}
	const agentCfg = cfg.agents?.defaults;
	const sessionAgentId = agentIdOverride ?? resolveAgentIdFromSessionKey(opts.sessionKey?.trim());
	const workspaceDirRaw = resolveAgentWorkspaceDir(cfg, sessionAgentId);
	const agentDir = resolveAgentDir(cfg, sessionAgentId);
	const workspaceDir = (await ensureAgentWorkspace({
		dir: workspaceDirRaw,
		ensureBootstrapFiles: !agentCfg?.skipBootstrap
	})).dir;
	const configuredModel = resolveConfiguredModelRef({
		cfg,
		defaultProvider: DEFAULT_PROVIDER,
		defaultModel: DEFAULT_MODEL
	});
	const thinkingLevelsHint = formatThinkingLevels(configuredModel.provider, configuredModel.model);
	const thinkOverride = normalizeThinkLevel(opts.thinking);
	const thinkOnce = normalizeThinkLevel(opts.thinkingOnce);
	if (opts.thinking && !thinkOverride) throw new Error(`Invalid thinking level. Use one of: ${thinkingLevelsHint}.`);
	if (opts.thinkingOnce && !thinkOnce) throw new Error(`Invalid one-shot thinking level. Use one of: ${thinkingLevelsHint}.`);
	const verboseOverride = normalizeVerboseLevel(opts.verbose);
	if (opts.verbose && !verboseOverride) throw new Error("Invalid verbose level. Use \"on\", \"full\", or \"off\".");
	const timeoutSecondsRaw = opts.timeout !== void 0 ? Number.parseInt(String(opts.timeout), 10) : void 0;
	if (timeoutSecondsRaw !== void 0 && (Number.isNaN(timeoutSecondsRaw) || timeoutSecondsRaw <= 0)) throw new Error("--timeout must be a positive integer (seconds)");
	const timeoutMs = resolveAgentTimeoutMs({
		cfg,
		overrideSeconds: timeoutSecondsRaw
	});
	const { sessionId, sessionKey, sessionEntry: resolvedSessionEntry, sessionStore, storePath, isNewSession, persistedThinking, persistedVerbose } = resolveSession({
		cfg,
		to: opts.to,
		sessionId: opts.sessionId,
		sessionKey: opts.sessionKey,
		agentId: agentIdOverride
	});
	let sessionEntry = resolvedSessionEntry;
	const runId = opts.runId?.trim() || sessionId;
	try {
		if (opts.deliver === true) {
			if (resolveSendPolicy({
				cfg,
				entry: sessionEntry,
				sessionKey,
				channel: sessionEntry?.channel,
				chatType: sessionEntry?.chatType
			}) === "deny") throw new Error("send blocked by session policy");
		}
		let resolvedThinkLevel = thinkOnce ?? thinkOverride ?? persistedThinking ?? agentCfg?.thinkingDefault;
		const resolvedVerboseLevel = verboseOverride ?? persistedVerbose ?? agentCfg?.verboseDefault;
		if (sessionKey) registerAgentRunContext(runId, {
			sessionKey,
			verboseLevel: resolvedVerboseLevel
		});
		const needsSkillsSnapshot = isNewSession || !sessionEntry?.skillsSnapshot;
		const skillsSnapshotVersion = getSkillsSnapshotVersion(workspaceDir);
		const skillFilter = resolveAgentSkillsFilter(cfg, sessionAgentId);
		const skillsSnapshot = needsSkillsSnapshot ? buildWorkspaceSkillSnapshot(workspaceDir, {
			config: cfg,
			eligibility: { remote: getRemoteSkillEligibility() },
			snapshotVersion: skillsSnapshotVersion,
			skillFilter
		}) : sessionEntry?.skillsSnapshot;
		if (skillsSnapshot && sessionStore && sessionKey && needsSkillsSnapshot) {
			const next = {
				...sessionEntry ?? {
					sessionId,
					updatedAt: Date.now()
				},
				sessionId,
				updatedAt: Date.now(),
				skillsSnapshot
			};
			sessionStore[sessionKey] = next;
			await updateSessionStore(storePath, (store) => {
				store[sessionKey] = next;
			});
			sessionEntry = next;
		}
		if (sessionStore && sessionKey) {
			const next = {
				...sessionStore[sessionKey] ?? sessionEntry ?? {
					sessionId,
					updatedAt: Date.now()
				},
				sessionId,
				updatedAt: Date.now()
			};
			if (thinkOverride) if (thinkOverride === "off") delete next.thinkingLevel;
			else next.thinkingLevel = thinkOverride;
			applyVerboseOverride(next, verboseOverride);
			sessionStore[sessionKey] = next;
			await updateSessionStore(storePath, (store) => {
				store[sessionKey] = next;
			});
		}
		const agentModelPrimary = resolveAgentModelPrimary(cfg, sessionAgentId);
		const { provider: defaultProvider, model: defaultModel } = resolveConfiguredModelRef({
			cfg: agentModelPrimary ? {
				...cfg,
				agents: {
					...cfg.agents,
					defaults: {
						...cfg.agents?.defaults,
						model: {
							...typeof cfg.agents?.defaults?.model === "object" ? cfg.agents.defaults.model : void 0,
							primary: agentModelPrimary
						}
					}
				}
			} : cfg,
			defaultProvider: DEFAULT_PROVIDER,
			defaultModel: DEFAULT_MODEL
		});
		let provider = defaultProvider;
		let model = defaultModel;
		const hasAllowlist = agentCfg?.models && Object.keys(agentCfg.models).length > 0;
		const hasStoredOverride = Boolean(sessionEntry?.modelOverride || sessionEntry?.providerOverride);
		const needsModelCatalog = hasAllowlist || hasStoredOverride;
		let allowedModelKeys = /* @__PURE__ */ new Set();
		let allowedModelCatalog = [];
		let modelCatalog = null;
		if (needsModelCatalog) {
			modelCatalog = await loadModelCatalog({ config: cfg });
			const allowed = buildAllowedModelSet({
				cfg,
				catalog: modelCatalog,
				defaultProvider,
				defaultModel
			});
			allowedModelKeys = allowed.allowedKeys;
			allowedModelCatalog = allowed.allowedCatalog;
		}
		if (sessionEntry && sessionStore && sessionKey && hasStoredOverride) {
			const entry = sessionEntry;
			const overrideProvider = sessionEntry.providerOverride?.trim() || defaultProvider;
			const overrideModel = sessionEntry.modelOverride?.trim();
			if (overrideModel) {
				const key = modelKey(overrideProvider, overrideModel);
				if (!isCliProvider(overrideProvider, cfg) && allowedModelKeys.size > 0 && !allowedModelKeys.has(key)) {
					const { updated } = applyModelOverrideToSessionEntry({
						entry,
						selection: {
							provider: defaultProvider,
							model: defaultModel,
							isDefault: true
						}
					});
					if (updated) {
						sessionStore[sessionKey] = entry;
						await updateSessionStore(storePath, (store) => {
							store[sessionKey] = entry;
						});
					}
				}
			}
		}
		const storedProviderOverride = sessionEntry?.providerOverride?.trim();
		const storedModelOverride = sessionEntry?.modelOverride?.trim();
		if (storedModelOverride) {
			const candidateProvider = storedProviderOverride || defaultProvider;
			const key = modelKey(candidateProvider, storedModelOverride);
			if (isCliProvider(candidateProvider, cfg) || allowedModelKeys.size === 0 || allowedModelKeys.has(key)) {
				provider = candidateProvider;
				model = storedModelOverride;
			}
		}
		if (sessionEntry) {
			const authProfileId = sessionEntry.authProfileOverride;
			if (authProfileId) {
				const entry = sessionEntry;
				const profile = ensureAuthProfileStore().profiles[authProfileId];
				if (!profile || profile.provider !== provider) {
					if (sessionStore && sessionKey) await clearSessionAuthProfileOverride({
						sessionEntry: entry,
						sessionStore,
						sessionKey,
						storePath
					});
				}
			}
		}
		if (!resolvedThinkLevel) {
			let catalogForThinking = modelCatalog ?? allowedModelCatalog;
			if (!catalogForThinking || catalogForThinking.length === 0) {
				modelCatalog = await loadModelCatalog({ config: cfg });
				catalogForThinking = modelCatalog;
			}
			resolvedThinkLevel = resolveThinkingDefault({
				cfg,
				provider,
				model,
				catalog: catalogForThinking
			});
		}
		if (resolvedThinkLevel === "xhigh" && !supportsXHighThinking(provider, model)) {
			if (Boolean(thinkOnce || thinkOverride)) throw new Error(`Thinking level "xhigh" is only supported for ${formatXHighModelHint()}.`);
			resolvedThinkLevel = "high";
			if (sessionEntry && sessionStore && sessionKey && sessionEntry.thinkingLevel === "xhigh") {
				const entry = sessionEntry;
				entry.thinkingLevel = "high";
				entry.updatedAt = Date.now();
				sessionStore[sessionKey] = entry;
				await updateSessionStore(storePath, (store) => {
					store[sessionKey] = entry;
				});
			}
		}
		const sessionFile = resolveSessionFilePath(sessionId, sessionEntry, { agentId: sessionAgentId });
		const startedAt = Date.now();
		let lifecycleEnded = false;
		let result;
		let fallbackProvider = provider;
		let fallbackModel = model;
		try {
			const runContext = resolveAgentRunContext(opts);
			const messageChannel = resolveMessageChannel(runContext.messageChannel, opts.replyChannel ?? opts.channel);
			const spawnedBy = opts.spawnedBy ?? sessionEntry?.spawnedBy;
			const fallbackResult = await runWithModelFallback({
				cfg,
				provider,
				model,
				agentDir,
				fallbacksOverride: resolveAgentModelFallbacksOverride(cfg, sessionAgentId),
				run: (providerOverride, modelOverride) => {
					if (isCliProvider(providerOverride, cfg)) {
						const cliSessionId = getCliSessionId(sessionEntry, providerOverride);
						return runCliAgent({
							sessionId,
							sessionKey,
							sessionFile,
							workspaceDir,
							config: cfg,
							prompt: body,
							provider: providerOverride,
							model: modelOverride,
							thinkLevel: resolvedThinkLevel,
							timeoutMs,
							runId,
							extraSystemPrompt: opts.extraSystemPrompt,
							cliSessionId,
							images: opts.images,
							streamParams: opts.streamParams
						});
					}
					const authProfileId = providerOverride === provider ? sessionEntry?.authProfileOverride : void 0;
					return runEmbeddedPiAgent({
						sessionId,
						sessionKey,
						messageChannel,
						agentAccountId: runContext.accountId,
						messageTo: opts.replyTo ?? opts.to,
						messageThreadId: opts.threadId,
						groupId: runContext.groupId,
						groupChannel: runContext.groupChannel,
						groupSpace: runContext.groupSpace,
						spawnedBy,
						currentChannelId: runContext.currentChannelId,
						currentThreadTs: runContext.currentThreadTs,
						replyToMode: runContext.replyToMode,
						hasRepliedRef: runContext.hasRepliedRef,
						sessionFile,
						workspaceDir,
						config: cfg,
						skillsSnapshot,
						prompt: body,
						images: opts.images,
						clientTools: opts.clientTools,
						provider: providerOverride,
						model: modelOverride,
						authProfileId,
						authProfileIdSource: authProfileId ? sessionEntry?.authProfileOverrideSource : void 0,
						thinkLevel: resolvedThinkLevel,
						verboseLevel: resolvedVerboseLevel,
						timeoutMs,
						runId,
						lane: opts.lane,
						abortSignal: opts.abortSignal,
						extraSystemPrompt: opts.extraSystemPrompt,
						streamParams: opts.streamParams,
						agentDir,
						onAgentEvent: (evt) => {
							if (evt.stream === "lifecycle" && typeof evt.data?.phase === "string" && (evt.data.phase === "end" || evt.data.phase === "error")) lifecycleEnded = true;
						}
					});
				}
			});
			result = fallbackResult.result;
			fallbackProvider = fallbackResult.provider;
			fallbackModel = fallbackResult.model;
			if (!lifecycleEnded) emitAgentEvent({
				runId,
				stream: "lifecycle",
				data: {
					phase: "end",
					startedAt,
					endedAt: Date.now(),
					aborted: result.meta.aborted ?? false
				}
			});
		} catch (err) {
			if (!lifecycleEnded) emitAgentEvent({
				runId,
				stream: "lifecycle",
				data: {
					phase: "error",
					startedAt,
					endedAt: Date.now(),
					error: String(err)
				}
			});
			throw err;
		}
		if (sessionStore && sessionKey) await updateSessionStoreAfterAgentRun({
			cfg,
			contextTokensOverride: agentCfg?.contextTokens,
			sessionId,
			sessionKey,
			storePath,
			sessionStore,
			defaultProvider: provider,
			defaultModel: model,
			fallbackProvider,
			fallbackModel,
			result
		});
		const payloads = result.payloads ?? [];
		const deliveryResult = await deliverAgentCommandResult({
			cfg,
			deps,
			runtime,
			opts,
			sessionEntry,
			result,
			payloads
		});
		const loadLatestSessionEntry = () => {
			if (!sessionStore || !sessionKey) return;
			const latest = loadSessionStore(storePath, { skipCache: true })[sessionKey] ?? sessionStore[sessionKey];
			if (latest) sessionStore[sessionKey] = latest;
			return latest;
		};
		const currentEntry = loadLatestSessionEntry();
		const currentTaskEntry = getActiveTask(currentEntry);
		const taskState = resolveTaskState(currentTaskEntry);
		const autoContinue = resolveAutoContinueState(currentEntry?.autoContinue);
		if (sessionStore && sessionKey && (taskState.autoContinueEnabled || autoContinue.enabled)) {
			const currentPrompt = buildTaskContinuationPrompt(currentTaskEntry);
			const isContinuationTurn = body === AUTO_CONTINUE_PROMPT || body === currentPrompt || body.startsWith("Continue the active task.\nTASK_");
			const taskEvaluation = evaluateTaskState(currentTaskEntry);
			const detectedStopReason = taskEvaluation.stopReason;
			const entry = sessionStore[sessionKey] ?? sessionEntry ?? {
				sessionId,
				updatedAt: Date.now()
			};
			let nextEntry;
			let shouldSchedule = false;
			let delayMs = 1e3;
			if (taskState.autoContinueEnabled) {
				const nextTask = nextTaskState({
					state: isContinuationTurn ? currentTaskEntry : {
						...currentTaskEntry,
						status: "active",
						iterationCount: 0,
						active: true,
						lastStopReason: void 0
					},
					stopReason: detectedStopReason,
					evaluationReason: taskEvaluation.reason
				});
				const updatedEntry = setActiveTask({
					...entry,
					sessionId,
					updatedAt: Date.now()
				}, nextTask);
				const advancedEntry = nextTask.active === true ? updatedEntry : advanceToNextRunnableTask(updatedEntry, { excludeTaskId: nextTask.id });
				const selectedTask = getActiveTask(advancedEntry);
				const advancedToNextTask = selectedTask?.id !== void 0 && selectedTask.id !== nextTask.id;
				nextEntry = {
					...advancedEntry,
					sessionId,
					updatedAt: Date.now()
				};
				shouldSchedule = shouldContinueTask(nextEntry);
				delayMs = selectedTask?.delayMs ?? nextTask.delayMs ?? taskState.delayMs;
				logSessionStateChange({
					sessionId,
					sessionKey,
					state: shouldSchedule ? "continuing" : "idle",
					reason: advancedToNextTask ? "task_queue_advance" : `task_${nextTask.lastStopReason ?? detectedStopReason}`
				});
			} else {
				const nextState = nextAutoContinueState({
					state: isContinuationTurn ? currentEntry?.autoContinue : {
						...currentEntry?.autoContinue,
						iterationCount: 0,
						active: true,
						lastStopReason: void 0
					},
					stopReason: classifyAutoContinueStopReason(getAutoContinueText(payloads))
				});
				nextEntry = {
					...entry,
					sessionId,
					updatedAt: Date.now(),
					autoContinue: nextState
				};
				shouldSchedule = nextState.active === true && nextState.lastStopReason === "continue";
				delayMs = nextState.delayMs ?? autoContinue.delayMs;
				logSessionStateChange({
					sessionId,
					sessionKey,
					state: shouldSchedule ? "continuing" : "idle",
					reason: `autocontinue_${nextState.lastStopReason ?? "continue"}`
				});
			}
			sessionStore[sessionKey] = nextEntry;
			await updateSessionStore(storePath, (store) => {
				store[sessionKey] = {
					...store[sessionKey] ?? {},
					...nextEntry
				};
			});
			if (shouldSchedule) setTimeout(() => {
				const latestEntry = loadLatestSessionEntry();
				let message = AUTO_CONTINUE_PROMPT;
				if (taskState.autoContinueEnabled) {
					const latestTask = getActiveTask(latestEntry);
					if (!latestEntry || !latestTask || !shouldContinueTask(latestEntry)) {
						logSessionStateChange({
							sessionId: latestEntry?.sessionId ?? sessionId,
							sessionKey,
							state: "idle",
							reason: "task_no_longer_runnable"
						});
						return;
					}
					message = buildTaskContinuationPrompt(latestTask);
				}
				agentCommand({
					...opts,
					message,
					sessionKey,
					sessionId: void 0,
					to: void 0,
					runId: randomUUID()
				}, runtime, deps).catch((err) => {
					runtime.error?.(`Auto-continue failed for ${sessionKey}: ${String(err)}`);
				});
			}, delayMs).unref?.();
		}
		return deliveryResult;
	} finally {
		clearAgentRunContext(runId);
	}
}

//#endregion
export { createOutboundSendDeps as a, resolveAgentOutboundTarget as i, resolveSessionKeyForRequest as n, buildTaskContinuationPrompt as o, resolveAgentDeliveryPlan as r, agentCommand as t };