Spaces:
Sleeping
Sleeping
File size: 5,486 Bytes
fb4d8fe | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | import type { GatewayRequestHandlers } from "./types.js";
import { resolveMainSessionKeyFromConfig } from "../../config/sessions.js";
import { getLastHeartbeatEvent } from "../../infra/heartbeat-events.js";
import { setHeartbeatsEnabled } from "../../infra/heartbeat-runner.js";
import { enqueueSystemEvent, isSystemEventContextChanged } from "../../infra/system-events.js";
import { listSystemPresence, updateSystemPresence } from "../../infra/system-presence.js";
import { ErrorCodes, errorShape } from "../protocol/index.js";
export const systemHandlers: GatewayRequestHandlers = {
"last-heartbeat": ({ respond }) => {
respond(true, getLastHeartbeatEvent(), undefined);
},
"set-heartbeats": ({ params, respond }) => {
const enabled = params.enabled;
if (typeof enabled !== "boolean") {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"invalid set-heartbeats params: enabled (boolean) required",
),
);
return;
}
setHeartbeatsEnabled(enabled);
respond(true, { ok: true, enabled }, undefined);
},
"system-presence": ({ respond }) => {
const presence = listSystemPresence();
respond(true, presence, undefined);
},
"system-event": ({ params, respond, context }) => {
const text = typeof params.text === "string" ? params.text.trim() : "";
if (!text) {
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "text required"));
return;
}
const sessionKey = resolveMainSessionKeyFromConfig();
const deviceId = typeof params.deviceId === "string" ? params.deviceId : undefined;
const instanceId = typeof params.instanceId === "string" ? params.instanceId : undefined;
const host = typeof params.host === "string" ? params.host : undefined;
const ip = typeof params.ip === "string" ? params.ip : undefined;
const mode = typeof params.mode === "string" ? params.mode : undefined;
const version = typeof params.version === "string" ? params.version : undefined;
const platform = typeof params.platform === "string" ? params.platform : undefined;
const deviceFamily = typeof params.deviceFamily === "string" ? params.deviceFamily : undefined;
const modelIdentifier =
typeof params.modelIdentifier === "string" ? params.modelIdentifier : undefined;
const lastInputSeconds =
typeof params.lastInputSeconds === "number" && Number.isFinite(params.lastInputSeconds)
? params.lastInputSeconds
: undefined;
const reason = typeof params.reason === "string" ? params.reason : undefined;
const roles =
Array.isArray(params.roles) && params.roles.every((t) => typeof t === "string")
? params.roles
: undefined;
const scopes =
Array.isArray(params.scopes) && params.scopes.every((t) => typeof t === "string")
? params.scopes
: undefined;
const tags =
Array.isArray(params.tags) && params.tags.every((t) => typeof t === "string")
? params.tags
: undefined;
const presenceUpdate = updateSystemPresence({
text,
deviceId,
instanceId,
host,
ip,
mode,
version,
platform,
deviceFamily,
modelIdentifier,
lastInputSeconds,
reason,
roles,
scopes,
tags,
});
const isNodePresenceLine = text.startsWith("Node:");
if (isNodePresenceLine) {
const next = presenceUpdate.next;
const changed = new Set(presenceUpdate.changedKeys);
const reasonValue = next.reason ?? reason;
const normalizedReason = (reasonValue ?? "").toLowerCase();
const ignoreReason =
normalizedReason.startsWith("periodic") || normalizedReason === "heartbeat";
const hostChanged = changed.has("host");
const ipChanged = changed.has("ip");
const versionChanged = changed.has("version");
const modeChanged = changed.has("mode");
const reasonChanged = changed.has("reason") && !ignoreReason;
const hasChanges = hostChanged || ipChanged || versionChanged || modeChanged || reasonChanged;
if (hasChanges) {
const contextChanged = isSystemEventContextChanged(sessionKey, presenceUpdate.key);
const parts: string[] = [];
if (contextChanged || hostChanged || ipChanged) {
const hostLabel = next.host?.trim() || "Unknown";
const ipLabel = next.ip?.trim();
parts.push(`Node: ${hostLabel}${ipLabel ? ` (${ipLabel})` : ""}`);
}
if (versionChanged) {
parts.push(`app ${next.version?.trim() || "unknown"}`);
}
if (modeChanged) {
parts.push(`mode ${next.mode?.trim() || "unknown"}`);
}
if (reasonChanged) {
parts.push(`reason ${reasonValue?.trim() || "event"}`);
}
const deltaText = parts.join(" · ");
if (deltaText) {
enqueueSystemEvent(deltaText, {
sessionKey,
contextKey: presenceUpdate.key,
});
}
}
} else {
enqueueSystemEvent(text, { sessionKey });
}
const nextPresenceVersion = context.incrementPresenceVersion();
context.broadcast(
"presence",
{ presence: listSystemPresence() },
{
dropIfSlow: true,
stateVersion: {
presence: nextPresenceVersion,
health: context.getHealthVersion(),
},
},
);
respond(true, { ok: true }, undefined);
},
};
|