feat: enrich presence with roles
This commit is contained in:
@@ -15,6 +15,9 @@ export const PresenceEntrySchema = Type.Object(
|
||||
tags: Type.Optional(Type.Array(NonEmptyString)),
|
||||
text: Type.Optional(Type.String()),
|
||||
ts: Type.Integer({ minimum: 0 }),
|
||||
deviceId: Type.Optional(NonEmptyString),
|
||||
roles: Type.Optional(Type.Array(NonEmptyString)),
|
||||
scopes: Type.Optional(Type.Array(NonEmptyString)),
|
||||
instanceId: Type.Optional(NonEmptyString),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
|
||||
@@ -37,6 +37,7 @@ export const systemHandlers: GatewayRequestHandlers = {
|
||||
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;
|
||||
@@ -51,12 +52,21 @@ export const systemHandlers: GatewayRequestHandlers = {
|
||||
? 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 as string[])
|
||||
: undefined;
|
||||
const scopes =
|
||||
Array.isArray(params.scopes) && params.scopes.every((t) => typeof t === "string")
|
||||
? (params.scopes as string[])
|
||||
: undefined;
|
||||
const tags =
|
||||
Array.isArray(params.tags) && params.tags.every((t) => typeof t === "string")
|
||||
? (params.tags as string[])
|
||||
: undefined;
|
||||
const presenceUpdate = updateSystemPresence({
|
||||
text,
|
||||
deviceId,
|
||||
instanceId,
|
||||
host,
|
||||
ip,
|
||||
@@ -67,6 +77,8 @@ export const systemHandlers: GatewayRequestHandlers = {
|
||||
modelIdentifier,
|
||||
lastInputSeconds,
|
||||
reason,
|
||||
roles,
|
||||
scopes,
|
||||
tags,
|
||||
});
|
||||
const isNodePresenceLine = text.startsWith("Node:");
|
||||
|
||||
@@ -619,6 +619,9 @@ export function attachGatewayWsMessageHandler(params: {
|
||||
deviceFamily: connectParams.client.deviceFamily,
|
||||
modelIdentifier: connectParams.client.modelIdentifier,
|
||||
mode: connectParams.client.mode,
|
||||
deviceId: connectParams.device?.id,
|
||||
roles: [role],
|
||||
scopes,
|
||||
instanceId: connectParams.device?.id ?? instanceId,
|
||||
reason: "connect",
|
||||
});
|
||||
|
||||
@@ -11,6 +11,9 @@ export type SystemPresence = {
|
||||
lastInputSeconds?: number;
|
||||
mode?: string;
|
||||
reason?: string;
|
||||
deviceId?: string;
|
||||
roles?: string[];
|
||||
scopes?: string[];
|
||||
instanceId?: string;
|
||||
text: string;
|
||||
ts: number;
|
||||
@@ -153,6 +156,7 @@ function parsePresence(text: string): SystemPresence {
|
||||
|
||||
type SystemPresencePayload = {
|
||||
text: string;
|
||||
deviceId?: string;
|
||||
instanceId?: string;
|
||||
host?: string;
|
||||
ip?: string;
|
||||
@@ -163,13 +167,28 @@ type SystemPresencePayload = {
|
||||
lastInputSeconds?: number;
|
||||
mode?: string;
|
||||
reason?: string;
|
||||
roles?: string[];
|
||||
scopes?: string[];
|
||||
tags?: string[];
|
||||
};
|
||||
|
||||
function mergeStringList(...values: Array<string[] | undefined>): string[] | undefined {
|
||||
const out = new Set<string>();
|
||||
for (const list of values) {
|
||||
if (!Array.isArray(list)) continue;
|
||||
for (const item of list) {
|
||||
const trimmed = String(item).trim();
|
||||
if (trimmed) out.add(trimmed);
|
||||
}
|
||||
}
|
||||
return out.size > 0 ? [...out] : undefined;
|
||||
}
|
||||
|
||||
export function updateSystemPresence(payload: SystemPresencePayload): SystemPresenceUpdate {
|
||||
ensureSelfPresence();
|
||||
const parsed = parsePresence(payload.text);
|
||||
const key =
|
||||
normalizePresenceKey(payload.deviceId) ||
|
||||
normalizePresenceKey(payload.instanceId) ||
|
||||
normalizePresenceKey(parsed.instanceId) ||
|
||||
normalizePresenceKey(parsed.host) ||
|
||||
@@ -191,6 +210,9 @@ export function updateSystemPresence(payload: SystemPresencePayload): SystemPres
|
||||
lastInputSeconds:
|
||||
payload.lastInputSeconds ?? parsed.lastInputSeconds ?? existing.lastInputSeconds,
|
||||
reason: payload.reason ?? parsed.reason ?? existing.reason,
|
||||
deviceId: payload.deviceId ?? existing.deviceId,
|
||||
roles: mergeStringList(existing.roles, payload.roles),
|
||||
scopes: mergeStringList(existing.scopes, payload.scopes),
|
||||
instanceId: payload.instanceId ?? parsed.instanceId ?? existing.instanceId,
|
||||
text: payload.text || parsed.text || existing.text,
|
||||
ts: Date.now(),
|
||||
@@ -221,9 +243,13 @@ export function upsertPresence(key: string, presence: Partial<SystemPresence>) {
|
||||
ensureSelfPresence();
|
||||
const normalizedKey = normalizePresenceKey(key) ?? os.hostname().toLowerCase();
|
||||
const existing = entries.get(normalizedKey) ?? ({} as SystemPresence);
|
||||
const roles = mergeStringList(existing.roles, presence.roles);
|
||||
const scopes = mergeStringList(existing.scopes, presence.scopes);
|
||||
const merged: SystemPresence = {
|
||||
...existing,
|
||||
...presence,
|
||||
roles,
|
||||
scopes,
|
||||
ts: Date.now(),
|
||||
text:
|
||||
presence.text ||
|
||||
|
||||
Reference in New Issue
Block a user