import { At as isRecord, J as shouldLogVerbose, _ as defaultRuntime, n as isTruthyEnvValue, o as createSubsystemLogger, w as DEFAULT_CHAT_CHANNEL } from "./entry.js";
import { b as ensureAuthProfileStore } from "./auth-profiles-D11Xw15i.js";
import { t as formatCliCommand } from "./command-format-B3nkKRhC.js";
import { c as resolveAgentIdFromSessionKey, o as normalizeAgentId, s as normalizeMainKey } from "./session-key-CFxFgYxM.js";
import { C as ensureAgentWorkspace, c as resolveAgentWorkspaceDir, d as resolveSessionAgentId, f as resolveSessionAgentIds, i as resolveAgentDir, n as listAgentIds, o as resolveAgentModelPrimary, s as resolveAgentSkillsFilter, u as resolveEffectiveModelFallbacks } from "./agent-scope-C-Jte08L.js";
import { C as DEFAULT_MODEL, S as DEFAULT_CONTEXT_TOKENS, b as resolveThinkingDefault, c as modelKey, h as resolveDefaultModelForAgent, l as normalizeModelRef, m as resolveConfiguredModelRef, s as isCliProvider, t as buildAllowedModelSet, u as normalizeProviderId, w as DEFAULT_PROVIDER } from "./model-selection-CMx1evaF.js";
import { a as buildModelAliasLines } from "./model-B4Btg-Q6.js";
import { r as buildWorkspaceSkillSnapshot } from "./skills-cLBEdkqu.js";
import { i as loadConfig } from "./config-D7TcU4qN.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-DXToSaWK.js";
import { A as resolveRunWorkspaceDir, At as buildAgentSystemPrompt, Cn as emitAgentEvent, En as registerAgentRunContext, Ht as applyVerboseOverride, It as resolveSendPolicy, Nt as getProcessSupervisor, Pt as detectRuntimeShell, Q as resolveFailoverStatus, Sn as clearAgentRunContext, T as runAgentTurn, U as resolveOutboundTarget, Vt as applyModelOverrideToSessionEntry, W as resolveSessionDeliveryTarget, X as FailoverError, Y as runWithModelFallback, an as clearSessionAuthProfileOverride, bt as AGENT_LANE_NESTED, hn as resolveBootstrapContextForRun, jt as buildSystemPromptParams, k as redactRunIdentifier, mn as makeBootstrapWarn, tn as resolveAgentTimeoutMs, un as resolveSymiDocsPath, xt as AGENT_LANE_SUBAGENT } from "./subagent-registry-CVhLz4p3.js";
import { D as resolveSessionResetPolicy, E as resolveChannelResetConfig, O as resolveSessionResetType, P as resolveExplicitAgentSessionKey, T as evaluateSessionFreshness, Y as normalizeAccountId, a as resolveAndPersistSessionFile, d as updateSessionStore, n as parseSessionThreadInfo, o as loadSessionStore, w as resolveSessionKey } from "./sessions-Dn6VXn4p.js";
import { r as normalizeChannelId, t as getChannelPlugin } from "./plugins-BsEhWvLn.js";
import { a as normalizeOutboundPayloadsForJson, i as normalizeOutboundPayloads, r as formatOutboundPayloadLog, t as deliverOutboundPayloads } from "./deliver-DIK2emIV.js";
import { D as isFailoverErrorMessage, g as classifyFailoverReason } from "./pi-embedded-helpers-BQjRftRI.js";
import { c as resolveStorePath, i as resolveSessionTranscriptPath, n as resolveSessionFilePath } from "./paths-DtiEyjsC.js";
import { d as supportsXHighThinking, l as normalizeVerboseLevel, n as formatXHighModelHint, s as normalizeThinkLevel, t as formatThinkingLevels } from "./thinking-BZDIJMl_.js";
import { g as getSkillsSnapshotVersion, t as getRemoteSkillEligibility } from "./skills-remote-DSGpkPJE.js";
import { n as loadModelCatalog } from "./model-catalog-CzKsiNZA.js";
import { u as lookupContextTokens } from "./session-utils-Zpe3t68b.js";
import { c as hasNonzeroUsage, s as deriveSessionTotalTokens } from "./session-cost-usage-CJWHHY-C.js";
import { n as createDefaultDeps, t as createOutboundSendDeps } from "./outbound-send-deps-BCyarBRf.js";
import os from "node:os";
import path from "node:path";
import fs from "node:fs/promises";
import crypto from "node:crypto";

//#region src/agents/cli-watchdog-defaults.ts
const CLI_WATCHDOG_MIN_TIMEOUT_MS = 1e3;
const CLI_FRESH_WATCHDOG_DEFAULTS = {
	noOutputTimeoutRatio: .8,
	minMs: 18e4,
	maxMs: 6e5
};
const CLI_RESUME_WATCHDOG_DEFAULTS = {
	noOutputTimeoutRatio: .3,
	minMs: 6e4,
	maxMs: 18e4
};

//#endregion
//#region src/agents/cli-backends.ts
const DEFAULT_CLAUDE_BACKEND = {
	command: "claude",
	args: [
		"-p",
		"--output-format",
		"json",
		"--dangerously-skip-permissions"
	],
	resumeArgs: [
		"-p",
		"--output-format",
		"json",
		"--dangerously-skip-permissions",
		"--resume",
		"{sessionId}"
	],
	output: "json",
	input: "arg",
	modelArg: "--model",
	modelAliases: {
		opus: "opus",
		"opus-4.6": "opus",
		"opus-4.5": "opus",
		"opus-4": "opus",
		"claude-opus-4-6": "opus",
		"claude-opus-4-5": "opus",
		"claude-opus-4": "opus",
		sonnet: "sonnet",
		"sonnet-4.6": "sonnet",
		"sonnet-4.5": "sonnet",
		"sonnet-4.1": "sonnet",
		"sonnet-4.0": "sonnet",
		"claude-sonnet-4-6": "sonnet",
		"claude-sonnet-4-5": "sonnet",
		"claude-sonnet-4-1": "sonnet",
		"claude-sonnet-4-0": "sonnet",
		haiku: "haiku",
		"haiku-3.5": "haiku",
		"claude-haiku-3-5": "haiku"
	},
	sessionArg: "--session-id",
	sessionMode: "always",
	sessionIdFields: [
		"session_id",
		"sessionId",
		"conversation_id",
		"conversationId"
	],
	systemPromptArg: "--append-system-prompt",
	systemPromptMode: "append",
	systemPromptWhen: "first",
	clearEnv: ["ANTHROPIC_API_KEY", "ANTHROPIC_API_KEY_OLD"],
	reliability: { watchdog: {
		fresh: { ...CLI_FRESH_WATCHDOG_DEFAULTS },
		resume: { ...CLI_RESUME_WATCHDOG_DEFAULTS }
	} },
	serialize: true
};
const DEFAULT_CODEX_BACKEND = {
	command: "codex",
	args: [
		"exec",
		"--json",
		"--color",
		"never",
		"--sandbox",
		"read-only",
		"--skip-git-repo-check"
	],
	resumeArgs: [
		"exec",
		"resume",
		"{sessionId}",
		"--color",
		"never",
		"--sandbox",
		"read-only",
		"--skip-git-repo-check"
	],
	output: "jsonl",
	resumeOutput: "text",
	input: "arg",
	modelArg: "--model",
	sessionIdFields: ["thread_id"],
	sessionMode: "existing",
	imageArg: "--image",
	imageMode: "repeat",
	reliability: { watchdog: {
		fresh: { ...CLI_FRESH_WATCHDOG_DEFAULTS },
		resume: { ...CLI_RESUME_WATCHDOG_DEFAULTS }
	} },
	serialize: true
};
function normalizeBackendKey(key) {
	return normalizeProviderId(key);
}
function pickBackendConfig(config, normalizedId) {
	for (const [key, entry] of Object.entries(config)) if (normalizeBackendKey(key) === normalizedId) return entry;
}
function mergeBackendConfig(base, override) {
	if (!override) return { ...base };
	const baseFresh = base.reliability?.watchdog?.fresh ?? {};
	const baseResume = base.reliability?.watchdog?.resume ?? {};
	const overrideFresh = override.reliability?.watchdog?.fresh ?? {};
	const overrideResume = override.reliability?.watchdog?.resume ?? {};
	return {
		...base,
		...override,
		args: override.args ?? base.args,
		env: {
			...base.env,
			...override.env
		},
		modelAliases: {
			...base.modelAliases,
			...override.modelAliases
		},
		clearEnv: Array.from(new Set([...base.clearEnv ?? [], ...override.clearEnv ?? []])),
		sessionIdFields: override.sessionIdFields ?? base.sessionIdFields,
		sessionArgs: override.sessionArgs ?? base.sessionArgs,
		resumeArgs: override.resumeArgs ?? base.resumeArgs,
		reliability: {
			...base.reliability,
			...override.reliability,
			watchdog: {
				...base.reliability?.watchdog,
				...override.reliability?.watchdog,
				fresh: {
					...baseFresh,
					...overrideFresh
				},
				resume: {
					...baseResume,
					...overrideResume
				}
			}
		}
	};
}
function resolveCliBackendConfig(provider, cfg) {
	const normalized = normalizeBackendKey(provider);
	const override = pickBackendConfig(cfg?.agents?.defaults?.cliBackends ?? {}, normalized);
	if (normalized === "claude-cli") {
		const merged = mergeBackendConfig(DEFAULT_CLAUDE_BACKEND, override);
		const command = merged.command?.trim();
		if (!command) return null;
		return {
			id: normalized,
			config: {
				...merged,
				command
			}
		};
	}
	if (normalized === "codex-cli") {
		const merged = mergeBackendConfig(DEFAULT_CODEX_BACKEND, override);
		const command = merged.command?.trim();
		if (!command) return null;
		return {
			id: normalized,
			config: {
				...merged,
				command
			}
		};
	}
	if (!override) return null;
	const command = override.command?.trim();
	if (!command) return null;
	return {
		id: normalized,
		config: {
			...override,
			command
		}
	};
}

//#endregion
//#region src/agents/cli-runner/reliability.ts
function pickWatchdogProfile(backend, useResume) {
	const defaults = useResume ? CLI_RESUME_WATCHDOG_DEFAULTS : CLI_FRESH_WATCHDOG_DEFAULTS;
	const configured = useResume ? backend.reliability?.watchdog?.resume : backend.reliability?.watchdog?.fresh;
	const ratio = (() => {
		const value = configured?.noOutputTimeoutRatio;
		if (typeof value !== "number" || !Number.isFinite(value)) return defaults.noOutputTimeoutRatio;
		return Math.max(.05, Math.min(.95, value));
	})();
	const minMs = (() => {
		const value = configured?.minMs;
		if (typeof value !== "number" || !Number.isFinite(value)) return defaults.minMs;
		return Math.max(CLI_WATCHDOG_MIN_TIMEOUT_MS, Math.floor(value));
	})();
	const maxMs = (() => {
		const value = configured?.maxMs;
		if (typeof value !== "number" || !Number.isFinite(value)) return defaults.maxMs;
		return Math.max(CLI_WATCHDOG_MIN_TIMEOUT_MS, Math.floor(value));
	})();
	return {
		noOutputTimeoutMs: typeof configured?.noOutputTimeoutMs === "number" && Number.isFinite(configured.noOutputTimeoutMs) ? Math.max(CLI_WATCHDOG_MIN_TIMEOUT_MS, Math.floor(configured.noOutputTimeoutMs)) : void 0,
		noOutputTimeoutRatio: ratio,
		minMs: Math.min(minMs, maxMs),
		maxMs: Math.max(minMs, maxMs)
	};
}
function resolveCliNoOutputTimeoutMs(params) {
	const profile = pickWatchdogProfile(params.backend, params.useResume);
	const cap = Math.max(CLI_WATCHDOG_MIN_TIMEOUT_MS, params.timeoutMs - 1e3);
	if (profile.noOutputTimeoutMs !== void 0) return Math.min(profile.noOutputTimeoutMs, cap);
	const computed = Math.floor(params.timeoutMs * profile.noOutputTimeoutRatio);
	const bounded = Math.min(profile.maxMs, Math.max(profile.minMs, computed));
	return Math.min(bounded, cap);
}
function buildCliSupervisorScopeKey(params) {
	const commandToken = path.basename(params.backend.command ?? "").trim().toLowerCase();
	const backendToken = params.backendId.trim().toLowerCase();
	const sessionToken = params.cliSessionId?.trim();
	if (!sessionToken) return;
	return `cli:${backendToken}:${commandToken}:${sessionToken}`;
}

//#endregion
//#region src/agents/cli-runner/helpers.ts
const CLI_RUN_QUEUE = /* @__PURE__ */ new Map();
function enqueueCliRun(key, task) {
	const chained = (CLI_RUN_QUEUE.get(key) ?? Promise.resolve()).catch(() => void 0).then(task);
	const tracked = chained.catch(() => void 0).finally(() => {
		if (CLI_RUN_QUEUE.get(key) === tracked) CLI_RUN_QUEUE.delete(key);
	});
	CLI_RUN_QUEUE.set(key, tracked);
	return chained;
}
function buildSystemPrompt(params) {
	const defaultModelRef = resolveDefaultModelForAgent({
		cfg: params.config ?? {},
		agentId: params.agentId
	});
	const defaultModelLabel = `${defaultModelRef.provider}/${defaultModelRef.model}`;
	const { runtimeInfo, userTimezone, userTime, userTimeFormat } = buildSystemPromptParams({
		config: params.config,
		agentId: params.agentId,
		workspaceDir: params.workspaceDir,
		cwd: process.cwd(),
		runtime: {
			host: "symi",
			os: `${os.type()} ${os.release()}`,
			arch: os.arch(),
			node: process.version,
			model: params.modelDisplay,
			defaultModel: defaultModelLabel,
			shell: detectRuntimeShell()
		}
	});
	return buildAgentSystemPrompt({
		workspaceDir: params.workspaceDir,
		defaultThinkLevel: params.defaultThinkLevel,
		extraSystemPrompt: params.extraSystemPrompt,
		ownerNumbers: params.ownerNumbers,
		ownerDisplay: params.config?.commands?.ownerDisplay,
		ownerDisplaySecret: params.config?.commands?.ownerDisplaySecret ?? params.config?.gateway?.auth?.token ?? params.config?.gateway?.remote?.token,
		reasoningTagHint: false,
		docsPath: params.docsPath,
		runtimeInfo,
		toolNames: params.tools.map((tool) => tool.name),
		modelAliasLines: buildModelAliasLines(params.config),
		userTimezone,
		userTime,
		userTimeFormat,
		contextFiles: params.contextFiles,
		memoryCitationsMode: params.config?.memory?.citations
	});
}
function normalizeCliModel(modelId, backend) {
	const trimmed = modelId.trim();
	if (!trimmed) return trimmed;
	const direct = backend.modelAliases?.[trimmed];
	if (direct) return direct;
	const lower = trimmed.toLowerCase();
	const mapped = backend.modelAliases?.[lower];
	if (mapped) return mapped;
	return trimmed;
}
function toUsage(raw) {
	const pick = (key) => typeof raw[key] === "number" && raw[key] > 0 ? raw[key] : void 0;
	const input = pick("input_tokens") ?? pick("inputTokens");
	const output = pick("output_tokens") ?? pick("outputTokens");
	const cacheRead = pick("cache_read_input_tokens") ?? pick("cached_input_tokens") ?? pick("cacheRead");
	const cacheWrite = pick("cache_write_input_tokens") ?? pick("cacheWrite");
	const total = pick("total_tokens") ?? pick("total");
	if (!input && !output && !cacheRead && !cacheWrite && !total) return;
	return {
		input,
		output,
		cacheRead,
		cacheWrite,
		total
	};
}
function collectText(value) {
	if (!value) return "";
	if (typeof value === "string") return value;
	if (Array.isArray(value)) return value.map((entry) => collectText(entry)).join("");
	if (!isRecord(value)) return "";
	if (typeof value.text === "string") return value.text;
	if (typeof value.content === "string") return value.content;
	if (Array.isArray(value.content)) return value.content.map((entry) => collectText(entry)).join("");
	if (isRecord(value.message)) return collectText(value.message);
	return "";
}
function pickSessionId(parsed, backend) {
	const fields = backend.sessionIdFields ?? [
		"session_id",
		"sessionId",
		"conversation_id",
		"conversationId"
	];
	for (const field of fields) {
		const value = parsed[field];
		if (typeof value === "string" && value.trim()) return value.trim();
	}
}
function parseCliJson(raw, backend) {
	const trimmed = raw.trim();
	if (!trimmed) return null;
	let parsed;
	try {
		parsed = JSON.parse(trimmed);
	} catch {
		return null;
	}
	if (!isRecord(parsed)) return null;
	const sessionId = pickSessionId(parsed, backend);
	const usage = isRecord(parsed.usage) ? toUsage(parsed.usage) : void 0;
	return {
		text: (collectText(parsed.message) || collectText(parsed.content) || collectText(parsed.result) || collectText(parsed)).trim(),
		sessionId,
		usage
	};
}
function parseCliJsonl(raw, backend) {
	const lines = raw.split(/\r?\n/g).map((line) => line.trim()).filter(Boolean);
	if (lines.length === 0) return null;
	let sessionId;
	let usage;
	const texts = [];
	for (const line of lines) {
		let parsed;
		try {
			parsed = JSON.parse(line);
		} catch {
			continue;
		}
		if (!isRecord(parsed)) continue;
		if (!sessionId) sessionId = pickSessionId(parsed, backend);
		if (!sessionId && typeof parsed.thread_id === "string") sessionId = parsed.thread_id.trim();
		if (isRecord(parsed.usage)) usage = toUsage(parsed.usage) ?? usage;
		const item = isRecord(parsed.item) ? parsed.item : null;
		if (item && typeof item.text === "string") {
			const type = typeof item.type === "string" ? item.type.toLowerCase() : "";
			if (!type || type.includes("message")) texts.push(item.text);
		}
	}
	const text = texts.join("\n").trim();
	if (!text) return null;
	return {
		text,
		sessionId,
		usage
	};
}
function resolveSystemPromptUsage(params) {
	const systemPrompt = params.systemPrompt?.trim();
	if (!systemPrompt) return null;
	const when = params.backend.systemPromptWhen ?? "first";
	if (when === "never") return null;
	if (when === "first" && !params.isNewSession) return null;
	if (!params.backend.systemPromptArg?.trim()) return null;
	return systemPrompt;
}
function resolveSessionIdToSend(params) {
	const mode = params.backend.sessionMode ?? "always";
	const existing = params.cliSessionId?.trim();
	if (mode === "none") return {
		sessionId: void 0,
		isNew: !existing
	};
	if (mode === "existing") return {
		sessionId: existing,
		isNew: !existing
	};
	if (existing) return {
		sessionId: existing,
		isNew: false
	};
	return {
		sessionId: crypto.randomUUID(),
		isNew: true
	};
}
function resolvePromptInput(params) {
	if ((params.backend.input ?? "arg") === "stdin") return { stdin: params.prompt };
	if (params.backend.maxPromptArgChars && params.prompt.length > params.backend.maxPromptArgChars) return { stdin: params.prompt };
	return { argsPrompt: params.prompt };
}
function resolveImageExtension(mimeType) {
	const normalized = mimeType.toLowerCase();
	if (normalized.includes("png")) return "png";
	if (normalized.includes("jpeg") || normalized.includes("jpg")) return "jpg";
	if (normalized.includes("gif")) return "gif";
	if (normalized.includes("webp")) return "webp";
	return "bin";
}
function appendImagePathsToPrompt(prompt, paths) {
	if (!paths.length) return prompt;
	const trimmed = prompt.trimEnd();
	return `${trimmed}${trimmed ? "\n\n" : ""}${paths.join("\n")}`;
}
async function writeCliImages(images) {
	const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "symi-cli-images-"));
	const paths = [];
	for (let i = 0; i < images.length; i += 1) {
		const image = images[i];
		const ext = resolveImageExtension(image.mimeType);
		const filePath = path.join(tempDir, `image-${i + 1}.${ext}`);
		const buffer = Buffer.from(image.data, "base64");
		await fs.writeFile(filePath, buffer, { mode: 384 });
		paths.push(filePath);
	}
	const cleanup = async () => {
		await fs.rm(tempDir, {
			recursive: true,
			force: true
		});
	};
	return {
		paths,
		cleanup
	};
}
function buildCliArgs(params) {
	const args = [...params.baseArgs];
	if (!params.useResume && params.backend.modelArg && params.modelId) args.push(params.backend.modelArg, params.modelId);
	if (!params.useResume && params.systemPrompt && params.backend.systemPromptArg) args.push(params.backend.systemPromptArg, params.systemPrompt);
	if (!params.useResume && params.sessionId) {
		if (params.backend.sessionArgs && params.backend.sessionArgs.length > 0) for (const entry of params.backend.sessionArgs) args.push(entry.replaceAll("{sessionId}", params.sessionId));
		else if (params.backend.sessionArg) args.push(params.backend.sessionArg, params.sessionId);
	}
	if (params.imagePaths && params.imagePaths.length > 0) {
		const mode = params.backend.imageMode ?? "repeat";
		const imageArg = params.backend.imageArg;
		if (imageArg) if (mode === "list") args.push(imageArg, params.imagePaths.join(","));
		else for (const imagePath of params.imagePaths) args.push(imageArg, imagePath);
	}
	if (params.promptArg !== void 0) args.push(params.promptArg);
	return args;
}

//#endregion
//#region src/agents/cli-runner.ts
const log = createSubsystemLogger("agent/claude-cli");
async function runCliAgent(params) {
	const started = Date.now();
	const workspaceResolution = resolveRunWorkspaceDir({
		workspaceDir: params.workspaceDir,
		sessionKey: params.sessionKey,
		agentId: params.agentId,
		config: params.config
	});
	const resolvedWorkspace = workspaceResolution.workspaceDir;
	const redactedSessionId = redactRunIdentifier(params.sessionId);
	const redactedSessionKey = redactRunIdentifier(params.sessionKey);
	const redactedWorkspace = redactRunIdentifier(resolvedWorkspace);
	if (workspaceResolution.usedFallback) log.warn(`[workspace-fallback] caller=runCliAgent reason=${workspaceResolution.fallbackReason} run=${params.runId} session=${redactedSessionId} sessionKey=${redactedSessionKey} agent=${workspaceResolution.agentId} workspace=${redactedWorkspace}`);
	const workspaceDir = resolvedWorkspace;
	const backendResolved = resolveCliBackendConfig(params.provider, params.config);
	if (!backendResolved) throw new Error(`Unknown CLI backend: ${params.provider}`);
	const backend = backendResolved.config;
	const modelId = (params.model ?? "default").trim() || "default";
	const normalizedModel = normalizeCliModel(modelId, backend);
	const modelDisplay = `${params.provider}/${modelId}`;
	const extraSystemPrompt = [params.extraSystemPrompt?.trim(), "Tools are disabled in this session. Do not call tools."].filter(Boolean).join("\n");
	const sessionLabel = params.sessionKey ?? params.sessionId;
	const { contextFiles } = await resolveBootstrapContextForRun({
		workspaceDir,
		config: params.config,
		sessionKey: params.sessionKey,
		sessionId: params.sessionId,
		warn: makeBootstrapWarn({
			sessionLabel,
			warn: (message) => log.warn(message)
		})
	});
	const { sessionAgentId } = resolveSessionAgentIds({
		sessionKey: params.sessionKey,
		config: params.config
	});
	const docsPath = await resolveSymiDocsPath({
		workspaceDir,
		argv1: process.argv[1],
		cwd: process.cwd(),
		moduleUrl: import.meta.url
	});
	const systemPrompt = buildSystemPrompt({
		workspaceDir,
		config: params.config,
		defaultThinkLevel: params.thinkLevel,
		extraSystemPrompt,
		ownerNumbers: params.ownerNumbers,
		docsPath: docsPath ?? void 0,
		tools: [],
		contextFiles,
		modelDisplay,
		agentId: sessionAgentId
	});
	const { sessionId: cliSessionIdToSend, isNew } = resolveSessionIdToSend({
		backend,
		cliSessionId: params.cliSessionId
	});
	const useResume = Boolean(params.cliSessionId && cliSessionIdToSend && backend.resumeArgs && backend.resumeArgs.length > 0);
	const sessionIdSent = cliSessionIdToSend ? useResume || Boolean(backend.sessionArg) || Boolean(backend.sessionArgs?.length) ? cliSessionIdToSend : void 0 : void 0;
	const systemPromptArg = resolveSystemPromptUsage({
		backend,
		isNewSession: isNew,
		systemPrompt
	});
	let imagePaths;
	let cleanupImages;
	let prompt = params.prompt;
	if (params.images && params.images.length > 0) {
		const imagePayload = await writeCliImages(params.images);
		imagePaths = imagePayload.paths;
		cleanupImages = imagePayload.cleanup;
		if (!backend.imageArg) prompt = appendImagePathsToPrompt(prompt, imagePaths);
	}
	const { argsPrompt, stdin } = resolvePromptInput({
		backend,
		prompt
	});
	const stdinPayload = stdin ?? "";
	const baseArgs = useResume ? backend.resumeArgs ?? backend.args ?? [] : backend.args ?? [];
	const args = buildCliArgs({
		backend,
		baseArgs: useResume ? baseArgs.map((entry) => entry.replaceAll("{sessionId}", cliSessionIdToSend ?? "")) : baseArgs,
		modelId: normalizedModel,
		sessionId: cliSessionIdToSend,
		systemPrompt: systemPromptArg,
		imagePaths,
		promptArg: argsPrompt,
		useResume
	});
	const queueKey = backend.serialize ?? true ? backendResolved.id : `${backendResolved.id}:${params.runId}`;
	try {
		const output = await enqueueCliRun(queueKey, async () => {
			log.info(`cli exec: provider=${params.provider} model=${normalizedModel} promptChars=${params.prompt.length}`);
			const logOutputText = isTruthyEnvValue(process.env.SYMI_CLAUDE_CLI_LOG_OUTPUT);
			if (logOutputText) {
				const logArgs = [];
				for (let i = 0; i < args.length; i += 1) {
					const arg = args[i] ?? "";
					if (arg === backend.systemPromptArg) {
						const systemPromptValue = args[i + 1] ?? "";
						logArgs.push(arg, `<systemPrompt:${systemPromptValue.length} chars>`);
						i += 1;
						continue;
					}
					if (arg === backend.sessionArg) {
						logArgs.push(arg, args[i + 1] ?? "");
						i += 1;
						continue;
					}
					if (arg === backend.modelArg) {
						logArgs.push(arg, args[i + 1] ?? "");
						i += 1;
						continue;
					}
					if (arg === backend.imageArg) {
						logArgs.push(arg, "<image>");
						i += 1;
						continue;
					}
					logArgs.push(arg);
				}
				if (argsPrompt) {
					const promptIndex = logArgs.indexOf(argsPrompt);
					if (promptIndex >= 0) logArgs[promptIndex] = `<prompt:${argsPrompt.length} chars>`;
				}
				log.info(`cli argv: ${backend.command} ${logArgs.join(" ")}`);
			}
			const env = (() => {
				const next = {
					...process.env,
					...backend.env
				};
				for (const key of backend.clearEnv ?? []) delete next[key];
				return next;
			})();
			const noOutputTimeoutMs = resolveCliNoOutputTimeoutMs({
				backend,
				timeoutMs: params.timeoutMs,
				useResume
			});
			const supervisor = getProcessSupervisor();
			const scopeKey = buildCliSupervisorScopeKey({
				backend,
				backendId: backendResolved.id,
				cliSessionId: useResume ? cliSessionIdToSend : void 0
			});
			const managedRun = await supervisor.spawn({
				sessionId: params.sessionId,
				backendId: backendResolved.id,
				scopeKey,
				replaceExistingScope: Boolean(useResume && scopeKey),
				mode: "child",
				argv: [backend.command, ...args],
				timeoutMs: params.timeoutMs,
				noOutputTimeoutMs,
				cwd: workspaceDir,
				env,
				input: stdinPayload
			});
			const result = await managedRun.wait();
			const stdout = result.stdout.trim();
			const stderr = result.stderr.trim();
			if (logOutputText) {
				if (stdout) log.info(`cli stdout:\n${stdout}`);
				if (stderr) log.info(`cli stderr:\n${stderr}`);
			}
			if (shouldLogVerbose()) {
				if (stdout) log.debug(`cli stdout:\n${stdout}`);
				if (stderr) log.debug(`cli stderr:\n${stderr}`);
			}
			if (result.exitCode !== 0 || result.reason !== "exit") {
				if (result.reason === "no-output-timeout" || result.noOutputTimedOut) {
					const timeoutReason = `CLI produced no output for ${Math.round(noOutputTimeoutMs / 1e3)}s and was terminated.`;
					log.warn(`cli watchdog timeout: provider=${params.provider} model=${modelId} session=${cliSessionIdToSend ?? params.sessionId} noOutputTimeoutMs=${noOutputTimeoutMs} pid=${managedRun.pid ?? "unknown"}`);
					throw new FailoverError(timeoutReason, {
						reason: "timeout",
						provider: params.provider,
						model: modelId,
						status: resolveFailoverStatus("timeout")
					});
				}
				if (result.reason === "overall-timeout") throw new FailoverError(`CLI exceeded timeout (${Math.round(params.timeoutMs / 1e3)}s) and was terminated.`, {
					reason: "timeout",
					provider: params.provider,
					model: modelId,
					status: resolveFailoverStatus("timeout")
				});
				const err = stderr || stdout || "CLI failed.";
				const reason = classifyFailoverReason(err) ?? "unknown";
				const status = resolveFailoverStatus(reason);
				throw new FailoverError(err, {
					reason,
					provider: params.provider,
					model: modelId,
					status
				});
			}
			const outputMode = useResume ? backend.resumeOutput ?? backend.output : backend.output;
			if (outputMode === "text") return {
				text: stdout,
				sessionId: void 0
			};
			if (outputMode === "jsonl") return parseCliJsonl(stdout, backend) ?? { text: stdout };
			return parseCliJson(stdout, backend) ?? { text: stdout };
		});
		const text = output.text?.trim();
		return {
			payloads: text ? [{ text }] : void 0,
			meta: {
				durationMs: Date.now() - started,
				agentMeta: {
					sessionId: output.sessionId ?? sessionIdSent ?? params.sessionId ?? "",
					provider: params.provider,
					model: modelId,
					usage: output.usage
				}
			}
		};
	} catch (err) {
		if (err instanceof FailoverError) throw err;
		const message = err instanceof Error ? err.message : String(err);
		if (isFailoverErrorMessage(message)) {
			const reason = classifyFailoverReason(message) ?? "unknown";
			const status = resolveFailoverStatus(reason);
			throw new FailoverError(message, {
				reason,
				provider: params.provider,
				model: modelId,
				status
			});
		}
		throw err;
	} finally {
		if (cleanupImages) await cleanupImages();
	}
}

//#endregion
//#region src/agents/cli-session.ts
function getCliSessionId(entry, provider) {
	if (!entry) return;
	const normalized = normalizeProviderId(provider);
	const fromMap = entry.cliSessionIds?.[normalized];
	if (fromMap?.trim()) return fromMap.trim();
	if (normalized === "claude-cli") {
		const legacy = entry.claudeCliSessionId?.trim();
		if (legacy) return legacy;
	}
}
function setCliSessionId(entry, provider, sessionId) {
	const normalized = normalizeProviderId(provider);
	const trimmed = sessionId.trim();
	if (!trimmed) return;
	entry.cliSessionIds = { ...entry.cliSessionIds ?? {} };
	entry.cliSessionIds[normalized] = trimmed;
	if (normalized === "claude-cli") entry.claudeCliSessionId = trimmed;
}

//#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,
			agentId: opts.agentId ?? (opts.sessionKey ? resolveSessionAgentId({
				sessionKey: opts.sessionKey,
				config: cfg
			}) : void 0),
			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);
	if (!merged.currentChannelId && opts.to) {
		const trimmedTo = opts.to.trim();
		if (trimmedTo) merged.currentChannelId = trimmedTo;
	}
	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 promptTokens = result.meta.agentMeta?.promptTokens;
	const compactionsThisRun = Math.max(0, result.meta.agentMeta?.compactionCount ?? 0);
	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 entry = sessionStore[sessionKey] ?? {
		sessionId,
		updatedAt: Date.now()
	};
	const next = {
		...entry,
		sessionId,
		updatedAt: Date.now(),
		modelProvider: providerUsed,
		model: modelUsed,
		contextTokens
	};
	if (isCliProvider(providerUsed, cfg)) {
		const cliSessionId = result.meta.agentMeta?.sessionId?.trim();
		if (cliSessionId) setCliSessionId(next, providerUsed, cliSessionId);
	}
	next.abortedLastRun = result.meta.aborted ?? false;
	if (hasNonzeroUsage(usage)) {
		const input = usage.input ?? 0;
		const output = usage.output ?? 0;
		const totalTokens = deriveSessionTotalTokens({
			usage,
			contextTokens,
			promptTokens
		}) ?? input;
		next.inputTokens = input;
		next.outputTokens = output;
		next.totalTokens = totalTokens;
		next.totalTokensFresh = true;
		next.cacheRead = usage.cacheRead ?? 0;
		next.cacheWrite = usage.cacheWrite ?? 0;
	}
	if (compactionsThisRun > 0) next.compactionCount = (entry.compactionCount ?? 0) + compactionsThisRun;
	sessionStore[sessionKey] = next;
	await updateSessionStore(storePath, (store) => {
		store[sessionKey] = 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 agentSessionKey = resolveExplicitAgentSessionKey({
		cfg: opts.cfg,
		agentId: opts.agentId
	});
	const explicitSessionKey = opts.sessionKey?.trim() || (agentSessionKey && opts.sessionId?.trim() ? `${agentSessionKey}:${opts.sessionId.trim()}` : agentSessionKey);
	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;
	}
	if (opts.sessionId && !explicitSessionKey && (!sessionKey || sessionStore[sessionKey]?.sessionId !== opts.sessionId)) {
		const allAgentIds = listAgentIds(opts.cfg);
		for (const agentId of allAgentIds) {
			if (agentId === storeAgentId) continue;
			const altStorePath = resolveStorePath(sessionCfg?.store, { agentId });
			const altStore = loadSessionStore(altStorePath);
			const foundKey = Object.keys(altStore).find((key) => altStore[key]?.sessionId === opts.sessionId);
			if (foundKey) return {
				sessionKey: foundKey,
				sessionStore: altStore,
				storePath: altStorePath
			};
		}
	}
	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 persistSessionEntry(params) {
	params.sessionStore[params.sessionKey] = params.entry;
	await updateSessionStore(params.storePath, (store) => {
		store[params.sessionKey] = params.entry;
	});
}
function resolveFallbackRetryPrompt(params) {
	if (!params.isFallbackRetry) return params.body;
	return "Continue where you left off. The previous model attempt failed or timed out.";
}
async function runAgentAttempt(params) {
	const effectivePrompt = resolveFallbackRetryPrompt({
		body: params.body,
		isFallbackRetry: params.isFallbackRetry
	});
	if (isCliProvider(params.providerOverride, params.cfg)) {
		const cliSessionId = getCliSessionId(params.sessionEntry, params.providerOverride);
		return runCliAgent({
			sessionId: params.sessionId,
			sessionKey: params.sessionKey,
			agentId: params.sessionAgentId,
			sessionFile: params.sessionFile,
			workspaceDir: params.workspaceDir,
			config: params.cfg,
			prompt: effectivePrompt,
			provider: params.providerOverride,
			model: params.modelOverride,
			thinkLevel: params.resolvedThinkLevel,
			timeoutMs: params.timeoutMs,
			runId: params.runId,
			extraSystemPrompt: params.opts.extraSystemPrompt,
			cliSessionId,
			images: params.isFallbackRetry ? void 0 : params.opts.images,
			streamParams: params.opts.streamParams
		});
	}
	const authProfileId = params.providerOverride === params.primaryProvider ? params.sessionEntry?.authProfileOverride : void 0;
	return (await runAgentTurn({
		sessionId: params.sessionId,
		sessionKey: params.sessionKey ?? params.sessionId,
		agentId: params.sessionAgentId,
		runId: params.runId,
		workspaceDir: params.workspaceDir,
		agentDir: params.agentDir,
		config: params.cfg,
		skillsSnapshot: params.skillsSnapshot,
		prompt: effectivePrompt,
		images: params.isFallbackRetry ? void 0 : params.opts.images,
		clientTools: params.opts.clientTools,
		extraSystemPrompt: params.opts.extraSystemPrompt,
		provider: params.providerOverride,
		modelId: params.modelOverride,
		authProfileId,
		authProfileIdSource: authProfileId ? params.sessionEntry?.authProfileOverrideSource : void 0,
		thinkLevel: params.resolvedThinkLevel,
		timeoutMs: params.timeoutMs,
		abortSignal: params.opts.abortSignal,
		channel: {
			messageChannel: params.messageChannel,
			messageProvider: void 0,
			agentAccountId: params.runContext.accountId,
			messageTo: params.opts.replyTo ?? params.opts.to,
			messageThreadId: params.opts.threadId,
			groupId: params.runContext.groupId,
			groupChannel: params.runContext.groupChannel,
			groupSpace: params.runContext.groupSpace,
			spawnedBy: params.spawnedBy,
			senderIsOwner: true,
			currentChannelId: params.runContext.currentChannelId,
			currentThreadTs: params.runContext.currentThreadTs,
			replyToMode: params.runContext.replyToMode,
			hasRepliedRef: params.runContext.hasRepliedRef
		},
		callbacks: { onAgentEvent: params.onAgentEvent }
	})).rawResult;
}
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("symi 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 isSubagentLane = (typeof opts.lane === "string" ? opts.lane.trim() : "") === String(AGENT_LANE_SUBAGENT);
	const timeoutSecondsRaw = opts.timeout !== void 0 ? Number.parseInt(String(opts.timeout), 10) : isSubagentLane ? 0 : void 0;
	if (timeoutSecondsRaw !== void 0 && (Number.isNaN(timeoutSecondsRaw) || timeoutSecondsRaw < 0)) throw new Error("--timeout must be a non-negative integer (seconds; 0 means no timeout)");
	const primaryModelKey = typeof cfg?.agents?.defaults?.model === "object" ? cfg.agents.defaults.model.primary : void 0;
	const timeoutMs = resolveAgentTimeoutMs({
		cfg,
		overrideSeconds: timeoutSecondsRaw,
		modelTimeoutSeconds: (primaryModelKey ? cfg?.agents?.defaults?.models?.[primaryModelKey]?.timeoutSeconds : void 0) ?? null
	});
	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
			};
			await persistSessionEntry({
				sessionStore,
				sessionKey,
				storePath,
				entry: next
			});
			sessionEntry = next;
		}
		if (sessionStore && sessionKey) {
			const next = {
				...sessionStore[sessionKey] ?? sessionEntry ?? {
					sessionId,
					updatedAt: Date.now()
				},
				sessionId,
				updatedAt: Date.now()
			};
			if (thinkOverride) next.thinkingLevel = thinkOverride;
			applyVerboseOverride(next, verboseOverride);
			await persistSessionEntry({
				sessionStore,
				sessionKey,
				storePath,
				entry: next
			});
			sessionEntry = next;
		}
		const agentModelPrimary = resolveAgentModelPrimary(cfg, sessionAgentId);
		const configuredDefaultRef = 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
		});
		const { provider: defaultProvider, model: defaultModel } = normalizeModelRef(configuredDefaultRef.provider, configuredDefaultRef.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 normalizedOverride = normalizeModelRef(overrideProvider, overrideModel);
				const key = modelKey(normalizedOverride.provider, normalizedOverride.model);
				if (!isCliProvider(normalizedOverride.provider, cfg) && allowedModelKeys.size > 0 && !allowedModelKeys.has(key)) {
					const { updated } = applyModelOverrideToSessionEntry({
						entry,
						selection: {
							provider: defaultProvider,
							model: defaultModel,
							isDefault: true
						}
					});
					if (updated) await persistSessionEntry({
						sessionStore,
						sessionKey,
						storePath,
						entry
					});
				}
			}
		}
		const storedProviderOverride = sessionEntry?.providerOverride?.trim();
		const storedModelOverride = sessionEntry?.modelOverride?.trim();
		if (storedModelOverride) {
			const normalizedStored = normalizeModelRef(storedProviderOverride || defaultProvider, storedModelOverride);
			const key = modelKey(normalizedStored.provider, normalizedStored.model);
			if (isCliProvider(normalizedStored.provider, cfg) || allowedModelKeys.size === 0 || allowedModelKeys.has(key)) {
				provider = normalizedStored.provider;
				model = normalizedStored.model;
			}
		}
		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();
				await persistSessionEntry({
					sessionStore,
					sessionKey,
					storePath,
					entry
				});
			}
		}
		let sessionFile = resolveSessionFilePath(sessionId, sessionEntry, { agentId: sessionAgentId });
		if (sessionStore && sessionKey) {
			const threadIdFromSessionKey = parseSessionThreadInfo(sessionKey).threadId;
			const fallbackSessionFile = !sessionEntry?.sessionFile ? resolveSessionTranscriptPath(sessionId, sessionAgentId, opts.threadId ?? threadIdFromSessionKey) : void 0;
			const resolvedSessionFile = await resolveAndPersistSessionFile({
				sessionId,
				sessionKey,
				sessionStore,
				storePath,
				sessionEntry,
				agentId: sessionAgentId,
				sessionsDir: path.dirname(storePath),
				fallbackSessionFile
			});
			sessionFile = resolvedSessionFile.sessionFile;
			sessionEntry = resolvedSessionFile.sessionEntry;
		}
		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 effectiveFallbacksOverride = resolveEffectiveModelFallbacks({
				cfg,
				agentId: sessionAgentId,
				hasSessionModelOverride: Boolean(storedModelOverride)
			});
			let fallbackAttemptIndex = 0;
			const fallbackResult = await runWithModelFallback({
				cfg,
				provider,
				model,
				agentDir,
				fallbacksOverride: effectiveFallbacksOverride,
				run: (providerOverride, modelOverride) => {
					const isFallbackRetry = fallbackAttemptIndex > 0;
					fallbackAttemptIndex += 1;
					return runAgentAttempt({
						providerOverride,
						modelOverride,
						cfg,
						sessionEntry,
						sessionId,
						sessionKey,
						sessionAgentId,
						sessionFile,
						workspaceDir,
						body,
						isFallbackRetry,
						resolvedThinkLevel,
						timeoutMs,
						runId,
						opts,
						runContext,
						spawnedBy,
						messageChannel,
						skillsSnapshot,
						resolvedVerboseLevel,
						agentDir,
						primaryProvider: provider,
						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 ?? [];
		return await deliverAgentCommandResult({
			cfg,
			deps,
			runtime,
			opts,
			sessionEntry,
			result,
			payloads
		});
	} finally {
		clearAgentRunContext(runId);
	}
}

//#endregion
export { getCliSessionId as a, resolveAgentOutboundTarget as i, resolveSessionKeyForRequest as n, setCliSessionId as o, resolveAgentDeliveryPlan as r, runCliAgent as s, agentCommand as t };