openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
153 lines (152 loc) • 5.52 kB
JavaScript
import { S as createConfigIO, n as getRuntimeConfig } from "./io.runtime-B9iJRs3w.js";
import { r as STATE_DIR } from "./paths-D2sRr1a_.js";
import { u as normalizeMainKey } from "./session-key-BnWWjqNc.js";
import { a as getRuntimeConfigAppliedHash } from "./runtime-snapshot-BaQikjTR.js";
import { o as resolveAgentEffectiveModelPrimary } from "./agent-scope-DbtJyKUL.js";
import "./io-bdCzpGWJ.js";
import { n as resolveGatewayAuth } from "./auth-resolve-O5AKX-sb.js";
import "./auth-CyN_wFeb.js";
import { c as getGatewaySuspendAdmissionPhase } from "./gateway-work-admission-R1IpuDim.js";
import { r as resolveAgentMainSessionKey } from "./main-session-Br0F9dzh.js";
import "./sessions-9nxpeTwt.js";
import { n as resolveGatewayAgentSelectionState } from "./agent-list-BefyS8Gv.js";
import { t as listSystemPresence } from "./system-presence-Y_GcutUC.js";
import { n as collectGatewayHealthSnapshot } from "./collector-D5rcSn9Z.js";
import { i as getUpdateSchedule, n as getUpdateAvailable } from "./update-startup-DPESvgYQ.js";
import { o as projectUpdateAvailable } from "./events-DFzVQFw-.js";
import { t as createPresenceRecipientProjection } from "./presence-projection-BjIM8edy.js";
//#region src/gateway/server/health-state.ts
let presenceVersion = 1;
let healthVersion = 1;
let healthCache = null;
let broadcastHealthUpdate = null;
const healthRefreshStates = {
public: {
nextGeneration: 0,
committedGeneration: 0,
inFlight: {
passive: null,
probe: null
}
},
admin: {
nextGeneration: 0,
committedGeneration: 0,
inFlight: {
passive: null,
probe: null
}
}
};
function buildGatewaySnapshot(opts) {
const cfg = getRuntimeConfig();
const selection = resolveGatewayAgentSelectionState(cfg);
const defaultAgentId = selection.defaultId;
const mainKey = normalizeMainKey(cfg.session?.mainKey);
const scope = cfg.session?.scope ?? "per-sender";
const mainSessionKey = scope === "global" ? "global" : resolveAgentMainSessionKey({
cfg,
agentId: defaultAgentId
});
const presence = createPresenceRecipientProjection({
cfg,
presence: listSystemPresence()
})(opts.client);
const uptimeMs = Math.round(process.uptime() * 1e3);
const includeUpdateDetails = opts?.includeUpdateDetails === true;
const updateAvailable = projectUpdateAvailable(getUpdateAvailable(), includeUpdateDetails) ?? void 0;
const updateSchedule = includeUpdateDetails ? getUpdateSchedule() ?? void 0 : void 0;
const appliedConfigHash = getRuntimeConfigAppliedHash();
const snapshot = {
suspension: { phase: getGatewaySuspendAdmissionPhase() },
presence,
health: {},
stateVersion: {
presence: presenceVersion,
health: healthVersion
},
uptimeMs,
appliedConfigHash: appliedConfigHash ? opts.revisionProjector.projectResolvedHash(appliedConfigHash) : null,
sessionDefaults: {
defaultAgentId,
modelConfigured: Boolean(resolveAgentEffectiveModelPrimary(cfg, defaultAgentId)),
ownership: selection.ownership,
selectionRequired: selection.selectionRequired,
mainKey,
mainSessionKey,
scope
},
updateAvailable,
updateSchedule
};
if (opts?.includeSensitive === true) {
const auth = resolveGatewayAuth({
authConfig: cfg.gateway?.auth,
env: process.env
});
snapshot.configPath = createConfigIO().configPath;
snapshot.stateDir = STATE_DIR;
snapshot.authMode = auth.mode;
}
return snapshot;
}
function getHealthCache() {
return healthCache;
}
function getHealthVersion() {
return healthVersion;
}
function incrementPresenceVersion() {
presenceVersion += 1;
return presenceVersion;
}
function getPresenceVersion() {
return presenceVersion;
}
function setBroadcastHealthUpdate(fn) {
broadcastHealthUpdate = fn;
}
async function refreshGatewayHealthSnapshot(opts) {
const includeSensitive = opts?.includeSensitive === true;
const audience = includeSensitive ? "admin" : "public";
const state = healthRefreshStates[audience];
const strength = opts?.probe === false ? "passive" : "probe";
const existing = strength === "passive" ? state.inFlight.probe ?? state.inFlight.passive : state.inFlight.probe;
if (existing) return existing.promise;
const generation = state.nextGeneration + 1;
state.nextGeneration = generation;
const promise = (async () => {
let runtimeSnapshot;
try {
runtimeSnapshot = opts?.getRuntimeSnapshot?.();
} catch {
runtimeSnapshot = void 0;
}
const eventLoop = opts?.getEventLoopHealth?.();
const configReloadHotReloadStatus = opts?.getConfigReloaderHotReloadStatus?.();
const snap = await collectGatewayHealthSnapshot({
audience,
probe: strength === "probe",
runtimeSnapshot,
...eventLoop ? { eventLoop } : {},
...configReloadHotReloadStatus ? { configReloadHotReloadStatus } : {}
});
if (strength === "probe" && state.inFlight.passive && state.inFlight.passive.generation < generation) state.inFlight.passive = null;
if (!includeSensitive && generation > state.committedGeneration) {
state.committedGeneration = generation;
healthCache = snap;
healthVersion += 1;
if (broadcastHealthUpdate) broadcastHealthUpdate(snap);
}
return snap;
})().finally(() => {
if (state.inFlight[strength]?.generation === generation) state.inFlight[strength] = null;
});
state.inFlight[strength] = {
generation,
promise
};
return promise;
}
//#endregion
export { incrementPresenceVersion as a, getPresenceVersion as i, getHealthCache as n, refreshGatewayHealthSnapshot as o, getHealthVersion as r, setBroadcastHealthUpdate as s, buildGatewaySnapshot as t };