Files
openclaw/src/gateway/agent-list.ts
2026-03-15 22:55:27 -07:00

89 lines
2.7 KiB
TypeScript

import fs from "node:fs";
import path from "node:path";
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
import type { OpenClawConfig } from "../config/config.js";
import { resolveStateDir } from "../config/paths.js";
import type { SessionScope } from "../config/sessions.js";
import { normalizeAgentId, normalizeMainKey } from "../routing/session-key.js";
export type GatewayAgentListRow = {
id: string;
name?: string;
};
function listExistingAgentIdsFromDisk(): string[] {
const root = resolveStateDir();
const agentsDir = path.join(root, "agents");
try {
const entries = fs.readdirSync(agentsDir, { withFileTypes: true });
return entries
.filter((entry) => entry.isDirectory())
.map((entry) => normalizeAgentId(entry.name))
.filter(Boolean);
} catch {
return [];
}
}
function listConfiguredAgentIds(cfg: OpenClawConfig): string[] {
const ids = new Set<string>();
const defaultId = normalizeAgentId(resolveDefaultAgentId(cfg));
ids.add(defaultId);
for (const entry of cfg.agents?.list ?? []) {
if (entry?.id) {
ids.add(normalizeAgentId(entry.id));
}
}
for (const id of listExistingAgentIdsFromDisk()) {
ids.add(id);
}
const sorted = Array.from(ids).filter(Boolean);
sorted.sort((a, b) => a.localeCompare(b));
return sorted.includes(defaultId)
? [defaultId, ...sorted.filter((id) => id !== defaultId)]
: sorted;
}
export function listGatewayAgentsBasic(cfg: OpenClawConfig): {
defaultId: string;
mainKey: string;
scope: SessionScope;
agents: GatewayAgentListRow[];
} {
const defaultId = normalizeAgentId(resolveDefaultAgentId(cfg));
const mainKey = normalizeMainKey(cfg.session?.mainKey);
const scope = cfg.session?.scope ?? "per-sender";
const configuredById = new Map<string, { name?: string }>();
for (const entry of cfg.agents?.list ?? []) {
if (!entry?.id) {
continue;
}
configuredById.set(normalizeAgentId(entry.id), {
name: typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : undefined,
});
}
const explicitIds = new Set(
(cfg.agents?.list ?? [])
.map((entry) => (entry?.id ? normalizeAgentId(entry.id) : ""))
.filter(Boolean),
);
const allowedIds = explicitIds.size > 0 ? new Set([...explicitIds, defaultId]) : null;
let agentIds = listConfiguredAgentIds(cfg).filter((id) =>
allowedIds ? allowedIds.has(id) : true,
);
if (mainKey && !agentIds.includes(mainKey) && (!allowedIds || allowedIds.has(mainKey))) {
agentIds = [...agentIds, mainKey];
}
const agents = agentIds.map((id) => {
const meta = configuredById.get(id);
return {
id,
name: meta?.name,
};
});
return { defaultId, mainKey, scope, agents };
}