| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- import fs from "node:fs/promises";
- import path from "node:path";
- import { demoAgents } from "@/data/demo-agents";
- import { AgentFeed, AgentProfile, AgentStatus } from "@/types/agent";
- const defaultFeedPath = path.join(process.cwd(), "storage", "agents", "openclaw-agents.json");
- function isAgentStatus(value: unknown): value is AgentStatus {
- return value === "working" || value === "idle" || value === "warning" || value === "offline";
- }
- function normalizeAgent(agent: Record<string, unknown>): AgentProfile | null {
- if (typeof agent.id !== "string" || typeof agent.name !== "string" || typeof agent.role !== "string") {
- return null;
- }
- const status = isAgentStatus(agent.status) ? agent.status : "offline";
- const statusLabelMap: Record<AgentStatus, string> = {
- working: "工作中",
- idle: "待命",
- warning: "待确认",
- offline: "离线"
- };
- return {
- id: agent.id,
- name: agent.name,
- role: agent.role,
- avatarKind: (agent.avatarKind as AgentProfile["avatarKind"]) ?? "male-dispatcher",
- status,
- statusLabel: typeof agent.statusLabel === "string" ? agent.statusLabel : statusLabelMap[status],
- host: typeof agent.host === "string" ? agent.host : "unknown-host",
- owner: typeof agent.owner === "string" ? agent.owner : "OpenClaw",
- currentTask: typeof agent.currentTask === "string" ? agent.currentTask : "未上报当前任务",
- taskId: typeof agent.taskId === "string" ? agent.taskId : "unknown",
- taskStage: typeof agent.taskStage === "string" ? agent.taskStage : "unknown",
- queueDepth: typeof agent.queueDepth === "number" ? agent.queueDepth : 0,
- todayCompleted: typeof agent.todayCompleted === "number" ? agent.todayCompleted : 0,
- uptime: typeof agent.uptime === "string" ? agent.uptime : "未知",
- lastHeartbeat: typeof agent.lastHeartbeat === "string" ? agent.lastHeartbeat : "未知",
- updatedAt: typeof agent.updatedAt === "string" ? agent.updatedAt : "刚刚",
- lastOutput: typeof agent.lastOutput === "string" ? agent.lastOutput : "暂无最近输出。",
- lastError: typeof agent.lastError === "string" ? agent.lastError : undefined,
- tags: Array.isArray(agent.tags) ? agent.tags.filter((tag): tag is string => typeof tag === "string") : []
- };
- }
- async function loadFileFeed(feedPath: string): Promise<AgentFeed | null> {
- try {
- const raw = await fs.readFile(feedPath, "utf8");
- const parsed = JSON.parse(raw) as {
- fetchedAt?: string;
- agents?: Array<Record<string, unknown>>;
- };
- if (!Array.isArray(parsed.agents)) {
- return null;
- }
- const agents = parsed.agents.map(normalizeAgent).filter((agent): agent is AgentProfile => agent !== null);
- return {
- source: "file",
- sourceLabel: path.basename(feedPath),
- fetchedAt: typeof parsed.fetchedAt === "string" ? parsed.fetchedAt : new Date().toISOString(),
- agents
- };
- } catch {
- return null;
- }
- }
- export async function loadAgentFeed(status?: "all" | AgentStatus): Promise<AgentFeed> {
- const feedPath = process.env.OPENCLAW_AGENT_FEED_PATH ?? defaultFeedPath;
- const fileFeed = await loadFileFeed(feedPath);
- const fallbackFeed: AgentFeed = {
- source: "demo",
- sourceLabel: "demo-agents.ts",
- fetchedAt: new Date().toISOString(),
- agents: demoAgents
- };
- const chosenFeed = fileFeed ?? fallbackFeed;
- const filteredAgents =
- status && status !== "all" ? chosenFeed.agents.filter((agent) => agent.status === status) : chosenFeed.agents;
- return {
- ...chosenFeed,
- agents: filteredAgents
- };
- }
|