import { g as readStringValue, l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js";
import { n as normalizeAgentId } from "./agent-id-CeT3w4ap.js";
import { c as parseAgentSessionKey } from "./session-key-utils-dXMHZk48.js";
import { t as ErrorCodes } from "./gateway-error-details-16gBJ-B1.js";
import { br as validateSessionsAbortParams } from "./src-CwDR-7yt.js";
import { a as resolveStoredSessionOwnerAgentId, i as resolveStoredSessionKeyForAgentStore, n as resolveSessionStoreAgentId, r as resolveSessionStoreKey } from "./session-store-key-CNP8gvID.js";
import { c as resolveExistingAgentSessionStoreTargetsSync, t as isConfiguredSessionStoreAgentId } from "./targets-UQqmco4C.js";
import "./sessions-DXJlwlTq.js";
import { d as errorShape } from "./error-codes-DEczInWy.js";
import { S as resolveActiveEmbeddedRunOwnerByRunId, n as abortEmbeddedAgentRun } from "./runs-DkiZS9mO.js";
import { i as tryResolveSessionCompatibilityOwnerAgentId, n as resolveRequestedSessionAgentId } from "./session-request-agent-D346KCgp.js";
import { r as loadGatewaySessionEntry } from "./session-utils-store-J_Y_NxYs.js";
import "./session-utils-DozBEUg6.js";
import { t as clearSessionQueues } from "./cleanup-CBdLrNVP.js";
import { r as resolveChatRunOwnerAgentId } from "./chat-run-owner-51GDFIgz.js";
import { t as assertValidParams } from "./validation-1fbJ5g3d.js";
import { t as setGatewayDedupeEntry } from "./agent-job-BuCBrAC5.js";
import { n as emitSessionsChanged } from "./session-change-event-cxPRDvOt.js";
import { t as asWorkerInferenceControl } from "./inference-control-CDvM08Nt.js";
import { n as resolveSessionKeyForRun } from "./server-session-key-CQJEkPY_.js";
import { s as requireSessionKey } from "./sessions-shared-DB--c8h8.js";
import { n as handleChatAbortRequestWithLifecycle } from "./chat-abort-handler-C1ik1IBY.js";
import { t as resolveWorkerSessionTarget } from "./session-target-CbVs5Jrp.js";
//#region src/gateway/server-methods/sessions-abort.ts
function resolveAbortSessionKey(params) {
	if (params.activeRunSessionKey) return params.activeRunSessionKey;
	const candidates = [
		params.canonicalKey,
		params.requestedKey,
		...params.aliasKeys ?? []
	];
	for (const active of params.context.chatAbortControllers.values()) {
		if (active.controlUiVisible === false) continue;
		for (const candidate of candidates) if (active.sessionKey === candidate) {
			const owner = resolveChatRunOwnerAgentId({
				agentId: active.agentId,
				sessionKey: active.sessionKey,
				defaultAgentId: params.defaultAgentId
			});
			if (!params.agentId || owner === normalizeAgentId(params.agentId)) return candidate;
		}
	}
	return params.requestedKey;
}
function resolveSessionKeyAgentId(sessionKey, cfg) {
	const key = normalizeOptionalString(sessionKey);
	if (!key) return;
	if (!parseAgentSessionKey(key) && key.toLowerCase().startsWith("agent:")) return;
	return parseAgentSessionKey(key)?.agentId ?? tryResolveSessionCompatibilityOwnerAgentId(cfg, key);
}
function sessionKeyBelongsToAgent(sessionKey, agentId, cfg) {
	return resolveSessionKeyAgentId(sessionKey, cfg) === normalizeAgentId(agentId);
}
function resolveScopedAbortKey(params) {
	const key = normalizeOptionalString(params.key);
	if (!key) return;
	const requestedAgentId = normalizeOptionalString(params.agentId);
	if (!requestedAgentId) return key;
	const scopedAgentId = normalizeAgentId(requestedAgentId);
	const ownerAgentId = resolveStoredSessionOwnerAgentId({
		cfg: params.cfg,
		agentId: scopedAgentId,
		sessionKey: key
	});
	if (ownerAgentId && ownerAgentId !== scopedAgentId) return;
	return resolveStoredSessionKeyForAgentStore({
		cfg: params.cfg,
		agentId: scopedAgentId,
		sessionKey: key
	});
}
const sessionAbortHandlers = { "sessions.abort": async ({ req, params, respond, context, client, isWebchatConnect }) => {
	if (!assertValidParams(params, validateSessionsAbortParams, "sessions.abort", respond)) return;
	const p = params;
	const cfg = context.getRuntimeConfig();
	const requestedRunId = readStringValue(p.runId);
	const requestedKey = normalizeOptionalString(p.key);
	const requestedParamAgentId = normalizeOptionalString(p.agentId);
	const clearQueued = p.clearQueued === true;
	const workerRunSessionId = requestedRunId ? asWorkerInferenceControl(context.workerEnvironmentService)?.resolveInferenceSessionForRunId(requestedRunId) : void 0;
	const workerRunTarget = workerRunSessionId ? resolveWorkerSessionTarget(cfg, workerRunSessionId) : void 0;
	const embeddedRun = requestedRunId ? resolveActiveEmbeddedRunOwnerByRunId(requestedRunId) : void 0;
	const embeddedRunSessionKey = embeddedRun?.sessionKey;
	const scopedRequestedKey = resolveScopedAbortKey({
		cfg,
		key: requestedKey,
		agentId: requestedParamAgentId
	});
	if (requestedKey && requestedParamAgentId && !scopedRequestedKey) {
		respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "session key agent does not match agentId"));
		return;
	}
	const requestedKeyAgentId = scopedRequestedKey ? resolveSessionKeyAgentId(scopedRequestedKey, cfg) : void 0;
	const activeRun = requestedRunId ? context.chatAbortControllers.get(requestedRunId) : void 0;
	const activeRunSessionKey = activeRun?.sessionKey;
	const activeRunAgentId = normalizeOptionalString(activeRun?.agentId);
	let inferredRunAgentId = requestedParamAgentId ?? activeRunAgentId ?? requestedKeyAgentId ?? workerRunTarget?.agentId ?? resolveSessionKeyAgentId(activeRunSessionKey, cfg) ?? resolveSessionKeyAgentId(embeddedRunSessionKey, cfg);
	if (requestedRunId && !inferredRunAgentId) {
		const runOwner = resolveRequestedSessionAgentId(cfg, scopedRequestedKey ?? activeRunSessionKey ?? workerRunTarget?.sessionKey ?? "main");
		if (!runOwner.ok) {
			respond(false, void 0, runOwner.error);
			return;
		}
		inferredRunAgentId = runOwner.agentId;
	}
	const requestedRunAgentId = requestedRunId ? inferredRunAgentId ? normalizeAgentId(inferredRunAgentId) : void 0 : void 0;
	const scopedActiveRunSessionKey = activeRunSessionKey ? requestedRunAgentId ? sessionKeyBelongsToAgent(activeRunSessionKey, requestedRunAgentId, cfg) ? activeRunSessionKey : void 0 : activeRunSessionKey : void 0;
	const keyCandidate = scopedRequestedKey ?? scopedActiveRunSessionKey ?? (requestedRunId ? resolveSessionKeyForRun(requestedRunId, requestedRunAgentId ? { agentId: requestedRunAgentId } : void 0) : void 0) ?? workerRunTarget?.sessionKey ?? embeddedRunSessionKey;
	if (!keyCandidate && requestedRunId) {
		respond(true, {
			ok: true,
			abortedRunId: null,
			status: "no-active-run"
		});
		return;
	}
	const key = requireSessionKey(keyCandidate, respond);
	if (!key) return;
	const requestedGlobalAgent = resolveRequestedSessionAgentId(cfg, key, requestedParamAgentId ?? requestedRunAgentId);
	if (!requestedGlobalAgent.ok) {
		respond(false, void 0, requestedGlobalAgent.error);
		return;
	}
	const requestedGlobalAgentId = requestedGlobalAgent.agentId;
	const targetAgentId = requestedGlobalAgentId ?? resolveSessionStoreAgentId(cfg, resolveSessionStoreKey({
		cfg,
		sessionKey: key
	}));
	const configuredTarget = isConfiguredSessionStoreAgentId(cfg, targetAgentId);
	const existingTargets = configuredTarget ? [] : resolveExistingAgentSessionStoreTargetsSync(cfg, targetAgentId);
	const stableTargetOwner = tryResolveSessionCompatibilityOwnerAgentId(cfg, key);
	const hasExactActiveRun = requestedRunId ? scopedActiveRunSessionKey === key && resolveChatRunOwnerAgentId({
		agentId: activeRunAgentId,
		sessionKey: activeRunSessionKey,
		defaultAgentId: stableTargetOwner
	}) === normalizeAgentId(targetAgentId) || embeddedRun !== void 0 && resolveSessionKeyAgentId(embeddedRunSessionKey, cfg) === normalizeAgentId(targetAgentId) : [...context.chatAbortControllers.values()].some((entry) => entry.controlUiVisible !== false && entry.sessionKey === key && resolveChatRunOwnerAgentId({
		agentId: entry.agentId,
		sessionKey: entry.sessionKey,
		defaultAgentId: stableTargetOwner
	}) === normalizeAgentId(targetAgentId));
	if (!configuredTarget && existingTargets.length === 0 && !hasExactActiveRun) {
		respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, `agent "${targetAgentId}" not found`));
		return;
	}
	const loadedSession = configuredTarget || existingTargets.length > 0 ? loadGatewaySessionEntry(key, { agentId: requestedGlobalAgentId }) : void 0;
	const canonicalKey = loadedSession?.canonicalKey ?? resolveSessionStoreKey({
		cfg,
		sessionKey: key,
		...requestedGlobalAgentId ? { storeAgentId: requestedGlobalAgentId } : {}
	});
	const sessionEntry = loadedSession?.entry;
	const embeddedRunMatchesSession = Boolean(embeddedRun && resolveSessionKeyAgentId(embeddedRun.sessionKey, cfg) === normalizeAgentId(targetAgentId) && (embeddedRun.sessionKey === key || embeddedRun.sessionKey === canonicalKey || sessionEntry?.sessionId === embeddedRun.sessionId));
	if (embeddedRun && !embeddedRunMatchesSession) {
		respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "runId does not match session"));
		return;
	}
	const requestedKeyAliases = requestedKey && requestedKey !== key && (!requestedParamAgentId || sessionKeyBelongsToAgent(requestedKey, requestedParamAgentId, cfg)) ? [requestedKey] : void 0;
	const resolvedAbortSessionKey = resolveAbortSessionKey({
		context,
		requestedKey: key,
		canonicalKey,
		activeRunSessionKey: scopedActiveRunSessionKey,
		aliasKeys: requestedKeyAliases,
		agentId: requestedGlobalAgentId,
		defaultAgentId: stableTargetOwner
	});
	const abortSessionKey = canonicalKey === "global" && requestedGlobalAgentId ? "global" : resolvedAbortSessionKey;
	const abortAgentId = requestedGlobalAgentId ?? activeRunAgentId;
	if (embeddedRun && !activeRun) {
		const aborted = embeddedRun.abort();
		respond(true, {
			ok: true,
			abortedRunId: aborted ? embeddedRun.runId : null,
			status: aborted ? "aborted" : "no-active-run"
		});
		if (aborted) emitSessionsChanged(context, {
			sessionKey: canonicalKey,
			...abortAgentId ? { agentId: abortAgentId } : {},
			reason: "abort"
		});
		return;
	}
	const preAbortRunKinds = /* @__PURE__ */ new Map();
	if (requestedRunId) preAbortRunKinds.set(requestedRunId, activeRun?.kind);
	else for (const [rid, entry] of context.chatAbortControllers) preAbortRunKinds.set(rid, entry.kind);
	let abortedRunId = null;
	let aborted = false;
	let chatAbortSucceeded = false;
	let responseMeta;
	const persistedSessionId = sessionEntry?.sessionId;
	const onAuthorizedAfterQueuedAbort = !requestedRunId && canonicalKey !== "global" && (clearQueued || persistedSessionId) ? () => {
		let queueCleared = false;
		if (clearQueued) {
			const cleared = clearSessionQueues([
				key,
				...requestedKeyAliases ?? [],
				canonicalKey,
				...persistedSessionId ? [persistedSessionId] : []
			]);
			queueCleared = cleared.followupCleared > 0 || cleared.laneCleared > 0;
		}
		return (persistedSessionId ? abortEmbeddedAgentRun(persistedSessionId) : false) || queueCleared;
	} : void 0;
	await handleChatAbortRequestWithLifecycle({
		req,
		params: {
			sessionKey: abortSessionKey,
			runId: requestedRunId,
			...abortAgentId ? { agentId: abortAgentId } : {}
		},
		respond: (ok, payload, error, meta) => {
			if (!ok) {
				respond(ok, payload, error, meta);
				return;
			}
			chatAbortSucceeded = true;
			responseMeta = meta;
			const firstAbortedRunId = (payload && typeof payload === "object" && Array.isArray(payload.runIds) ? payload.runIds.filter((value) => Boolean(normalizeOptionalString(value))) : [])[0] ?? null;
			abortedRunId = firstAbortedRunId;
			aborted = firstAbortedRunId !== null || payload !== null && typeof payload === "object" && payload.aborted === true;
			if (firstAbortedRunId && !Boolean(workerRunSessionId && !activeRun)) {
				const endedAt = Date.now();
				const dedupePrefix = preAbortRunKinds.get(firstAbortedRunId) === "agent" ? "agent" : "chat";
				setGatewayDedupeEntry({
					dedupe: context.dedupe,
					key: `${dedupePrefix}:${firstAbortedRunId}`,
					entry: {
						ts: endedAt,
						ok: true,
						payload: {
							status: "timeout",
							runId: firstAbortedRunId,
							...abortAgentId ? { agentId: abortAgentId } : {},
							stopReason: "rpc",
							endedAt
						}
					}
				});
			}
		},
		context,
		client,
		isWebchatConnect
	}, {
		...onAuthorizedAfterQueuedAbort ? { onAuthorizedAfterQueuedAbort } : {},
		...!requestedRunId ? { cascadeDescendants: true } : {}
	});
	if (!chatAbortSucceeded) return;
	respond(true, {
		ok: true,
		abortedRunId,
		status: aborted ? "aborted" : "no-active-run"
	}, void 0, responseMeta);
	if (aborted) emitSessionsChanged(context, {
		sessionKey: canonicalKey,
		...abortAgentId ? { agentId: abortAgentId } : {},
		reason: "abort"
	});
} };
//#endregion
export { sessionAbortHandlers as n, resolveAbortSessionKey as t };
