@memberjunction/ai-agents 2.48.0 → 2.50.0
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/dist/AgentRunner.d.ts +5 -0
- package/dist/AgentRunner.d.ts.map +1 -0
- package/dist/AgentRunner.js +36 -0
- package/dist/AgentRunner.js.map +1 -0
- package/dist/agent-types/LoopAgentType.d.ts +9 -0
- package/dist/agent-types/LoopAgentType.d.ts.map +1 -0
- package/dist/agent-types/LoopAgentType.js +134 -0
- package/dist/agent-types/LoopAgentType.js.map +1 -0
- package/dist/agent-types/index.d.ts +2 -0
- package/dist/agent-types/index.d.ts.map +1 -0
- package/dist/agent-types/index.js +20 -0
- package/dist/agent-types/index.js.map +1 -0
- package/dist/base-agent-type.d.ts +6 -0
- package/dist/base-agent-type.d.ts.map +1 -0
- package/dist/base-agent-type.js +7 -0
- package/dist/base-agent-type.js.map +1 -0
- package/dist/base-agent.d.ts +5 -55
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +120 -221
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +34 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +9 -9
- package/dist/agent-factory.d.ts +0 -19
- package/dist/agent-factory.d.ts.map +0 -1
- package/dist/agent-factory.js +0 -137
- package/dist/agent-factory.js.map +0 -1
- package/dist/agent-runner.d.ts +0 -36
- package/dist/agent-runner.d.ts.map +0 -1
- package/dist/agent-runner.js +0 -509
- package/dist/agent-runner.js.map +0 -1
- package/dist/base-agent-original.d.ts +0 -205
- package/dist/base-agent-original.d.ts.map +0 -1
- package/dist/base-agent-original.js +0 -1243
- package/dist/base-agent-original.js.map +0 -1
- package/dist/conductor-agent.d.ts +0 -93
- package/dist/conductor-agent.d.ts.map +0 -1
- package/dist/conductor-agent.js +0 -319
- package/dist/conductor-agent.js.map +0 -1
|
@@ -1,1243 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LoadBaseAgent = exports.BaseAgent = void 0;
|
|
4
|
-
const core_1 = require("@memberjunction/core");
|
|
5
|
-
const aiengine_1 = require("@memberjunction/aiengine");
|
|
6
|
-
const ai_prompts_1 = require("@memberjunction/ai-prompts");
|
|
7
|
-
const actions_1 = require("@memberjunction/actions");
|
|
8
|
-
class BaseAgent {
|
|
9
|
-
constructor(agent, factory, contextUser, promptRunner) {
|
|
10
|
-
this._agent = agent;
|
|
11
|
-
this._factory = factory;
|
|
12
|
-
this._promptRunner = promptRunner ? promptRunner : new ai_prompts_1.AIPromptRunner();
|
|
13
|
-
this._contextUser = contextUser;
|
|
14
|
-
this._metadata = new core_1.Metadata();
|
|
15
|
-
}
|
|
16
|
-
get agent() {
|
|
17
|
-
return this._agent;
|
|
18
|
-
}
|
|
19
|
-
get factory() {
|
|
20
|
-
return this._factory;
|
|
21
|
-
}
|
|
22
|
-
get promptRunner() {
|
|
23
|
-
return this._promptRunner;
|
|
24
|
-
}
|
|
25
|
-
get contextUser() {
|
|
26
|
-
return this._contextUser;
|
|
27
|
-
}
|
|
28
|
-
async Execute(params) {
|
|
29
|
-
const startTime = new Date();
|
|
30
|
-
try {
|
|
31
|
-
const context = await this.initializeContext(params, startTime);
|
|
32
|
-
if (params.cancellationToken?.aborted) {
|
|
33
|
-
return this.createCancelledResult(startTime);
|
|
34
|
-
}
|
|
35
|
-
this.sendProgress(params.onProgress, {
|
|
36
|
-
step: 'initialization',
|
|
37
|
-
percentage: 10,
|
|
38
|
-
message: `Initializing agent '${this.agent.Name}'`,
|
|
39
|
-
metadata: { agentName: this.agent.Name, agentId: this.agent.ID }
|
|
40
|
-
});
|
|
41
|
-
await this.processContext(context);
|
|
42
|
-
if (params.cancellationToken?.aborted) {
|
|
43
|
-
return this.createCancelledResult(startTime);
|
|
44
|
-
}
|
|
45
|
-
this.sendProgress(params.onProgress, {
|
|
46
|
-
step: 'context_processing',
|
|
47
|
-
percentage: 20,
|
|
48
|
-
message: 'Processing conversation context',
|
|
49
|
-
});
|
|
50
|
-
const result = await this.executeCore(context);
|
|
51
|
-
const endTime = new Date();
|
|
52
|
-
result.executionTimeMS = endTime.getTime() - startTime.getTime();
|
|
53
|
-
this.sendProgress(params.onProgress, {
|
|
54
|
-
step: 'completion',
|
|
55
|
-
percentage: 100,
|
|
56
|
-
message: `Agent '${this.agent.Name}' execution completed`,
|
|
57
|
-
metadata: {
|
|
58
|
-
success: result.success,
|
|
59
|
-
executionTimeMS: result.executionTimeMS
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
return result;
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
(0, core_1.LogError)(`Error executing agent '${this.agent?.Name || 'Unknown'}': ${error.message}`);
|
|
66
|
-
const endTime = new Date();
|
|
67
|
-
return {
|
|
68
|
-
success: false,
|
|
69
|
-
errorMessage: error.message,
|
|
70
|
-
executionTimeMS: endTime.getTime() - startTime.getTime(),
|
|
71
|
-
cancelled: params.cancellationToken?.aborted || false
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
async executeCore(context) {
|
|
76
|
-
let executionStepEntity = null;
|
|
77
|
-
try {
|
|
78
|
-
executionStepEntity = await this.createExecutionStep(context, 'decision', 'Agent core execution loop', this.agent.ID, { maxIterations: 10 });
|
|
79
|
-
const decisionHistory = [];
|
|
80
|
-
const executionHistory = [];
|
|
81
|
-
const actionResults = [];
|
|
82
|
-
let currentMessages = [...context.conversationMessages];
|
|
83
|
-
let maxIterations = 10;
|
|
84
|
-
let iteration = 0;
|
|
85
|
-
while (iteration < maxIterations) {
|
|
86
|
-
iteration++;
|
|
87
|
-
context.currentStep = `decision-iteration-${iteration}`;
|
|
88
|
-
await this.updateAgentRunState(context, executionHistory, decisionHistory, actionResults);
|
|
89
|
-
if (context.params.cancellationToken?.aborted) {
|
|
90
|
-
if (executionStepEntity) {
|
|
91
|
-
await this.completeExecutionStep(executionStepEntity, false, null, 'Execution cancelled by user');
|
|
92
|
-
}
|
|
93
|
-
await this.finalizeAgentRun(context, false, 'Execution cancelled by user', null, null, null);
|
|
94
|
-
return this.createCancelledResult(context.startTime);
|
|
95
|
-
}
|
|
96
|
-
this.sendProgress(context.params.onProgress, {
|
|
97
|
-
step: 'subagent_coordination',
|
|
98
|
-
percentage: 30 + (50 * iteration / maxIterations),
|
|
99
|
-
message: `Decision-making iteration ${iteration}/${maxIterations}`,
|
|
100
|
-
metadata: {
|
|
101
|
-
iteration,
|
|
102
|
-
maxIterations,
|
|
103
|
-
runId: context.agentRun?.ID,
|
|
104
|
-
stepNumber: context.currentStepNumber
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
const decisionStepEntity = await this.createExecutionStep(context, 'decision', `Decision making - iteration ${iteration}`, undefined, { iteration, maxIterations, messagesCount: currentMessages.length });
|
|
108
|
-
let decision;
|
|
109
|
-
try {
|
|
110
|
-
const decisionInput = await this.createDecisionInput(context, currentMessages, executionHistory);
|
|
111
|
-
decision = await this.makeDecision(context, decisionInput);
|
|
112
|
-
decisionHistory.push(decision);
|
|
113
|
-
await this.completeExecutionStep(decisionStepEntity, true, {
|
|
114
|
-
decision: decision.decision,
|
|
115
|
-
reasoning: decision.reasoning,
|
|
116
|
-
executionPlanLength: decision.executionPlan.length,
|
|
117
|
-
confidence: decision.confidence
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
await this.completeExecutionStep(decisionStepEntity, false, null, error.message);
|
|
122
|
-
throw error;
|
|
123
|
-
}
|
|
124
|
-
if (decision.isTaskComplete || decision.decision === 'complete_task') {
|
|
125
|
-
const completionStepEntity = await this.createExecutionStep(context, 'completion', 'Task completion', undefined, { finalResponse: decision.finalResponse });
|
|
126
|
-
await this.completeExecutionStep(completionStepEntity, true, {
|
|
127
|
-
taskComplete: true,
|
|
128
|
-
finalResponse: decision.finalResponse
|
|
129
|
-
});
|
|
130
|
-
if (executionStepEntity) {
|
|
131
|
-
await this.completeExecutionStep(executionStepEntity, true, {
|
|
132
|
-
iterations: iteration,
|
|
133
|
-
decisionCount: decisionHistory.length,
|
|
134
|
-
taskCompleted: true
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
const result = {
|
|
138
|
-
success: true,
|
|
139
|
-
result: decision.finalResponse || decision.reasoning,
|
|
140
|
-
conversationMessages: currentMessages,
|
|
141
|
-
decisionHistory,
|
|
142
|
-
actionResults: actionResults,
|
|
143
|
-
finalDecision: decision,
|
|
144
|
-
metadata: {
|
|
145
|
-
iterations: iteration,
|
|
146
|
-
decisionCount: decisionHistory.length,
|
|
147
|
-
actionExecutions: actionResults.length,
|
|
148
|
-
runId: context.agentRun?.ID
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
await this.finalizeAgentRun(context, true, null, result.result, decisionHistory, actionResults);
|
|
152
|
-
return result;
|
|
153
|
-
}
|
|
154
|
-
if (decision.decision === 'request_clarification') {
|
|
155
|
-
const clarificationStepEntity = await this.createExecutionStep(context, 'clarification', 'Requesting user clarification', undefined, { reasoning: decision.reasoning });
|
|
156
|
-
await this.completeExecutionStep(clarificationStepEntity, true, {
|
|
157
|
-
clarificationRequest: decision.reasoning
|
|
158
|
-
});
|
|
159
|
-
if (executionStepEntity) {
|
|
160
|
-
await this.completeExecutionStep(executionStepEntity, false, null, 'Clarification needed from user');
|
|
161
|
-
}
|
|
162
|
-
const result = {
|
|
163
|
-
success: false,
|
|
164
|
-
errorMessage: decision.reasoning,
|
|
165
|
-
conversationMessages: currentMessages,
|
|
166
|
-
decisionHistory,
|
|
167
|
-
metadata: {
|
|
168
|
-
needsClarification: true,
|
|
169
|
-
clarificationRequest: decision.reasoning,
|
|
170
|
-
runId: context.agentRun?.ID
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
await this.finalizeAgentRun(context, false, decision.reasoning, null, decisionHistory, actionResults);
|
|
174
|
-
return result;
|
|
175
|
-
}
|
|
176
|
-
let executionResults;
|
|
177
|
-
try {
|
|
178
|
-
executionResults = await this.executeDecidedActions(context, decision, executionHistory);
|
|
179
|
-
executionHistory.push(...executionResults.historyItems);
|
|
180
|
-
actionResults.push(...executionResults.actionResults);
|
|
181
|
-
if (executionResults.newMessages.length > 0) {
|
|
182
|
-
currentMessages.push(...executionResults.newMessages);
|
|
183
|
-
}
|
|
184
|
-
const executionSummary = this.createExecutionSummary(decision, executionResults);
|
|
185
|
-
currentMessages.push({
|
|
186
|
-
role: 'assistant',
|
|
187
|
-
content: executionSummary
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
catch (error) {
|
|
191
|
-
(0, core_1.LogError)(`Error executing actions in iteration ${iteration}: ${error.message}`);
|
|
192
|
-
}
|
|
193
|
-
await this.updateAgentRunState(context, executionHistory, decisionHistory, actionResults);
|
|
194
|
-
}
|
|
195
|
-
if (executionStepEntity) {
|
|
196
|
-
await this.completeExecutionStep(executionStepEntity, false, {
|
|
197
|
-
iterations: iteration,
|
|
198
|
-
maxIterationsReached: true
|
|
199
|
-
}, `Reached maximum iterations (${maxIterations}) without task completion`);
|
|
200
|
-
}
|
|
201
|
-
const result = {
|
|
202
|
-
success: false,
|
|
203
|
-
errorMessage: `Agent reached maximum iterations (${maxIterations}) without completing the task`,
|
|
204
|
-
conversationMessages: currentMessages,
|
|
205
|
-
decisionHistory,
|
|
206
|
-
actionResults: actionResults,
|
|
207
|
-
metadata: {
|
|
208
|
-
maxIterationsReached: true,
|
|
209
|
-
iterations: iteration,
|
|
210
|
-
decisionCount: decisionHistory.length,
|
|
211
|
-
runId: context.agentRun?.ID
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
await this.finalizeAgentRun(context, false, result.errorMessage, null, decisionHistory, actionResults);
|
|
215
|
-
return result;
|
|
216
|
-
}
|
|
217
|
-
catch (error) {
|
|
218
|
-
(0, core_1.LogError)(`Error in executeCore for agent '${this.agent.Name}': ${error.message}`);
|
|
219
|
-
if (executionStepEntity) {
|
|
220
|
-
await this.completeExecutionStep(executionStepEntity, false, null, error.message);
|
|
221
|
-
}
|
|
222
|
-
const result = {
|
|
223
|
-
success: false,
|
|
224
|
-
errorMessage: error.message,
|
|
225
|
-
metadata: {
|
|
226
|
-
errorStep: 'executeCore',
|
|
227
|
-
agentName: this.agent.Name,
|
|
228
|
-
runId: context.agentRun?.ID
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
await this.finalizeAgentRun(context, false, error.message, null, [], []);
|
|
232
|
-
return result;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
async initializeContext(params, startTime) {
|
|
236
|
-
const agentRun = await this._metadata.GetEntityObject('MJ: AI Agent Runs', this.contextUser);
|
|
237
|
-
agentRun.NewRecord();
|
|
238
|
-
agentRun.AgentID = this.agent.ID;
|
|
239
|
-
agentRun.Status = 'Running';
|
|
240
|
-
agentRun.StartedAt = startTime;
|
|
241
|
-
if (params.contextUser) {
|
|
242
|
-
agentRun.UserID = params.contextUser.ID;
|
|
243
|
-
}
|
|
244
|
-
const conversationId = params.data?.conversationId ||
|
|
245
|
-
params.data?.conversationID;
|
|
246
|
-
if (conversationId) {
|
|
247
|
-
agentRun.ConversationID = conversationId;
|
|
248
|
-
}
|
|
249
|
-
const parentRunId = params.data?.parentRunId ||
|
|
250
|
-
params.data?.parentRunID;
|
|
251
|
-
if (parentRunId) {
|
|
252
|
-
agentRun.ParentRunID = parentRunId;
|
|
253
|
-
}
|
|
254
|
-
const saveResult = await agentRun.Save();
|
|
255
|
-
if (!saveResult) {
|
|
256
|
-
throw new Error('Failed to create agent run record in database');
|
|
257
|
-
}
|
|
258
|
-
const initialState = {
|
|
259
|
-
conversationMessages: params.conversationMessages || [],
|
|
260
|
-
executionHistory: [],
|
|
261
|
-
decisionHistory: [],
|
|
262
|
-
actionResults: [],
|
|
263
|
-
currentStep: 'initialization',
|
|
264
|
-
currentStepNumber: 1,
|
|
265
|
-
contextData: params.data || {},
|
|
266
|
-
agentConfiguration: {},
|
|
267
|
-
serializedAt: new Date(),
|
|
268
|
-
version: '1.0'
|
|
269
|
-
};
|
|
270
|
-
agentRun.AgentState = JSON.stringify(initialState);
|
|
271
|
-
await agentRun.Save();
|
|
272
|
-
return {
|
|
273
|
-
conversationMessages: params.conversationMessages || [],
|
|
274
|
-
params,
|
|
275
|
-
data: params.data || {},
|
|
276
|
-
currentStep: 'initialization',
|
|
277
|
-
startTime,
|
|
278
|
-
agentRun,
|
|
279
|
-
currentStepNumber: 1
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
async processContext(context) {
|
|
283
|
-
if (this.agent.EnableContextCompression &&
|
|
284
|
-
this.agent.ContextCompressionMessageThreshold &&
|
|
285
|
-
context.conversationMessages.length > this.agent.ContextCompressionMessageThreshold) {
|
|
286
|
-
await this.compressContext(context);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
async compressContext(context) {
|
|
290
|
-
try {
|
|
291
|
-
if (!this.agent.ContextCompressionPromptID) {
|
|
292
|
-
(0, core_1.LogStatus)(`Context compression enabled but no compression prompt configured for agent '${this.agent.Name}'`);
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
const retentionCount = this.agent.ContextCompressionMessageRetentionCount || 5;
|
|
296
|
-
const messagesToCompress = context.conversationMessages.slice(0, -retentionCount);
|
|
297
|
-
const messagesToKeep = context.conversationMessages.slice(-retentionCount);
|
|
298
|
-
if (messagesToCompress.length === 0) {
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
const compressionPrompt = aiengine_1.AIEngine.Instance.Prompts.find(p => p.ID === this.agent.ContextCompressionPromptID);
|
|
302
|
-
if (!compressionPrompt) {
|
|
303
|
-
(0, core_1.LogError)(`Compression prompt not found: ${this.agent.ContextCompressionPromptID}`);
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
const compressionParams = {
|
|
307
|
-
prompt: compressionPrompt,
|
|
308
|
-
data: {
|
|
309
|
-
messages: messagesToCompress,
|
|
310
|
-
messageCount: messagesToCompress.length
|
|
311
|
-
},
|
|
312
|
-
contextUser: context.params.contextUser,
|
|
313
|
-
agentRunId: context.agentRun?.ID
|
|
314
|
-
};
|
|
315
|
-
const compressionResult = await this.promptRunner.ExecutePrompt(compressionParams);
|
|
316
|
-
if (compressionResult.success && compressionResult.rawResult) {
|
|
317
|
-
const summaryMessage = {
|
|
318
|
-
role: 'system',
|
|
319
|
-
content: `[Conversation Summary] ${compressionResult.rawResult}`
|
|
320
|
-
};
|
|
321
|
-
context.conversationMessages = [summaryMessage, ...messagesToKeep];
|
|
322
|
-
(0, core_1.LogStatus)(`Compressed ${messagesToCompress.length} messages into summary for agent '${this.agent.Name}'`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
catch (error) {
|
|
326
|
-
(0, core_1.LogError)(`Error compressing context for agent '${this.agent.Name}': ${error.message}`);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
async loadAgentPrompts() {
|
|
330
|
-
try {
|
|
331
|
-
await aiengine_1.AIEngine.Instance.Config(false, this.contextUser);
|
|
332
|
-
const agentPrompts = aiengine_1.AIEngine.Instance.AgentPrompts
|
|
333
|
-
.filter(ap => ap.AgentID === this.agent.ID && ap.Status === 'Active')
|
|
334
|
-
.sort((a, b) => (a.ExecutionOrder || 0) - (b.ExecutionOrder || 0));
|
|
335
|
-
const results = [];
|
|
336
|
-
for (const agentPrompt of agentPrompts) {
|
|
337
|
-
const prompt = aiengine_1.AIEngine.Instance.Prompts.find(p => p.ID === agentPrompt.PromptID);
|
|
338
|
-
if (prompt && prompt.Status === 'Active') {
|
|
339
|
-
results.push(prompt);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
if (results.length === 0) {
|
|
343
|
-
const agentType = await this.loadAgentType();
|
|
344
|
-
if (agentType && agentType.SystemPromptID) {
|
|
345
|
-
const systemPrompt = aiengine_1.AIEngine.Instance.Prompts.find(p => p.ID === agentType.SystemPromptID);
|
|
346
|
-
if (systemPrompt && systemPrompt.Status === 'Active') {
|
|
347
|
-
results.push(systemPrompt);
|
|
348
|
-
}
|
|
349
|
-
else {
|
|
350
|
-
(0, core_1.LogStatus)(`System prompt not found or inactive for agent type '${agentType.Name}'`);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
|
-
(0, core_1.LogStatus)(`No active prompts found for agent '${this.agent.Name}' and no system prompt configured`);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return results;
|
|
358
|
-
}
|
|
359
|
-
catch (error) {
|
|
360
|
-
(0, core_1.LogError)(`Error loading agent prompts for '${this.agent.Name}': ${error.message}`);
|
|
361
|
-
return [];
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
async loadAgentType() {
|
|
365
|
-
try {
|
|
366
|
-
if (!this.agent.TypeID) {
|
|
367
|
-
(0, core_1.LogStatus)(`Agent '${this.agent.Name}' has no AgentTypeID defined`);
|
|
368
|
-
return null;
|
|
369
|
-
}
|
|
370
|
-
await aiengine_1.AIEngine.Instance.Config(false, this.contextUser);
|
|
371
|
-
const agentType = aiengine_1.AIEngine.Instance.AgentTypes.find(at => at.ID === this.agent.TypeID);
|
|
372
|
-
if (!agentType) {
|
|
373
|
-
(0, core_1.LogError)(`Agent type not found for ID: ${this.agent.TypeID}`);
|
|
374
|
-
return null;
|
|
375
|
-
}
|
|
376
|
-
return agentType;
|
|
377
|
-
}
|
|
378
|
-
catch (error) {
|
|
379
|
-
(0, core_1.LogError)(`Error loading agent type for '${this.agent.Name}': ${error.message}`);
|
|
380
|
-
return null;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
async loadChildAgents() {
|
|
384
|
-
try {
|
|
385
|
-
const childAgents = aiengine_1.AIEngine.Instance.Agents
|
|
386
|
-
.filter(a => a.ParentID === this.agent.ID)
|
|
387
|
-
.sort((a, b) => (a.ExecutionOrder || 0) - (b.ExecutionOrder || 0));
|
|
388
|
-
return childAgents;
|
|
389
|
-
}
|
|
390
|
-
catch (error) {
|
|
391
|
-
(0, core_1.LogError)(`Error loading child agents for '${this.agent.Name}': ${error.message}`);
|
|
392
|
-
return [];
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
sendProgress(callback, progress) {
|
|
396
|
-
if (callback) {
|
|
397
|
-
try {
|
|
398
|
-
callback(progress);
|
|
399
|
-
}
|
|
400
|
-
catch (error) {
|
|
401
|
-
(0, core_1.LogError)(`Error in progress callback: ${error.message}`);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
async createExecutionStep(context, stepType, stepName, targetId, inputData) {
|
|
406
|
-
try {
|
|
407
|
-
if (!context.agentRun) {
|
|
408
|
-
throw new Error('Agent run record not found in context');
|
|
409
|
-
}
|
|
410
|
-
const stepEntity = await this._metadata.GetEntityObject('MJ: AI Agent Run Steps', this.contextUser);
|
|
411
|
-
stepEntity.NewRecord();
|
|
412
|
-
stepEntity.AgentRunID = context.agentRun.ID;
|
|
413
|
-
stepEntity.StepNumber = context.currentStepNumber;
|
|
414
|
-
stepEntity.StepType = stepType;
|
|
415
|
-
stepEntity.StepName = stepName;
|
|
416
|
-
stepEntity.Status = 'Running';
|
|
417
|
-
stepEntity.StartedAt = new Date();
|
|
418
|
-
if (targetId) {
|
|
419
|
-
stepEntity.TargetID = targetId;
|
|
420
|
-
}
|
|
421
|
-
if (inputData) {
|
|
422
|
-
stepEntity.InputData = JSON.stringify(inputData);
|
|
423
|
-
}
|
|
424
|
-
const saveResult = await stepEntity.Save();
|
|
425
|
-
if (!saveResult) {
|
|
426
|
-
throw new Error(`Failed to create execution step: ${stepName}`);
|
|
427
|
-
}
|
|
428
|
-
context.currentStepNumber++;
|
|
429
|
-
return stepEntity;
|
|
430
|
-
}
|
|
431
|
-
catch (error) {
|
|
432
|
-
(0, core_1.LogError)(`Error creating execution step '${stepName}': ${error.message}`);
|
|
433
|
-
throw error;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
async completeExecutionStep(stepEntity, success, outputData, errorMessage) {
|
|
437
|
-
try {
|
|
438
|
-
stepEntity.Status = success ? 'Completed' : 'Failed';
|
|
439
|
-
stepEntity.Success = success;
|
|
440
|
-
stepEntity.CompletedAt = new Date();
|
|
441
|
-
if (outputData) {
|
|
442
|
-
stepEntity.OutputData = JSON.stringify(outputData);
|
|
443
|
-
}
|
|
444
|
-
if (errorMessage) {
|
|
445
|
-
stepEntity.ErrorMessage = errorMessage;
|
|
446
|
-
}
|
|
447
|
-
await stepEntity.Save();
|
|
448
|
-
}
|
|
449
|
-
catch (error) {
|
|
450
|
-
(0, core_1.LogError)(`Error completing execution step: ${error.message}`);
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
serializeAgentState(context, executionHistory, decisionHistory, actionResults) {
|
|
454
|
-
return {
|
|
455
|
-
conversationMessages: context.conversationMessages,
|
|
456
|
-
executionHistory,
|
|
457
|
-
decisionHistory,
|
|
458
|
-
actionResults,
|
|
459
|
-
currentStep: context.currentStep,
|
|
460
|
-
currentStepNumber: context.currentStepNumber,
|
|
461
|
-
contextData: context.data,
|
|
462
|
-
agentConfiguration: context.configuration || {},
|
|
463
|
-
serializedAt: new Date(),
|
|
464
|
-
version: '1.0'
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
deserializeAgentState(serializedState, context) {
|
|
468
|
-
context.conversationMessages = serializedState.conversationMessages;
|
|
469
|
-
context.currentStep = serializedState.currentStep;
|
|
470
|
-
context.currentStepNumber = serializedState.currentStepNumber;
|
|
471
|
-
context.data = { ...context.data, ...serializedState.contextData };
|
|
472
|
-
context.configuration = { ...context.configuration, ...serializedState.agentConfiguration };
|
|
473
|
-
return {
|
|
474
|
-
executionHistory: serializedState.executionHistory,
|
|
475
|
-
decisionHistory: serializedState.decisionHistory,
|
|
476
|
-
actionResults: serializedState.actionResults
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
|
-
async updateAgentRunState(context, executionHistory, decisionHistory, actionResults) {
|
|
480
|
-
try {
|
|
481
|
-
if (!context.agentRun) {
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
const serializedState = this.serializeAgentState(context, executionHistory, decisionHistory, actionResults);
|
|
485
|
-
context.agentRun.AgentState = JSON.stringify(serializedState);
|
|
486
|
-
await context.agentRun.Save();
|
|
487
|
-
}
|
|
488
|
-
catch (error) {
|
|
489
|
-
(0, core_1.LogError)(`Error updating agent run state: ${error.message}`);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
async finalizeAgentRun(context, success, errorMessage, finalResult, decisionHistory, actionResults) {
|
|
493
|
-
try {
|
|
494
|
-
if (!context.agentRun) {
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
context.agentRun.Status = success ? 'Completed' : 'Failed';
|
|
498
|
-
context.agentRun.Success = success;
|
|
499
|
-
context.agentRun.CompletedAt = new Date();
|
|
500
|
-
if (errorMessage) {
|
|
501
|
-
context.agentRun.ErrorMessage = errorMessage;
|
|
502
|
-
}
|
|
503
|
-
if (finalResult) {
|
|
504
|
-
context.agentRun.Result = typeof finalResult === 'string' ? finalResult : JSON.stringify(finalResult);
|
|
505
|
-
}
|
|
506
|
-
if (actionResults && actionResults.length > 0) {
|
|
507
|
-
let totalTokens = 0;
|
|
508
|
-
let totalCost = 0;
|
|
509
|
-
for (const actionResult of actionResults) {
|
|
510
|
-
if (actionResult.Params) {
|
|
511
|
-
for (const param of actionResult.Params) {
|
|
512
|
-
if (param.Name === 'tokensUsed' && typeof param.Value === 'number') {
|
|
513
|
-
totalTokens += param.Value;
|
|
514
|
-
}
|
|
515
|
-
if (param.Name === 'cost' && typeof param.Value === 'number') {
|
|
516
|
-
totalCost += param.Value;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
if (totalTokens > 0) {
|
|
522
|
-
context.agentRun.TotalTokensUsed = totalTokens;
|
|
523
|
-
}
|
|
524
|
-
if (totalCost > 0) {
|
|
525
|
-
context.agentRun.TotalCost = totalCost;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
if (decisionHistory && actionResults) {
|
|
529
|
-
const finalState = this.serializeAgentState(context, [], decisionHistory, actionResults);
|
|
530
|
-
context.agentRun.AgentState = JSON.stringify(finalState);
|
|
531
|
-
}
|
|
532
|
-
await context.agentRun.Save();
|
|
533
|
-
}
|
|
534
|
-
catch (error) {
|
|
535
|
-
(0, core_1.LogError)(`Error finalizing agent run: ${error.message}`);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
async createDecisionInput(context, currentMessages, executionHistory) {
|
|
539
|
-
const availableActions = await this.getAvailableActionDescriptions();
|
|
540
|
-
const availableSubAgents = await this.getAvailableSubAgentDescriptions();
|
|
541
|
-
const currentGoal = context.data.goal ||
|
|
542
|
-
context.data.task ||
|
|
543
|
-
this.agent.Description ||
|
|
544
|
-
'Complete the requested task';
|
|
545
|
-
return {
|
|
546
|
-
messages: currentMessages,
|
|
547
|
-
availableActions,
|
|
548
|
-
availableSubAgents,
|
|
549
|
-
currentGoal,
|
|
550
|
-
executionHistory,
|
|
551
|
-
contextData: context.data
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
async makeDecision(context, decisionInput) {
|
|
555
|
-
try {
|
|
556
|
-
const prompts = await this.loadAgentPrompts();
|
|
557
|
-
const agentType = await this.loadAgentType();
|
|
558
|
-
if (prompts.length === 0) {
|
|
559
|
-
throw new Error(`No prompts found for agent ${this.agent.Name}`);
|
|
560
|
-
}
|
|
561
|
-
const primaryprompt = prompts[0];
|
|
562
|
-
const contextualPrompt = this.buildContextualDecisionPrompt(decisionInput);
|
|
563
|
-
const promptData = {
|
|
564
|
-
agentName: this.agent.Name,
|
|
565
|
-
agentDescription: this.agent.Description,
|
|
566
|
-
availableActions: decisionInput.availableActions,
|
|
567
|
-
availableSubAgents: decisionInput.availableSubAgents,
|
|
568
|
-
currentGoal: decisionInput.currentGoal,
|
|
569
|
-
executionHistory: decisionInput.executionHistory,
|
|
570
|
-
contextData: decisionInput.contextData
|
|
571
|
-
};
|
|
572
|
-
const conversationMessages = [
|
|
573
|
-
...decisionInput.messages,
|
|
574
|
-
{
|
|
575
|
-
role: 'user',
|
|
576
|
-
content: contextualPrompt
|
|
577
|
-
}
|
|
578
|
-
];
|
|
579
|
-
const promptParams = new ai_prompts_1.AIPromptParams();
|
|
580
|
-
if (agentType && agentType.SystemPromptID && agentType.SystemPromptID !== primaryprompt.ID) {
|
|
581
|
-
const systemPrompt = prompts.find(p => p.ID === agentType.SystemPromptID);
|
|
582
|
-
if (systemPrompt) {
|
|
583
|
-
const childPromptParams = new ai_prompts_1.AIPromptParams();
|
|
584
|
-
childPromptParams.prompt = primaryprompt;
|
|
585
|
-
childPromptParams.data = promptData;
|
|
586
|
-
childPromptParams.contextUser = context.params.contextUser;
|
|
587
|
-
const childPrompt = new ai_prompts_1.ChildPromptParam(childPromptParams, 'agentPrompt');
|
|
588
|
-
promptParams.prompt = systemPrompt;
|
|
589
|
-
promptParams.childPrompts = [childPrompt];
|
|
590
|
-
promptParams.data = promptData;
|
|
591
|
-
}
|
|
592
|
-
else {
|
|
593
|
-
promptParams.prompt = primaryprompt;
|
|
594
|
-
promptParams.data = promptData;
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
else {
|
|
598
|
-
promptParams.prompt = primaryprompt;
|
|
599
|
-
promptParams.data = promptData;
|
|
600
|
-
}
|
|
601
|
-
promptParams.conversationMessages = conversationMessages;
|
|
602
|
-
promptParams.templateMessageRole = 'system';
|
|
603
|
-
promptParams.contextUser = context.params.contextUser;
|
|
604
|
-
promptParams.agentRunId = context.agentRun.ID;
|
|
605
|
-
const promptResult = await this._promptRunner.ExecutePrompt(promptParams);
|
|
606
|
-
if (!promptResult.success) {
|
|
607
|
-
throw new Error(`AI prompt execution failed: ${promptResult.errorMessage}`);
|
|
608
|
-
}
|
|
609
|
-
const decision = await this.parseAndValidateDecision(promptResult.rawResult || '');
|
|
610
|
-
return decision;
|
|
611
|
-
}
|
|
612
|
-
catch (error) {
|
|
613
|
-
(0, core_1.LogError)(`Error making decision: ${error.message}`);
|
|
614
|
-
return {
|
|
615
|
-
decision: 'request_clarification',
|
|
616
|
-
reasoning: `Error occurred while making decision: ${error.message}`,
|
|
617
|
-
executionPlan: [],
|
|
618
|
-
isTaskComplete: false,
|
|
619
|
-
confidence: 0.1
|
|
620
|
-
};
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
buildContextualDecisionPrompt(decisionInput) {
|
|
624
|
-
const executionSummary = decisionInput.executionHistory.length > 0
|
|
625
|
-
? this.summarizeExecutionHistory(decisionInput.executionHistory)
|
|
626
|
-
: 'No previous actions taken.';
|
|
627
|
-
const actionDetails = decisionInput.availableActions.length > 0
|
|
628
|
-
? this.formatActionsForDecision(decisionInput.availableActions)
|
|
629
|
-
: '';
|
|
630
|
-
const subAgentDetails = decisionInput.availableSubAgents.length > 0
|
|
631
|
-
? this.formatSubAgentsForDecision(decisionInput.availableSubAgents)
|
|
632
|
-
: '';
|
|
633
|
-
return `## Current Situation Analysis
|
|
634
|
-
|
|
635
|
-
**Primary Goal:** ${decisionInput.currentGoal}
|
|
636
|
-
|
|
637
|
-
**Conversation Context:** ${decisionInput.messages.length} messages in conversation
|
|
638
|
-
**Previous Actions:** ${executionSummary}
|
|
639
|
-
**Available Actions:** ${decisionInput.availableActions.length} actions
|
|
640
|
-
**Available Sub-Agents:** ${decisionInput.availableSubAgents.length} sub-agents${actionDetails}${subAgentDetails}
|
|
641
|
-
|
|
642
|
-
## Decision Request
|
|
643
|
-
|
|
644
|
-
Based on your specialized instructions, the current context, and available resources, what should you do next to achieve the goal: "${decisionInput.currentGoal}"?
|
|
645
|
-
|
|
646
|
-
Consider:
|
|
647
|
-
1. Have you fully understood what the user is asking for?
|
|
648
|
-
2. Do you have all the information needed to proceed?
|
|
649
|
-
3. Which approach would be most effective and efficient?
|
|
650
|
-
4. Should any actions be performed in parallel?
|
|
651
|
-
5. Are you ready to provide a final response?
|
|
652
|
-
|
|
653
|
-
**Respond with a JSON object following the specified structure.**`;
|
|
654
|
-
}
|
|
655
|
-
formatActionsForDecision(actions) {
|
|
656
|
-
if (actions.length === 0)
|
|
657
|
-
return '';
|
|
658
|
-
let section = '\n## Available Actions Details\n';
|
|
659
|
-
for (const action of actions.slice(0, 5)) {
|
|
660
|
-
section += `**${action.name}** (${action.id}): ${action.description}\n`;
|
|
661
|
-
if (action.metadata) {
|
|
662
|
-
if (action.metadata.estimatedDuration) {
|
|
663
|
-
section += ` - Duration: ~${action.metadata.estimatedDuration}ms\n`;
|
|
664
|
-
}
|
|
665
|
-
if (action.metadata.reliability) {
|
|
666
|
-
section += ` - Reliability: ${(action.metadata.reliability * 100).toFixed(0)}%\n`;
|
|
667
|
-
}
|
|
668
|
-
if (action.metadata.costLevel) {
|
|
669
|
-
section += ` - Cost level: ${action.metadata.costLevel}\n`;
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
if (actions.length > 5) {
|
|
674
|
-
section += `... and ${actions.length - 5} more actions available\n`;
|
|
675
|
-
}
|
|
676
|
-
return section;
|
|
677
|
-
}
|
|
678
|
-
formatSubAgentsForDecision(subAgents) {
|
|
679
|
-
if (subAgents.length === 0)
|
|
680
|
-
return '';
|
|
681
|
-
let section = '\n## Available Sub-Agents Details\n';
|
|
682
|
-
const sortedAgents = [...subAgents].sort((a, b) => (a.executionOrder || 0) - (b.executionOrder || 0));
|
|
683
|
-
for (const agent of sortedAgents.slice(0, 5)) {
|
|
684
|
-
section += `**${agent.name}** (${agent.id}): ${agent.description}\n`;
|
|
685
|
-
section += ` - Suggested execution order: ${agent.executionOrder || 0}\n`;
|
|
686
|
-
section += ` - Supports parallel execution: ${agent.supportsParallel}\n`;
|
|
687
|
-
if (agent.metadata) {
|
|
688
|
-
if (agent.metadata.availabilityStatus) {
|
|
689
|
-
section += ` - Status: ${agent.metadata.availabilityStatus}\n`;
|
|
690
|
-
}
|
|
691
|
-
if (agent.metadata.executionContext) {
|
|
692
|
-
section += ` - Context: ${agent.metadata.executionContext}\n`;
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
section += '\n';
|
|
696
|
-
}
|
|
697
|
-
if (subAgents.length > 5) {
|
|
698
|
-
section += `... and ${subAgents.length - 5} more sub-agents available\n`;
|
|
699
|
-
}
|
|
700
|
-
section += '\n**Note**: Execution order values are suggestions. You have complete autonomy to choose any sequence that best achieves the goal.\n';
|
|
701
|
-
return section;
|
|
702
|
-
}
|
|
703
|
-
summarizeExecutionHistory(history) {
|
|
704
|
-
if (history.length === 0)
|
|
705
|
-
return 'None';
|
|
706
|
-
const successful = history.filter(h => h.success).length;
|
|
707
|
-
const failed = history.filter(h => !h.success).length;
|
|
708
|
-
const recent = history.slice(-3).map(h => `${h.type}:${h.targetId}(${h.success ? 'success' : 'failed'})`).join(', ');
|
|
709
|
-
return `${history.length} total actions (${successful} successful, ${failed} failed). Recent: ${recent}`;
|
|
710
|
-
}
|
|
711
|
-
async parseAndValidateDecision(llmResponse) {
|
|
712
|
-
try {
|
|
713
|
-
const jsonMatch = llmResponse.match(/```json\s*([\s\S]*?)\s*```/) ||
|
|
714
|
-
llmResponse.match(/\{[\s\S]*\}/);
|
|
715
|
-
const jsonString = jsonMatch ? (jsonMatch[1] || jsonMatch[0]) : llmResponse;
|
|
716
|
-
let decision;
|
|
717
|
-
try {
|
|
718
|
-
decision = JSON.parse(jsonString.trim());
|
|
719
|
-
}
|
|
720
|
-
catch (parseError) {
|
|
721
|
-
(0, core_1.LogError)(`Failed to parse LLM decision response: ${parseError.message}`);
|
|
722
|
-
return this.createFallbackDecision(llmResponse);
|
|
723
|
-
}
|
|
724
|
-
return this.validateAndNormalizeDecision(decision);
|
|
725
|
-
}
|
|
726
|
-
catch (error) {
|
|
727
|
-
(0, core_1.LogError)(`Error parsing decision: ${error.message}`);
|
|
728
|
-
return this.createFallbackDecision(llmResponse);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
createFallbackDecision(llmResponse) {
|
|
732
|
-
const response = llmResponse.toLowerCase();
|
|
733
|
-
if (response.includes('complete') || response.includes('finished') || response.includes('done')) {
|
|
734
|
-
return {
|
|
735
|
-
decision: 'complete_task',
|
|
736
|
-
reasoning: `Task appears to be complete based on response: ${llmResponse}`,
|
|
737
|
-
executionPlan: [],
|
|
738
|
-
isTaskComplete: true,
|
|
739
|
-
finalResponse: llmResponse,
|
|
740
|
-
confidence: 0.3
|
|
741
|
-
};
|
|
742
|
-
}
|
|
743
|
-
if (response.includes('need') || response.includes('require') || response.includes('clarify')) {
|
|
744
|
-
return {
|
|
745
|
-
decision: 'request_clarification',
|
|
746
|
-
reasoning: `Clarification needed based on response: ${llmResponse}`,
|
|
747
|
-
executionPlan: [],
|
|
748
|
-
isTaskComplete: false,
|
|
749
|
-
confidence: 0.4
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
|
-
return {
|
|
753
|
-
decision: 'request_clarification',
|
|
754
|
-
reasoning: `Unable to parse LLM response format. Raw response: ${llmResponse}`,
|
|
755
|
-
executionPlan: [],
|
|
756
|
-
isTaskComplete: false,
|
|
757
|
-
confidence: 0.1
|
|
758
|
-
};
|
|
759
|
-
}
|
|
760
|
-
async executeDecidedActions(context, decision, executionHistory) {
|
|
761
|
-
const historyItems = [];
|
|
762
|
-
const actionResults = [];
|
|
763
|
-
const newMessages = [];
|
|
764
|
-
if (!decision.executionPlan || decision.executionPlan.length === 0) {
|
|
765
|
-
return { historyItems, actionResults, newMessages };
|
|
766
|
-
}
|
|
767
|
-
const executionGroups = this.groupExecutionStepsByOrder(decision.executionPlan);
|
|
768
|
-
for (const [order, steps] of executionGroups) {
|
|
769
|
-
this.sendProgress(context.params.onProgress, {
|
|
770
|
-
step: 'subagent_coordination',
|
|
771
|
-
percentage: 40 + (40 * order / executionGroups.size),
|
|
772
|
-
message: `Executing steps at order ${order}`,
|
|
773
|
-
metadata: {
|
|
774
|
-
executionOrder: order,
|
|
775
|
-
stepCount: steps.length,
|
|
776
|
-
stepTypes: steps.map(s => s.type)
|
|
777
|
-
}
|
|
778
|
-
});
|
|
779
|
-
const hasSequentialSteps = steps.some(step => step.allowParallel === false);
|
|
780
|
-
if (hasSequentialSteps) {
|
|
781
|
-
const sequentialResults = await this.executeStepsSequentially(context, steps, executionHistory);
|
|
782
|
-
historyItems.push(...sequentialResults.historyItems);
|
|
783
|
-
actionResults.push(...sequentialResults.actionResults);
|
|
784
|
-
newMessages.push(...sequentialResults.newMessages);
|
|
785
|
-
}
|
|
786
|
-
else {
|
|
787
|
-
const parallelResults = await this.executeStepsInParallel(context, steps, executionHistory);
|
|
788
|
-
historyItems.push(...parallelResults.historyItems);
|
|
789
|
-
actionResults.push(...parallelResults.actionResults);
|
|
790
|
-
newMessages.push(...parallelResults.newMessages);
|
|
791
|
-
}
|
|
792
|
-
if (steps.length > 0) {
|
|
793
|
-
const successCount = historyItems.filter(h => h.success).length;
|
|
794
|
-
const orderSummary = `Completed execution order ${order}: ${successCount}/${steps.length} steps successful`;
|
|
795
|
-
newMessages.push({
|
|
796
|
-
role: 'assistant',
|
|
797
|
-
content: orderSummary
|
|
798
|
-
});
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
return { historyItems, actionResults, newMessages };
|
|
802
|
-
}
|
|
803
|
-
groupExecutionStepsByOrder(executionPlan) {
|
|
804
|
-
const groups = new Map();
|
|
805
|
-
for (const step of executionPlan) {
|
|
806
|
-
const order = step.executionOrder || 1;
|
|
807
|
-
if (!groups.has(order)) {
|
|
808
|
-
groups.set(order, []);
|
|
809
|
-
}
|
|
810
|
-
groups.get(order).push(step);
|
|
811
|
-
}
|
|
812
|
-
return new Map([...groups.entries()].sort(([a], [b]) => a - b));
|
|
813
|
-
}
|
|
814
|
-
async executeStepsInParallel(context, steps, executionHistory) {
|
|
815
|
-
const promises = steps.map(step => this.executeSingleStep(context, step, executionHistory));
|
|
816
|
-
const results = await Promise.allSettled(promises);
|
|
817
|
-
const historyItems = [];
|
|
818
|
-
const actionResults = [];
|
|
819
|
-
const newMessages = [];
|
|
820
|
-
for (let i = 0; i < results.length; i++) {
|
|
821
|
-
const result = results[i];
|
|
822
|
-
const step = steps[i];
|
|
823
|
-
if (result.status === 'fulfilled') {
|
|
824
|
-
historyItems.push(result.value.historyItem);
|
|
825
|
-
if (result.value.actionResult) {
|
|
826
|
-
actionResults.push(result.value.actionResult);
|
|
827
|
-
}
|
|
828
|
-
if (result.value.newMessage) {
|
|
829
|
-
newMessages.push(result.value.newMessage);
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
else {
|
|
833
|
-
historyItems.push({
|
|
834
|
-
type: step.type,
|
|
835
|
-
targetId: step.targetId,
|
|
836
|
-
parameters: step.parameters,
|
|
837
|
-
result: null,
|
|
838
|
-
success: false,
|
|
839
|
-
errorMessage: result.reason?.message || 'Parallel execution failed',
|
|
840
|
-
timestamp: new Date()
|
|
841
|
-
});
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
return { historyItems, actionResults, newMessages };
|
|
845
|
-
}
|
|
846
|
-
async executeStepsSequentially(context, steps, executionHistory) {
|
|
847
|
-
const historyItems = [];
|
|
848
|
-
const actionResults = [];
|
|
849
|
-
const newMessages = [];
|
|
850
|
-
for (const step of steps) {
|
|
851
|
-
try {
|
|
852
|
-
const result = await this.executeSingleStep(context, step, executionHistory);
|
|
853
|
-
historyItems.push(result.historyItem);
|
|
854
|
-
if (result.actionResult) {
|
|
855
|
-
actionResults.push(result.actionResult);
|
|
856
|
-
}
|
|
857
|
-
if (result.newMessage) {
|
|
858
|
-
newMessages.push(result.newMessage);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
catch (error) {
|
|
862
|
-
historyItems.push({
|
|
863
|
-
type: step.type,
|
|
864
|
-
targetId: step.targetId,
|
|
865
|
-
parameters: step.parameters,
|
|
866
|
-
result: null,
|
|
867
|
-
success: false,
|
|
868
|
-
errorMessage: error.message,
|
|
869
|
-
timestamp: new Date()
|
|
870
|
-
});
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
return { historyItems, actionResults, newMessages };
|
|
874
|
-
}
|
|
875
|
-
async executeSingleStep(context, step, executionHistory) {
|
|
876
|
-
const timestamp = new Date();
|
|
877
|
-
const stepEntity = await this.createExecutionStep(context, step.type, step.description || `Execute ${step.type} '${step.targetId}'`, step.targetId, step.parameters);
|
|
878
|
-
try {
|
|
879
|
-
if (step.type === 'action') {
|
|
880
|
-
const actionResult = await this.executeAction(step.targetId, step.parameters || {});
|
|
881
|
-
const statusMessage = step.description
|
|
882
|
-
? `${step.description} - ${actionResult.Success ? 'Completed' : 'Failed'}`
|
|
883
|
-
: `Executed action '${step.targetId}': ${actionResult.Success ? 'Success' : actionResult.Message}`;
|
|
884
|
-
await this.completeExecutionStep(stepEntity, actionResult.Success, {
|
|
885
|
-
actionResult: {
|
|
886
|
-
success: actionResult.Success,
|
|
887
|
-
message: actionResult.Message,
|
|
888
|
-
paramsCount: actionResult.Params?.length || 0
|
|
889
|
-
}
|
|
890
|
-
}, actionResult.Success ? undefined : actionResult.Message);
|
|
891
|
-
return {
|
|
892
|
-
historyItem: {
|
|
893
|
-
type: 'action',
|
|
894
|
-
targetId: step.targetId,
|
|
895
|
-
parameters: step.parameters,
|
|
896
|
-
result: actionResult,
|
|
897
|
-
success: actionResult.Success,
|
|
898
|
-
errorMessage: actionResult.Success ? undefined : actionResult.Message,
|
|
899
|
-
timestamp
|
|
900
|
-
},
|
|
901
|
-
actionResult,
|
|
902
|
-
newMessage: {
|
|
903
|
-
role: 'assistant',
|
|
904
|
-
content: statusMessage
|
|
905
|
-
}
|
|
906
|
-
};
|
|
907
|
-
}
|
|
908
|
-
else if (step.type === 'subagent') {
|
|
909
|
-
const subagentResult = await this.executeSubAgent(step.targetId, step.parameters || {}, context);
|
|
910
|
-
const statusMessage = step.description
|
|
911
|
-
? `${step.description} - ${subagentResult.success ? 'Completed' : 'Failed'}`
|
|
912
|
-
: `Executed subagent '${step.targetId}': ${subagentResult.success ? 'Success' : subagentResult.errorMessage}`;
|
|
913
|
-
await this.completeExecutionStep(stepEntity, subagentResult.success, {
|
|
914
|
-
subagentResult: {
|
|
915
|
-
success: subagentResult.success,
|
|
916
|
-
executionTimeMS: subagentResult.executionTimeMS,
|
|
917
|
-
resultLength: subagentResult.result ? JSON.stringify(subagentResult.result).length : 0
|
|
918
|
-
}
|
|
919
|
-
}, subagentResult.success ? undefined : subagentResult.errorMessage);
|
|
920
|
-
return {
|
|
921
|
-
historyItem: {
|
|
922
|
-
type: 'subagent',
|
|
923
|
-
targetId: step.targetId,
|
|
924
|
-
parameters: step.parameters,
|
|
925
|
-
result: subagentResult,
|
|
926
|
-
success: subagentResult.success,
|
|
927
|
-
errorMessage: subagentResult.success ? undefined : subagentResult.errorMessage,
|
|
928
|
-
timestamp
|
|
929
|
-
},
|
|
930
|
-
newMessage: {
|
|
931
|
-
role: 'assistant',
|
|
932
|
-
content: statusMessage
|
|
933
|
-
}
|
|
934
|
-
};
|
|
935
|
-
}
|
|
936
|
-
else {
|
|
937
|
-
const errorMessage = `Unknown execution step type: ${step.type}`;
|
|
938
|
-
await this.completeExecutionStep(stepEntity, false, null, errorMessage);
|
|
939
|
-
throw new Error(errorMessage);
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
catch (error) {
|
|
943
|
-
await this.completeExecutionStep(stepEntity, false, null, error.message);
|
|
944
|
-
return {
|
|
945
|
-
historyItem: {
|
|
946
|
-
type: step.type,
|
|
947
|
-
targetId: step.targetId,
|
|
948
|
-
parameters: step.parameters,
|
|
949
|
-
result: null,
|
|
950
|
-
success: false,
|
|
951
|
-
errorMessage: error.message,
|
|
952
|
-
timestamp
|
|
953
|
-
}
|
|
954
|
-
};
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
async getAvailableActionDescriptions() {
|
|
958
|
-
try {
|
|
959
|
-
const agentActions = aiengine_1.AIEngine.Instance.AgentActions
|
|
960
|
-
.filter(aa => aa.AgentID === this.agent.ID && aa.Status === 'Active');
|
|
961
|
-
const actions = [];
|
|
962
|
-
await actions_1.ActionEngineServer.Instance.Config(false, this.contextUser);
|
|
963
|
-
for (const agentAction of agentActions) {
|
|
964
|
-
const action = actions_1.ActionEngineServer.Instance.Actions.find(a => a.ID === agentAction.ActionID);
|
|
965
|
-
if (action && action.Status === 'Active') {
|
|
966
|
-
actions.push({
|
|
967
|
-
id: action.ID,
|
|
968
|
-
name: action.Name,
|
|
969
|
-
description: action.Description || '',
|
|
970
|
-
parameters: action.Params?.map(p => ({
|
|
971
|
-
name: p.Name,
|
|
972
|
-
type: p.Type,
|
|
973
|
-
description: p.Description || '',
|
|
974
|
-
required: p.IsRequired || false,
|
|
975
|
-
defaultValue: p.DefaultValue
|
|
976
|
-
})) || [],
|
|
977
|
-
supportsParallel: true
|
|
978
|
-
});
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
return actions;
|
|
982
|
-
}
|
|
983
|
-
catch (error) {
|
|
984
|
-
(0, core_1.LogError)(`Error loading available actions: ${error.message}`);
|
|
985
|
-
return [];
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
async getAvailableSubAgentDescriptions() {
|
|
989
|
-
try {
|
|
990
|
-
const childAgents = await this.loadChildAgents();
|
|
991
|
-
return childAgents.map(agent => ({
|
|
992
|
-
id: agent.ID,
|
|
993
|
-
name: agent.Name,
|
|
994
|
-
description: agent.Description || '',
|
|
995
|
-
supportsParallel: agent.ExecutionMode === 'Parallel',
|
|
996
|
-
executionOrder: agent.ExecutionOrder || 0,
|
|
997
|
-
metadata: {
|
|
998
|
-
executionContext: `Default execution order: ${agent.ExecutionOrder || 0}. Mode: ${agent.ExecutionMode || 'Sequential'}`,
|
|
999
|
-
availabilityStatus: 'available'
|
|
1000
|
-
}
|
|
1001
|
-
}));
|
|
1002
|
-
}
|
|
1003
|
-
catch (error) {
|
|
1004
|
-
(0, core_1.LogError)(`Error loading available sub-agents: ${error.message}`);
|
|
1005
|
-
return [];
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
async executeAction(actionId, parameters) {
|
|
1009
|
-
try {
|
|
1010
|
-
const actionParams = Object.entries(parameters).map(([name, value]) => ({
|
|
1011
|
-
Name: name,
|
|
1012
|
-
Value: value,
|
|
1013
|
-
Type: 'Input'
|
|
1014
|
-
}));
|
|
1015
|
-
return await actions_1.ActionEngineServer.Instance.RunActionByID({
|
|
1016
|
-
ActionID: actionId,
|
|
1017
|
-
ContextUser: this.contextUser,
|
|
1018
|
-
Params: actionParams,
|
|
1019
|
-
SkipActionLog: false
|
|
1020
|
-
});
|
|
1021
|
-
}
|
|
1022
|
-
catch (error) {
|
|
1023
|
-
(0, core_1.LogError)(`Error executing action '${actionId}': ${error.message}`);
|
|
1024
|
-
return {
|
|
1025
|
-
Success: false,
|
|
1026
|
-
Message: error.message,
|
|
1027
|
-
LogEntry: null,
|
|
1028
|
-
Params: [],
|
|
1029
|
-
RunParams: null
|
|
1030
|
-
};
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
async executeSubAgent(subAgentId, parameters, parentContext) {
|
|
1034
|
-
try {
|
|
1035
|
-
const subAgentEntity = aiengine_1.AIEngine.Instance.Agents.find(a => a.ID === subAgentId);
|
|
1036
|
-
if (!subAgentEntity) {
|
|
1037
|
-
throw new Error(`Sub-agent with ID '${subAgentId}' not found`);
|
|
1038
|
-
}
|
|
1039
|
-
const subAgent = this.factory.CreateAgentFromEntity(subAgentEntity, null, this._contextUser);
|
|
1040
|
-
const subAgentParams = {
|
|
1041
|
-
contextUser: parentContext.params.contextUser,
|
|
1042
|
-
data: {
|
|
1043
|
-
...parentContext.data,
|
|
1044
|
-
...parameters,
|
|
1045
|
-
parentRunId: parentContext.agentRun?.ID,
|
|
1046
|
-
parentRunID: parentContext.agentRun?.ID
|
|
1047
|
-
},
|
|
1048
|
-
conversationMessages: [...parentContext.conversationMessages],
|
|
1049
|
-
cancellationToken: parentContext.params.cancellationToken,
|
|
1050
|
-
onProgress: parentContext.params.onProgress,
|
|
1051
|
-
onStreaming: parentContext.params.onStreaming
|
|
1052
|
-
};
|
|
1053
|
-
return await subAgent.Execute(subAgentParams);
|
|
1054
|
-
}
|
|
1055
|
-
catch (error) {
|
|
1056
|
-
(0, core_1.LogError)(`Error executing sub-agent '${subAgentId}': ${error.message}`);
|
|
1057
|
-
return {
|
|
1058
|
-
success: false,
|
|
1059
|
-
errorMessage: error.message
|
|
1060
|
-
};
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
validateAndNormalizeDecision(decision) {
|
|
1064
|
-
let executionPlan = [];
|
|
1065
|
-
if (decision.executionPlan && Array.isArray(decision.executionPlan)) {
|
|
1066
|
-
executionPlan = decision.executionPlan.map((step, index) => ({
|
|
1067
|
-
type: step.type || 'action',
|
|
1068
|
-
targetId: step.targetId || '',
|
|
1069
|
-
parameters: step.parameters || {},
|
|
1070
|
-
executionOrder: step.executionOrder || (index + 1),
|
|
1071
|
-
allowParallel: step.allowParallel !== false,
|
|
1072
|
-
description: step.description || `Step ${index + 1}: ${step.type} ${step.targetId}`
|
|
1073
|
-
}));
|
|
1074
|
-
}
|
|
1075
|
-
return {
|
|
1076
|
-
decision: decision.decision || 'request_clarification',
|
|
1077
|
-
reasoning: decision.reasoning || 'No reasoning provided',
|
|
1078
|
-
executionPlan,
|
|
1079
|
-
isTaskComplete: decision.isTaskComplete || false,
|
|
1080
|
-
finalResponse: decision.finalResponse,
|
|
1081
|
-
confidence: typeof decision.confidence === 'number' ? decision.confidence : 0.5,
|
|
1082
|
-
metadata: decision.metadata
|
|
1083
|
-
};
|
|
1084
|
-
}
|
|
1085
|
-
createExecutionSummary(decision, executionResults) {
|
|
1086
|
-
const { historyItems } = executionResults;
|
|
1087
|
-
const successful = historyItems.filter(h => h.success);
|
|
1088
|
-
const failed = historyItems.filter(h => !h.success);
|
|
1089
|
-
const parts = [
|
|
1090
|
-
`Executed ${decision.executionPlan.length} steps: ${decision.reasoning}`
|
|
1091
|
-
];
|
|
1092
|
-
if (successful.length) {
|
|
1093
|
-
parts.push(`✅ Success: ${successful.map(h => h.targetId).join(', ')}`);
|
|
1094
|
-
}
|
|
1095
|
-
if (failed.length) {
|
|
1096
|
-
parts.push(`❌ Failed: ${failed.map(h => h.targetId).join(', ')}`);
|
|
1097
|
-
}
|
|
1098
|
-
return parts.join('\n');
|
|
1099
|
-
}
|
|
1100
|
-
createCancelledResult(startTime) {
|
|
1101
|
-
const endTime = new Date();
|
|
1102
|
-
return {
|
|
1103
|
-
success: false,
|
|
1104
|
-
cancelled: true,
|
|
1105
|
-
errorMessage: 'Agent execution was cancelled',
|
|
1106
|
-
executionTimeMS: endTime.getTime() - startTime.getTime()
|
|
1107
|
-
};
|
|
1108
|
-
}
|
|
1109
|
-
async getRunHistory(agentRunId) {
|
|
1110
|
-
try {
|
|
1111
|
-
const agentRun = await this._metadata.GetEntityObject('MJ: AI Agent Runs', this.contextUser);
|
|
1112
|
-
const loadSuccess = await agentRun.Load(agentRunId);
|
|
1113
|
-
if (!loadSuccess) {
|
|
1114
|
-
return null;
|
|
1115
|
-
}
|
|
1116
|
-
const runView = new core_1.RunView();
|
|
1117
|
-
const stepsResult = await runView.RunView({
|
|
1118
|
-
EntityName: 'MJ: AI Agent Run Steps',
|
|
1119
|
-
ExtraFilter: `AgentRunID = '${agentRunId}'`,
|
|
1120
|
-
OrderBy: 'StepNumber ASC',
|
|
1121
|
-
ResultType: 'entity_object'
|
|
1122
|
-
}, this.contextUser);
|
|
1123
|
-
return {
|
|
1124
|
-
agentRun,
|
|
1125
|
-
steps: stepsResult.Results
|
|
1126
|
-
};
|
|
1127
|
-
}
|
|
1128
|
-
catch (error) {
|
|
1129
|
-
(0, core_1.LogError)(`Error retrieving run history for '${agentRunId}': ${error.message}`);
|
|
1130
|
-
return null;
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
async pauseExecution(context, reason = 'Execution paused by user') {
|
|
1134
|
-
try {
|
|
1135
|
-
if (!context.agentRun) {
|
|
1136
|
-
throw new Error('No active agent run to pause');
|
|
1137
|
-
}
|
|
1138
|
-
context.agentRun.Status = 'Paused';
|
|
1139
|
-
context.agentRun.ErrorMessage = reason;
|
|
1140
|
-
await this.updateAgentRunState(context, [], [], []);
|
|
1141
|
-
await context.agentRun.Save();
|
|
1142
|
-
(0, core_1.LogStatus)(`Agent run '${context.agentRun.ID}' paused: ${reason}`);
|
|
1143
|
-
return context.agentRun.ID;
|
|
1144
|
-
}
|
|
1145
|
-
catch (error) {
|
|
1146
|
-
(0, core_1.LogError)(`Error pausing execution: ${error.message}`);
|
|
1147
|
-
return null;
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
async resumeExecution(agentRunId, contextUser) {
|
|
1151
|
-
try {
|
|
1152
|
-
const agentRun = await this._metadata.GetEntityObject('MJ: AI Agent Runs', this.contextUser);
|
|
1153
|
-
const loadSuccess = await agentRun.Load(agentRunId);
|
|
1154
|
-
if (!loadSuccess) {
|
|
1155
|
-
throw new Error(`Agent run '${agentRunId}' not found`);
|
|
1156
|
-
}
|
|
1157
|
-
if (agentRun.Status !== 'Paused') {
|
|
1158
|
-
throw new Error(`Agent run '${agentRunId}' is not in paused state (current status: ${agentRun.Status})`);
|
|
1159
|
-
}
|
|
1160
|
-
const agentEntity = aiengine_1.AIEngine.Instance.Agents.find(a => a.ID === agentRun.AgentID);
|
|
1161
|
-
if (!agentEntity) {
|
|
1162
|
-
throw new Error(`Agent entity not found for run '${agentRunId}'`);
|
|
1163
|
-
}
|
|
1164
|
-
let serializedState;
|
|
1165
|
-
try {
|
|
1166
|
-
serializedState = JSON.parse(agentRun.AgentState || '{}');
|
|
1167
|
-
}
|
|
1168
|
-
catch (error) {
|
|
1169
|
-
throw new Error(`Failed to parse saved agent state: ${error.message}`);
|
|
1170
|
-
}
|
|
1171
|
-
const resumedContext = {
|
|
1172
|
-
conversationMessages: serializedState.conversationMessages || [],
|
|
1173
|
-
params: {
|
|
1174
|
-
contextUser,
|
|
1175
|
-
data: serializedState.contextData || {},
|
|
1176
|
-
conversationMessages: serializedState.conversationMessages || []
|
|
1177
|
-
},
|
|
1178
|
-
data: serializedState.contextData || {},
|
|
1179
|
-
configuration: serializedState.agentConfiguration || {},
|
|
1180
|
-
currentStep: serializedState.currentStep || 'resumed',
|
|
1181
|
-
startTime: agentRun.StartedAt,
|
|
1182
|
-
agentRun,
|
|
1183
|
-
currentStepNumber: serializedState.currentStepNumber || 1
|
|
1184
|
-
};
|
|
1185
|
-
agentRun.Status = 'Running';
|
|
1186
|
-
agentRun.ErrorMessage = null;
|
|
1187
|
-
await agentRun.Save();
|
|
1188
|
-
const { executionHistory, decisionHistory, actionResults } = this.deserializeAgentState(serializedState, resumedContext);
|
|
1189
|
-
(0, core_1.LogStatus)(`Resuming agent run '${agentRunId}' from step: ${resumedContext.currentStep}`);
|
|
1190
|
-
return await this.executeCore(resumedContext);
|
|
1191
|
-
}
|
|
1192
|
-
catch (error) {
|
|
1193
|
-
(0, core_1.LogError)(`Error resuming execution for '${agentRunId}': ${error.message}`);
|
|
1194
|
-
return {
|
|
1195
|
-
success: false,
|
|
1196
|
-
errorMessage: error.message,
|
|
1197
|
-
metadata: {
|
|
1198
|
-
errorStep: 'resumeExecution',
|
|
1199
|
-
runId: agentRunId
|
|
1200
|
-
}
|
|
1201
|
-
};
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
async cleanupFailedRuns(maxAgeHours = 24) {
|
|
1205
|
-
try {
|
|
1206
|
-
const cutoffTime = new Date();
|
|
1207
|
-
cutoffTime.setHours(cutoffTime.getHours() - maxAgeHours);
|
|
1208
|
-
const runView = new core_1.RunView();
|
|
1209
|
-
const staleRunsResult = await runView.RunView({
|
|
1210
|
-
EntityName: 'MJ: AI Agent Runs',
|
|
1211
|
-
ExtraFilter: `Status = 'Running' AND StartedAt < '${cutoffTime.toISOString()}'`,
|
|
1212
|
-
ResultType: 'entity_object'
|
|
1213
|
-
}, this.contextUser);
|
|
1214
|
-
const staleRuns = staleRunsResult.Results;
|
|
1215
|
-
let cleanedCount = 0;
|
|
1216
|
-
for (const run of staleRuns) {
|
|
1217
|
-
try {
|
|
1218
|
-
run.Status = 'Failed';
|
|
1219
|
-
run.Success = false;
|
|
1220
|
-
run.CompletedAt = new Date();
|
|
1221
|
-
run.ErrorMessage = `Run marked as failed due to cleanup - exceeded maximum age of ${maxAgeHours} hours`;
|
|
1222
|
-
await run.Save();
|
|
1223
|
-
cleanedCount++;
|
|
1224
|
-
(0, core_1.LogStatus)(`Cleaned up stale agent run: ${run.ID} (Agent: ${run.AgentID})`);
|
|
1225
|
-
}
|
|
1226
|
-
catch (error) {
|
|
1227
|
-
(0, core_1.LogError)(`Failed to clean up run ${run.ID}: ${error.message}`);
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
(0, core_1.LogStatus)(`Cleaned up ${cleanedCount} stale agent runs`);
|
|
1231
|
-
return cleanedCount;
|
|
1232
|
-
}
|
|
1233
|
-
catch (error) {
|
|
1234
|
-
(0, core_1.LogError)(`Error during cleanup of failed runs: ${error.message}`);
|
|
1235
|
-
return 0;
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
exports.BaseAgent = BaseAgent;
|
|
1240
|
-
function LoadBaseAgent() {
|
|
1241
|
-
}
|
|
1242
|
-
exports.LoadBaseAgent = LoadBaseAgent;
|
|
1243
|
-
//# sourceMappingURL=base-agent-original.js.map
|