UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

209 lines (208 loc) 7.74 kB
import "./src-vebZIeLe.js"; import { t as expectDefined } from "./expect-CyE8FADM.js"; import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js"; import { O as parseAgentSessionKey } from "./session-key-BnWWjqNc.js"; import { t as ErrorCodes } from "./gateway-error-details-w0nAGBBp.js"; import { Li as validateSessionsSendParams } from "./src-BiL5aQto.js"; import { d as errorShape } from "./error-codes-Bo8q2D1o.js"; import "./sessions-9nxpeTwt.js"; import { f as resolveSessionWorkStartError } from "./lifecycle-BaroCBMc.js"; import { g as terminateAcceptedCollectorRun } from "./subagent-announce-output-Cy2Rx3_K.js"; import { n as resolveRequestedSessionAgentId } from "./session-request-agent-CCRSEGCB.js"; import { i as loadGatewaySessionEntryReadOnly, l as resolveDeletedAgentIdFromSessionKey, r as loadGatewaySessionEntry } from "./session-utils-store-CInT2loy.js"; import "./session-utils-Cai0_C6U.js"; import { n as handleDirectExternalChatSend, t as chatHandlers } from "./chat-IsrqkYID.js"; import { t as assertValidParams } from "./validation-pzrlzFvo.js"; import { n as emitSessionsChanged } from "./session-change-event-DzmH4zlz.js"; import { t as reactivateCompletedSubagentSession } from "./session-subagent-reactivation-D4NwQBzD.js"; import { n as isAgentMainSessionKey, s as requireSessionKey } from "./sessions-shared-D_lV07q2.js"; import { n as isFreshChatSendStarted, t as sessionCreateHandlers } from "./sessions-create-BSGvT-wJ.js"; import { randomUUID } from "node:crypto"; //#region src/gateway/server-methods/sessions-messaging.ts async function createAgentMainSessionForSend(params) { const agentId = parseAgentSessionKey(params.canonicalKey)?.agentId; if (!agentId) return { ok: false, error: errorShape(ErrorCodes.INVALID_REQUEST, `session not found: ${params.canonicalKey}`) }; let createResult; await expectDefined(sessionCreateHandlers["sessions.create"], "sessions.create handler")({ req: params.req, params: { key: params.canonicalKey, agentId }, respond: (ok, payload, error) => { createResult = { ok, payload: payload && typeof payload === "object" ? payload : void 0, error }; }, context: params.context, client: params.client, isWebchatConnect: params.isWebchatConnect }); if (!createResult) return { ok: false, error: errorShape(ErrorCodes.UNAVAILABLE, "sessions.create did not respond") }; if (!createResult.ok) return { ok: false, error: createResult.error ?? errorShape(ErrorCodes.UNAVAILABLE, "failed to create session") }; const createdKey = normalizeOptionalString(createResult.payload?.key) ?? params.canonicalKey; const loaded = loadGatewaySessionEntryReadOnly(createdKey, { agentId }); if (!loaded.entry?.sessionId) return { ok: false, error: errorShape(ErrorCodes.UNAVAILABLE, `session not created: ${createdKey}`) }; return { ok: true, entry: loaded.entry, canonicalKey: loaded.canonicalKey }; } async function handleSessionSend(params) { if (!assertValidParams(params.params, validateSessionsSendParams, params.method, params.respond)) return; const p = params.params; const key = requireSessionKey(p.key, params.respond); if (!key) return; const cfg = params.context.getRuntimeConfig(); const requestedAgent = resolveRequestedSessionAgentId(cfg, key, p.agentId); if (!requestedAgent.ok) { params.respond(false, void 0, requestedAgent.error); return; } const requestedAgentId = requestedAgent.agentId; const loaded = loadGatewaySessionEntry(key, { agentId: requestedAgentId }); const { legacyKey } = loaded; let { entry, canonicalKey } = loaded; const deletedAgentId = resolveDeletedAgentIdFromSessionKey(cfg, canonicalKey, entry, { acpMetadataSessionKey: legacyKey ?? canonicalKey }); if (deletedAgentId !== null) { params.respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, `Agent "${deletedAgentId}" no longer exists in configuration`)); return; } const rawIdempotencyKey = p.idempotencyKey; const explicitIdempotencyKey = typeof rawIdempotencyKey === "string" && rawIdempotencyKey.trim() ? rawIdempotencyKey.trim() : void 0; const idempotencyKey = explicitIdempotencyKey ?? randomUUID(); const respond = params.respond; const dispatchChatSend = async (dispatchRespond) => { const options = { req: params.req, params: { sessionKey: canonicalKey, ...requestedAgentId ? { agentId: requestedAgentId } : {}, message: p.message, ...p.mentions ? { mentions: p.mentions } : {}, thinking: p.thinking, attachments: p.attachments, timeoutMs: p.timeoutMs, idempotencyKey, ...params.queueMode ? { queueMode: params.queueMode } : {} }, respond: dispatchRespond, context: params.context, client: params.client, isWebchatConnect: params.isWebchatConnect }; if (params.queueMode === "interrupt") { await handleDirectExternalChatSend(options); return; } await expectDefined(chatHandlers["chat.send"], "chat.send handler")(options); }; const archivedSessionError = resolveSessionWorkStartError(canonicalKey, entry, { allowPendingWorkspace: true }); if (archivedSessionError) { if (explicitIdempotencyKey) { await dispatchChatSend(respond); return; } respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, archivedSessionError)); return; } if (!entry?.sessionId && params.queueMode !== "interrupt" && isAgentMainSessionKey(cfg, canonicalKey)) { const created = await createAgentMainSessionForSend({ req: params.req, canonicalKey, context: params.context, client: params.client, isWebchatConnect: params.isWebchatConnect }); if (!created.ok) { respond(false, void 0, created.error); return; } entry = created.entry; canonicalKey = created.canonicalKey; } if (!entry?.sessionId) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, `session not found: ${key}`)); return; } let sendAcked = false; let sendPayload; let sendCached = false; let startedRunId; let interruptedActiveRun = false; await dispatchChatSend((ok, payload, error, meta) => { sendAcked = ok; sendPayload = payload; sendCached = meta?.cached === true; startedRunId = payload && typeof payload === "object" && typeof payload.runId === "string" ? payload.runId : void 0; interruptedActiveRun = ok && payload !== null && typeof payload === "object" && "interruptedActiveRun" in payload && payload.interruptedActiveRun === true; respond(ok, payload, error, meta); }); if (sendAcked) { if (isFreshChatSendStarted({ payload: sendPayload, cached: sendCached })) try { await reactivateCompletedSubagentSession({ sessionKey: canonicalKey, runId: startedRunId, task: p.message, gatewayContextResolver: params.context.resolveGatewayContext }); } catch (error) { if (startedRunId) await terminateAcceptedCollectorRun({ childSessionKey: canonicalKey, gatewayRunId: startedRunId, sessionCleanup: "preserve" }); throw error; } emitSessionsChanged(params.context, { sessionKey: canonicalKey, ...requestedAgentId ? { agentId: requestedAgentId } : {}, reason: interruptedActiveRun ? "steer" : "send" }); } } const sessionMessagingHandlers = { "sessions.send": async ({ req, params, respond, context, client, isWebchatConnect }) => { await handleSessionSend({ method: "sessions.send", req, params, respond, context, client, isWebchatConnect }); }, "sessions.steer": async ({ req, params, respond, context, client, isWebchatConnect }) => { await handleSessionSend({ method: "sessions.steer", req, params, respond, context, client, isWebchatConnect, queueMode: "interrupt" }); } }; //#endregion export { sessionMessagingHandlers };