@loxia-labs/loxia-autopilot-one 1.0.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.
Files changed (80) hide show
  1. package/LICENSE +267 -0
  2. package/README.md +509 -0
  3. package/bin/cli.js +117 -0
  4. package/package.json +94 -0
  5. package/scripts/install-scanners.js +236 -0
  6. package/src/analyzers/CSSAnalyzer.js +297 -0
  7. package/src/analyzers/ConfigValidator.js +690 -0
  8. package/src/analyzers/ESLintAnalyzer.js +320 -0
  9. package/src/analyzers/JavaScriptAnalyzer.js +261 -0
  10. package/src/analyzers/PrettierFormatter.js +247 -0
  11. package/src/analyzers/PythonAnalyzer.js +266 -0
  12. package/src/analyzers/SecurityAnalyzer.js +729 -0
  13. package/src/analyzers/TypeScriptAnalyzer.js +247 -0
  14. package/src/analyzers/codeCloneDetector/analyzer.js +344 -0
  15. package/src/analyzers/codeCloneDetector/detector.js +203 -0
  16. package/src/analyzers/codeCloneDetector/index.js +160 -0
  17. package/src/analyzers/codeCloneDetector/parser.js +199 -0
  18. package/src/analyzers/codeCloneDetector/reporter.js +148 -0
  19. package/src/analyzers/codeCloneDetector/scanner.js +59 -0
  20. package/src/core/agentPool.js +1474 -0
  21. package/src/core/agentScheduler.js +2147 -0
  22. package/src/core/contextManager.js +709 -0
  23. package/src/core/messageProcessor.js +732 -0
  24. package/src/core/orchestrator.js +548 -0
  25. package/src/core/stateManager.js +877 -0
  26. package/src/index.js +631 -0
  27. package/src/interfaces/cli.js +549 -0
  28. package/src/interfaces/webServer.js +2162 -0
  29. package/src/modules/fileExplorer/controller.js +280 -0
  30. package/src/modules/fileExplorer/index.js +37 -0
  31. package/src/modules/fileExplorer/middleware.js +92 -0
  32. package/src/modules/fileExplorer/routes.js +125 -0
  33. package/src/modules/fileExplorer/types.js +44 -0
  34. package/src/services/aiService.js +1232 -0
  35. package/src/services/apiKeyManager.js +164 -0
  36. package/src/services/benchmarkService.js +366 -0
  37. package/src/services/budgetService.js +539 -0
  38. package/src/services/contextInjectionService.js +247 -0
  39. package/src/services/conversationCompactionService.js +637 -0
  40. package/src/services/errorHandler.js +810 -0
  41. package/src/services/fileAttachmentService.js +544 -0
  42. package/src/services/modelRouterService.js +366 -0
  43. package/src/services/modelsService.js +322 -0
  44. package/src/services/qualityInspector.js +796 -0
  45. package/src/services/tokenCountingService.js +536 -0
  46. package/src/tools/agentCommunicationTool.js +1344 -0
  47. package/src/tools/agentDelayTool.js +485 -0
  48. package/src/tools/asyncToolManager.js +604 -0
  49. package/src/tools/baseTool.js +800 -0
  50. package/src/tools/browserTool.js +920 -0
  51. package/src/tools/cloneDetectionTool.js +621 -0
  52. package/src/tools/dependencyResolverTool.js +1215 -0
  53. package/src/tools/fileContentReplaceTool.js +875 -0
  54. package/src/tools/fileSystemTool.js +1107 -0
  55. package/src/tools/fileTreeTool.js +853 -0
  56. package/src/tools/imageTool.js +901 -0
  57. package/src/tools/importAnalyzerTool.js +1060 -0
  58. package/src/tools/jobDoneTool.js +248 -0
  59. package/src/tools/seekTool.js +956 -0
  60. package/src/tools/staticAnalysisTool.js +1778 -0
  61. package/src/tools/taskManagerTool.js +2873 -0
  62. package/src/tools/terminalTool.js +2304 -0
  63. package/src/tools/webTool.js +1430 -0
  64. package/src/types/agent.js +519 -0
  65. package/src/types/contextReference.js +972 -0
  66. package/src/types/conversation.js +730 -0
  67. package/src/types/toolCommand.js +747 -0
  68. package/src/utilities/attachmentValidator.js +292 -0
  69. package/src/utilities/configManager.js +582 -0
  70. package/src/utilities/constants.js +722 -0
  71. package/src/utilities/directoryAccessManager.js +535 -0
  72. package/src/utilities/fileProcessor.js +307 -0
  73. package/src/utilities/logger.js +436 -0
  74. package/src/utilities/tagParser.js +1246 -0
  75. package/src/utilities/toolConstants.js +317 -0
  76. package/web-ui/build/index.html +15 -0
  77. package/web-ui/build/logo.png +0 -0
  78. package/web-ui/build/logo2.png +0 -0
  79. package/web-ui/build/static/index-CjkkcnFA.js +344 -0
  80. package/web-ui/build/static/index-Dy2bYbOa.css +1 -0
@@ -0,0 +1,519 @@
1
+ /**
2
+ * Agent Data Model - Type definitions and validation for AI agents
3
+ *
4
+ * Purpose:
5
+ * - Define the structure and properties of AI agents
6
+ * - Provide validation functions for agent data
7
+ * - Ensure data integrity and consistency
8
+ */
9
+
10
+ import { AGENT_STATUS, AGENT_TYPES, MODELS } from '../utilities/constants.js';
11
+
12
+ /**
13
+ * Agent data model
14
+ * @typedef {Object} Agent
15
+ * @property {string} id - Unique agent identifier
16
+ * @property {string} name - Human-readable agent name
17
+ * @property {string} type - Agent type (user-created, system-agent, agent-engineer)
18
+ * @property {string} status - Current agent status (active, idle, busy, suspended, paused)
19
+ * @property {string} currentModel - AI model being used
20
+ * @property {string} systemPrompt - System prompt defining agent behavior
21
+ * @property {AgentConfiguration} configuration - Agent configuration settings
22
+ * @property {AgentMetrics} metrics - Performance and usage metrics
23
+ * @property {AgentState} state - Current agent state information
24
+ * @property {string} createdAt - ISO timestamp of creation
25
+ * @property {string} updatedAt - ISO timestamp of last update
26
+ * @property {string} lastActivity - ISO timestamp of last activity
27
+ * @property {string|null} pausedUntil - ISO timestamp when pause expires (null if not paused)
28
+ * @property {string|null} pauseReason - Reason for current pause (null if not paused)
29
+ * @property {Object} metadata - Additional metadata and tags
30
+ */
31
+
32
+ /**
33
+ * Agent configuration settings
34
+ * @typedef {Object} AgentConfiguration
35
+ * @property {number} maxContextLength - Maximum context length in tokens
36
+ * @property {number} temperature - Sampling temperature (0.0-1.0)
37
+ * @property {number} maxTokens - Maximum tokens per response
38
+ * @property {number} timeout - Request timeout in milliseconds
39
+ * @property {boolean} persistConversations - Whether to persist conversation history
40
+ * @property {string[]} enabledTools - List of enabled tool names
41
+ * @property {Object} toolConfigurations - Tool-specific configurations
42
+ * @property {boolean} autoRetry - Whether to automatically retry failed requests
43
+ * @property {number} maxRetries - Maximum number of retry attempts
44
+ * @property {Object} customSettings - Custom configuration properties
45
+ */
46
+
47
+ /**
48
+ * Agent performance and usage metrics
49
+ * @typedef {Object} AgentMetrics
50
+ * @property {number} totalMessages - Total messages processed
51
+ * @property {number} totalTokensUsed - Total tokens consumed
52
+ * @property {number} totalCost - Total cost incurred (USD)
53
+ * @property {number} averageResponseTime - Average response time in milliseconds
54
+ * @property {number} successRate - Success rate (0.0-1.0)
55
+ * @property {number} errorCount - Total number of errors
56
+ * @property {number} toolExecutions - Number of tool executions
57
+ * @property {number} conversationsStarted - Number of conversations initiated
58
+ * @property {Object} dailyUsage - Daily usage statistics
59
+ * @property {Object} weeklyUsage - Weekly usage statistics
60
+ * @property {Object} monthlyUsage - Monthly usage statistics
61
+ * @property {string} lastMetricsUpdate - ISO timestamp of last metrics update
62
+ */
63
+
64
+ /**
65
+ * Agent state information
66
+ * @typedef {Object} AgentState
67
+ * @property {string} currentConversationId - ID of current active conversation
68
+ * @property {number} messageCount - Number of messages in current conversation
69
+ * @property {Object} context - Current conversation context
70
+ * @property {string[]} activeTools - Currently executing tools
71
+ * @property {Object} pendingOperations - Pending asynchronous operations
72
+ * @property {Object} cache - Cached data and responses
73
+ * @property {boolean} isProcessing - Whether agent is currently processing
74
+ * @property {string|null} lastError - Last error encountered (null if none)
75
+ * @property {Object} sessionData - Session-specific data
76
+ */
77
+
78
+ /**
79
+ * Agent creation parameters
80
+ * @typedef {Object} AgentCreationParams
81
+ * @property {string} name - Agent name (required)
82
+ * @property {string} [type=user-created] - Agent type
83
+ * @property {string} [model=anthropic-sonnet] - AI model to use
84
+ * @property {string} [systemPrompt=''] - System prompt
85
+ * @property {Partial<AgentConfiguration>} [configuration] - Initial configuration
86
+ * @property {Object} [metadata] - Initial metadata
87
+ * @property {string[]} [enabledTools] - Initial enabled tools
88
+ */
89
+
90
+ /**
91
+ * Agent update parameters
92
+ * @typedef {Object} AgentUpdateParams
93
+ * @property {string} [name] - New agent name
94
+ * @property {string} [systemPrompt] - New system prompt
95
+ * @property {string} [currentModel] - New AI model
96
+ * @property {Partial<AgentConfiguration>} [configuration] - Configuration updates
97
+ * @property {Object} [metadata] - Metadata updates
98
+ * @property {string[]} [enabledTools] - Updated enabled tools list
99
+ */
100
+
101
+ /**
102
+ * Agent validation functions
103
+ */
104
+ export class AgentValidator {
105
+ /**
106
+ * Validate agent data structure
107
+ * @param {Object} agent - Agent data to validate
108
+ * @returns {Object} Validation result
109
+ */
110
+ static validate(agent) {
111
+ const errors = [];
112
+ const warnings = [];
113
+
114
+ // Required fields
115
+ if (!agent.id || typeof agent.id !== 'string') {
116
+ errors.push('Agent ID is required and must be a string');
117
+ }
118
+
119
+ if (!agent.name || typeof agent.name !== 'string') {
120
+ errors.push('Agent name is required and must be a string');
121
+ }
122
+
123
+ if (agent.name && agent.name.length < 2) {
124
+ errors.push('Agent name must be at least 2 characters long');
125
+ }
126
+
127
+ if (agent.name && agent.name.length > 100) {
128
+ errors.push('Agent name must be less than 100 characters');
129
+ }
130
+
131
+ // Type validation
132
+ if (agent.type && !Object.values(AGENT_TYPES).includes(agent.type)) {
133
+ errors.push(`Invalid agent type: ${agent.type}`);
134
+ }
135
+
136
+ // Status validation
137
+ if (agent.status && !Object.values(AGENT_STATUS).includes(agent.status)) {
138
+ errors.push(`Invalid agent status: ${agent.status}`);
139
+ }
140
+
141
+ // Model validation
142
+ if (agent.currentModel && !Object.values(MODELS).includes(agent.currentModel)) {
143
+ warnings.push(`Unknown AI model: ${agent.currentModel}`);
144
+ }
145
+
146
+ // System prompt validation
147
+ if (agent.systemPrompt && typeof agent.systemPrompt !== 'string') {
148
+ errors.push('System prompt must be a string');
149
+ }
150
+
151
+ if (agent.systemPrompt && agent.systemPrompt.length > 10000) {
152
+ warnings.push('System prompt is very long (>10000 characters)');
153
+ }
154
+
155
+ // Configuration validation
156
+ if (agent.configuration) {
157
+ const configValidation = this.validateConfiguration(agent.configuration);
158
+ errors.push(...configValidation.errors);
159
+ warnings.push(...configValidation.warnings);
160
+ }
161
+
162
+ // Timestamp validation
163
+ const timestampFields = ['createdAt', 'updatedAt', 'lastActivity', 'pausedUntil'];
164
+ timestampFields.forEach(field => {
165
+ if (agent[field] && !this.isValidTimestamp(agent[field])) {
166
+ errors.push(`Invalid timestamp for ${field}: ${agent[field]}`);
167
+ }
168
+ });
169
+
170
+ return {
171
+ isValid: errors.length === 0,
172
+ errors,
173
+ warnings
174
+ };
175
+ }
176
+
177
+ /**
178
+ * Validate agent configuration
179
+ * @param {Object} configuration - Configuration to validate
180
+ * @returns {Object} Validation result
181
+ */
182
+ static validateConfiguration(configuration) {
183
+ const errors = [];
184
+ const warnings = [];
185
+
186
+ if (configuration.maxContextLength && typeof configuration.maxContextLength !== 'number') {
187
+ errors.push('maxContextLength must be a number');
188
+ }
189
+
190
+ if (configuration.maxContextLength && configuration.maxContextLength < 1000) {
191
+ warnings.push('maxContextLength is very low (<1000)');
192
+ }
193
+
194
+ if (configuration.temperature !== undefined) {
195
+ if (typeof configuration.temperature !== 'number') {
196
+ errors.push('temperature must be a number');
197
+ } else if (configuration.temperature < 0 || configuration.temperature > 2) {
198
+ errors.push('temperature must be between 0 and 2');
199
+ }
200
+ }
201
+
202
+ if (configuration.maxTokens && typeof configuration.maxTokens !== 'number') {
203
+ errors.push('maxTokens must be a number');
204
+ }
205
+
206
+ if (configuration.timeout && typeof configuration.timeout !== 'number') {
207
+ errors.push('timeout must be a number');
208
+ }
209
+
210
+ if (configuration.timeout && configuration.timeout < 1000) {
211
+ warnings.push('timeout is very low (<1000ms)');
212
+ }
213
+
214
+ if (configuration.maxRetries && typeof configuration.maxRetries !== 'number') {
215
+ errors.push('maxRetries must be a number');
216
+ }
217
+
218
+ if (configuration.enabledTools && !Array.isArray(configuration.enabledTools)) {
219
+ errors.push('enabledTools must be an array');
220
+ }
221
+
222
+ return { errors, warnings };
223
+ }
224
+
225
+ /**
226
+ * Validate agent creation parameters
227
+ * @param {Object} params - Creation parameters to validate
228
+ * @returns {Object} Validation result
229
+ */
230
+ static validateCreationParams(params) {
231
+ const errors = [];
232
+ const warnings = [];
233
+
234
+ if (!params.name || typeof params.name !== 'string') {
235
+ errors.push('Agent name is required and must be a string');
236
+ }
237
+
238
+ if (params.name && params.name.length < 2) {
239
+ errors.push('Agent name must be at least 2 characters long');
240
+ }
241
+
242
+ if (params.type && !Object.values(AGENT_TYPES).includes(params.type)) {
243
+ errors.push(`Invalid agent type: ${params.type}`);
244
+ }
245
+
246
+ if (params.model && !Object.values(MODELS).includes(params.model)) {
247
+ warnings.push(`Unknown AI model: ${params.model}`);
248
+ }
249
+
250
+ if (params.systemPrompt && typeof params.systemPrompt !== 'string') {
251
+ errors.push('System prompt must be a string');
252
+ }
253
+
254
+ if (params.enabledTools && !Array.isArray(params.enabledTools)) {
255
+ errors.push('enabledTools must be an array');
256
+ }
257
+
258
+ return {
259
+ isValid: errors.length === 0,
260
+ errors,
261
+ warnings
262
+ };
263
+ }
264
+
265
+ /**
266
+ * Check if a timestamp is valid ISO string
267
+ * @param {string} timestamp - Timestamp to validate
268
+ * @returns {boolean} True if valid
269
+ */
270
+ static isValidTimestamp(timestamp) {
271
+ if (typeof timestamp !== 'string') return false;
272
+ const date = new Date(timestamp);
273
+ return date instanceof Date && !isNaN(date.getTime());
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Agent factory functions
279
+ */
280
+ export class AgentFactory {
281
+ /**
282
+ * Create a new agent with default values
283
+ * @param {AgentCreationParams} params - Creation parameters
284
+ * @returns {Agent} New agent object
285
+ */
286
+ static create(params) {
287
+ // Validate parameters
288
+ const validation = AgentValidator.validateCreationParams(params);
289
+ if (!validation.isValid) {
290
+ throw new Error(`Invalid agent parameters: ${validation.errors.join(', ')}`);
291
+ }
292
+
293
+ const now = new Date().toISOString();
294
+ const agentId = this.generateAgentId();
295
+
296
+ return {
297
+ id: agentId,
298
+ name: params.name,
299
+ type: params.type || AGENT_TYPES.USER_CREATED,
300
+ status: AGENT_STATUS.IDLE,
301
+ currentModel: params.model || MODELS.ANTHROPIC_SONNET,
302
+ systemPrompt: params.systemPrompt || '',
303
+ configuration: this.createDefaultConfiguration(params.configuration),
304
+ metrics: this.createDefaultMetrics(),
305
+ state: this.createDefaultState(),
306
+ createdAt: now,
307
+ updatedAt: now,
308
+ lastActivity: now,
309
+ pausedUntil: null,
310
+ pauseReason: null,
311
+ metadata: params.metadata || {}
312
+ };
313
+ }
314
+
315
+ /**
316
+ * Create default agent configuration
317
+ * @param {Partial<AgentConfiguration>} overrides - Configuration overrides
318
+ * @returns {AgentConfiguration} Default configuration
319
+ */
320
+ static createDefaultConfiguration(overrides = {}) {
321
+ return {
322
+ maxContextLength: 50000,
323
+ temperature: 0.7,
324
+ maxTokens: 4096,
325
+ timeout: 30000,
326
+ persistConversations: true,
327
+ enabledTools: ['terminal', 'filesys', 'editor'],
328
+ toolConfigurations: {},
329
+ autoRetry: true,
330
+ maxRetries: 3,
331
+ customSettings: {},
332
+ ...overrides
333
+ };
334
+ }
335
+
336
+ /**
337
+ * Create default agent metrics
338
+ * @returns {AgentMetrics} Default metrics
339
+ */
340
+ static createDefaultMetrics() {
341
+ const now = new Date().toISOString();
342
+
343
+ return {
344
+ totalMessages: 0,
345
+ totalTokensUsed: 0,
346
+ totalCost: 0,
347
+ averageResponseTime: 0,
348
+ successRate: 1.0,
349
+ errorCount: 0,
350
+ toolExecutions: 0,
351
+ conversationsStarted: 0,
352
+ dailyUsage: { tokens: 0, cost: 0, messages: 0 },
353
+ weeklyUsage: { tokens: 0, cost: 0, messages: 0 },
354
+ monthlyUsage: { tokens: 0, cost: 0, messages: 0 },
355
+ lastMetricsUpdate: now
356
+ };
357
+ }
358
+
359
+ /**
360
+ * Create default agent state
361
+ * @returns {AgentState} Default state
362
+ */
363
+ static createDefaultState() {
364
+ return {
365
+ currentConversationId: null,
366
+ messageCount: 0,
367
+ context: {},
368
+ activeTools: [],
369
+ pendingOperations: {},
370
+ cache: {},
371
+ isProcessing: false,
372
+ lastError: null,
373
+ sessionData: {}
374
+ };
375
+ }
376
+
377
+ /**
378
+ * Generate unique agent ID
379
+ * @returns {string} Unique agent ID
380
+ */
381
+ static generateAgentId() {
382
+ const timestamp = Date.now().toString(36);
383
+ const random = Math.random().toString(36).substr(2, 9);
384
+ return `agent_${timestamp}_${random}`;
385
+ }
386
+
387
+ /**
388
+ * Clone an existing agent with new ID
389
+ * @param {Agent} agent - Agent to clone
390
+ * @param {string} newName - Name for cloned agent
391
+ * @returns {Agent} Cloned agent
392
+ */
393
+ static clone(agent, newName) {
394
+ const cloned = { ...agent };
395
+ const now = new Date().toISOString();
396
+
397
+ cloned.id = this.generateAgentId();
398
+ cloned.name = newName;
399
+ cloned.status = AGENT_STATUS.IDLE;
400
+ cloned.createdAt = now;
401
+ cloned.updatedAt = now;
402
+ cloned.lastActivity = now;
403
+ cloned.pausedUntil = null;
404
+ cloned.pauseReason = null;
405
+
406
+ // Reset metrics and state
407
+ cloned.metrics = this.createDefaultMetrics();
408
+ cloned.state = this.createDefaultState();
409
+
410
+ return cloned;
411
+ }
412
+ }
413
+
414
+ /**
415
+ * Agent utility functions
416
+ */
417
+ export class AgentUtils {
418
+ /**
419
+ * Check if agent is currently active
420
+ * @param {Agent} agent - Agent to check
421
+ * @returns {boolean} True if active
422
+ */
423
+ static isActive(agent) {
424
+ return agent.status === AGENT_STATUS.ACTIVE || agent.status === AGENT_STATUS.BUSY;
425
+ }
426
+
427
+ /**
428
+ * Check if agent is paused
429
+ * @param {Agent} agent - Agent to check
430
+ * @returns {boolean} True if paused
431
+ */
432
+ static isPaused(agent) {
433
+ if (agent.status !== AGENT_STATUS.PAUSED) return false;
434
+
435
+ if (agent.pausedUntil) {
436
+ const pauseExpiry = new Date(agent.pausedUntil);
437
+ return new Date() < pauseExpiry;
438
+ }
439
+
440
+ return true;
441
+ }
442
+
443
+ /**
444
+ * Get agent's effective status considering pause expiry
445
+ * @param {Agent} agent - Agent to check
446
+ * @returns {string} Effective status
447
+ */
448
+ static getEffectiveStatus(agent) {
449
+ if (agent.status === AGENT_STATUS.PAUSED && agent.pausedUntil) {
450
+ const pauseExpiry = new Date(agent.pausedUntil);
451
+ if (new Date() >= pauseExpiry) {
452
+ return AGENT_STATUS.IDLE; // Pause has expired
453
+ }
454
+ }
455
+
456
+ return agent.status;
457
+ }
458
+
459
+ /**
460
+ * Calculate time until pause expires
461
+ * @param {Agent} agent - Agent to check
462
+ * @returns {number|null} Milliseconds until pause expires, null if not paused
463
+ */
464
+ static getTimeUntilPauseExpiry(agent) {
465
+ if (!this.isPaused(agent) || !agent.pausedUntil) {
466
+ return null;
467
+ }
468
+
469
+ const pauseExpiry = new Date(agent.pausedUntil);
470
+ const now = new Date();
471
+
472
+ return Math.max(0, pauseExpiry.getTime() - now.getTime());
473
+ }
474
+
475
+ /**
476
+ * Format agent for display
477
+ * @param {Agent} agent - Agent to format
478
+ * @returns {Object} Formatted agent data
479
+ */
480
+ static formatForDisplay(agent) {
481
+ return {
482
+ id: agent.id,
483
+ name: agent.name,
484
+ type: agent.type,
485
+ status: this.getEffectiveStatus(agent),
486
+ model: agent.currentModel,
487
+ messageCount: agent.metrics.totalMessages,
488
+ lastActivity: agent.lastActivity,
489
+ isPaused: this.isPaused(agent),
490
+ timeUntilPauseExpiry: this.getTimeUntilPauseExpiry(agent)
491
+ };
492
+ }
493
+
494
+ /**
495
+ * Sanitize agent data for API responses
496
+ * @param {Agent} agent - Agent to sanitize
497
+ * @returns {Object} Sanitized agent data
498
+ */
499
+ static sanitize(agent) {
500
+ const sanitized = { ...agent };
501
+
502
+ // Remove sensitive or internal data
503
+ delete sanitized.state.cache;
504
+ delete sanitized.state.sessionData;
505
+
506
+ // Truncate long system prompt for API responses
507
+ if (sanitized.systemPrompt && sanitized.systemPrompt.length > 500) {
508
+ sanitized.systemPrompt = sanitized.systemPrompt.substring(0, 500) + '...';
509
+ }
510
+
511
+ return sanitized;
512
+ }
513
+ }
514
+
515
+ export default {
516
+ AgentValidator,
517
+ AgentFactory,
518
+ AgentUtils
519
+ };