UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

244 lines (243 loc) • 9.81 kB
import { l as normalizeOptionalString } from "./string-coerce-1VuiLaaR.mjs"; import { r as jsonUtf8Bytes } from "./json-utf8-bytes-C0-PtdPX.mjs"; import { J as validateChatMessageGetParams, Q as validateChatToolTitlesParams, q as validateChatInjectParams } from "./src-D6kL8tMP.mjs"; import { r as getCliSessionBinding } from "./cli-session-binding-Dx1VbkI8.mjs"; import { t as ErrorCodes } from "./gateway-error-details-gTekQWj2.mjs"; import { d as errorShape } from "./error-codes-D0WRV4Bq.mjs"; import { r as CHAT_PENDING_INPUT_MESSAGE_PREFIX } from "./chat-history-constants-BGgHv5E_.mjs"; import { n as beginSessionWorkAdmission } from "./session-lifecycle-admission-B5CJ-emz.mjs"; import "./session-accessor-C3ljJ974.mjs"; import { a as MAX_PAYLOAD_BYTES } from "./server-constants-BH_EolwD.mjs"; import { r as readSessionPendingInput } from "./session-pending-input-history-DHrvjo_s.mjs"; import { r as resolveRequestedSessionAgentId } from "./session-request-agent-BWnhhVvT.mjs"; import { i as resolveSessionWorkStartError } from "./session-work-start-Bkld8CTK.mjs"; import "./sessions-CRUJeu5H.mjs"; import { r as resolveSessionModelRef } from "./session-model-ref-CS-wdkCn.mjs"; import { C as resolveEffectiveChatHistoryMaxChars, r as augmentChatHistoryWithCanvasBlocks } from "./chat-display-projection.canvas-BMMjLtjY.mjs"; import { t as resolveCurrentUserProfileDisplay } from "./current-user-profile-display-DwUynhPw.mjs"; import { u as prepareForwardedMessageCronJobNameResolver } from "./chat-display-projection.history-DcguyM30.mjs"; import { a as projectChatDisplayMessage } from "./chat-display-projection.core-BOF-lEvI.mjs"; import { i as withReadySessionRows } from "./session-row-prepared-read-BEDhe5gP.mjs"; import { r as loadGatewaySessionEntry } from "./session-utils-store-qn-zT-Fk.mjs"; import { r as projectOperatorModelRead } from "./operator-model-presentation-QCZKBgRU.mjs"; import "./session-utils-BLqrCe75.mjs"; import "./chat-display-projection-B_RuafB6.mjs"; import { t as readChatHistoryMessageById } from "./chat-history-pages-AnXqOtgh.mjs"; import { t as formatForLog } from "./ws-log-DmZrdpqI.mjs"; import { c as resolveGlobalAwareNodeChatDeliveryKeys, l as sendGlobalAwareNodeChatPayload } from "./chat-broadcast-C5jCvi-5.mjs"; import { t as appendInjectedAssistantMessageToTranscript } from "./chat-transcript-inject-CC_wJAPK.mjs"; import { t as assertValidParams } from "./validation-UW_NLjlV.mjs"; import { i as prepareChatHistorySessionRead, r as projectPendingInputMessage, t as chatHistoryHandlers } from "./chat-history-handler-DXDGiWoN.mjs"; //#region src/gateway/server-methods/chat-message-get-handler.ts const chatMessageGetHandlers = { "chat.message.get": async ({ params, respond, context, client, sessionMutationAuthorization, signal }) => { if (!assertValidParams(params, validateChatMessageGetParams, "chat.message.get", respond)) return; const { sessionKey, messageId, maxChars, sessionId: requestedSessionId } = params; const agentIdOverride = normalizeOptionalString(params.agentId); const selection = await prepareChatHistorySessionRead({ context, client, respond, sessionMutationAuthorization, signal, method: "chat.message.get", sessionKey, agentIdOverride, requestedSessionId }); if (!selection) return; try { const { selectedSession, entry, queries, readCurrentSharing, rowProjection } = selection; const { cfg, agentId: sessionAgentId, storePath, canonicalKey } = selectedSession; const sessionId = requestedSessionId ?? entry?.sessionId; const historyEntry = requestedSessionId && requestedSessionId !== entry?.sessionId ? void 0 : entry; const withCurrentSession = (consume) => withReadySessionRows(rowProjection, queries, (read) => { signal?.throwIfAborted(); return readCurrentSharing(read) ? consume() : void 0; }); const respondNotFound = () => respond(true, { ok: false, unavailableReason: "not_found" }); const respondMessage = (message, applyModelPolicy = false) => { if (!message) { respond(true, { ok: false, unavailableReason: "not_visible" }); return; } respond(true, jsonUtf8Bytes(message) > 26213376 ? { ok: false, unavailableReason: "oversized" } : applyModelPolicy ? projectOperatorModelRead({ context, client, agentId: sessionAgentId }, { ok: true, message }) : { ok: true, message }); }; if (!sessionId) { await withCurrentSession(respondNotFound); return; } const effectiveMaxChars = maxChars ?? Math.min(26214400, 1e6); if (messageId.startsWith("pending:")) { if (sessionId !== entry?.sessionId) { await withCurrentSession(respondNotFound); return; } const pending = await readSessionPendingInput({ agentId: sessionAgentId, sessionKey: canonicalKey, sessionId, storePath }, messageId.slice(CHAT_PENDING_INPUT_MESSAGE_PREFIX.length)); if (!await withCurrentSession(() => true)) return; if (!pending) { await withCurrentSession(respondNotFound); return; } const resolveCronJobName = await prepareForwardedMessageCronJobNameResolver([pending.message], context.cronStorePath); await withCurrentSession(() => { const message = projectPendingInputMessage(pending, effectiveMaxChars, void 0, resolveCronJobName); respondMessage(message); }); return; } const resolved = await readChatHistoryMessageById({ entry: historyEntry, provider: getCliSessionBinding(historyEntry, "claude-cli")?.sessionId ? resolveSessionModelRef(cfg, historyEntry, sessionAgentId, { allowPluginNormalization: false }).provider : void 0, sessionAgentId, sessionId, canonicalKey, storePath, messageId, max: 1, maxHistoryBytes: MAX_PAYLOAD_BYTES, effectiveMaxChars, offset: void 0 }); if (!await withCurrentSession(() => true)) return; if (!resolved.found) { await withCurrentSession(respondNotFound); return; } if (resolved.oversized) { await withCurrentSession(() => respond(true, { ok: false, unavailableReason: "oversized" })); return; } const resolveCronJobName = await prepareForwardedMessageCronJobNameResolver([resolved.message], context.cronStorePath); await withCurrentSession(() => { const projectedMessage = resolved.message ? projectChatDisplayMessage(resolved.message, { includeCommentaryFallbacks: true, maxChars: effectiveMaxChars, resolveCurrentUserProfileDisplay, resolveCronJobName }) : void 0; const projected = projectedMessage ? augmentChatHistoryWithCanvasBlocks([projectedMessage])[0] : void 0; respondMessage(projected, true); }); } finally { selection.release(); } } }; //#endregion //#region src/gateway/server-methods/chat.ts const chatHandlers = { ...chatHistoryHandlers, ...chatMessageGetHandlers, "chat.toolTitles": async ({ params, respond }) => { if (!assertValidParams(params, validateChatToolTitlesParams, "chat.toolTitles", respond)) return; respond(true, { titles: {}, disabled: true }); }, "chat.inject": async ({ params, respond, context }) => { if (!assertValidParams(params, validateChatInjectParams, "chat.inject", respond)) return; const rawSessionKey = params.sessionKey; const agentIdOverride = normalizeOptionalString(params.agentId); const cfg = context.getRuntimeConfig(); const requestedAgent = resolveRequestedSessionAgentId(cfg, rawSessionKey, agentIdOverride); if (!requestedAgent.ok) { respond(false, void 0, requestedAgent.error); return; } const sessionLoadOptions = { agentId: requestedAgent.agentId }; const { agentId, storePath, entry, canonicalKey: sessionKey } = loadGatewaySessionEntry(rawSessionKey, sessionLoadOptions, cfg); const sessionId = entry?.sessionId; if (!sessionId || !storePath) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "session not found")); return; } let appended; try { const admission = await beginSessionWorkAdmission({ scope: storePath, identities: [sessionKey, sessionId], assertAllowed: () => { const latestEntry = loadGatewaySessionEntry(rawSessionKey, sessionLoadOptions).entry; if (!latestEntry) throw new Error(`Session "${sessionKey}" was deleted while starting work. Retry.`); if (latestEntry.sessionId !== sessionId) throw new Error(`Session "${sessionKey}" changed while starting work. Retry.`); const archivedError = resolveSessionWorkStartError(sessionKey, latestEntry); if (archivedError) throw new Error(archivedError); } }); try { appended = await admission.run(async () => await appendInjectedAssistantMessageToTranscript({ sessionKey, message: params.message, label: params.label, sessionId, storePath, agentId, config: cfg })); } finally { admission.release(); } } catch (err) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, formatForLog(err))); return; } if (!appended.ok || !appended.messageId || !appended.message) { respond(false, void 0, errorShape(ErrorCodes.UNAVAILABLE, `failed to write transcript: ${appended.error ?? "unknown error"}`)); return; } const message = projectChatDisplayMessage(appended.message, { maxChars: resolveEffectiveChatHistoryMaxChars() }); const chatPayload = { runId: `inject-${appended.messageId}`, sessionKey, ...agentId ? { agentId } : {}, seq: 0, state: "final", message }; context.broadcast("chat", chatPayload, { sessionKeys: resolveGlobalAwareNodeChatDeliveryKeys({ cfg, sessionKey, agentId }) }); sendGlobalAwareNodeChatPayload({ context, sessionKey, agentId, event: "chat", payload: chatPayload }); respond(true, { ok: true, messageId: appended.messageId }); } }; //#endregion export { chatHandlers };