refactor(board): use agent_profile projection instead of event replay

Much simpler — one API call per agent to /projections/agent_profile
instead of fetching full event streams and filtering manually.
This commit is contained in:
小糯 🐱 2026-04-13 16:56:15 +08:00
parent 6f73544e96
commit cc9f3eb88f

View File

@ -274,9 +274,9 @@ export class OGraphClient implements TaskAPI {
}
/**
* Load agent profiles from OGraph agent_profile_updated events.
* For each agent object, fetches its event stream and picks the latest
* agent_profile_updated event (LWW). Falls back to FALLBACK_AGENT_MAP.
* Load agent profiles from OGraph agent_profile projections.
* For each agent object, queries the agent_profile projection.
* Falls back to FALLBACK_AGENT_MAP on failure.
*/
async loadAgentProfiles(): Promise<Record<number, { name: string; emoji: string }>> {
const map: Record<number, { name: string; emoji: string }> = { ...FALLBACK_AGENT_MAP }
@ -285,24 +285,18 @@ export class OGraphClient implements TaskAPI {
const agentIds = await this.getAgentIds()
if (agentIds.length === 0) return map
// 2. For each agent, fetch events and find latest agent_profile_updated
for (const agentId of agentIds) {
try {
const eventsRes = await this.request<{ events: OGraphEvent[] }>(`/events?ref=${agentId}&limit=200`)
const events = eventsRes.events ?? []
const profileEvents = events.filter(e => e.type_name === "agent_profile_updated")
if (profileEvents.length > 0) {
// Sort by id (chronological) and take the latest
const latest = profileEvents.sort((a, b) => a.id - b.id).at(-1)!
const p = latest.payload as { name?: string; emoji?: string }
if (p.name) {
map[agentId] = { name: p.name, emoji: p.emoji ?? "👤" }
}
}
} catch {
// Failed to fetch events for this agent, keep fallback
}
// 2. For each agent, query the agent_profile projection
await Promise.allSettled(
agentIds.map(async (agentId) => {
const res = await this.request<{ value: { name?: string; emoji?: string } }>(
`/projections/agent_profile?agent=${agentId}`
)
const profile = res.value
if (profile?.name) {
map[agentId] = { name: profile.name, emoji: profile.emoji ?? "👤" }
}
})
)
} catch {
// Failed to fetch agent objects, return fallback map
}