UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

300 lines (299 loc) 14.1 kB
import { g as readStringValue, l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js"; import { n as normalizeAgentId } from "./agent-id-CeT3w4ap.js"; import { O as parseAgentSessionKey } from "./session-key-BnWWjqNc.js"; import { t as ErrorCodes } from "./gateway-error-details-w0nAGBBp.js"; import { Lr as validateSessionsAbortParams } from "./src-BiL5aQto.js"; import { d as errorShape } from "./error-codes-Bo8q2D1o.js"; import { a as resolveStoredSessionKeyForAgentStore, i as resolveSessionStoreKey, n as resolveSessionStoreAgentId, o as resolveStoredSessionOwnerAgentId } from "./session-store-key-8xEjWSNi.js"; import { l as resolveExistingAgentSessionStoreTargetsSync, t as isConfiguredSessionStoreAgentId } from "./targets-Cknmo7YZ.js"; import { C as resolveActiveEmbeddedRunOwnerByRunId, n as abortEmbeddedAgentRun } from "./runs-Cb42qain.js"; import "./sessions-9nxpeTwt.js"; import { i as tryResolveSessionCompatibilityOwnerAgentId, n as resolveRequestedSessionAgentId } from "./session-request-agent-CCRSEGCB.js"; import { r as loadGatewaySessionEntry } from "./session-utils-store-CInT2loy.js"; import "./session-utils-Cai0_C6U.js"; import { t as clearSessionQueues } from "./cleanup-DKkilV3a.js"; import { r as resolveChatRunOwnerAgentId } from "./chat-run-owner-DPtcuc7L.js"; import { t as assertValidParams } from "./validation-pzrlzFvo.js"; import { a as descendantAbortError, f as resolveChatAbortRequester, n as abortControlledSubagents, r as abortQueuedCollectorSession } from "./chat-abort-runtime-CKI3fkKr.js"; import { n as setGatewayDedupeEntry } from "./chat-abort-ops-zvMvu0-3.js"; import { n as emitSessionsChanged } from "./session-change-event-DzmH4zlz.js"; import { t as asWorkerInferenceControl } from "./inference-control-CDvM08Nt.js"; import { n as resolveSessionKeyForRun } from "./server-session-key-CesREwK4.js"; import { s as requireSessionKey } from "./sessions-shared-D_lV07q2.js"; import { n as handleChatAbortRequestWithLifecycle } from "./chat-abort-handler-Cs4t_nYG.js"; import { t as resolveWorkerSessionTarget } from "./session-target-BDNR3YFZ.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, sessionMutationAuthorization }) => { 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) { let aborted = false; const descendants = await abortControlledSubagents({ cfg, sessionKey: embeddedRun.sessionKey ?? canonicalKey, agentId: targetAgentId, requesterTurnRunId: embeddedRun.runId, beforeKill: () => aborted = embeddedRun.abort() }); const error = descendantAbortError(descendants, "Parent run"); if (error) respond(false, void 0, error); else 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; const queuedAbort = abortQueuedCollectorSession({ context, sessionKey: canonicalKey, sessionKeyAliases: [key, ...requestedKeyAliases ?? []], agentId: targetAgentId, sessionId: persistedSessionId, session: loadedSession ? { ok: true, value: loadedSession } : void 0, defaultAgentId: stableTargetOwner, runId: requestedRunId, abortOrigin: "rpc", stopReason: "rpc", requester: resolveChatAbortRequester(client), assertCurrent: sessionMutationAuthorization?.assertCurrent, onAuthorizedAfterQueuedAbort }); if (queuedAbort) { const result = await queuedAbort; if (!result.ok) respond(false, void 0, result.error); else respond(true, { ok: true, abortedRunId: result.value.runIds[0] ?? null, status: result.value.aborted ? "aborted" : "no-active-run" }, void 0, void 0); return; } 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 };