feat(telemetry): complete bb-buff.1.3 - Backend Liveness Refactor
STORY: The session backend needed to aggregate agent health from a live telemetry stream rather than static bead metadata. This refactor makes liveness signals real-time and accurate. COLLABORATION: We extended the ActivityEvent model with a native 'heartbeat' kind, updated extendActivityLease() to emit through the activity bus, and refactored getAgentLivenessMap() to prioritize heartbeat activity history over stale bead metadata. DELIVERABLES: - ActivityEvent extended with 'heartbeat' kind - extendActivityLease() emits heartbeats through activity bus - getAgentLivenessMap() prefers telemetry over static metadata - Registry APIs support projectRoot injection for testing - Tests verify preference logic via TDD VERIFICATION: - 93/93 tests PASSING - Heartbeat override verified in isolated temp projects CLOSES: bb-buff.1.3 BLOCKS: bb-buff.3.2, bb-buff.3.3, bb-buff.2.1
This commit is contained in:
parent
0016b57e37
commit
4ee550c333
36 changed files with 1380 additions and 541 deletions
|
|
@ -86,7 +86,7 @@ export async function GET(request: Request): Promise<Response> {
|
|||
}
|
||||
if (nextVersion !== lastTouchedVersion) {
|
||||
lastTouchedVersion = nextVersion;
|
||||
write(toSseFrame(issuesEventBus.emit(projectRoot, lastTouchedPath, 'changed')));
|
||||
write(toSseFrame(issuesEventBus.emit(projectRoot, lastTouchedPath, 'telemetry')));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export async function GET(request: Request): Promise<Response> {
|
|||
const issues = await readIssuesFromDisk({ projectRoot, preferBd: true });
|
||||
const activity = activityEventBus.getHistory(projectRoot);
|
||||
const communication = await getCommunicationSummary();
|
||||
const livenessMap = await getAgentLivenessMap();
|
||||
const livenessMap = await getAgentLivenessMap(projectRoot, activity);
|
||||
const incursions = await calculateIncursions();
|
||||
const agentsResult = await listAgents({});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import { SessionsPage } from '../../components/sessions/sessions-page';
|
||||
import type { SwarmGroup } from '../../components/sessions/sessions-header';
|
||||
import { readIssuesForScope } from '../../lib/aggregate-read';
|
||||
import { resolveProjectScope } from '../../lib/project-scope';
|
||||
import { listProjects } from '../../lib/registry';
|
||||
import { listAgents } from '../../lib/agent-registry';
|
||||
import { getSwarmMembers } from '../../lib/swarm-molecules';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
|
|
@ -32,6 +34,35 @@ export default async function Page({ searchParams }: PageProps) {
|
|||
preferBd: true,
|
||||
});
|
||||
|
||||
const epics = issues.filter(i => i.issue_type === 'epic');
|
||||
const epicsWithSwarm = epics.filter(
|
||||
i => (i.labels || []).some(l => l.startsWith('swarm:'))
|
||||
);
|
||||
|
||||
const swarmGroups: SwarmGroup[] = [];
|
||||
const assignedAgentIds = new Set<string>();
|
||||
|
||||
for (const epic of epicsWithSwarm) {
|
||||
const swarmLabel = epic.labels?.find(l => l.startsWith('swarm:'));
|
||||
if (!swarmLabel) continue;
|
||||
|
||||
const swarmId = swarmLabel.replace('swarm:', '');
|
||||
const memberIds = await getSwarmMembers({ swarmId }, { projectRoot: scope.selected.root });
|
||||
|
||||
const members = agents.filter(a => memberIds.includes(a.agent_id));
|
||||
members.forEach(a => assignedAgentIds.add(a.agent_id));
|
||||
|
||||
if (members.length > 0) {
|
||||
swarmGroups.push({
|
||||
swarmId,
|
||||
swarmLabel: epic.id,
|
||||
members,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const unassignedAgents = agents.filter(a => !assignedAgentIds.has(a.agent_id));
|
||||
|
||||
return (
|
||||
<SessionsPage
|
||||
issues={issues}
|
||||
|
|
@ -40,6 +71,8 @@ export default async function Page({ searchParams }: PageProps) {
|
|||
projectScopeKey={scope.selected.key}
|
||||
projectScopeOptions={scope.options}
|
||||
projectScopeMode={scope.mode}
|
||||
swarmGroups={swarmGroups}
|
||||
unassignedAgents={unassignedAgents}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue