refactor: extract agent bounded context + fix SSE comments + cleanup unused
- Extract src/lib/agent/ bounded context with types, registry, messaging - Add comments_count to BeadIssue for SSE comment detection - Create batch endpoints for mail/reservations APIs - Add memory validation to session-preflight - Remove unused empty dirs (mockup, sessions, timeline) - Move stashes to docs/references, gitignore them
This commit is contained in:
parent
6f41c4af31
commit
18fbafdce4
34 changed files with 62714 additions and 1970 deletions
|
|
@ -305,29 +305,24 @@ export function ActivityPanel({ issues, collapsed = false, projectRoot }: Activi
|
|||
return;
|
||||
}
|
||||
|
||||
const mailResponses = await Promise.all(
|
||||
agentRoster.map(async (agent) => {
|
||||
const response = await fetch(`/api/agents/mail?agent=${encodeURIComponent(agent.name)}&limit=15`);
|
||||
const payload = await response.json().catch(() => ({ ok: false }));
|
||||
return [agent.name, response.ok && payload.ok ? (payload.data as CoordMessage[]) : []] as const;
|
||||
}),
|
||||
);
|
||||
// Use batch endpoints to reduce API calls from 2N to 2
|
||||
const agentNames = agentRoster.map(a => a.name).join(',');
|
||||
|
||||
const reservationResponses = await Promise.all(
|
||||
agentRoster.map(async (agent) => {
|
||||
const response = await fetch(`/api/agents/reservations?agent=${encodeURIComponent(agent.name)}`);
|
||||
const payload = await response.json().catch(() => ({ ok: false }));
|
||||
if (!response.ok || !payload.ok) {
|
||||
return [agent.name, undefined] as const;
|
||||
}
|
||||
return [agent.name, payload.data?.reservations?.[0]?.scope as string | undefined] as const;
|
||||
}),
|
||||
);
|
||||
const [mailResponse, reservationsResponse] = await Promise.all([
|
||||
fetch(`/api/agents/mail/batch?agents=${encodeURIComponent(agentNames)}&limit=15`),
|
||||
fetch(`/api/agents/reservations/batch?agents=${encodeURIComponent(agentNames)}`),
|
||||
]);
|
||||
|
||||
const mailPayload = await mailResponse.json().catch(() => ({ ok: false, data: [] }));
|
||||
const reservationsPayload = await reservationsResponse.json().catch(() => ({ ok: false, data: [] }));
|
||||
|
||||
// Collect all messages from all agents
|
||||
const uniqueMessages = new Map<string, CoordMessage>();
|
||||
for (const [, messages] of mailResponses) {
|
||||
for (const message of messages) {
|
||||
uniqueMessages.set(message.message_id, message);
|
||||
if (mailPayload.ok && mailPayload.data) {
|
||||
for (const entry of mailPayload.data) {
|
||||
for (const message of (entry.messages ?? [])) {
|
||||
uniqueMessages.set(message.message_id, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -346,8 +341,16 @@ export function ActivityPanel({ issues, collapsed = false, projectRoot }: Activi
|
|||
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
|
||||
.slice(0, 25);
|
||||
|
||||
// Build reservation map
|
||||
const reservationMap: Record<string, string | undefined> = {};
|
||||
if (reservationsPayload.ok && reservationsPayload.data) {
|
||||
for (const entry of reservationsPayload.data) {
|
||||
reservationMap[entry.agent] = entry.scope;
|
||||
}
|
||||
}
|
||||
|
||||
setCoordActivities(mapped);
|
||||
setReservationByAgent(Object.fromEntries(reservationResponses));
|
||||
setReservationByAgent(reservationMap);
|
||||
};
|
||||
|
||||
void fetchCoordination();
|
||||
|
|
|
|||
|
|
@ -184,38 +184,39 @@ export function SocialPage({
|
|||
return;
|
||||
}
|
||||
|
||||
const mailPairs = await Promise.all(
|
||||
agentNames.map(async (agent) => {
|
||||
const response = await fetch(`/api/agents/mail?agent=${encodeURIComponent(agent)}&limit=25`);
|
||||
const payload = await response.json().catch(() => ({ ok: false }));
|
||||
if (!response.ok || !payload.ok) {
|
||||
return [agent, [] as CoordMessage[]] as const;
|
||||
}
|
||||
return [agent, (payload.data ?? []) as CoordMessage[]] as const;
|
||||
}),
|
||||
);
|
||||
// Use batch endpoints to reduce API calls from 2N to 2
|
||||
const agentsParam = agentNames.join(',');
|
||||
|
||||
const reservationsPairs = await Promise.all(
|
||||
agentNames.map(async (agent) => {
|
||||
const response = await fetch(`/api/agents/reservations?agent=${encodeURIComponent(agent)}`);
|
||||
const payload = await response.json().catch(() => ({ ok: false }));
|
||||
if (!response.ok || !payload.ok) {
|
||||
return [agent, undefined] as const;
|
||||
}
|
||||
const first = (payload.data?.reservations ?? [])[0];
|
||||
return [agent, first?.scope as string | undefined] as const;
|
||||
}),
|
||||
);
|
||||
const [mailResponse, reservationsResponse] = await Promise.all([
|
||||
fetch(`/api/agents/mail/batch?agents=${encodeURIComponent(agentsParam)}&limit=25`),
|
||||
fetch(`/api/agents/reservations/batch?agents=${encodeURIComponent(agentsParam)}`),
|
||||
]);
|
||||
|
||||
const mailPayload = await mailResponse.json().catch(() => ({ ok: false, data: [] }));
|
||||
const reservationsPayload = await reservationsResponse.json().catch(() => ({ ok: false, data: [] }));
|
||||
|
||||
const nextMessages: Record<string, CoordMessage[]> = {};
|
||||
const nextUnread: Record<string, number> = {};
|
||||
for (const [agent, messages] of mailPairs) {
|
||||
nextMessages[agent] = messages;
|
||||
nextUnread[agent] = messages.filter((m) => m.state === 'unread').length;
|
||||
const nextReservations: Record<string, string | undefined> = {};
|
||||
|
||||
// Process mail results
|
||||
if (mailPayload.ok && mailPayload.data) {
|
||||
for (const entry of mailPayload.data) {
|
||||
nextMessages[entry.agent] = entry.messages ?? [];
|
||||
nextUnread[entry.agent] = (entry.messages ?? []).filter((m: CoordMessage) => m.state === 'unread').length;
|
||||
}
|
||||
}
|
||||
|
||||
// Process reservations results
|
||||
if (reservationsPayload.ok && reservationsPayload.data) {
|
||||
for (const entry of reservationsPayload.data) {
|
||||
nextReservations[entry.agent] = entry.scope;
|
||||
}
|
||||
}
|
||||
|
||||
setAgentMessagesByName(nextMessages);
|
||||
setAgentUnreadByName(nextUnread);
|
||||
setAgentReservationsByName(Object.fromEntries(reservationsPairs));
|
||||
setAgentReservationsByName(nextReservations);
|
||||
}, [agentNames]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue