openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
108 lines (107 loc) • 4.02 kB
JavaScript
import { l as normalizeOptionalString, o as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIXf7egm.js";
import { t as formatErrorMessage } from "./errors-Db3Ymjlb.js";
import { r as logVerbose } from "./globals-CTaGxEqj.js";
import { t as getAcpSessionManager } from "./manager-Bbp2Ogkb.js";
import { t as buildConfiguredAcpSessionKey } from "./persistent-bindings.types--DEYLak-.js";
//#region src/acp/persistent-bindings.lifecycle.ts
/** Ensures configured channel-to-ACP bindings have live sessions and matching runtime options. */
function sessionStructurallyMatchesConfiguredBinding(params) {
if (params.meta.state === "error") return false;
const desiredAgent = normalizeLowercaseStringOrEmpty(params.spec.acpAgentId ?? params.spec.agentId);
const currentAgent = normalizeLowercaseStringOrEmpty(params.meta.agent);
if (!currentAgent || currentAgent !== desiredAgent) return false;
if (params.meta.mode !== params.spec.mode) return false;
const desiredBackend = normalizeOptionalString(params.spec.backend) ?? normalizeOptionalString(params.cfg.acp?.backend) ?? "";
if (desiredBackend) {
const currentBackend = (params.meta.backend ?? "").trim();
if (!currentBackend || currentBackend !== desiredBackend) return false;
}
const desiredCwd = normalizeOptionalString(params.spec.cwd);
if (desiredCwd !== void 0) {
if (desiredCwd !== (params.meta.runtimeOptions?.cwd ?? params.meta.cwd ?? "").trim()) return false;
}
return true;
}
/** Creates or replaces the ACP session required by one configured binding. */
async function ensureConfiguredAcpBindingSession(params) {
const sessionKey = buildConfiguredAcpSessionKey(params.spec);
const acpManager = getAcpSessionManager();
const runtimeOptions = {
...params.spec.model ? { model: params.spec.model } : {},
...params.spec.thinking ? { thinking: params.spec.thinking } : {}
};
try {
const resolution = acpManager.resolveSession({
cfg: params.cfg,
agentId: params.spec.agentId,
sessionKey
});
if (resolution.kind === "ready" && sessionStructurallyMatchesConfiguredBinding({
cfg: params.cfg,
spec: params.spec,
meta: resolution.meta
})) {
let currentOptions = resolution.meta.runtimeOptions;
for (const key of ["model", "thinking"]) {
const value = runtimeOptions[key];
if (value !== void 0 && normalizeOptionalString(currentOptions?.[key]) !== value) currentOptions = await acpManager.setSessionConfigOption({
cfg: params.cfg,
agentId: params.spec.agentId,
sessionKey,
key,
value
});
}
return {
ok: true,
sessionKey
};
}
if (resolution.kind !== "none") await acpManager.closeSession({
cfg: params.cfg,
agentId: params.spec.agentId,
sessionKey,
reason: "config-binding-reconfigure",
clearMeta: false,
allowBackendUnavailable: true,
requireAcpSession: false
});
await acpManager.initializeSession({
cfg: params.cfg,
agentId: params.spec.agentId,
sessionKey,
agent: params.spec.acpAgentId ?? params.spec.agentId,
mode: params.spec.mode,
runtimeOptions,
cwd: params.spec.cwd,
backendId: params.spec.backend
});
return {
ok: true,
sessionKey
};
} catch (error) {
const message = formatErrorMessage(error);
logVerbose(`acp-configured-binding: failed ensuring ${params.spec.channel}:${params.spec.accountId}:${params.spec.conversationId} -> ${sessionKey}: ${message}`);
return {
ok: false,
sessionKey,
error: message
};
}
}
/** Resolves a configured binding for a conversation and ensures its ACP session exists. */
async function ensureConfiguredAcpBindingReadyCore(params) {
if (!params.configuredBinding) return { ok: true };
const ensured = await ensureConfiguredAcpBindingSession({
cfg: params.cfg,
spec: params.configuredBinding.spec
});
if (ensured.ok) return { ok: true };
return {
ok: false,
error: ensured.error ?? "unknown error"
};
}
//#endregion
export { ensureConfiguredAcpBindingSession as n, ensureConfiguredAcpBindingReadyCore as t };