openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
111 lines (110 loc) • 3.99 kB
JavaScript
//#region src/gateway/server-chat-metadata-lifecycle.ts
/** A committed auth change remains successful even if its best-effort UI notification fails. */
function broadcastChatMetadataChanged(context) {
try {
context.broadcast("chat.metadata.changed", {}, { dropIfSlow: true });
} catch {
context.logGateway.warn("chat metadata change notification failed");
}
}
async function createGatewayChatMetadataLifecycle(params) {
let context;
let preparedModelRuntimeAvailable = false;
let preparedModelRuntimeEventVersion = 0;
const { ChatMetadataSnapshotUnavailableError, createGatewayChatMetadataRuntime } = await import("./chat-metadata-runtime-DTIZx2Bh.js");
const runtime = createGatewayChatMetadataRuntime({
getConfig: params.getConfig,
getContext: () => {
if (!context) throw new Error("gateway request context is unavailable during chat metadata preparation");
return context;
},
...params.minimalTestGateway ? {
beforeRefresh: async () => {
const { refreshPreparedModelRuntimeSnapshots } = await import("./prepared-model-runtime-D7Vr1U41.js");
await refreshPreparedModelRuntimeSnapshots(params.getConfig(), {
gatewayLifecycle: true,
catalogMode: "static",
allowGatewaySubagentBinding: true
});
},
refreshOnRead: true
} : {},
onChanged: () => {
if (context) broadcastChatMetadataChanged(context);
},
log: params.log
});
const refreshLogged = () => {
runtime.refresh().catch((error) => {
params.log.warn(`chat metadata refresh failed: ${String(error)}`);
});
};
const invalidateForSubordinateChange = () => {
runtime.invalidate();
if (preparedModelRuntimeAvailable) refreshLogged();
};
const registerRefreshListeners = async () => {
if (params.minimalTestGateway) return;
const [{ registerRuntimeAuthProfileStoreMutationListener }, { registerPreparedModelRuntimePublicationListener }, { registerSkillsChangeListener }] = await Promise.all([
import("./runtime-snapshots-CtPLOgNA.js"),
import("./prepared-model-runtime-D7Vr1U41.js"),
import("./refresh-DEmFkd11.js")
]);
const unregisterPreparedModelRuntimePublication = registerPreparedModelRuntimePublicationListener((event) => {
if (event.phase === "catalog-published") {
invalidateForSubordinateChange();
return;
}
preparedModelRuntimeEventVersion += 1;
if (event.phase === "invalidated") {
preparedModelRuntimeAvailable = false;
runtime.invalidate();
return;
}
if (event.phase === "failed") {
preparedModelRuntimeAvailable = false;
runtime.fail(event.error);
return;
}
preparedModelRuntimeAvailable = true;
refreshLogged();
});
const unregisterSkillsChange = registerSkillsChangeListener(() => {
invalidateForSubordinateChange();
});
const unregisterRuntimeAuthProfileStoreMutation = registerRuntimeAuthProfileStoreMutationListener(() => {
invalidateForSubordinateChange();
});
return () => {
unregisterRuntimeAuthProfileStoreMutation();
unregisterPreparedModelRuntimePublication();
unregisterSkillsChange();
};
};
return {
attachContext: async (next, sidecars) => {
context = next;
const unregister = await registerRefreshListeners();
sidecars.push({ stop: async () => {
unregister?.();
await runtime.stop();
} });
if (unregister) {
const eventVersion = preparedModelRuntimeEventVersion;
await runtime.refresh().then(() => {
if (preparedModelRuntimeEventVersion === eventVersion) preparedModelRuntimeAvailable = true;
}, (error) => {
if (!(error instanceof ChatMetadataSnapshotUnavailableError)) {
if (preparedModelRuntimeEventVersion === eventVersion) preparedModelRuntimeAvailable = true;
params.log.warn(`chat metadata catch-up refresh failed: ${String(error)}`);
}
});
}
},
read: runtime.read,
readStartup: runtime.readStartup,
refresh: runtime.refresh
};
}
//#endregion
export { createGatewayChatMetadataLifecycle as n, broadcastChatMetadataChanged as t };