From cc9f3eb88fdc603c5d94af51704ce23d5adbb75f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=B3=AF=20=F0=9F=90=B1?= Date: Mon, 13 Apr 2026 16:56:15 +0800 Subject: [PATCH] refactor(board): use agent_profile projection instead of event replay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Much simpler — one API call per agent to /projections/agent_profile instead of fetching full event streams and filtering manually. --- packages/board/src/api/ograph-client.ts | 34 ++++++++++--------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/packages/board/src/api/ograph-client.ts b/packages/board/src/api/ograph-client.ts index 7a200f8..c2e60c9 100644 --- a/packages/board/src/api/ograph-client.ts +++ b/packages/board/src/api/ograph-client.ts @@ -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> { const map: Record = { ...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 ?? "👤" } - } + // 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 events for this agent, keep fallback - } - } + }) + ) } catch { // Failed to fetch agent objects, return fallback map }