From 73309c7e63ce96b2ced3b050dc5ac69390165b3d Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Fri, 17 Apr 2026 12:43:51 +0200 Subject: [PATCH] feat(ui): replace useAgentEvents with useInfiniteAgentEvents Cursor-paginated timeline stream matching the new /agents/events endpoint. Consumers (AgentHealth, AgentInstance) updated in follow-up commits. --- ui/src/api/queries/agents.ts | 51 +++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/ui/src/api/queries/agents.ts b/ui/src/api/queries/agents.ts index 0e18f846..a37aa3a2 100644 --- a/ui/src/api/queries/agents.ts +++ b/ui/src/api/queries/agents.ts @@ -3,6 +3,7 @@ import { config } from '../../config'; import { useAuthStore } from '../../auth/auth-store'; import { useEnvironmentStore } from '../environment-store'; import { useRefreshInterval } from './use-refresh-interval'; +import { useInfiniteStream, type UseInfiniteStreamResult } from '../../hooks/useInfiniteStream'; export function useAgents(status?: string, application?: string) { const environment = useEnvironmentStore((s) => s.environment); @@ -31,18 +32,45 @@ export function useAgents(status?: string, application?: string) { }); } -export function useAgentEvents(appId?: string, agentId?: string, limit = 50, toOverride?: string) { +export interface AgentEventResponse { + id: number; + instanceId: string; + applicationId: string; + eventType: string; + detail: string; + timestamp: string; +} + +interface AgentEventPageResponse { + data: AgentEventResponse[]; + nextCursor: string | null; + hasMore: boolean; +} + +export interface UseInfiniteAgentEventsArgs { + appId?: string; + agentId?: string; + isAtTop: boolean; + pageSize?: number; +} + +export function useInfiniteAgentEvents( + args: UseInfiniteAgentEventsArgs, +): UseInfiniteStreamResult { const environment = useEnvironmentStore((s) => s.environment); - const refetchInterval = useRefreshInterval(15_000); - return useQuery({ - queryKey: ['agents', 'events', environment, appId, agentId, limit, toOverride], - queryFn: async () => { + const pageSize = args.pageSize ?? 50; + + return useInfiniteStream({ + queryKey: ['agents', 'events', 'infinite', environment ?? '', args.appId ?? '', args.agentId ?? '', pageSize], + enabled: !!environment, + isAtTop: args.isAtTop, + fetchPage: async (cursor) => { const token = useAuthStore.getState().accessToken; const params = new URLSearchParams(); - if (appId) params.set('appId', appId); - if (agentId) params.set('agentId', agentId); - if (toOverride) params.set('to', toOverride); - params.set('limit', String(limit)); + if (args.appId) params.set('appId', args.appId); + if (args.agentId) params.set('agentId', args.agentId); + if (cursor) params.set('cursor', cursor); + params.set('limit', String(pageSize)); const res = await fetch( `${config.apiBaseUrl}/environments/${encodeURIComponent(environment!)}/agents/events?${params}`, { @@ -52,9 +80,8 @@ export function useAgentEvents(appId?: string, agentId?: string, limit = 50, toO }, }); if (!res.ok) throw new Error('Failed to load agent events'); - return res.json(); + const page: AgentEventPageResponse = await res.json(); + return { data: page.data, nextCursor: page.nextCursor, hasMore: page.hasMore }; }, - enabled: !!environment, - refetchInterval, }); }