1+ // Agent health monitoring service
2+
3+ import { Agent , AgentHealthStatus } from "@/lib/config" ;
4+ import { testAgentConnection } from "@/lib/agent-storage" ;
5+
6+ // Cache for health check results to prevent excessive requests
7+ const healthCheckCache = new Map < string , { status : AgentHealthStatus ; timestamp : number } > ( ) ;
8+
9+ // Cache timeout in milliseconds (5 minutes)
10+ const CACHE_TIMEOUT = 5 * 60 * 1000 ;
11+
12+ /**
13+ * Check if a cached health status is still valid
14+ */
15+ function isCacheValid ( timestamp : number ) : boolean {
16+ return Date . now ( ) - timestamp < CACHE_TIMEOUT ;
17+ }
18+
19+ /**
20+ * Get cached health status for an agent
21+ */
22+ function getCachedHealth ( agentUrl : string ) : AgentHealthStatus | null {
23+ const cached = healthCheckCache . get ( agentUrl ) ;
24+ if ( cached && isCacheValid ( cached . timestamp ) ) {
25+ return cached . status ;
26+ }
27+ return null ;
28+ }
29+
30+ /**
31+ * Update cached health status for an agent
32+ */
33+ function setCachedHealth ( agentUrl : string , status : AgentHealthStatus ) : void {
34+ healthCheckCache . set ( agentUrl , {
35+ status,
36+ timestamp : Date . now ( ) ,
37+ } ) ;
38+ }
39+
40+ /**
41+ * Check the health of a single agent
42+ *
43+ * @param agent - The agent to check
44+ * @param force - Skip cache and force a new check
45+ * @returns Updated agent with health status
46+ */
47+ export async function checkAgentHealth ( agent : Agent , force : boolean = false ) : Promise < Agent > {
48+ // Return cached status if available and not forced
49+ if ( ! force ) {
50+ const cached = getCachedHealth ( agent . url ) ;
51+ if ( cached ) {
52+ return {
53+ ...agent ,
54+ health : cached ,
55+ lastChecked : cached . lastChecked ,
56+ } ;
57+ }
58+ }
59+
60+ const startTime = Date . now ( ) ;
61+
62+ try {
63+ const result = await testAgentConnection ( agent . url ) ;
64+ const responseTime = Date . now ( ) - startTime ;
65+
66+ const healthStatus : AgentHealthStatus = {
67+ isOnline : result . isOnline ,
68+ lastChecked : Date . now ( ) ,
69+ responseTime,
70+ error : result . error ,
71+ } ;
72+
73+ setCachedHealth ( agent . url , healthStatus ) ;
74+
75+ return {
76+ ...agent ,
77+ health : healthStatus ,
78+ lastChecked : healthStatus . lastChecked ,
79+ } ;
80+ } catch ( error ) {
81+ const healthStatus : AgentHealthStatus = {
82+ isOnline : false ,
83+ lastChecked : Date . now ( ) ,
84+ error : error instanceof Error ? error . message : "Unknown error" ,
85+ } ;
86+
87+ setCachedHealth ( agent . url , healthStatus ) ;
88+
89+ return {
90+ ...agent ,
91+ health : healthStatus ,
92+ lastChecked : healthStatus . lastChecked ,
93+ } ;
94+ }
95+ }
96+
97+ /**
98+ * Check the health of multiple agents
99+ *
100+ * @param agents - Array of agents to check
101+ * @param force - Skip cache and force new checks
102+ * @returns Array of agents with updated health status
103+ */
104+ export async function checkAgentsHealth ( agents : Agent [ ] , force : boolean = false ) : Promise < Agent [ ] > {
105+ // Run health checks in parallel for better performance
106+ const healthChecks = agents . map ( agent => checkAgentHealth ( agent , force ) ) ;
107+ return Promise . all ( healthChecks ) ;
108+ }
109+
110+ /**
111+ * Get a human-readable status message for an agent's health
112+ *
113+ * @param agent - The agent to get status for
114+ * @returns Status message string
115+ */
116+ export function getAgentStatusMessage ( agent : Agent ) : string {
117+ if ( ! agent . health ) {
118+ return "Unknown" ;
119+ }
120+
121+ if ( ! agent . health . isOnline ) {
122+ return agent . health . error || "Offline" ;
123+ }
124+
125+ if ( agent . health . responseTime ) {
126+ return `Online (${ agent . health . responseTime } ms)` ;
127+ }
128+
129+ return "Online" ;
130+ }
131+
132+ /**
133+ * Get status color for an agent based on health
134+ *
135+ * @param agent - The agent to get color for
136+ * @returns Color string for UI
137+ */
138+ export function getAgentStatusColor ( agent : Agent ) : "green" | "red" | "yellow" | "gray" {
139+ if ( ! agent . health ) {
140+ return "gray" ;
141+ }
142+
143+ if ( ! agent . health . isOnline ) {
144+ return "red" ;
145+ }
146+
147+ if ( agent . health . responseTime && agent . health . responseTime > 2000 ) {
148+ return "yellow" ;
149+ }
150+
151+ return "green" ;
152+ }
0 commit comments