Skip to content

feat(agent-logs): SSE real-time updates, filter controls, enhanced status indicators#284

Open
Awaiskhan404 wants to merge 6 commits intoabhi1693:masterfrom
Awaiskhan404:feature/inter-agent-comms-api
Open

feat(agent-logs): SSE real-time updates, filter controls, enhanced status indicators#284
Awaiskhan404 wants to merge 6 commits intoabhi1693:masterfrom
Awaiskhan404:feature/inter-agent-comms-api

Conversation

@Awaiskhan404
Copy link

Summary

Enhances the Agent Live Logs Dashboard with three major features:

1. SSE Real-Time Updates

  • New reusable useSSE hook at lib/use-sse.ts
  • Connects to /api/v1/agents/stream and /api/v1/activity/task-comments/stream
  • Merges SSE events into React Query cache for instant UI updates
  • Polling reduced from 15s to 60s when SSE is active (fallback preserved)
  • Live connection indicator in header (Live / Connecting / Polling)

2. Filter Controls

  • Agent name search (text input)
  • Board filter (dropdown)
  • Status filter (online / offline / all)
  • Time range filter (1h / 6h / 24h / 7d / all)
  • All filters URL-persisted via searchParams
  • Clear-all button

3. Enhanced Status Indicators

  • Working: pulsing green dot (online + task + activity <5min)
  • Idle: amber dot (online + no recent activity >5min)
  • Waiting: pulsing orange dot (online + task + no activity >15min)
  • Offline: grey dot
  • Agents sorted by activity state > online status > name
  • Working count badge in header

Files Changed

  • frontend/src/lib/use-sse.ts (new)
  • frontend/src/app/agent-logs/page.tsx (enhanced)

Notes

  • TypeScript compiles clean (pre-existing errors in agents/[agentId]/page.tsx are unrelated)
  • No changes to auto-generated API files
  • SSE auth uses _token query param (EventSource API limitation)

Dembe and others added 5 commits March 16, 2026 03:43
- Backend: Add agent_id query param to activity, task-comments, and
  task-comments/stream endpoints for per-agent filtering
- Frontend: New /agent-logs page with agent cards showing status, role,
  current task, and recent activity log per agent
- Nav: Add Agent Logs link to sidebar with ScrollText icon
- Types: Update generated API params to include agent_id

Resolves: Improve mission control - live agent logs section
- New AgentMessage model (board_id, sender/receiver agent, task, content)
- POST /agent/boards/{board_id}/agent-comms - send message
- GET /agent/boards/{board_id}/agent-comms - list messages (since/task_id filters)
- GET /agent/boards/{board_id}/agent-comms/stream - SSE real-time feed
- Alembic migration for agent_messages table with indexes
- Schemas: AgentMessageCreate, AgentMessageRead
…atus indicators

- Add reusable useSSE hook for EventSource-based real-time data
- SSE connects to /api/v1/agents/stream and /api/v1/activity/task-comments/stream
- Merges SSE events into React Query cache; polling reduced to 60s when SSE active
- Add filter bar: agent search, board dropdown, status filter, time range
- Filters persisted in URL search params
- Enhanced activity states: working (pulsing green), idle (amber), waiting (pulsing orange), offline
- Activity state derived from agent status, task assignment, and last activity timestamp
- SSE connection indicator in header (Live/Connecting/Polling)
- Working agent count badge in header
- Sort agents by activity state > online status > name
- GET /api/v1/agent/boards/{board_id}/agents/{agent_id}/activity
  Paginated recent activity for a specific agent with since/event_type filters

- GET /api/v1/agent/boards/{board_id}/activity/live
  SSE stream of board activity events with agent_id/event_type filters

- POST /api/v1/agent/log
  Agent posts own activity log entry via record_activity()

All endpoints include OpenAPI hints (x-llm-intent, x-when-to-use).
Refs task 1cc3d630.
Copilot AI review requested due to automatic review settings March 16, 2026 05:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Agent Logs dashboard view and supporting backend capabilities to surface agent activity in near real time, plus new inter-agent messaging persistence and API filters.

Changes:

  • Frontend: new /agent-logs page with URL-persisted filters, status indicators, and attempted SSE-driven cache updates.
  • Frontend: new reusable useSSE hook and sidebar navigation link to Agent Logs.
  • Backend: new agent_messages table + models/schemas and new agent inter-comms + activity streaming/listing endpoints; activity APIs add agent_id filtering and generated client params updated.

Reviewed changes

Copilot reviewed 9 out of 12 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
frontend/src/lib/use-sse.ts Introduces an SSE hook intended for authenticated real-time updates.
frontend/src/components/organisms/DashboardSidebar.tsx Adds navigation entry for the Agent Logs page.
frontend/src/app/agent-logs/page.tsx New Agent Logs dashboard page with filters, status indicators, and SSE-to-React-Query merging logic.
frontend/src/api/generated/model/streamTaskCommentFeedApiV1ActivityTaskCommentsStreamGetParams.ts Generated client param update to support agent_id filtering.
frontend/src/api/generated/model/listTaskCommentFeedApiV1ActivityTaskCommentsGetParams.ts Generated client param update to support agent_id filtering.
frontend/src/api/generated/model/listActivityApiV1ActivityGetParams.ts Generated client param update to support agent_id filtering.
backend/migrations/versions/d1a2b3c4e5f7_add_agent_messages_table.py Adds agent_messages table and indexes.
backend/app/schemas/agent_messages.py Adds create/read schemas for agent messages.
backend/app/models/agent_messages.py Adds SQLModel for persisted agent messages.
backend/app/models/init.py Exports AgentMessage for metadata discovery.
backend/app/api/agent.py Adds agent-comms endpoints and new board activity streaming/listing endpoints.
backend/app/api/activity.py Adds agent_id filtering to activity listing and task-comment feed/list/stream.

Comment on lines +110 to +113
es.onmessage = (event) => {
if (!cancelled) onMessageRef.current(event);
};

Comment on lines +98 to +101
// Pass token as query param since EventSource doesn't support headers
if (token) {
url.searchParams.set("_token", token);
}
Comment on lines +327 to +331
<select
value={boardFilter}
onChange={(e) => onBoardFilterChange(e.target.value)}
className="rounded-lg border border-slate-200 bg-slate-50 px-3 py-2 text-sm text-slate-700 focus:border-slate-300 focus:outline-none focus:ring-1 focus:ring-slate-300 transition"
>
Comment on lines +2068 to +2073
"""Fetch agent messages created after *since* for a board."""
statement = (
select(AgentMessage)
.where(col(AgentMessage.board_id) == board_id)
.where(col(AgentMessage.created_at) > since)
.order_by(col(AgentMessage.created_at).asc())
Comment on lines +2081 to +2085
@router.post(
"/boards/{board_id}/agent-comms",
response_model=AgentMessageRead,
status_code=status.HTTP_201_CREATED,
tags=AGENT_BOARD_TAGS,
Comment on lines +602 to +613
const data = JSON.parse(event.data as string) as AgentRead;
// Merge into React Query cache
queryClient.setQueryData(
getListAgentsApiV1AgentsGetQueryKey(),
(old: listAgentsApiV1AgentsGetResponse | undefined) => {
if (!old || old.status !== 200) return old;
const items = [...(old.data.items ?? [])];
const idx = items.findIndex((a) => a.id === data.id);
if (idx >= 0) {
items[idx] = { ...items[idx], ...data };
} else {
items.push(data);
Comment on lines +631 to +635
const data = JSON.parse(event.data as string) as ActivityEventRead;
queryClient.setQueryData(
getListActivityApiV1ActivityGetQueryKey({ limit: ACTIVITY_LIMIT }),
(old: listActivityApiV1ActivityGetResponse | undefined) => {
if (!old || old.status !== 200) return old;
Comment on lines 249 to 252
@router.get("", response_model=DefaultLimitOffsetPage[ActivityEventRead])
async def list_activity(
agent_id: UUID | None = AGENT_ID_QUERY,
session: AsyncSession = SESSION_DEP,
Comment on lines +567 to +571
export default function AgentLogsPage() {
const { isSignedIn } = useAuth();
const { isAdmin } = useOrganizationMembership(isSignedIn);
const queryClient = useQueryClient();
const searchParams = useSearchParams();
* we pass the auth token as a query parameter (`_token`). The backend
* should accept this for SSE endpoints.
*
* Falls back to fetch-based SSE reading if the token approach fails.
- Replace EventSource with fetch/ReadableStream SSE client (supports Authorization headers)
- Handle named SSE events (event: agent, event: comment) via proper SSE parsing
- Fix deriveActivityState: return 'idle' not 'working' when no task assigned
- Add aria-labels to all filter select controls for accessibility
- Remove unused imports (formatTimestamp)
- Fix ActivityEventRead type: include required task_id field
- Handle { agent: ... } and { comment: ... } envelope payloads from SSE
- Deduplicate SSE events by id before merging into cache
- Remove misleading docstring about fetch fallback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants