openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
244 lines (243 loc) • 9.81 kB
JavaScript
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 };