feat(dispatcher): load agent profiles from OGraph events (#33)

- 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)
This commit is contained in:
小墨 2026-04-13 08:16:57 +00:00
parent c6d880fd71
commit 452bfba424

View File

@ -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<void> {
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<string, string> = { ...config.names }; // config as fallback
const agentIds = new Set<number>();
// 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) {