From 452bfba424abcbfc16505ef14904911e503a3ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E5=A2=A8?= Date: Mon, 13 Apr 2026 08:16:57 +0000 Subject: [PATCH] feat(dispatcher): load agent profiles from OGraph events (#33) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Startup fetches agent_profile_updated events for known agents - Builds id→name cache from event payloads (LWW) - Config names as fallback if event fetch fails - Registered profiles: 小墨 🖊️ (id=3), 小橘 🍊 (id=5) --- packages/dispatcher/src/index.ts | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/packages/dispatcher/src/index.ts b/packages/dispatcher/src/index.ts index a4c75a4..ccd6bd0 100644 --- a/packages/dispatcher/src/index.ts +++ b/packages/dispatcher/src/index.ts @@ -5,6 +5,7 @@ import { loadConfig } from './config.js'; import { ProjectionWatcher } from './watcher.js'; import { OcScheduler } from './scheduler.js'; import { OcPluginAgentClient } from './agent-client.js'; +import { OGraphClient } from './ograph-client.js'; import type { PendingEntry, AgentConfig } from './types.js'; import type { AgentClient } from './agent-client.js'; @@ -37,6 +38,58 @@ async function main(): Promise { console.log(`[${ts()}] [dispatcher] intervals.schedulerIdle = ${config.intervals.schedulerIdle}ms`); console.log(`[${ts()}] [dispatcher] intervals.schedulerActive= ${config.intervals.schedulerActive}ms`); + // Load agent profiles from OGraph events (agent_profile_updated) + const ographClient = new OGraphClient(config); + try { + const allEvents = await ographClient.fetchEvents(0); // ref=0 won't match, need all agents + // Fetch profiles for all known agent objects + const profileNames: Record = { ...config.names }; // config as fallback + const agentIds = new Set(); + // Discover agent ids from discovery config + any refs in existing events + if (config.discovery?.agentId) agentIds.add(config.discovery.agentId); + // Fetch profile events for each known agent + for (const agentId of agentIds) { + try { + const events = await ographClient.fetchEvents(agentId); + const profileEvents = events.filter(e => e.type_name === 'agent_profile_updated'); + if (profileEvents.length > 0) { + const latest = profileEvents[profileEvents.length - 1]!; + const p = latest.payload as { name?: string; emoji?: string }; + if (p.name) { + profileNames[String(agentId)] = p.emoji ? `${p.name} ${p.emoji}` : p.name; + } + } + } catch { + // Profile fetch failed for this agent, use config fallback + } + } + // Also try to fetch profiles for other agents mentioned in config.names + for (const id of Object.keys(config.names ?? {})) { + if (!agentIds.has(Number(id))) { + try { + const events = await ographClient.fetchEvents(Number(id)); + const profileEvents = events.filter(e => e.type_name === 'agent_profile_updated'); + if (profileEvents.length > 0) { + const latest = profileEvents[profileEvents.length - 1]!; + const p = latest.payload as { name?: string; emoji?: string }; + if (p.name) { + profileNames[id] = p.emoji ? `${p.name} ${p.emoji}` : p.name; + } + } + } catch { + // Use config fallback + } + } + } + config.names = profileNames; + console.log(`[${ts()}] [dispatcher] loaded ${Object.keys(profileNames).length} agent profile(s):`); + for (const [id, name] of Object.entries(profileNames)) { + console.log(`[${ts()}] [dispatcher] agent #${id} = ${name}`); + } + } catch (err) { + console.warn(`[${ts()}] [dispatcher] failed to load agent profiles, using config fallback: ${err instanceof Error ? err.message : String(err)}`); + } + // Create agent clients from config const agentClients: AgentClient[] = []; if (config.agents && config.agents.length > 0) {