@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.
- package/LICENSE +267 -0
- package/README.md +509 -0
- package/bin/cli.js +117 -0
- package/package.json +94 -0
- package/scripts/install-scanners.js +236 -0
- package/src/analyzers/CSSAnalyzer.js +297 -0
- package/src/analyzers/ConfigValidator.js +690 -0
- package/src/analyzers/ESLintAnalyzer.js +320 -0
- package/src/analyzers/JavaScriptAnalyzer.js +261 -0
- package/src/analyzers/PrettierFormatter.js +247 -0
- package/src/analyzers/PythonAnalyzer.js +266 -0
- package/src/analyzers/SecurityAnalyzer.js +729 -0
- package/src/analyzers/TypeScriptAnalyzer.js +247 -0
- package/src/analyzers/codeCloneDetector/analyzer.js +344 -0
- package/src/analyzers/codeCloneDetector/detector.js +203 -0
- package/src/analyzers/codeCloneDetector/index.js +160 -0
- package/src/analyzers/codeCloneDetector/parser.js +199 -0
- package/src/analyzers/codeCloneDetector/reporter.js +148 -0
- package/src/analyzers/codeCloneDetector/scanner.js +59 -0
- package/src/core/agentPool.js +1474 -0
- package/src/core/agentScheduler.js +2147 -0
- package/src/core/contextManager.js +709 -0
- package/src/core/messageProcessor.js +732 -0
- package/src/core/orchestrator.js +548 -0
- package/src/core/stateManager.js +877 -0
- package/src/index.js +631 -0
- package/src/interfaces/cli.js +549 -0
- package/src/interfaces/webServer.js +2162 -0
- package/src/modules/fileExplorer/controller.js +280 -0
- package/src/modules/fileExplorer/index.js +37 -0
- package/src/modules/fileExplorer/middleware.js +92 -0
- package/src/modules/fileExplorer/routes.js +125 -0
- package/src/modules/fileExplorer/types.js +44 -0
- package/src/services/aiService.js +1232 -0
- package/src/services/apiKeyManager.js +164 -0
- package/src/services/benchmarkService.js +366 -0
- package/src/services/budgetService.js +539 -0
- package/src/services/contextInjectionService.js +247 -0
- package/src/services/conversationCompactionService.js +637 -0
- package/src/services/errorHandler.js +810 -0
- package/src/services/fileAttachmentService.js +544 -0
- package/src/services/modelRouterService.js +366 -0
- package/src/services/modelsService.js +322 -0
- package/src/services/qualityInspector.js +796 -0
- package/src/services/tokenCountingService.js +536 -0
- package/src/tools/agentCommunicationTool.js +1344 -0
- package/src/tools/agentDelayTool.js +485 -0
- package/src/tools/asyncToolManager.js +604 -0
- package/src/tools/baseTool.js +800 -0
- package/src/tools/browserTool.js +920 -0
- package/src/tools/cloneDetectionTool.js +621 -0
- package/src/tools/dependencyResolverTool.js +1215 -0
- package/src/tools/fileContentReplaceTool.js +875 -0
- package/src/tools/fileSystemTool.js +1107 -0
- package/src/tools/fileTreeTool.js +853 -0
- package/src/tools/imageTool.js +901 -0
- package/src/tools/importAnalyzerTool.js +1060 -0
- package/src/tools/jobDoneTool.js +248 -0
- package/src/tools/seekTool.js +956 -0
- package/src/tools/staticAnalysisTool.js +1778 -0
- package/src/tools/taskManagerTool.js +2873 -0
- package/src/tools/terminalTool.js +2304 -0
- package/src/tools/webTool.js +1430 -0
- package/src/types/agent.js +519 -0
- package/src/types/contextReference.js +972 -0
- package/src/types/conversation.js +730 -0
- package/src/types/toolCommand.js +747 -0
- package/src/utilities/attachmentValidator.js +292 -0
- package/src/utilities/configManager.js +582 -0
- package/src/utilities/constants.js +722 -0
- package/src/utilities/directoryAccessManager.js +535 -0
- package/src/utilities/fileProcessor.js +307 -0
- package/src/utilities/logger.js +436 -0
- package/src/utilities/tagParser.js +1246 -0
- package/src/utilities/toolConstants.js +317 -0
- package/web-ui/build/index.html +15 -0
- package/web-ui/build/logo.png +0 -0
- package/web-ui/build/logo2.png +0 -0
- package/web-ui/build/static/index-CjkkcnFA.js +344 -0
- package/web-ui/build/static/index-Dy2bYbOa.css +1 -0
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentDelayTool - Allows agents to pause their activity for specified duration
|
|
3
|
+
*
|
|
4
|
+
* Purpose:
|
|
5
|
+
* - Pause agent activity during waiting periods
|
|
6
|
+
* - Prevent unnecessary message exchanges
|
|
7
|
+
* - Handle installation and startup delays
|
|
8
|
+
* - Manage agent status during long operations
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { BaseTool } from './baseTool.js';
|
|
12
|
+
import TagParser from '../utilities/tagParser.js';
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
TOOL_STATUS,
|
|
16
|
+
SYSTEM_DEFAULTS,
|
|
17
|
+
AGENT_STATUS
|
|
18
|
+
} from '../utilities/constants.js';
|
|
19
|
+
|
|
20
|
+
class AgentDelayTool extends BaseTool {
|
|
21
|
+
constructor(config = {}, logger = null, agentPool = null) {
|
|
22
|
+
super(config, logger);
|
|
23
|
+
|
|
24
|
+
this.agentPool = agentPool;
|
|
25
|
+
this.maxPauseDuration = config.maxDuration || SYSTEM_DEFAULTS.MAX_PAUSE_DURATION;
|
|
26
|
+
this.minPauseDuration = config.minDuration || 1;
|
|
27
|
+
|
|
28
|
+
// Tool metadata
|
|
29
|
+
this.requiresProject = false;
|
|
30
|
+
this.isAsync = false; // Synchronous - immediately updates agent status
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get tool description for LLM consumption
|
|
35
|
+
* @returns {string} Tool description
|
|
36
|
+
*/
|
|
37
|
+
getDescription() {
|
|
38
|
+
return `
|
|
39
|
+
Agent Delay Tool: Pause agent activity for a specified duration to prevent unnecessary message exchanges during waiting periods.
|
|
40
|
+
|
|
41
|
+
USAGE:
|
|
42
|
+
[tool id="agentdelay"]
|
|
43
|
+
<pause-duration>30</pause-duration>
|
|
44
|
+
<reason>Waiting for npm install to complete</reason>
|
|
45
|
+
[/tool]
|
|
46
|
+
|
|
47
|
+
PARAMETERS:
|
|
48
|
+
- pause-duration: Number of seconds to pause (${this.minPauseDuration}-${this.maxPauseDuration})
|
|
49
|
+
- reason: Optional explanation for the pause
|
|
50
|
+
|
|
51
|
+
USE CASES:
|
|
52
|
+
- After running 'npm install' or similar long-running commands
|
|
53
|
+
- Waiting for services to start up
|
|
54
|
+
- Allowing time for file system operations to complete
|
|
55
|
+
- Preventing rapid status checking loops
|
|
56
|
+
- During build processes or compilation
|
|
57
|
+
|
|
58
|
+
BEHAVIOR:
|
|
59
|
+
The agent will be marked as '${AGENT_STATUS.PAUSED}' and will not process new messages until the duration expires.
|
|
60
|
+
Other agents can still send messages, but they will be queued until the agent resumes.
|
|
61
|
+
|
|
62
|
+
EXAMPLES:
|
|
63
|
+
Basic pause for 1 minute:
|
|
64
|
+
[tool id="agentdelay"]
|
|
65
|
+
<pause-duration>60</pause-duration>
|
|
66
|
+
[/tool]
|
|
67
|
+
|
|
68
|
+
Pause with reason:
|
|
69
|
+
[tool id="agentdelay"]
|
|
70
|
+
<pause-duration>120</pause-duration>
|
|
71
|
+
<reason>Installing dependencies</reason>
|
|
72
|
+
[/tool]
|
|
73
|
+
|
|
74
|
+
Brief pause for service startup:
|
|
75
|
+
[tool id="agentdelay"]
|
|
76
|
+
<pause-duration>30</pause-duration>
|
|
77
|
+
<reason>Waiting for server startup</reason>
|
|
78
|
+
[/tool]
|
|
79
|
+
|
|
80
|
+
IMPORTANT: Use this tool judiciously. Only pause when genuinely waiting for external processes.
|
|
81
|
+
The maximum pause duration is ${this.maxPauseDuration} seconds (${Math.floor(this.maxPauseDuration / 60)} minutes).
|
|
82
|
+
`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Parse parameters from tool command content
|
|
87
|
+
* @param {string} content - Raw tool command content
|
|
88
|
+
* @returns {Object} Parsed parameters
|
|
89
|
+
*/
|
|
90
|
+
parseParameters(content) {
|
|
91
|
+
try {
|
|
92
|
+
// Extract pause-duration and reason using TagParser
|
|
93
|
+
const durationMatches = TagParser.extractContent(content, 'pause-duration');
|
|
94
|
+
const reasonMatches = TagParser.extractContent(content, 'reason');
|
|
95
|
+
|
|
96
|
+
const duration = durationMatches.length > 0 ? parseInt(durationMatches[0], 10) : null;
|
|
97
|
+
const reason = reasonMatches.length > 0 ? reasonMatches[0].trim() : 'Agent pause requested';
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
duration,
|
|
101
|
+
reason,
|
|
102
|
+
rawContent: content.trim()
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
} catch (error) {
|
|
106
|
+
throw new Error(`Failed to parse agent delay parameters: ${error.message}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get required parameters
|
|
112
|
+
* @returns {Array<string>} Array of required parameter names
|
|
113
|
+
*/
|
|
114
|
+
getRequiredParameters() {
|
|
115
|
+
return ['duration'];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Validate parameter types
|
|
120
|
+
* @param {Object} params - Parameters to validate
|
|
121
|
+
* @returns {Object} Validation result
|
|
122
|
+
*/
|
|
123
|
+
validateParameterTypes(params) {
|
|
124
|
+
const errors = [];
|
|
125
|
+
|
|
126
|
+
if (params.duration !== null && params.duration !== undefined) {
|
|
127
|
+
if (typeof params.duration !== 'number' || isNaN(params.duration)) {
|
|
128
|
+
errors.push('pause-duration must be a valid number');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (params.reason && typeof params.reason !== 'string') {
|
|
133
|
+
errors.push('reason must be a string');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
valid: errors.length === 0,
|
|
138
|
+
errors
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Custom parameter validation
|
|
144
|
+
* @param {Object} params - Parameters to validate
|
|
145
|
+
* @returns {Object} Validation result
|
|
146
|
+
*/
|
|
147
|
+
customValidateParameters(params) {
|
|
148
|
+
const errors = [];
|
|
149
|
+
|
|
150
|
+
if (params.duration === null || params.duration === undefined) {
|
|
151
|
+
errors.push('pause-duration is required');
|
|
152
|
+
} else {
|
|
153
|
+
if (params.duration < this.minPauseDuration) {
|
|
154
|
+
errors.push(`pause-duration must be at least ${this.minPauseDuration} second(s)`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (params.duration > this.maxPauseDuration) {
|
|
158
|
+
errors.push(`pause-duration cannot exceed ${this.maxPauseDuration} seconds (${Math.floor(this.maxPauseDuration / 60)} minutes)`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!Number.isInteger(params.duration)) {
|
|
162
|
+
errors.push('pause-duration must be a whole number of seconds');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (params.reason && params.reason.length > 200) {
|
|
167
|
+
errors.push('reason cannot exceed 200 characters');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
valid: errors.length === 0,
|
|
172
|
+
errors
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Execute tool with parsed parameters
|
|
178
|
+
* @param {Object} params - Parsed parameters
|
|
179
|
+
* @param {Object} context - Execution context
|
|
180
|
+
* @returns {Promise<Object>} Execution result
|
|
181
|
+
*/
|
|
182
|
+
async execute(params, context) {
|
|
183
|
+
const { duration, reason } = params;
|
|
184
|
+
const { agentId } = context;
|
|
185
|
+
|
|
186
|
+
if (!agentId) {
|
|
187
|
+
throw new Error('Agent ID is required for agent delay tool');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (!this.agentPool) {
|
|
191
|
+
throw new Error('Agent pool not available - cannot pause agent');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
// Calculate pause end time
|
|
196
|
+
const pausedUntil = new Date(Date.now() + duration * 1000);
|
|
197
|
+
|
|
198
|
+
// Pause the agent via agent pool
|
|
199
|
+
const pauseResult = await this.agentPool.pauseAgent(agentId, pausedUntil, reason);
|
|
200
|
+
|
|
201
|
+
// Also set delayEndTime for the new scheduler architecture
|
|
202
|
+
const agent = await this.agentPool.getAgent(agentId);
|
|
203
|
+
if (agent) {
|
|
204
|
+
agent.delayEndTime = pausedUntil.toISOString();
|
|
205
|
+
await this.agentPool.persistAgentState(agentId);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (!pauseResult.success) {
|
|
209
|
+
throw new Error(`Failed to pause agent: ${pauseResult.message || 'Unknown error'}`);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const result = {
|
|
213
|
+
success: true,
|
|
214
|
+
action: 'agent-pause',
|
|
215
|
+
agentId,
|
|
216
|
+
pauseDuration: duration,
|
|
217
|
+
pausedUntil: pausedUntil.toISOString(),
|
|
218
|
+
reason,
|
|
219
|
+
message: `Agent will resume activity in ${duration} second${duration !== 1 ? 's' : ''}`,
|
|
220
|
+
resumeTime: this.formatResumeTime(pausedUntil),
|
|
221
|
+
toolUsed: 'agent-delay'
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
this.logger?.info(`Agent paused via agent-delay tool: ${agentId}`, {
|
|
225
|
+
duration,
|
|
226
|
+
reason,
|
|
227
|
+
pausedUntil: pausedUntil.toISOString(),
|
|
228
|
+
toolUsage: true
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
return result;
|
|
232
|
+
|
|
233
|
+
} catch (error) {
|
|
234
|
+
this.logger?.error(`Agent delay tool execution failed: ${error.message}`, {
|
|
235
|
+
agentId,
|
|
236
|
+
duration,
|
|
237
|
+
reason,
|
|
238
|
+
error: error.stack
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
throw error;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Get supported actions for this tool
|
|
247
|
+
* @returns {Array<string>} Array of supported action names
|
|
248
|
+
*/
|
|
249
|
+
getSupportedActions() {
|
|
250
|
+
return ['pause', 'delay'];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Get parameter schema for validation
|
|
255
|
+
* @returns {Object} Parameter schema
|
|
256
|
+
*/
|
|
257
|
+
getParameterSchema() {
|
|
258
|
+
return {
|
|
259
|
+
type: 'object',
|
|
260
|
+
properties: {
|
|
261
|
+
duration: {
|
|
262
|
+
type: 'integer',
|
|
263
|
+
minimum: this.minPauseDuration,
|
|
264
|
+
maximum: this.maxPauseDuration,
|
|
265
|
+
description: 'Number of seconds to pause agent activity'
|
|
266
|
+
},
|
|
267
|
+
reason: {
|
|
268
|
+
type: 'string',
|
|
269
|
+
maxLength: 200,
|
|
270
|
+
description: 'Optional reason for the pause'
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
required: ['duration']
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Get tool capabilities metadata
|
|
279
|
+
* @returns {Object} Enhanced capabilities object
|
|
280
|
+
*/
|
|
281
|
+
getCapabilities() {
|
|
282
|
+
const baseCapabilities = super.getCapabilities();
|
|
283
|
+
|
|
284
|
+
return {
|
|
285
|
+
...baseCapabilities,
|
|
286
|
+
pauseRange: {
|
|
287
|
+
min: this.minPauseDuration,
|
|
288
|
+
max: this.maxPauseDuration,
|
|
289
|
+
unit: 'seconds'
|
|
290
|
+
},
|
|
291
|
+
affects: 'agent-status',
|
|
292
|
+
interactsWithAgentPool: true,
|
|
293
|
+
useCases: [
|
|
294
|
+
'installation-waiting',
|
|
295
|
+
'service-startup',
|
|
296
|
+
'file-operations',
|
|
297
|
+
'build-processes',
|
|
298
|
+
'compilation',
|
|
299
|
+
'deployment-delays'
|
|
300
|
+
]
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Format resume time for human readability
|
|
306
|
+
* @private
|
|
307
|
+
*/
|
|
308
|
+
formatResumeTime(resumeDate) {
|
|
309
|
+
const now = new Date();
|
|
310
|
+
const diffSeconds = Math.round((resumeDate.getTime() - now.getTime()) / 1000);
|
|
311
|
+
|
|
312
|
+
if (diffSeconds < 60) {
|
|
313
|
+
return `in ${diffSeconds} second${diffSeconds !== 1 ? 's' : ''}`;
|
|
314
|
+
} else if (diffSeconds < 3600) {
|
|
315
|
+
const minutes = Math.round(diffSeconds / 60);
|
|
316
|
+
return `in ${minutes} minute${minutes !== 1 ? 's' : ''}`;
|
|
317
|
+
} else {
|
|
318
|
+
const hours = Math.round(diffSeconds / 3600);
|
|
319
|
+
return `in ${hours} hour${hours !== 1 ? 's' : ''}`;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Get usage examples for documentation
|
|
325
|
+
* @returns {Array<Object>} Array of usage examples
|
|
326
|
+
*/
|
|
327
|
+
getUsageExamples() {
|
|
328
|
+
return [
|
|
329
|
+
{
|
|
330
|
+
title: 'Basic pause for 30 seconds',
|
|
331
|
+
command: `[tool id="agentdelay"]
|
|
332
|
+
<pause-duration>30</pause-duration>
|
|
333
|
+
[/tool]`,
|
|
334
|
+
description: 'Simple 30-second pause without specific reason'
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
title: 'Pause during package installation',
|
|
338
|
+
command: `[tool id="agentdelay"]
|
|
339
|
+
<pause-duration>120</pause-duration>
|
|
340
|
+
<reason>Waiting for npm install to complete</reason>
|
|
341
|
+
[/tool]`,
|
|
342
|
+
description: 'Pause for 2 minutes while packages are being installed'
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
title: 'Brief pause for service startup',
|
|
346
|
+
command: `[tool id="agentdelay"]
|
|
347
|
+
<pause-duration>45</pause-duration>
|
|
348
|
+
<reason>Allowing database service to start</reason>
|
|
349
|
+
[/tool]`,
|
|
350
|
+
description: 'Short pause to allow a service to fully initialize'
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
title: 'Extended pause for build process',
|
|
354
|
+
command: `[tool id="agentdelay"]
|
|
355
|
+
<pause-duration>300</pause-duration>
|
|
356
|
+
<reason>Waiting for large project compilation</reason>
|
|
357
|
+
[/tool]`,
|
|
358
|
+
description: 'Maximum duration pause for lengthy build operations'
|
|
359
|
+
}
|
|
360
|
+
];
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Check if agent can be paused
|
|
365
|
+
* @param {string} agentId - Agent identifier
|
|
366
|
+
* @returns {Promise<Object>} Check result
|
|
367
|
+
*/
|
|
368
|
+
async canPauseAgent(agentId) {
|
|
369
|
+
if (!this.agentPool) {
|
|
370
|
+
return {
|
|
371
|
+
canPause: false,
|
|
372
|
+
reason: 'Agent pool not available'
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
try {
|
|
377
|
+
const agent = await this.agentPool.getAgent(agentId);
|
|
378
|
+
|
|
379
|
+
if (!agent) {
|
|
380
|
+
return {
|
|
381
|
+
canPause: false,
|
|
382
|
+
reason: 'Agent not found'
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (agent.status === AGENT_STATUS.PAUSED) {
|
|
387
|
+
return {
|
|
388
|
+
canPause: false,
|
|
389
|
+
reason: 'Agent is already paused',
|
|
390
|
+
pausedUntil: agent.pausedUntil
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return {
|
|
395
|
+
canPause: true,
|
|
396
|
+
currentStatus: agent.status
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
} catch (error) {
|
|
400
|
+
return {
|
|
401
|
+
canPause: false,
|
|
402
|
+
reason: `Error checking agent status: ${error.message}`
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Get pause recommendations based on context
|
|
409
|
+
* @param {Object} context - Execution context
|
|
410
|
+
* @returns {Object} Pause recommendations
|
|
411
|
+
*/
|
|
412
|
+
getPauseRecommendations(context) {
|
|
413
|
+
const recommendations = {
|
|
414
|
+
suggested: [],
|
|
415
|
+
warnings: []
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
// Analyze context for pause suggestions
|
|
419
|
+
if (context.lastCommand && typeof context.lastCommand === 'string') {
|
|
420
|
+
const command = context.lastCommand.toLowerCase();
|
|
421
|
+
|
|
422
|
+
if (command.includes('npm install') || command.includes('yarn install')) {
|
|
423
|
+
recommendations.suggested.push({
|
|
424
|
+
duration: 90,
|
|
425
|
+
reason: 'Package installation typically takes 1-2 minutes',
|
|
426
|
+
confidence: 'high'
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (command.includes('docker build') || command.includes('docker run')) {
|
|
431
|
+
recommendations.suggested.push({
|
|
432
|
+
duration: 120,
|
|
433
|
+
reason: 'Docker operations often require extended time',
|
|
434
|
+
confidence: 'medium'
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (command.includes('make') || command.includes('build') || command.includes('compile')) {
|
|
439
|
+
recommendations.suggested.push({
|
|
440
|
+
duration: 180,
|
|
441
|
+
reason: 'Build/compilation processes can be time-intensive',
|
|
442
|
+
confidence: 'medium'
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (command.includes('git clone') || command.includes('git pull')) {
|
|
447
|
+
recommendations.suggested.push({
|
|
448
|
+
duration: 30,
|
|
449
|
+
reason: 'Git operations usually complete quickly',
|
|
450
|
+
confidence: 'high'
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Add warnings for very short or long pauses
|
|
456
|
+
if (context.requestedDuration) {
|
|
457
|
+
if (context.requestedDuration < 10) {
|
|
458
|
+
recommendations.warnings.push('Very short pauses may not be necessary');
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (context.requestedDuration > 240) {
|
|
462
|
+
recommendations.warnings.push('Consider if such a long pause is really needed');
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return recommendations;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Enable/disable tool based on agent pool availability
|
|
471
|
+
* @param {Object} agentPool - Agent pool instance
|
|
472
|
+
*/
|
|
473
|
+
setAgentPool(agentPool) {
|
|
474
|
+
this.agentPool = agentPool;
|
|
475
|
+
this.isEnabled = !!agentPool;
|
|
476
|
+
|
|
477
|
+
if (this.isEnabled) {
|
|
478
|
+
this.logger?.info('Agent delay tool enabled with agent pool');
|
|
479
|
+
} else {
|
|
480
|
+
this.logger?.warn('Agent delay tool disabled - no agent pool available');
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export default AgentDelayTool;
|