@theaiinc/yggdrasil 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,227 +0,0 @@
1
- import axios from 'axios';
2
- import { getLogger } from './logger';
3
- import { nanoid } from 'nanoid';
4
- /**
5
- * Manages agent registration, health checks, and lifecycle
6
- * Uses stable, well-documented libraries for reliability
7
- */
8
- export class AgentManager {
9
- agents = new Map();
10
- logger = getLogger();
11
- healthCheckInterval = null;
12
- healthCheckPath;
13
- constructor(healthCheckPath = '/health') {
14
- this.healthCheckPath = healthCheckPath;
15
- }
16
- /**
17
- * Register a new agent
18
- */
19
- registerAgent(url, sessionId) {
20
- const agentId = nanoid();
21
- const agentInfo = {
22
- id: agentId,
23
- url,
24
- health: {
25
- status: 'unknown',
26
- lastCheck: new Date(),
27
- responseTime: 0,
28
- errorCount: 0,
29
- consecutiveFailures: 0,
30
- },
31
- metrics: {
32
- cpuUsage: 0,
33
- memoryUsage: 0,
34
- requestCount: 0,
35
- errorRate: 0,
36
- averageResponseTime: 0,
37
- activeConnections: 0,
38
- },
39
- lastSeen: new Date(),
40
- ...(sessionId && { sessionId }),
41
- };
42
- this.agents.set(agentId, agentInfo);
43
- this.logger.info('Agent registered', { agentId, url, sessionId });
44
- return agentId;
45
- }
46
- /**
47
- * Unregister an agent
48
- */
49
- unregisterAgent(agentId) {
50
- const removed = this.agents.delete(agentId);
51
- if (removed) {
52
- this.logger.info('Agent unregistered', { agentId });
53
- }
54
- return removed;
55
- }
56
- /**
57
- * Get all healthy agents
58
- */
59
- getHealthyAgents() {
60
- return Array.from(this.agents.values()).filter(agent => agent.health.status === 'healthy');
61
- }
62
- /**
63
- * Get agent by ID
64
- */
65
- getAgent(agentId) {
66
- return this.agents.get(agentId);
67
- }
68
- /**
69
- * Get agent by session ID
70
- */
71
- getAgentBySession(sessionId) {
72
- return Array.from(this.agents.values()).find(agent => agent.sessionId === sessionId);
73
- }
74
- /**
75
- * Start health check monitoring
76
- */
77
- startHealthChecks(intervalMs = 30000) {
78
- if (this.healthCheckInterval) {
79
- clearInterval(this.healthCheckInterval);
80
- }
81
- this.healthCheckInterval = setInterval(() => {
82
- this.performHealthChecks();
83
- }, intervalMs);
84
- this.logger.info('Health checks started', { intervalMs });
85
- }
86
- /**
87
- * Stop health check monitoring
88
- */
89
- stopHealthChecks() {
90
- if (this.healthCheckInterval) {
91
- clearInterval(this.healthCheckInterval);
92
- this.healthCheckInterval = null;
93
- this.logger.info('Health checks stopped');
94
- }
95
- }
96
- /**
97
- * Perform health check on a specific agent
98
- */
99
- async checkAgentHealth(agentId) {
100
- const agent = this.agents.get(agentId);
101
- if (!agent) {
102
- return {
103
- agentId,
104
- healthy: false,
105
- responseTime: 0,
106
- error: 'Agent not found',
107
- timestamp: new Date(),
108
- };
109
- }
110
- const startTime = Date.now();
111
- try {
112
- const response = await axios.get(`${agent.url}${this.healthCheckPath}`, { timeout: 5000 });
113
- const responseTime = Date.now() - startTime;
114
- const healthy = response.status === 200;
115
- // Update agent health
116
- agent.health = {
117
- status: healthy ? 'healthy' : 'unhealthy',
118
- lastCheck: new Date(),
119
- responseTime,
120
- errorCount: healthy
121
- ? agent.health.errorCount
122
- : agent.health.errorCount + 1,
123
- consecutiveFailures: healthy ? 0 : agent.health.consecutiveFailures + 1,
124
- };
125
- agent.lastSeen = new Date();
126
- this.logger.info('Agent health check completed', {
127
- agentId,
128
- healthy,
129
- responseTime,
130
- status: agent.health.status,
131
- });
132
- return {
133
- agentId,
134
- healthy,
135
- responseTime,
136
- timestamp: new Date(),
137
- };
138
- }
139
- catch (error) {
140
- const responseTime = Date.now() - startTime;
141
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
142
- // Update agent health
143
- agent.health = {
144
- status: 'unhealthy',
145
- lastCheck: new Date(),
146
- responseTime,
147
- errorCount: agent.health.errorCount + 1,
148
- consecutiveFailures: agent.health.consecutiveFailures + 1,
149
- };
150
- this.logger.warn('Agent health check failed', {
151
- agentId,
152
- error: errorMessage,
153
- responseTime,
154
- });
155
- return {
156
- agentId,
157
- healthy: false,
158
- responseTime,
159
- error: errorMessage,
160
- timestamp: new Date(),
161
- };
162
- }
163
- }
164
- /**
165
- * Perform health checks on all agents
166
- */
167
- async performHealthChecks() {
168
- const promises = Array.from(this.agents.keys()).map(agentId => this.checkAgentHealth(agentId));
169
- try {
170
- await Promise.allSettled(promises);
171
- }
172
- catch (error) {
173
- this.logger.error('Health check batch failed', { error });
174
- }
175
- }
176
- /**
177
- * Update agent metrics
178
- */
179
- updateAgentMetrics(agentId, metrics) {
180
- const agent = this.agents.get(agentId);
181
- if (agent) {
182
- agent.metrics = { ...agent.metrics, ...metrics };
183
- agent.lastSeen = new Date();
184
- }
185
- }
186
- /**
187
- * Get all agents
188
- */
189
- getAllAgents() {
190
- return Array.from(this.agents.values());
191
- }
192
- /**
193
- * Get agent count by health status
194
- */
195
- getAgentCounts() {
196
- const agents = this.getAllAgents();
197
- return {
198
- total: agents.length,
199
- healthy: agents.filter(a => a.health.status === 'healthy').length,
200
- unhealthy: agents.filter(a => a.health.status === 'unhealthy').length,
201
- };
202
- }
203
- /**
204
- * Clean up stale agents (not seen for more than threshold)
205
- */
206
- cleanupStaleAgents(thresholdMs = 300000) {
207
- const now = new Date();
208
- const staleAgents = [];
209
- for (const [agentId, agent] of this.agents.entries()) {
210
- const timeSinceLastSeen = now.getTime() - agent.lastSeen.getTime();
211
- if (timeSinceLastSeen > thresholdMs) {
212
- staleAgents.push(agentId);
213
- }
214
- }
215
- staleAgents.forEach(agentId => {
216
- this.unregisterAgent(agentId);
217
- });
218
- if (staleAgents.length > 0) {
219
- this.logger.info('Cleaned up stale agents', {
220
- count: staleAgents.length,
221
- agentIds: staleAgents,
222
- });
223
- }
224
- return staleAgents.length;
225
- }
226
- }
227
- //# sourceMappingURL=agent-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent-manager.js","sourceRoot":"","sources":["../../../src/services/agent-manager.ts"],"names":[],"mappings":"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"}
@@ -1,62 +0,0 @@
1
- import { AgentInfo, RequestContext } from '@/types';
2
- /**
3
- * Load balancer for distributing requests across healthy agents
4
- * Implements multiple algorithms and session affinity
5
- */
6
- export declare class LoadBalancer {
7
- private logger;
8
- private currentIndex;
9
- private sessionMap;
10
- private algorithm;
11
- private sessionAffinity;
12
- private stickySessionTimeout;
13
- constructor(algorithm?: 'round-robin' | 'least-connections' | 'ip-hash' | 'weighted', sessionAffinity?: boolean, stickySessionTimeout?: number);
14
- /**
15
- * Select an agent for the given request
16
- */
17
- selectAgent(agents: AgentInfo[], context: RequestContext): AgentInfo | null;
18
- /**
19
- * Round-robin algorithm
20
- */
21
- private roundRobin;
22
- /**
23
- * Least connections algorithm
24
- */
25
- private leastConnections;
26
- /**
27
- * IP hash algorithm (uses request ID as hash input)
28
- */
29
- private ipHash;
30
- /**
31
- * Weighted algorithm (based on agent health and performance)
32
- */
33
- private weighted;
34
- /**
35
- * Simple hash function for IP hash algorithm
36
- */
37
- private hashCode;
38
- /**
39
- * Clean up stale session mappings
40
- */
41
- private cleanupStaleSessions;
42
- /**
43
- * Remove session mapping
44
- */
45
- removeSession(sessionId: string): void;
46
- /**
47
- * Get session statistics
48
- */
49
- getSessionStats(): {
50
- totalSessions: number;
51
- sessionMapSize: number;
52
- };
53
- /**
54
- * Update algorithm
55
- */
56
- setAlgorithm(algorithm: 'round-robin' | 'least-connections' | 'ip-hash' | 'weighted'): void;
57
- /**
58
- * Update session affinity settings
59
- */
60
- setSessionAffinity(enabled: boolean, timeout?: number): void;
61
- }
62
- //# sourceMappingURL=load-balancer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"load-balancer.d.ts","sourceRoot":"","sources":["../../../src/services/load-balancer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGpD;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,SAAS,CAIF;IACf,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,oBAAoB,CAAS;gBAGnC,SAAS,GACL,aAAa,GACb,mBAAmB,GACnB,SAAS,GACT,UAA0B,EAC9B,eAAe,GAAE,OAAc,EAC/B,oBAAoB,GAAE,MAAgB;IAOxC;;OAEG;IACI,WAAW,CAChB,MAAM,EAAE,SAAS,EAAE,EACnB,OAAO,EAAE,cAAc,GACtB,SAAS,GAAG,IAAI;IA2EnB;;OAEG;IACH,OAAO,CAAC,UAAU;IASlB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;OAEG;IACH,OAAO,CAAC,MAAM;IASd;;OAEG;IACH,OAAO,CAAC,QAAQ;IA+BhB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAUhB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA+B5B;;OAEG;IACI,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI7C;;OAEG;IACI,eAAe,IAAI;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;IAO3E;;OAEG;IACI,YAAY,CACjB,SAAS,EAAE,aAAa,GAAG,mBAAmB,GAAG,SAAS,GAAG,UAAU,GACtE,IAAI;IAKP;;OAEG;IACI,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;CAUpE"}
@@ -1,221 +0,0 @@
1
- import { getLogger } from './logger';
2
- /**
3
- * Load balancer for distributing requests across healthy agents
4
- * Implements multiple algorithms and session affinity
5
- */
6
- export class LoadBalancer {
7
- logger = getLogger();
8
- currentIndex = 0;
9
- sessionMap = new Map(); // sessionId -> agentId
10
- algorithm;
11
- sessionAffinity;
12
- stickySessionTimeout;
13
- constructor(algorithm = 'round-robin', sessionAffinity = true, stickySessionTimeout = 3600000 // 1 hour
14
- ) {
15
- this.algorithm = algorithm;
16
- this.sessionAffinity = sessionAffinity;
17
- this.stickySessionTimeout = stickySessionTimeout;
18
- }
19
- /**
20
- * Select an agent for the given request
21
- */
22
- selectAgent(agents, context) {
23
- if (agents.length === 0) {
24
- this.logger.warn('No healthy agents available');
25
- return null;
26
- }
27
- // Filter to only healthy agents
28
- const healthyAgents = agents.filter(agent => agent.health.status === 'healthy');
29
- if (healthyAgents.length === 0) {
30
- this.logger.warn('No healthy agents available');
31
- return null;
32
- }
33
- // Check session affinity first
34
- if (this.sessionAffinity && context.sessionId) {
35
- const sessionAgentId = this.sessionMap.get(context.sessionId);
36
- if (sessionAgentId) {
37
- const sessionAgent = healthyAgents.find(agent => agent.id === sessionAgentId);
38
- if (sessionAgent) {
39
- this.logger.debug('Using session affinity', {
40
- sessionId: context.sessionId,
41
- agentId: sessionAgent.id,
42
- });
43
- return sessionAgent;
44
- }
45
- else {
46
- // Remove stale session mapping
47
- this.sessionMap.delete(context.sessionId);
48
- }
49
- }
50
- }
51
- // Select agent based on algorithm
52
- let selectedAgent = null;
53
- try {
54
- switch (this.algorithm) {
55
- case 'round-robin':
56
- selectedAgent = this.roundRobin(healthyAgents);
57
- break;
58
- case 'least-connections':
59
- selectedAgent = this.leastConnections(healthyAgents);
60
- break;
61
- case 'ip-hash':
62
- selectedAgent = this.ipHash(healthyAgents, context);
63
- break;
64
- case 'weighted':
65
- selectedAgent = this.weighted(healthyAgents);
66
- break;
67
- default:
68
- selectedAgent = this.roundRobin(healthyAgents);
69
- }
70
- }
71
- catch (error) {
72
- this.logger.error('Agent selection failed', {
73
- error,
74
- algorithm: this.algorithm,
75
- });
76
- return null;
77
- }
78
- // Update session mapping if session affinity is enabled
79
- if (this.sessionAffinity && context.sessionId && selectedAgent) {
80
- this.sessionMap.set(context.sessionId, selectedAgent.id);
81
- // Clean up old session mappings periodically
82
- this.cleanupStaleSessions();
83
- }
84
- return selectedAgent;
85
- }
86
- /**
87
- * Round-robin algorithm
88
- */
89
- roundRobin(agents) {
90
- const agent = agents[this.currentIndex % agents.length];
91
- if (!agent) {
92
- throw new Error('No agents available for round-robin selection');
93
- }
94
- this.currentIndex = (this.currentIndex + 1) % agents.length;
95
- return agent;
96
- }
97
- /**
98
- * Least connections algorithm
99
- */
100
- leastConnections(agents) {
101
- return agents.reduce((min, current) => current.metrics.activeConnections < min.metrics.activeConnections
102
- ? current
103
- : min);
104
- }
105
- /**
106
- * IP hash algorithm (uses request ID as hash input)
107
- */
108
- ipHash(agents, context) {
109
- const hash = this.hashCode(context.id);
110
- const agent = agents[Math.abs(hash) % agents.length];
111
- if (!agent) {
112
- throw new Error('No agents available for IP hash selection');
113
- }
114
- return agent;
115
- }
116
- /**
117
- * Weighted algorithm (based on agent health and performance)
118
- */
119
- weighted(agents) {
120
- const weights = agents.map(agent => {
121
- let weight = 1;
122
- // Reduce weight for agents with high error rates
123
- if (agent.metrics.errorRate > 0.1) {
124
- weight *= 0.5;
125
- }
126
- // Reduce weight for agents with high response times
127
- if (agent.metrics.averageResponseTime > 1000) {
128
- weight *= 0.7;
129
- }
130
- // Increase weight for agents with low CPU usage
131
- if (agent.metrics.cpuUsage < 0.5) {
132
- weight *= 1.2;
133
- }
134
- return { agent, weight };
135
- });
136
- // Sort by weight and return the highest weighted agent
137
- weights.sort((a, b) => b.weight - a.weight);
138
- const selectedAgent = weights[0]?.agent;
139
- if (!selectedAgent) {
140
- throw new Error('No agents available for weighted selection');
141
- }
142
- return selectedAgent;
143
- }
144
- /**
145
- * Simple hash function for IP hash algorithm
146
- */
147
- hashCode(str) {
148
- let hash = 0;
149
- for (let i = 0; i < str.length; i++) {
150
- const char = str.charCodeAt(i);
151
- hash = (hash << 5) - hash + char;
152
- hash = hash & hash; // Convert to 32-bit integer
153
- }
154
- return hash;
155
- }
156
- /**
157
- * Clean up stale session mappings
158
- */
159
- cleanupStaleSessions() {
160
- const staleSessions = [];
161
- // This is a simplified cleanup - in a real implementation,
162
- // you'd want to track session creation times
163
- if (this.sessionMap.size > 1000) {
164
- // If we have too many sessions, clean up some randomly
165
- const sessions = Array.from(this.sessionMap.keys());
166
- const toRemove = Math.floor(sessions.length * 0.1); // Remove 10%
167
- for (let i = 0; i < toRemove; i++) {
168
- const randomIndex = Math.floor(Math.random() * sessions.length);
169
- const sessionId = sessions[randomIndex];
170
- if (sessionId) {
171
- staleSessions.push(sessionId);
172
- sessions.splice(randomIndex, 1);
173
- }
174
- }
175
- }
176
- staleSessions.forEach(sessionId => {
177
- this.sessionMap.delete(sessionId);
178
- });
179
- if (staleSessions.length > 0) {
180
- this.logger.debug('Cleaned up stale sessions', {
181
- count: staleSessions.length,
182
- });
183
- }
184
- }
185
- /**
186
- * Remove session mapping
187
- */
188
- removeSession(sessionId) {
189
- this.sessionMap.delete(sessionId);
190
- }
191
- /**
192
- * Get session statistics
193
- */
194
- getSessionStats() {
195
- return {
196
- totalSessions: this.sessionMap.size,
197
- sessionMapSize: this.sessionMap.size,
198
- };
199
- }
200
- /**
201
- * Update algorithm
202
- */
203
- setAlgorithm(algorithm) {
204
- this.algorithm = algorithm;
205
- this.logger.info('Load balancer algorithm updated', { algorithm });
206
- }
207
- /**
208
- * Update session affinity settings
209
- */
210
- setSessionAffinity(enabled, timeout) {
211
- this.sessionAffinity = enabled;
212
- if (timeout) {
213
- this.stickySessionTimeout = timeout;
214
- }
215
- this.logger.info('Session affinity settings updated', {
216
- enabled: this.sessionAffinity,
217
- timeout: this.stickySessionTimeout,
218
- });
219
- }
220
- }
221
- //# sourceMappingURL=load-balancer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"load-balancer.js","sourceRoot":"","sources":["../../../src/services/load-balancer.ts"],"names":[],"mappings":"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"}