@memberjunction/ai-agents 2.58.0 → 2.60.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/README.md +182 -1357
- package/dist/AgentRunner.d.ts.map +1 -1
- package/dist/AgentRunner.js +10 -5
- package/dist/AgentRunner.js.map +1 -1
- package/dist/PayloadManager.d.ts +16 -0
- package/dist/PayloadManager.d.ts.map +1 -0
- package/dist/PayloadManager.js +340 -0
- package/dist/PayloadManager.js.map +1 -0
- package/dist/agent-types/base-agent-type.d.ts +8 -2
- package/dist/agent-types/base-agent-type.d.ts.map +1 -1
- package/dist/agent-types/base-agent-type.js +28 -0
- package/dist/agent-types/base-agent-type.js.map +1 -1
- package/dist/agent-types/loop-agent-response-type.d.ts +1 -1
- package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.d.ts +5 -2
- package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.js +63 -30
- package/dist/agent-types/loop-agent-type.js.map +1 -1
- package/dist/base-agent.d.ts +21 -19
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +446 -591
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +12 -10
package/dist/base-agent.js
CHANGED
|
@@ -9,15 +9,51 @@ const aiengine_1 = require("@memberjunction/aiengine");
|
|
|
9
9
|
const actions_1 = require("@memberjunction/actions");
|
|
10
10
|
const ai_core_plus_1 = require("@memberjunction/ai-core-plus");
|
|
11
11
|
const AgentRunner_1 = require("./AgentRunner");
|
|
12
|
+
const PayloadManager_1 = require("./PayloadManager");
|
|
12
13
|
class BaseAgent {
|
|
13
14
|
constructor() {
|
|
14
15
|
this._promptRunner = new ai_prompts_1.AIPromptRunner();
|
|
15
16
|
this._metadata = new core_1.Metadata();
|
|
16
|
-
this._runContext = null;
|
|
17
17
|
this._agentRun = null;
|
|
18
|
-
this.
|
|
18
|
+
this._agentHierarchy = [];
|
|
19
|
+
this._depth = 0;
|
|
19
20
|
this._allProgressSteps = [];
|
|
20
21
|
this._subAgentRuns = [];
|
|
22
|
+
this._payloadManager = new PayloadManager_1.PayloadManager();
|
|
23
|
+
}
|
|
24
|
+
logStatus(message, verboseOnly = false, params) {
|
|
25
|
+
if (verboseOnly) {
|
|
26
|
+
(0, core_1.LogStatusEx)({
|
|
27
|
+
message,
|
|
28
|
+
verboseOnly: true,
|
|
29
|
+
isVerboseEnabled: () => params?.verbose === true || (0, core_1.IsVerboseLoggingEnabled)()
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
(0, core_1.LogStatus)(message);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
logError(error, options) {
|
|
37
|
+
const errorMessage = error instanceof Error ? error.message : error;
|
|
38
|
+
const errorObj = error instanceof Error ? error : undefined;
|
|
39
|
+
const metadata = {
|
|
40
|
+
...options?.metadata
|
|
41
|
+
};
|
|
42
|
+
if (options?.agent) {
|
|
43
|
+
metadata.agentId = options.agent.ID;
|
|
44
|
+
metadata.agentName = options.agent.Name;
|
|
45
|
+
}
|
|
46
|
+
if (options?.agentType) {
|
|
47
|
+
metadata.agentTypeId = options.agentType.ID;
|
|
48
|
+
metadata.agentTypeName = options.agentType.Name;
|
|
49
|
+
}
|
|
50
|
+
(0, core_1.LogErrorEx)({
|
|
51
|
+
message: errorMessage,
|
|
52
|
+
error: errorObj,
|
|
53
|
+
category: options?.category || 'BaseAgent',
|
|
54
|
+
severity: options?.severity || 'error',
|
|
55
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined
|
|
56
|
+
});
|
|
21
57
|
}
|
|
22
58
|
wrapProgressCallback(originalCallback) {
|
|
23
59
|
if (!originalCallback)
|
|
@@ -26,19 +62,40 @@ class BaseAgent {
|
|
|
26
62
|
this._allProgressSteps.push({
|
|
27
63
|
...progress,
|
|
28
64
|
timestamp: new Date(),
|
|
29
|
-
agentHierarchy: this.
|
|
30
|
-
depth: this.
|
|
65
|
+
agentHierarchy: this._agentHierarchy || [],
|
|
66
|
+
depth: this._depth || 0
|
|
31
67
|
});
|
|
32
|
-
|
|
68
|
+
try {
|
|
69
|
+
const enhancedProgress = {
|
|
70
|
+
...progress,
|
|
71
|
+
metadata: {
|
|
72
|
+
...progress.metadata,
|
|
73
|
+
agentRun: this._agentRun
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
originalCallback(enhancedProgress);
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
this.logError(`Failed to enhance progress with agent run: ${e instanceof Error ? e.message : e}`, {
|
|
80
|
+
category: 'ProgressEnhancement',
|
|
81
|
+
metadata: {
|
|
82
|
+
progress: progress,
|
|
83
|
+
agentRunId: this._agentRun?.ID || 'N/A'
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
originalCallback(progress);
|
|
87
|
+
}
|
|
33
88
|
};
|
|
34
89
|
}
|
|
35
90
|
async Execute(params) {
|
|
36
91
|
try {
|
|
92
|
+
this.logStatus(`🤖 Starting execution of agent '${params.agent.Name}'`, true, params);
|
|
37
93
|
const wrappedParams = {
|
|
38
94
|
...params,
|
|
39
95
|
onProgress: this.wrapProgressCallback(params.onProgress)
|
|
40
96
|
};
|
|
41
97
|
if (params.cancellationToken?.aborted) {
|
|
98
|
+
this.logStatus(`⚠️ Agent '${params.agent.Name}' execution cancelled before start`, true, params);
|
|
42
99
|
return await this.createCancelledResult('Cancelled before execution started', params.contextUser);
|
|
43
100
|
}
|
|
44
101
|
wrappedParams.onProgress?.({
|
|
@@ -59,22 +116,36 @@ class BaseAgent {
|
|
|
59
116
|
const validationResult = await this.validateAgentWithTracking(params.agent, params.contextUser);
|
|
60
117
|
if (validationResult)
|
|
61
118
|
return validationResult;
|
|
119
|
+
this.logStatus(`📋 Loading configuration for agent '${params.agent.Name}'`, true, params);
|
|
62
120
|
const config = await this.loadAgentConfiguration(params.agent);
|
|
63
121
|
if (!config.success) {
|
|
122
|
+
this.logError(`Failed to load agent configuration: ${config.errorMessage}`, {
|
|
123
|
+
agent: params.agent,
|
|
124
|
+
category: 'AgentConfiguration'
|
|
125
|
+
});
|
|
64
126
|
return await this.createFailureResult(config.errorMessage || 'Failed to load agent configuration', params.contextUser);
|
|
65
127
|
}
|
|
128
|
+
this.logStatus(`🚀 Executing agent '${params.agent.Name}' internal logic`, true, params);
|
|
66
129
|
const executionResult = await this.executeAgentInternal(wrappedParams, config);
|
|
67
130
|
wrappedParams.onProgress?.({
|
|
68
131
|
step: 'finalization',
|
|
69
132
|
percentage: 95,
|
|
133
|
+
metadata: { result: executionResult },
|
|
70
134
|
message: this.formatHierarchicalMessage('Finalizing agent execution')
|
|
71
135
|
});
|
|
72
|
-
|
|
136
|
+
this.logStatus(`✅ Finalizing execution for agent '${params.agent.Name}'`, true, params);
|
|
137
|
+
return await this.finalizeAgentRun(executionResult.finalStep, executionResult.finalStep.payload, params.contextUser);
|
|
73
138
|
}
|
|
74
139
|
catch (error) {
|
|
75
140
|
if (params.cancellationToken?.aborted || error.message === 'Cancelled during execution') {
|
|
141
|
+
this.logStatus(`⚠️ Agent '${params.agent.Name}' execution cancelled: ${error.message}`, true, params);
|
|
76
142
|
return await this.createCancelledResult(error.message || 'Cancelled due to error during execution', params.contextUser);
|
|
77
143
|
}
|
|
144
|
+
this.logError(error, {
|
|
145
|
+
agent: params.agent,
|
|
146
|
+
category: 'AgentExecution',
|
|
147
|
+
severity: 'critical'
|
|
148
|
+
});
|
|
78
149
|
return await this.createFailureResult(error.message, params.contextUser);
|
|
79
150
|
}
|
|
80
151
|
}
|
|
@@ -86,14 +157,17 @@ class BaseAgent {
|
|
|
86
157
|
if (params.cancellationToken?.aborted) {
|
|
87
158
|
throw new Error('Cancelled during execution');
|
|
88
159
|
}
|
|
160
|
+
this.logStatus(`🔄 Executing step ${stepCount + 1} for agent '${params.agent.Name}'`, true, params);
|
|
89
161
|
const nextStep = await this.executeNextStep(params, config, currentNextStep);
|
|
90
162
|
stepCount++;
|
|
91
163
|
if (nextStep.terminate) {
|
|
92
164
|
continueExecution = false;
|
|
93
165
|
currentNextStep = nextStep;
|
|
166
|
+
this.logStatus(`🏁 Agent '${params.agent.Name}' terminating after ${stepCount} steps with result: ${nextStep.step}`, true, params);
|
|
94
167
|
}
|
|
95
168
|
else {
|
|
96
169
|
currentNextStep = nextStep;
|
|
170
|
+
this.logStatus(`➡️ Agent '${params.agent.Name}' continuing to next step: ${nextStep.step}`, true, params);
|
|
97
171
|
}
|
|
98
172
|
}
|
|
99
173
|
return { finalStep: currentNextStep, stepCount };
|
|
@@ -104,12 +178,15 @@ class BaseAgent {
|
|
|
104
178
|
}
|
|
105
179
|
async validateAgent(agent) {
|
|
106
180
|
if (agent.Status !== 'Active') {
|
|
181
|
+
if (this._agentRun) {
|
|
182
|
+
this._agentRun.ErrorMessage = `Agent '${agent.Name}' is not active. Current status: ${agent.Status}`;
|
|
183
|
+
this._agentRun.Status = 'Failed';
|
|
184
|
+
this._agentRun.Success = false;
|
|
185
|
+
this._agentRun.FinalStep = 'Failed';
|
|
186
|
+
}
|
|
107
187
|
return {
|
|
108
188
|
success: false,
|
|
109
|
-
|
|
110
|
-
errorMessage: `Agent '${agent.Name}' is not active. Current status: ${agent.Status}`,
|
|
111
|
-
agentRun: this._agentRun,
|
|
112
|
-
executionTree: []
|
|
189
|
+
agentRun: this._agentRun
|
|
113
190
|
};
|
|
114
191
|
}
|
|
115
192
|
return null;
|
|
@@ -159,7 +236,10 @@ class BaseAgent {
|
|
|
159
236
|
childPrompt
|
|
160
237
|
};
|
|
161
238
|
}
|
|
162
|
-
async preparePromptParams(
|
|
239
|
+
async preparePromptParams(config, payload, params) {
|
|
240
|
+
const agentType = config.agentType;
|
|
241
|
+
const systemPrompt = config.systemPrompt;
|
|
242
|
+
const childPrompt = config.childPrompt;
|
|
163
243
|
const promptTemplateData = await this.gatherPromptTemplateData(params.agent, params.contextUser, params.data);
|
|
164
244
|
const promptParams = new ai_core_plus_1.AIPromptParams();
|
|
165
245
|
promptParams.prompt = systemPrompt;
|
|
@@ -167,22 +247,28 @@ class BaseAgent {
|
|
|
167
247
|
promptParams.contextUser = params.contextUser;
|
|
168
248
|
promptParams.conversationMessages = params.conversationMessages;
|
|
169
249
|
promptParams.templateMessageRole = 'system';
|
|
250
|
+
promptParams.verbose = params.verbose;
|
|
251
|
+
if (payload) {
|
|
252
|
+
const atInstance = await base_agent_type_1.BaseAgentType.GetAgentTypeInstance(config.agentType);
|
|
253
|
+
await atInstance.InjectPayload(payload, promptParams);
|
|
254
|
+
}
|
|
170
255
|
promptParams.childPrompts = [
|
|
171
256
|
new ai_core_plus_1.ChildPromptParam({
|
|
172
257
|
prompt: childPrompt,
|
|
173
258
|
data: promptTemplateData,
|
|
174
259
|
contextUser: params.contextUser,
|
|
175
260
|
conversationMessages: params.conversationMessages,
|
|
176
|
-
templateMessageRole: 'user'
|
|
261
|
+
templateMessageRole: 'user',
|
|
262
|
+
verbose: params.verbose
|
|
177
263
|
}, agentType.AgentPromptPlaceholder)
|
|
178
264
|
];
|
|
179
265
|
if (params.agent.ModelSelectionMode === 'Agent') {
|
|
180
266
|
promptParams.modelSelectionPrompt = childPrompt;
|
|
181
|
-
|
|
267
|
+
this.logStatus(`🎯 Agent '${params.agent.Name}' configured to use its own prompt for model selection`, true, params);
|
|
182
268
|
}
|
|
183
269
|
if (params.override) {
|
|
184
270
|
promptParams.override = params.override;
|
|
185
|
-
|
|
271
|
+
this.logStatus(`🎯 Using runtime override: ${params.override.modelId || 'model'} ${params.override.vendorId ? `from vendor ${params.override.vendorId}` : ''}`, true, params);
|
|
186
272
|
}
|
|
187
273
|
return promptParams;
|
|
188
274
|
}
|
|
@@ -190,18 +276,11 @@ class BaseAgent {
|
|
|
190
276
|
return await this._promptRunner.ExecutePrompt(promptParams);
|
|
191
277
|
}
|
|
192
278
|
async processNextStep(params, agentType, promptResult) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
return {
|
|
199
|
-
terminate: false,
|
|
200
|
-
step: 'failed',
|
|
201
|
-
errorMessage: error.message
|
|
202
|
-
};
|
|
203
|
-
}
|
|
279
|
+
this.logStatus(`🤔 Processing next step for agent '${params.agent.Name}' with agent type '${agentType.Name}'`, true, params);
|
|
280
|
+
const agentTypeInstance = await base_agent_type_1.BaseAgentType.GetAgentTypeInstance(agentType);
|
|
281
|
+
this.logStatus(`🎯 Agent type '${agentType.Name}' determining next step`, true, params);
|
|
204
282
|
const nextStep = await agentTypeInstance.DetermineNextStep(promptResult);
|
|
283
|
+
this.logStatus(`📌 Next step determined: ${nextStep.step}${nextStep.terminate ? ' (terminating)' : ''}`, true, params);
|
|
205
284
|
return nextStep;
|
|
206
285
|
}
|
|
207
286
|
createActionResultMessage(actions, results) {
|
|
@@ -241,6 +320,7 @@ class BaseAgent {
|
|
|
241
320
|
const contextData = {
|
|
242
321
|
agentName: agent.Name,
|
|
243
322
|
agentDescription: agent.Description,
|
|
323
|
+
parentAgentName: agent.Parent ? agent.Parent.trim() : "",
|
|
244
324
|
subAgentCount: subAgents.length,
|
|
245
325
|
subAgentDetails: this.formatSubAgentDetails(subAgents),
|
|
246
326
|
actionCount: actions.length,
|
|
@@ -260,37 +340,16 @@ class BaseAgent {
|
|
|
260
340
|
throw new Error(`Error gathering context data: ${error.message}`);
|
|
261
341
|
}
|
|
262
342
|
}
|
|
263
|
-
async
|
|
264
|
-
return this.getAgentInstanceWithDriverClass(agentType.DriverClass || agentType.Name);
|
|
265
|
-
}
|
|
266
|
-
async getAgentInstanceWithDriverClass(driverClass) {
|
|
267
|
-
const instance = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(base_agent_type_1.BaseAgentType, driverClass);
|
|
268
|
-
if (!instance) {
|
|
269
|
-
throw new Error(`No implementation found for agent with DriverClass '${driverClass}'. Please ensure the class is registered with the ClassFactory.`);
|
|
270
|
-
}
|
|
271
|
-
return instance;
|
|
272
|
-
}
|
|
273
|
-
async ExecuteSingleAction(params, action, contextUser) {
|
|
343
|
+
async ExecuteSingleAction(params, action, actionEntity, contextUser) {
|
|
274
344
|
try {
|
|
345
|
+
this.logStatus(`⚡ Executing action '${action.name}'`, true, params);
|
|
275
346
|
const actionEngine = actions_1.ActionEngineServer.Instance;
|
|
276
|
-
if (!action.id) {
|
|
277
|
-
throw new Error(`Action ID is required for action: ${action.name || 'unknown'}`);
|
|
278
|
-
}
|
|
279
|
-
const actionEntity = actionEngine.Actions.find(a => a.ID === action.id);
|
|
280
|
-
if (!actionEntity) {
|
|
281
|
-
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
282
|
-
if (!uuidRegex.test(action.id)) {
|
|
283
|
-
throw new Error(`${action.id} is not a valid UUID and must be a UUID representing the Action ID`);
|
|
284
|
-
}
|
|
285
|
-
else {
|
|
286
|
-
throw new Error(`Action with ID ${action.id} not found in the action table`);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
347
|
const actionParams = Object.entries(action.params || {}).map(([key, value]) => ({
|
|
290
348
|
Name: key,
|
|
291
349
|
Value: value,
|
|
292
350
|
Type: 'Input'
|
|
293
351
|
}));
|
|
352
|
+
this.logStatus(`📥 Action parameters: ${JSON.stringify(action.params)}`, true, params);
|
|
294
353
|
const result = await actionEngine.RunAction({
|
|
295
354
|
Action: actionEntity,
|
|
296
355
|
Params: actionParams,
|
|
@@ -302,36 +361,34 @@ class BaseAgent {
|
|
|
302
361
|
if (!result.Success) {
|
|
303
362
|
throw new Error(`Action '${action.name}' failed: ${result.Message || 'Unknown error'}`);
|
|
304
363
|
}
|
|
364
|
+
this.logStatus(`✅ Action '${action.name}' completed successfully`, true, params);
|
|
305
365
|
return result;
|
|
306
366
|
}
|
|
307
367
|
catch (error) {
|
|
368
|
+
this.logError(error, {
|
|
369
|
+
category: 'ActionExecution',
|
|
370
|
+
metadata: {
|
|
371
|
+
actionName: action.name,
|
|
372
|
+
actionParams: action.params
|
|
373
|
+
}
|
|
374
|
+
});
|
|
308
375
|
throw new Error(`Error executing actions: ${error.message}`);
|
|
309
376
|
}
|
|
310
377
|
}
|
|
311
|
-
async ExecuteSubAgent(params, subAgentRequest) {
|
|
378
|
+
async ExecuteSubAgent(params, subAgentRequest, subAgent, stepEntity, payload) {
|
|
312
379
|
try {
|
|
313
|
-
|
|
314
|
-
if (!subAgentRequest.id) {
|
|
315
|
-
throw new Error('Sub-agent ID is required');
|
|
316
|
-
}
|
|
317
|
-
const subAgent = engine.Agents.find(a => a.ID === subAgentRequest.id);
|
|
318
|
-
if (!subAgent) {
|
|
319
|
-
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
320
|
-
if (!uuidRegex.test(subAgentRequest.id)) {
|
|
321
|
-
throw new Error(`${subAgentRequest.id} is not a valid UUID and must be a UUID representing the Agent ID`);
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
throw new Error(`Sub-agent with ID ${subAgentRequest.id} not found in the agent table`);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
380
|
+
this.logStatus(`🤖 Executing sub-agent '${subAgentRequest.name}'`, true, params);
|
|
327
381
|
const runner = new AgentRunner_1.AgentRunner();
|
|
328
382
|
const subAgentMessages = [
|
|
329
|
-
...params.conversationMessages,
|
|
330
383
|
{
|
|
331
384
|
role: 'user',
|
|
332
385
|
content: subAgentRequest.message
|
|
333
386
|
}
|
|
334
387
|
];
|
|
388
|
+
this.logStatus(`📨 Sub-agent message: "${subAgentRequest.message}"`, true, params);
|
|
389
|
+
if (subAgentRequest.templateParameters) {
|
|
390
|
+
this.logStatus(`📎 Template parameters: ${JSON.stringify(subAgentRequest.templateParameters)}`, true, params);
|
|
391
|
+
}
|
|
335
392
|
const result = await runner.RunAgent({
|
|
336
393
|
agent: subAgent,
|
|
337
394
|
conversationMessages: subAgentMessages,
|
|
@@ -339,24 +396,34 @@ class BaseAgent {
|
|
|
339
396
|
cancellationToken: params.cancellationToken,
|
|
340
397
|
onProgress: params.onProgress,
|
|
341
398
|
onStreaming: params.onStreaming,
|
|
342
|
-
parentAgentHierarchy: this.
|
|
343
|
-
parentDepth: this.
|
|
399
|
+
parentAgentHierarchy: this._agentHierarchy,
|
|
400
|
+
parentDepth: this._depth,
|
|
344
401
|
parentRun: this._agentRun,
|
|
402
|
+
payload: payload,
|
|
345
403
|
data: subAgentRequest.templateParameters,
|
|
346
|
-
context: params.context
|
|
404
|
+
context: params.context,
|
|
405
|
+
verbose: params.verbose
|
|
347
406
|
});
|
|
348
407
|
if (!result.success) {
|
|
349
|
-
throw new Error(`Sub-agent '${subAgentRequest.name}' failed: ${result.
|
|
408
|
+
throw new Error(`Sub-agent '${subAgentRequest.name}' failed: ${result.agentRun?.ErrorMessage || 'Unknown error'}`);
|
|
350
409
|
}
|
|
410
|
+
this.logStatus(`✅ Sub-agent '${subAgentRequest.name}' completed successfully`, true, params);
|
|
351
411
|
return result;
|
|
352
412
|
}
|
|
353
413
|
catch (error) {
|
|
414
|
+
this.logError(error, {
|
|
415
|
+
category: 'SubAgentExecution',
|
|
416
|
+
metadata: {
|
|
417
|
+
agentName: params.agent.Name,
|
|
418
|
+
subAgentName: subAgentRequest.name,
|
|
419
|
+
message: subAgentRequest.message
|
|
420
|
+
}
|
|
421
|
+
});
|
|
354
422
|
throw new Error(`Error executing sub-agent: ${error.message}`);
|
|
355
423
|
}
|
|
356
424
|
}
|
|
357
425
|
formatSubAgentDetails(subAgents) {
|
|
358
426
|
return JSON.stringify(subAgents.map(sa => ({
|
|
359
|
-
ID: sa.ID,
|
|
360
427
|
Name: sa.Name,
|
|
361
428
|
Description: sa.Description,
|
|
362
429
|
Type: sa.TypeID ? this.getAgentTypeName(sa.TypeID) : 'Unknown',
|
|
@@ -390,7 +457,6 @@ class BaseAgent {
|
|
|
390
457
|
}
|
|
391
458
|
formatActionDetails(actions) {
|
|
392
459
|
return JSON.stringify(actions.map(action => ({
|
|
393
|
-
ID: action.ID,
|
|
394
460
|
Name: action.Name,
|
|
395
461
|
Description: action.Description,
|
|
396
462
|
Parameters: {
|
|
@@ -405,7 +471,6 @@ class BaseAgent {
|
|
|
405
471
|
Code: rc.ResultCode,
|
|
406
472
|
IsSuccess: rc.IsSuccess,
|
|
407
473
|
Description: rc.Description || 'No description provided',
|
|
408
|
-
Usage: this.inferResultCodeUsage(rc.ResultCode, rc.IsSuccess)
|
|
409
474
|
})),
|
|
410
475
|
Category: action.CategoryID ? this.getActionCategoryName(action.CategoryID) : null,
|
|
411
476
|
Status: action.Status
|
|
@@ -432,34 +497,6 @@ class BaseAgent {
|
|
|
432
497
|
getActionCategoryName(categoryID) {
|
|
433
498
|
return 'General';
|
|
434
499
|
}
|
|
435
|
-
inferResultCodeUsage(resultCode, isSuccess) {
|
|
436
|
-
if (resultCode === 'SUCCESS') {
|
|
437
|
-
return 'Returned when the action completes successfully';
|
|
438
|
-
}
|
|
439
|
-
else if (resultCode === 'FAILED') {
|
|
440
|
-
return 'Generic failure - check error message for details';
|
|
441
|
-
}
|
|
442
|
-
else if (resultCode.includes('MISSING_PARAMETERS')) {
|
|
443
|
-
return 'Returned when required parameters are not provided';
|
|
444
|
-
}
|
|
445
|
-
else if (resultCode.includes('INVALID')) {
|
|
446
|
-
return 'Returned when input validation fails';
|
|
447
|
-
}
|
|
448
|
-
else if (resultCode.includes('NOT_FOUND')) {
|
|
449
|
-
return 'Returned when the requested resource cannot be found';
|
|
450
|
-
}
|
|
451
|
-
else if (resultCode.includes('TIMEOUT')) {
|
|
452
|
-
return 'Returned when the operation times out';
|
|
453
|
-
}
|
|
454
|
-
else if (resultCode.includes('PERMISSION') || resultCode.includes('UNAUTHORIZED')) {
|
|
455
|
-
return 'Returned when permission is denied';
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
458
|
-
return isSuccess
|
|
459
|
-
? 'Specific success condition - see description'
|
|
460
|
-
: 'Specific error condition - see description';
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
500
|
async initializeAgentRun(params) {
|
|
464
501
|
this._agentRun = await this._metadata.GetEntityObject('MJ: AI Agent Runs', params.contextUser);
|
|
465
502
|
this._agentRun.AgentID = params.agent.ID;
|
|
@@ -471,68 +508,21 @@ class BaseAgent {
|
|
|
471
508
|
const errorMessage = JSON.stringify((0, global_1.CopyScalarsAndArrays)(this._agentRun.LatestResult));
|
|
472
509
|
throw new Error(`Failed to create agent run record: Details: ${errorMessage}`);
|
|
473
510
|
}
|
|
474
|
-
this.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
? [...params.parentAgentHierarchy, params.agent.Name || 'Unknown Agent']
|
|
479
|
-
: [params.agent.Name || 'Unknown Agent'],
|
|
480
|
-
depth: params.parentDepth !== undefined ? params.parentDepth + 1 : 0,
|
|
481
|
-
conversationId: undefined,
|
|
482
|
-
userId: params.contextUser?.ID,
|
|
483
|
-
agentState: {}
|
|
484
|
-
};
|
|
485
|
-
this._executionChain = [];
|
|
511
|
+
this._agentHierarchy = params.parentAgentHierarchy
|
|
512
|
+
? [...params.parentAgentHierarchy, params.agent.Name || 'Unknown Agent']
|
|
513
|
+
: [params.agent.Name || 'Unknown Agent'];
|
|
514
|
+
this._depth = params.parentDepth !== undefined ? params.parentDepth + 1 : 0;
|
|
486
515
|
this._allProgressSteps = [];
|
|
487
516
|
}
|
|
488
517
|
async validateAgentWithTracking(agent, contextUser) {
|
|
489
|
-
const startTime = new Date();
|
|
490
518
|
try {
|
|
491
519
|
const validationResult = await this.validateAgent(agent);
|
|
492
520
|
if (validationResult) {
|
|
493
|
-
const stepEntity = await this.createStepEntity('
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
validationTarget: 'agent configuration',
|
|
497
|
-
result: { valid: false, errors: [validationResult.errorMessage || 'Validation failed'] }
|
|
498
|
-
};
|
|
499
|
-
const nextStepDecision = {
|
|
500
|
-
decision: 'failed',
|
|
501
|
-
reasoning: 'Agent validation failed',
|
|
502
|
-
nextStepDetails: { type: 'complete' }
|
|
503
|
-
};
|
|
504
|
-
this._executionChain.push({
|
|
505
|
-
stepEntity,
|
|
506
|
-
executionType: 'validation',
|
|
507
|
-
executionResult,
|
|
508
|
-
nextStepDecision,
|
|
509
|
-
startTime,
|
|
510
|
-
endTime: new Date(),
|
|
511
|
-
durationMs: new Date().getTime() - startTime.getTime()
|
|
512
|
-
});
|
|
513
|
-
await this.finalizeStepEntity(stepEntity, false, validationResult.errorMessage);
|
|
514
|
-
return await this.createFailureResult(validationResult.errorMessage || 'Validation failed', contextUser);
|
|
521
|
+
const stepEntity = await this.createStepEntity('Validation', 'Agent Validation', contextUser);
|
|
522
|
+
await this.finalizeStepEntity(stepEntity, false, validationResult.agentRun?.ErrorMessage);
|
|
523
|
+
return await this.createFailureResult(validationResult.agentRun?.ErrorMessage || 'Validation failed', contextUser);
|
|
515
524
|
}
|
|
516
|
-
const stepEntity = await this.createStepEntity('
|
|
517
|
-
const executionResult = {
|
|
518
|
-
type: 'validation',
|
|
519
|
-
validationTarget: 'agent configuration',
|
|
520
|
-
result: { valid: true }
|
|
521
|
-
};
|
|
522
|
-
const nextStepDecision = {
|
|
523
|
-
decision: 'success',
|
|
524
|
-
reasoning: 'Agent validation passed',
|
|
525
|
-
nextStepDetails: { type: 'prompt', promptId: agent.ID, promptName: 'Initial Prompt' }
|
|
526
|
-
};
|
|
527
|
-
this._executionChain.push({
|
|
528
|
-
stepEntity,
|
|
529
|
-
executionType: 'validation',
|
|
530
|
-
executionResult,
|
|
531
|
-
nextStepDecision,
|
|
532
|
-
startTime,
|
|
533
|
-
endTime: new Date(),
|
|
534
|
-
durationMs: new Date().getTime() - startTime.getTime()
|
|
535
|
-
});
|
|
525
|
+
const stepEntity = await this.createStepEntity('Validation', 'Agent Validation', contextUser);
|
|
536
526
|
await this.finalizeStepEntity(stepEntity, true);
|
|
537
527
|
return null;
|
|
538
528
|
}
|
|
@@ -543,10 +533,15 @@ class BaseAgent {
|
|
|
543
533
|
async createStepEntity(stepType, stepName, contextUser, targetId, inputData, targetLogId) {
|
|
544
534
|
const stepEntity = await this._metadata.GetEntityObject('MJ: AI Agent Run Steps', contextUser);
|
|
545
535
|
stepEntity.AgentRunID = this._agentRun.ID;
|
|
546
|
-
stepEntity.StepNumber = this.
|
|
536
|
+
stepEntity.StepNumber = (this._agentRun.Steps?.length || 0) + 1;
|
|
547
537
|
stepEntity.StepType = stepType;
|
|
548
538
|
stepEntity.StepName = this.formatHierarchicalMessage(stepName);
|
|
549
|
-
|
|
539
|
+
if (targetId && !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(targetId)) {
|
|
540
|
+
console.warn(`Invalid target ID format: ${targetId}`);
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
stepEntity.TargetID = targetId || null;
|
|
544
|
+
}
|
|
550
545
|
stepEntity.TargetLogID = targetLogId || null;
|
|
551
546
|
stepEntity.Status = 'Running';
|
|
552
547
|
stepEntity.StartedAt = new Date();
|
|
@@ -554,8 +549,8 @@ class BaseAgent {
|
|
|
554
549
|
stepEntity.InputData = JSON.stringify({
|
|
555
550
|
...inputData,
|
|
556
551
|
context: {
|
|
557
|
-
agentHierarchy: this.
|
|
558
|
-
depth: this.
|
|
552
|
+
agentHierarchy: this._agentHierarchy,
|
|
553
|
+
depth: this._depth,
|
|
559
554
|
stepNumber: stepEntity.StepNumber
|
|
560
555
|
}
|
|
561
556
|
});
|
|
@@ -563,7 +558,9 @@ class BaseAgent {
|
|
|
563
558
|
if (!await stepEntity.Save()) {
|
|
564
559
|
throw new Error(`Failed to create agent run step record: ${JSON.stringify(stepEntity.LatestResult)}`);
|
|
565
560
|
}
|
|
566
|
-
this.
|
|
561
|
+
if (this._agentRun) {
|
|
562
|
+
this._agentRun.Steps.push(stepEntity);
|
|
563
|
+
}
|
|
567
564
|
return stepEntity;
|
|
568
565
|
}
|
|
569
566
|
async finalizeStepEntity(stepEntity, success, errorMessage, outputData) {
|
|
@@ -586,61 +583,89 @@ class BaseAgent {
|
|
|
586
583
|
}
|
|
587
584
|
}
|
|
588
585
|
formatHierarchicalMessage(baseMessage) {
|
|
589
|
-
if (this.
|
|
590
|
-
const breadcrumb = this.
|
|
586
|
+
if (this._depth > 0) {
|
|
587
|
+
const breadcrumb = this._agentHierarchy
|
|
591
588
|
.slice(1)
|
|
592
589
|
.join(' → ');
|
|
593
590
|
return breadcrumb ? `${breadcrumb}: ${baseMessage}` : baseMessage;
|
|
594
591
|
}
|
|
595
592
|
return baseMessage;
|
|
596
593
|
}
|
|
594
|
+
getNextStepReasoning(nextStep) {
|
|
595
|
+
switch (nextStep.step) {
|
|
596
|
+
case 'Success':
|
|
597
|
+
return 'Agent completed task successfully';
|
|
598
|
+
case 'Failed':
|
|
599
|
+
return nextStep.errorMessage || 'Agent execution failed';
|
|
600
|
+
case 'Retry':
|
|
601
|
+
return nextStep.retryReason || 'Retrying with updated context';
|
|
602
|
+
case 'Sub-Agent':
|
|
603
|
+
return `Delegating to sub-agent: ${nextStep.subAgent?.name || 'Unknown'}`;
|
|
604
|
+
case 'Actions':
|
|
605
|
+
const actionCount = nextStep.actions?.length || 0;
|
|
606
|
+
return `Executing ${actionCount} action${actionCount !== 1 ? 's' : ''}`;
|
|
607
|
+
case 'Chat':
|
|
608
|
+
return 'Requesting user input';
|
|
609
|
+
default:
|
|
610
|
+
return 'Unknown decision';
|
|
611
|
+
}
|
|
612
|
+
}
|
|
597
613
|
async executeNextStep(params, config, previousDecision) {
|
|
598
614
|
if (!previousDecision) {
|
|
599
615
|
return await this.executePromptStep(params, config);
|
|
600
616
|
}
|
|
601
617
|
switch (previousDecision.step) {
|
|
602
|
-
case '
|
|
618
|
+
case 'Retry':
|
|
603
619
|
return await this.executePromptStep(params, config, previousDecision);
|
|
604
|
-
case '
|
|
605
|
-
return await this.executeSubAgentStep(params, previousDecision
|
|
606
|
-
case '
|
|
607
|
-
return await this.executeActionsStep(params, previousDecision
|
|
608
|
-
case '
|
|
609
|
-
return await this.executeChatStep(params, previousDecision
|
|
610
|
-
case '
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
}
|
|
620
|
+
case 'Sub-Agent':
|
|
621
|
+
return await this.executeSubAgentStep(params, previousDecision);
|
|
622
|
+
case 'Actions':
|
|
623
|
+
return await this.executeActionsStep(params, previousDecision);
|
|
624
|
+
case 'Chat':
|
|
625
|
+
return await this.executeChatStep(params, previousDecision);
|
|
626
|
+
case 'Success':
|
|
627
|
+
const pd = previousDecision;
|
|
628
|
+
if (pd.payload?.taskComplete === true && previousDecision.terminate) {
|
|
629
|
+
return {
|
|
630
|
+
terminate: true,
|
|
631
|
+
step: 'Success',
|
|
632
|
+
payload: previousDecision.payload
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
return await this.executePromptStep(params, config, previousDecision);
|
|
637
|
+
}
|
|
638
|
+
case 'Failed':
|
|
639
|
+
if (previousDecision.terminate) {
|
|
640
|
+
return {
|
|
641
|
+
terminate: true,
|
|
642
|
+
step: 'Failed',
|
|
643
|
+
payload: previousDecision.payload
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
return await this.executePromptStep(params, config, previousDecision);
|
|
648
|
+
}
|
|
622
649
|
default:
|
|
623
650
|
throw new Error(`Unsupported next step: ${previousDecision.step}`);
|
|
624
651
|
}
|
|
625
652
|
}
|
|
626
|
-
async executePromptStep(params, config,
|
|
627
|
-
const startTime = new Date();
|
|
653
|
+
async executePromptStep(params, config, previousDecision) {
|
|
628
654
|
const inputData = {
|
|
629
655
|
promptId: config.childPrompt?.ID,
|
|
630
656
|
promptName: config.childPrompt?.Name,
|
|
631
|
-
isRetry: !!
|
|
632
|
-
retryContext:
|
|
633
|
-
reason:
|
|
634
|
-
instructions:
|
|
657
|
+
isRetry: !!previousDecision,
|
|
658
|
+
retryContext: previousDecision ? {
|
|
659
|
+
reason: previousDecision.retryReason,
|
|
660
|
+
instructions: previousDecision.retryInstructions
|
|
635
661
|
} : undefined,
|
|
636
662
|
conversationMessages: params.conversationMessages,
|
|
637
|
-
agentState: this._runContext?.agentState
|
|
638
663
|
};
|
|
639
|
-
const stepEntity = await this.createStepEntity('
|
|
664
|
+
const stepEntity = await this.createStepEntity('Prompt', 'Execute Agent Prompt', params.contextUser, config.childPrompt?.ID, inputData);
|
|
640
665
|
try {
|
|
641
|
-
const isRetry = !!
|
|
666
|
+
const isRetry = !!previousDecision;
|
|
642
667
|
const promptMessage = isRetry
|
|
643
|
-
? `Running ${params.agent.Name} with context from ${
|
|
668
|
+
? `Running ${params.agent.Name} with context from ${previousDecision.retryReason || 'previous actions'}`
|
|
644
669
|
: `Running ${params.agent.Name}'s initial prompt...`;
|
|
645
670
|
params.onProgress?.({
|
|
646
671
|
step: 'prompt_execution',
|
|
@@ -653,7 +678,11 @@ class BaseAgent {
|
|
|
653
678
|
},
|
|
654
679
|
displayMode: 'live'
|
|
655
680
|
});
|
|
656
|
-
const
|
|
681
|
+
const payload = previousDecision?.payload || params.payload;
|
|
682
|
+
if (stepEntity && payload) {
|
|
683
|
+
stepEntity.PayloadAtStart = JSON.stringify(payload);
|
|
684
|
+
}
|
|
685
|
+
const promptParams = await this.preparePromptParams(config, payload, params);
|
|
657
686
|
promptParams.cancellationToken = params.cancellationToken;
|
|
658
687
|
promptParams.onStreaming = params.onStreaming ? (chunk) => {
|
|
659
688
|
params.onStreaming({
|
|
@@ -665,7 +694,7 @@ class BaseAgent {
|
|
|
665
694
|
const promptResult = await this.executePrompt(promptParams);
|
|
666
695
|
if (promptResult.promptRun?.ID) {
|
|
667
696
|
stepEntity.TargetLogID = promptResult.promptRun.ID;
|
|
668
|
-
|
|
697
|
+
stepEntity.PromptRun = promptResult.promptRun;
|
|
669
698
|
}
|
|
670
699
|
if (params.cancellationToken?.aborted) {
|
|
671
700
|
await this.finalizeStepEntity(stepEntity, false, 'Cancelled during prompt execution');
|
|
@@ -673,16 +702,10 @@ class BaseAgent {
|
|
|
673
702
|
return {
|
|
674
703
|
...cancelledResult,
|
|
675
704
|
terminate: true,
|
|
676
|
-
step:
|
|
677
|
-
|
|
705
|
+
step: 'Failed',
|
|
706
|
+
payload: cancelledResult.payload,
|
|
678
707
|
};
|
|
679
708
|
}
|
|
680
|
-
const executionResult = {
|
|
681
|
-
type: 'prompt',
|
|
682
|
-
promptId: config.childPrompt.ID,
|
|
683
|
-
promptName: config.childPrompt.Name,
|
|
684
|
-
result: promptResult
|
|
685
|
-
};
|
|
686
709
|
params.onProgress?.({
|
|
687
710
|
step: 'decision_processing',
|
|
688
711
|
percentage: 70,
|
|
@@ -690,20 +713,6 @@ class BaseAgent {
|
|
|
690
713
|
displayMode: 'both'
|
|
691
714
|
});
|
|
692
715
|
const nextStep = await this.processNextStep(params, config.agentType, promptResult);
|
|
693
|
-
const nextStepDecision = {
|
|
694
|
-
decision: nextStep.step,
|
|
695
|
-
reasoning: this.getNextStepReasoning(nextStep),
|
|
696
|
-
nextStepDetails: this.getNextStepDetails(nextStep)
|
|
697
|
-
};
|
|
698
|
-
this._executionChain.push({
|
|
699
|
-
stepEntity,
|
|
700
|
-
executionType: 'prompt',
|
|
701
|
-
executionResult,
|
|
702
|
-
nextStepDecision,
|
|
703
|
-
startTime,
|
|
704
|
-
endTime: new Date(),
|
|
705
|
-
durationMs: new Date().getTime() - startTime.getTime()
|
|
706
|
-
});
|
|
707
716
|
const outputData = {
|
|
708
717
|
promptResult: {
|
|
709
718
|
success: promptResult.success,
|
|
@@ -714,14 +723,21 @@ class BaseAgent {
|
|
|
714
723
|
},
|
|
715
724
|
nextStep: {
|
|
716
725
|
decision: nextStep.step,
|
|
717
|
-
reasoning:
|
|
726
|
+
reasoning: this.getNextStepReasoning(nextStep),
|
|
727
|
+
payload: nextStep.payload
|
|
718
728
|
}
|
|
719
729
|
};
|
|
730
|
+
if (stepEntity && nextStep.payload) {
|
|
731
|
+
stepEntity.PayloadAtEnd = JSON.stringify(nextStep.payload);
|
|
732
|
+
}
|
|
733
|
+
if (this._agentRun && nextStep.payload) {
|
|
734
|
+
this._agentRun.FinalPayloadObject = nextStep.payload;
|
|
735
|
+
}
|
|
720
736
|
await this.finalizeStepEntity(stepEntity, promptResult.success, promptResult.success ? undefined : promptResult.errorMessage, outputData);
|
|
721
|
-
if (nextStep.step === '
|
|
737
|
+
if (nextStep.step === 'Chat') {
|
|
722
738
|
return { ...nextStep, terminate: true };
|
|
723
739
|
}
|
|
724
|
-
else if (nextStep.step === '
|
|
740
|
+
else if (nextStep.step === 'Success' || nextStep.step === 'Failed') {
|
|
725
741
|
return { ...nextStep, terminate: true };
|
|
726
742
|
}
|
|
727
743
|
else {
|
|
@@ -730,10 +746,16 @@ class BaseAgent {
|
|
|
730
746
|
}
|
|
731
747
|
catch (error) {
|
|
732
748
|
await this.finalizeStepEntity(stepEntity, false, error.message);
|
|
733
|
-
|
|
749
|
+
const errString = error?.message || error || 'Unknown error';
|
|
750
|
+
return {
|
|
751
|
+
errorMessage: `Prompt execution failed: ${errString}`,
|
|
752
|
+
step: 'Failed',
|
|
753
|
+
terminate: false,
|
|
754
|
+
};
|
|
734
755
|
}
|
|
735
756
|
}
|
|
736
|
-
async executeSubAgentStep(params,
|
|
757
|
+
async executeSubAgentStep(params, previousDecision) {
|
|
758
|
+
const subAgentRequest = previousDecision.subAgent;
|
|
737
759
|
if (params.cancellationToken?.aborted) {
|
|
738
760
|
throw new Error('Cancelled before sub-agent execution');
|
|
739
761
|
}
|
|
@@ -742,7 +764,7 @@ class BaseAgent {
|
|
|
742
764
|
percentage: 60,
|
|
743
765
|
message: this.formatHierarchicalMessage(`Delegating to ${subAgentRequest.name} agent`),
|
|
744
766
|
metadata: {
|
|
745
|
-
|
|
767
|
+
agentName: params.agent.Name,
|
|
746
768
|
subAgentName: subAgentRequest.name,
|
|
747
769
|
reason: subAgentRequest.message
|
|
748
770
|
}
|
|
@@ -751,69 +773,79 @@ class BaseAgent {
|
|
|
751
773
|
role: 'assistant',
|
|
752
774
|
content: `I'm delegating this task to the "${subAgentRequest.name}" agent.\n\nReason: ${subAgentRequest.message}`
|
|
753
775
|
});
|
|
754
|
-
const startTime = new Date();
|
|
755
776
|
const inputData = {
|
|
756
|
-
|
|
777
|
+
agentName: params.agent.Name,
|
|
757
778
|
subAgentName: subAgentRequest.name,
|
|
758
779
|
message: subAgentRequest.message,
|
|
759
780
|
terminateAfter: subAgentRequest.terminateAfter,
|
|
760
781
|
conversationMessages: params.conversationMessages,
|
|
761
|
-
parentAgentHierarchy: this.
|
|
782
|
+
parentAgentHierarchy: this._agentHierarchy
|
|
762
783
|
};
|
|
763
|
-
const
|
|
784
|
+
const subAgentEntity = aiengine_1.AIEngine.Instance.Agents.find(a => a.Name === subAgentRequest.name &&
|
|
785
|
+
a.ParentID === params.agent.ID);
|
|
786
|
+
if (!subAgentEntity) {
|
|
787
|
+
throw new Error(`Sub-agent '${subAgentRequest.name}' not found`);
|
|
788
|
+
}
|
|
789
|
+
const stepEntity = await this.createStepEntity('Sub-Agent', `Execute Sub-Agent: ${subAgentRequest.name}`, params.contextUser, subAgentEntity.ID, inputData);
|
|
764
790
|
try {
|
|
765
|
-
|
|
791
|
+
let downstreamPaths = ['*'];
|
|
792
|
+
let upstreamPaths = ['*'];
|
|
793
|
+
try {
|
|
794
|
+
if (subAgentEntity.PayloadDownstreamPaths) {
|
|
795
|
+
downstreamPaths = JSON.parse(subAgentEntity.PayloadDownstreamPaths);
|
|
796
|
+
}
|
|
797
|
+
if (subAgentEntity.PayloadUpstreamPaths) {
|
|
798
|
+
upstreamPaths = JSON.parse(subAgentEntity.PayloadUpstreamPaths);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
catch (parseError) {
|
|
802
|
+
this.logError(`Failed to parse payload paths for sub-agent ${subAgentRequest.name}: ${parseError.message}`, {
|
|
803
|
+
category: 'SubAgentExecution',
|
|
804
|
+
metadata: {
|
|
805
|
+
agentName: params.agent.Name,
|
|
806
|
+
subAgentName: subAgentRequest.name,
|
|
807
|
+
subAgentId: subAgentEntity.ID,
|
|
808
|
+
downstreamPaths: subAgentEntity.PayloadDownstreamPaths,
|
|
809
|
+
upstreamPaths: subAgentEntity.PayloadUpstreamPaths
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
const downstreamPayload = this._payloadManager.extractDownstreamPayload(subAgentRequest.name, previousDecision.payload, downstreamPaths);
|
|
814
|
+
stepEntity.PayloadAtStart = JSON.stringify(previousDecision.payload);
|
|
815
|
+
const subAgentResult = await this.ExecuteSubAgent(params, subAgentRequest, subAgentEntity, stepEntity, downstreamPayload);
|
|
816
|
+
const mergedPayload = this._payloadManager.mergeUpstreamPayload(subAgentRequest.name, previousDecision.payload, subAgentResult.payload, upstreamPaths);
|
|
766
817
|
if (subAgentResult.agentRun?.ID) {
|
|
767
818
|
stepEntity.TargetLogID = subAgentResult.agentRun.ID;
|
|
768
|
-
|
|
819
|
+
stepEntity.SubAgentRun = subAgentResult.agentRun;
|
|
820
|
+
stepEntity.PayloadAtEnd = JSON.stringify(mergedPayload);
|
|
769
821
|
}
|
|
770
822
|
if (params.cancellationToken?.aborted) {
|
|
771
823
|
await this.finalizeStepEntity(stepEntity, false, 'Cancelled during sub-agent execution');
|
|
772
824
|
throw new Error('Cancelled during sub-agent execution');
|
|
773
825
|
}
|
|
774
|
-
const executionResult = {
|
|
775
|
-
type: 'sub-agent',
|
|
776
|
-
subAgentId: subAgentRequest.id,
|
|
777
|
-
subAgentName: subAgentRequest.name,
|
|
778
|
-
result: subAgentResult
|
|
779
|
-
};
|
|
780
826
|
this._subAgentRuns.push(subAgentResult);
|
|
781
827
|
const shouldTerminate = subAgentRequest.terminateAfter;
|
|
782
|
-
const nextStepType = subAgentResult.returnValue?.step || 'retry';
|
|
783
|
-
const nextStepDecision = {
|
|
784
|
-
decision: shouldTerminate ? 'success' : 'retry',
|
|
785
|
-
reasoning: shouldTerminate ? 'Sub-agent execution completed, terminating as requested' : 'Sub-agent completed, continuing execution',
|
|
786
|
-
nextStepDetails: { type: nextStepType, returnValue: subAgentResult.returnValue }
|
|
787
|
-
};
|
|
788
|
-
this._executionChain.push({
|
|
789
|
-
stepEntity,
|
|
790
|
-
executionType: 'sub-agent',
|
|
791
|
-
executionResult,
|
|
792
|
-
nextStepDecision,
|
|
793
|
-
startTime,
|
|
794
|
-
endTime: new Date(),
|
|
795
|
-
durationMs: new Date().getTime() - startTime.getTime()
|
|
796
|
-
});
|
|
797
828
|
const outputData = {
|
|
798
829
|
subAgentResult: {
|
|
799
830
|
success: subAgentResult.success,
|
|
800
|
-
finalStep: subAgentResult.
|
|
801
|
-
|
|
802
|
-
errorMessage: subAgentResult.
|
|
831
|
+
finalStep: subAgentResult.agentRun?.FinalStep,
|
|
832
|
+
payload: subAgentResult.payload,
|
|
833
|
+
errorMessage: subAgentResult.agentRun?.ErrorMessage,
|
|
803
834
|
agentRunId: subAgentResult.agentRun?.ID,
|
|
804
|
-
stepCount:
|
|
835
|
+
stepCount: subAgentResult.agentRun?.Steps?.length || 0
|
|
805
836
|
},
|
|
806
837
|
shouldTerminate: shouldTerminate,
|
|
807
|
-
nextStep:
|
|
838
|
+
nextStep: shouldTerminate ? 'success' : 'retry'
|
|
808
839
|
};
|
|
809
|
-
await this.finalizeStepEntity(stepEntity, subAgentResult.success, subAgentResult.
|
|
840
|
+
await this.finalizeStepEntity(stepEntity, subAgentResult.success, subAgentResult.agentRun?.ErrorMessage, outputData);
|
|
810
841
|
const subAgentSummary = {
|
|
842
|
+
agentName: params.agent.Name,
|
|
811
843
|
subAgentName: subAgentRequest.name,
|
|
812
|
-
subAgentId:
|
|
844
|
+
subAgentId: subAgentEntity.ID,
|
|
813
845
|
success: subAgentResult.success,
|
|
814
|
-
finalStep: subAgentResult.
|
|
815
|
-
|
|
816
|
-
errorMessage: subAgentResult.
|
|
846
|
+
finalStep: subAgentResult.agentRun?.FinalStep,
|
|
847
|
+
payload: subAgentResult.payload,
|
|
848
|
+
errorMessage: subAgentResult.agentRun?.ErrorMessage || null
|
|
817
849
|
};
|
|
818
850
|
const resultMessage = subAgentResult.success
|
|
819
851
|
? `Sub-agent completed successfully:\n${JSON.stringify(subAgentSummary, null, 2)}`
|
|
@@ -822,43 +854,37 @@ class BaseAgent {
|
|
|
822
854
|
role: 'user',
|
|
823
855
|
content: resultMessage
|
|
824
856
|
});
|
|
857
|
+
if (this._agentRun) {
|
|
858
|
+
this._agentRun.FinalPayloadObject = mergedPayload;
|
|
859
|
+
}
|
|
825
860
|
return {
|
|
826
861
|
...subAgentResult,
|
|
827
|
-
step: subAgentResult.success ? '
|
|
828
|
-
terminate: shouldTerminate
|
|
862
|
+
step: subAgentResult.success ? 'Success' : 'Failed',
|
|
863
|
+
terminate: shouldTerminate,
|
|
864
|
+
payload: mergedPayload
|
|
829
865
|
};
|
|
830
866
|
}
|
|
831
867
|
catch (error) {
|
|
832
868
|
await this.finalizeStepEntity(stepEntity, false, error.message);
|
|
833
|
-
|
|
869
|
+
return {
|
|
870
|
+
errorMessage: `Sub-agent execution failed: ${error.message}`,
|
|
871
|
+
step: 'Failed',
|
|
872
|
+
terminate: false,
|
|
873
|
+
};
|
|
834
874
|
}
|
|
835
875
|
}
|
|
836
|
-
async executeActionsStep(params,
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
if (actions.length === 1) {
|
|
842
|
-
const action = actions[0];
|
|
843
|
-
progressMessage = `Executing action: **${action.name}**`;
|
|
844
|
-
if (action.params && Object.keys(action.params).length > 0) {
|
|
845
|
-
const paramsList = Object.entries(action.params)
|
|
846
|
-
.map(([key, value]) => {
|
|
847
|
-
const displayValue = typeof value === 'object'
|
|
848
|
-
? JSON.stringify(value, null, 2)
|
|
849
|
-
: String(value);
|
|
850
|
-
return ` - \`${key}\`: ${displayValue}`;
|
|
851
|
-
})
|
|
852
|
-
.join('\n');
|
|
853
|
-
progressMessage += `\n${paramsList}`;
|
|
876
|
+
async executeActionsStep(params, previousDecision) {
|
|
877
|
+
try {
|
|
878
|
+
const actions = previousDecision.actions || [];
|
|
879
|
+
if (params.cancellationToken?.aborted) {
|
|
880
|
+
throw new Error('Cancelled before action execution');
|
|
854
881
|
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
const paramsList = Object.entries(action.params)
|
|
882
|
+
let progressMessage;
|
|
883
|
+
if (actions.length === 1) {
|
|
884
|
+
const aa = actions[0];
|
|
885
|
+
progressMessage = `Executing action: **${aa.name}**`;
|
|
886
|
+
if (aa.params && Object.keys(aa.params).length > 0) {
|
|
887
|
+
const paramsList = Object.entries(aa.params)
|
|
862
888
|
.map(([key, value]) => {
|
|
863
889
|
const displayValue = typeof value === 'object'
|
|
864
890
|
? JSON.stringify(value, null, 2)
|
|
@@ -868,129 +894,124 @@ class BaseAgent {
|
|
|
868
894
|
.join('\n');
|
|
869
895
|
progressMessage += `\n${paramsList}`;
|
|
870
896
|
}
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
progressMessage = `Executing ${actions.length} actions:`;
|
|
900
|
+
actions.forEach(aa => {
|
|
901
|
+
progressMessage += `\n\n• **${aa.name}**`;
|
|
902
|
+
if (aa.params && Object.keys(aa.params).length > 0) {
|
|
903
|
+
const paramsList = Object.entries(aa.params)
|
|
904
|
+
.map(([key, value]) => {
|
|
905
|
+
const displayValue = typeof value === 'object'
|
|
906
|
+
? JSON.stringify(value, null, 2)
|
|
907
|
+
: String(value);
|
|
908
|
+
return ` - \`${key}\`: ${displayValue}`;
|
|
909
|
+
})
|
|
910
|
+
.join('\n');
|
|
911
|
+
progressMessage += `\n${paramsList}`;
|
|
912
|
+
}
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
params.onProgress?.({
|
|
916
|
+
step: 'action_execution',
|
|
917
|
+
percentage: 50,
|
|
918
|
+
message: this.formatHierarchicalMessage(progressMessage),
|
|
919
|
+
metadata: {
|
|
920
|
+
actionCount: actions.length,
|
|
921
|
+
actionNames: actions.map(a => a.name)
|
|
922
|
+
},
|
|
923
|
+
displayMode: 'live'
|
|
871
924
|
});
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
: `I'm executing ${actions.length} actions to gather the information needed:\n${actions.map(a => `• ${a.name}`).join('\n')}`;
|
|
886
|
-
params.conversationMessages.push({
|
|
887
|
-
role: 'assistant',
|
|
888
|
-
content: actionMessage
|
|
889
|
-
});
|
|
890
|
-
const actionPromises = actions.map(async (action) => {
|
|
891
|
-
const startTime = new Date();
|
|
892
|
-
const stepEntity = await this.createStepEntity('action', `Execute Action: ${action.name}`, params.contextUser, action.id);
|
|
893
|
-
let actionResult;
|
|
894
|
-
try {
|
|
895
|
-
actionResult = await this.ExecuteSingleAction(params, action, params.contextUser);
|
|
896
|
-
if (actionResult.LogEntry?.ID) {
|
|
897
|
-
stepEntity.TargetLogID = actionResult.LogEntry.ID;
|
|
898
|
-
await stepEntity.Save();
|
|
925
|
+
const actionMessage = actions.length === 1
|
|
926
|
+
? `I'm executing the "${actions[0].name}" action...`
|
|
927
|
+
: `I'm executing ${actions.length} actions to gather the information needed:\n${actions.map(a => `• ${a.name}`).join('\n')}`;
|
|
928
|
+
params.conversationMessages.push({
|
|
929
|
+
role: 'assistant',
|
|
930
|
+
content: actionMessage
|
|
931
|
+
});
|
|
932
|
+
const actionEngine = actions_1.ActionEngineServer.Instance;
|
|
933
|
+
const agentActions = aiengine_1.AIEngine.Instance.AgentActions.filter(aa => aa.AgentID === params.agent.ID);
|
|
934
|
+
const actionPromises = actions.map(async (aa) => {
|
|
935
|
+
const actionEntity = actionEngine.Actions.find(a => a.Name === aa.name && agentActions.some(aa => aa.ActionID === a.ID));
|
|
936
|
+
if (!actionEntity) {
|
|
937
|
+
throw new Error(`Action "${aa.name}" Not Found for Agent "${params.agent.Name}"`);
|
|
899
938
|
}
|
|
900
|
-
const
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
decision: 'retry',
|
|
908
|
-
reasoning: 'Action completed successfully',
|
|
909
|
-
nextStepDetails: undefined
|
|
910
|
-
};
|
|
911
|
-
this._executionChain.push({
|
|
912
|
-
stepEntity,
|
|
913
|
-
executionType: 'action',
|
|
914
|
-
executionResult,
|
|
915
|
-
nextStepDecision,
|
|
916
|
-
startTime,
|
|
917
|
-
endTime: new Date(),
|
|
918
|
-
durationMs: new Date().getTime() - startTime.getTime()
|
|
919
|
-
});
|
|
920
|
-
const outputData = {
|
|
921
|
-
actionResult: {
|
|
922
|
-
success: actionResult.Success,
|
|
923
|
-
resultCode: actionResult.Result?.ResultCode,
|
|
924
|
-
message: actionResult.Message,
|
|
925
|
-
parameters: actionResult.Params
|
|
939
|
+
const stepEntity = await this.createStepEntity('Actions', `Execute Action: ${aa.name}`, params.contextUser, actionEntity.ID);
|
|
940
|
+
let actionResult;
|
|
941
|
+
try {
|
|
942
|
+
actionResult = await this.ExecuteSingleAction(params, aa, actionEntity, params.contextUser);
|
|
943
|
+
if (actionResult.LogEntry?.ID) {
|
|
944
|
+
stepEntity.TargetLogID = actionResult.LogEntry.ID;
|
|
945
|
+
await stepEntity.Save();
|
|
926
946
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
947
|
+
const outputData = {
|
|
948
|
+
actionResult: {
|
|
949
|
+
success: actionResult.Success,
|
|
950
|
+
resultCode: actionResult.Result?.ResultCode,
|
|
951
|
+
message: actionResult.Message,
|
|
952
|
+
parameters: actionResult.Params
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
await this.finalizeStepEntity(stepEntity, actionResult.Success, actionResult.Success ? undefined : actionResult.Message, outputData);
|
|
956
|
+
return { success: true, result: actionResult, action: aa, actionEntity, stepEntity };
|
|
957
|
+
}
|
|
958
|
+
catch (error) {
|
|
959
|
+
await this.finalizeStepEntity(stepEntity, false, error.message);
|
|
960
|
+
return { success: false, result: actionResult, error: error.message, action: aa, actionEntity, stepEntity };
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
const actionResults = await Promise.all(actionPromises);
|
|
964
|
+
if (params.cancellationToken?.aborted) {
|
|
965
|
+
throw new Error('Cancelled after action execution');
|
|
934
966
|
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
967
|
+
const actionSummaries = actionResults.map(result => {
|
|
968
|
+
const actionResult = result.success ? result.result : null;
|
|
969
|
+
return {
|
|
970
|
+
actionName: result.action.name,
|
|
971
|
+
actionId: result.actionEntity?.ID,
|
|
972
|
+
params: result.result?.Params || {},
|
|
973
|
+
success: result.success,
|
|
974
|
+
resultCode: actionResult?.Result?.ResultCode || (result.success ? 'SUCCESS' : 'ERROR'),
|
|
975
|
+
message: result.success ? actionResult?.Message || 'Action completed' : result.error
|
|
976
|
+
};
|
|
977
|
+
});
|
|
978
|
+
const failedActions = actionSummaries.filter(a => !a.success);
|
|
979
|
+
const resultsMessage = failedActions.length > 0
|
|
980
|
+
? `Action results (${failedActions.length} failed):\n${JSON.stringify(actionSummaries, null, 2)}`
|
|
981
|
+
: `Action results (all succeeded):\n${JSON.stringify(actionSummaries, null, 2)}`;
|
|
982
|
+
params.conversationMessages.push({
|
|
983
|
+
role: 'user',
|
|
984
|
+
content: resultsMessage
|
|
985
|
+
});
|
|
986
|
+
return {
|
|
987
|
+
terminate: false,
|
|
988
|
+
step: 'Retry',
|
|
989
|
+
payload: previousDecision?.payload || null,
|
|
990
|
+
priorStepResult: actionSummaries,
|
|
991
|
+
retryReason: failedActions.length > 0
|
|
992
|
+
? `Processing results with ${failedActions.length} failed action(s): ${failedActions.map(a => a.actionName).join(', ')}`
|
|
993
|
+
: `Analyzing results from ${actionSummaries.length} completed action(s) to formulate response`
|
|
994
|
+
};
|
|
939
995
|
}
|
|
940
|
-
|
|
941
|
-
const actionResult = result.success ? result.result : null;
|
|
996
|
+
catch (e) {
|
|
942
997
|
return {
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
resultCode: actionResult?.Result?.ResultCode || (result.success ? 'SUCCESS' : 'ERROR'),
|
|
948
|
-
message: result.success ? actionResult?.Message || 'Action completed' : result.error
|
|
998
|
+
terminate: false,
|
|
999
|
+
step: 'Retry',
|
|
1000
|
+
payload: e && e.message ? e.message : e ? e : 'Unknown error execution actions',
|
|
1001
|
+
retryReason: 'Error while processing actions, retry'
|
|
949
1002
|
};
|
|
950
|
-
}
|
|
951
|
-
const failedActions = actionSummaries.filter(a => !a.success);
|
|
952
|
-
const resultsMessage = failedActions.length > 0
|
|
953
|
-
? `Action results (${failedActions.length} failed):\n${JSON.stringify(actionSummaries, null, 2)}`
|
|
954
|
-
: `Action results (all succeeded):\n${JSON.stringify(actionSummaries, null, 2)}`;
|
|
955
|
-
params.conversationMessages.push({
|
|
956
|
-
role: 'user',
|
|
957
|
-
content: resultsMessage
|
|
958
|
-
});
|
|
959
|
-
return {
|
|
960
|
-
terminate: false,
|
|
961
|
-
step: 'retry',
|
|
962
|
-
returnValue: actionSummaries,
|
|
963
|
-
retryReason: failedActions.length > 0
|
|
964
|
-
? `Processing results with ${failedActions.length} failed action(s): ${failedActions.map(a => a.actionName).join(', ')}`
|
|
965
|
-
: `Analyzing results from ${actionSummaries.length} completed action(s) to formulate response`
|
|
966
|
-
};
|
|
1003
|
+
}
|
|
967
1004
|
}
|
|
968
|
-
async executeChatStep(params,
|
|
969
|
-
const
|
|
970
|
-
const stepEntity = await this.createStepEntity('chat', 'User Interaction', params.contextUser);
|
|
971
|
-
const executionResult = {
|
|
972
|
-
type: 'chat',
|
|
973
|
-
userMessage,
|
|
974
|
-
result: { success: false, continueExecution: false }
|
|
975
|
-
};
|
|
976
|
-
const nextStepDecision = {
|
|
977
|
-
decision: 'failed',
|
|
978
|
-
reasoning: 'Chat functionality not implemented in base agent'
|
|
979
|
-
};
|
|
980
|
-
this._executionChain.push({
|
|
981
|
-
stepEntity,
|
|
982
|
-
executionType: 'chat',
|
|
983
|
-
executionResult,
|
|
984
|
-
nextStepDecision,
|
|
985
|
-
startTime,
|
|
986
|
-
endTime: new Date(),
|
|
987
|
-
durationMs: new Date().getTime() - startTime.getTime()
|
|
988
|
-
});
|
|
1005
|
+
async executeChatStep(params, previousDecision) {
|
|
1006
|
+
const stepEntity = await this.createStepEntity('Chat', 'User Interaction', params.contextUser);
|
|
989
1007
|
await this.finalizeStepEntity(stepEntity, false, 'Chat not implemented');
|
|
990
1008
|
return {
|
|
991
|
-
step: '
|
|
1009
|
+
step: 'Chat',
|
|
992
1010
|
terminate: true,
|
|
993
|
-
|
|
1011
|
+
priorStepResult: previousDecision.message,
|
|
1012
|
+
reasoning: previousDecision.reasoning,
|
|
1013
|
+
confidence: previousDecision.confidence,
|
|
1014
|
+
payload: previousDecision.payload,
|
|
994
1015
|
};
|
|
995
1016
|
}
|
|
996
1017
|
async createFailureResult(errorMessage, contextUser) {
|
|
@@ -1008,10 +1029,7 @@ class BaseAgent {
|
|
|
1008
1029
|
}
|
|
1009
1030
|
return {
|
|
1010
1031
|
success: false,
|
|
1011
|
-
|
|
1012
|
-
errorMessage,
|
|
1013
|
-
agentRun: this._agentRun,
|
|
1014
|
-
executionTree: this.buildExecutionTree()
|
|
1032
|
+
agentRun: this._agentRun
|
|
1015
1033
|
};
|
|
1016
1034
|
}
|
|
1017
1035
|
async createCancelledResult(message, contextUser) {
|
|
@@ -1029,220 +1047,57 @@ class BaseAgent {
|
|
|
1029
1047
|
}
|
|
1030
1048
|
return {
|
|
1031
1049
|
success: false,
|
|
1032
|
-
|
|
1033
|
-
errorMessage: message,
|
|
1034
|
-
cancelled: true,
|
|
1035
|
-
cancellationReason: 'user_requested',
|
|
1036
|
-
agentRun: this._agentRun,
|
|
1037
|
-
executionTree: this.buildExecutionTree()
|
|
1050
|
+
agentRun: this._agentRun
|
|
1038
1051
|
};
|
|
1039
1052
|
}
|
|
1040
|
-
async finalizeAgentRun(finalStep,
|
|
1053
|
+
async finalizeAgentRun(finalStep, payload, contextUser) {
|
|
1041
1054
|
if (this._agentRun) {
|
|
1042
1055
|
this._agentRun.Status = 'Completed';
|
|
1043
1056
|
this._agentRun.CompletedAt = new Date();
|
|
1044
|
-
this._agentRun.Success = finalStep === '
|
|
1045
|
-
this._agentRun.Result =
|
|
1057
|
+
this._agentRun.Success = finalStep.step === 'Success' || finalStep.step === 'Chat';
|
|
1058
|
+
this._agentRun.Result = payload ? JSON.stringify(payload) : null;
|
|
1059
|
+
this._agentRun.FinalStep = finalStep.step;
|
|
1060
|
+
this._agentRun.Message = finalStep.message;
|
|
1061
|
+
this._agentRun.FinalPayloadObject = payload;
|
|
1046
1062
|
const tokenStats = this.calculateTokenStats();
|
|
1047
1063
|
this._agentRun.TotalTokensUsed = tokenStats.totalTokens;
|
|
1048
1064
|
this._agentRun.TotalPromptTokensUsed = tokenStats.promptTokens;
|
|
1049
1065
|
this._agentRun.TotalCompletionTokensUsed = tokenStats.completionTokens;
|
|
1050
1066
|
this._agentRun.TotalCost = tokenStats.totalCost;
|
|
1051
|
-
await this._agentRun.Save();
|
|
1067
|
+
const ok = await this._agentRun.Save();
|
|
1068
|
+
if (!ok) {
|
|
1069
|
+
(0, core_1.LogError)(`Failed to finalize agent run ${this._agentRun.ID}`);
|
|
1070
|
+
}
|
|
1052
1071
|
}
|
|
1053
1072
|
return {
|
|
1054
|
-
success: finalStep === '
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
agentRun: this._agentRun,
|
|
1058
|
-
executionTree: this.buildExecutionTree()
|
|
1073
|
+
success: finalStep.step === 'Success' || finalStep.step === 'Chat',
|
|
1074
|
+
payload,
|
|
1075
|
+
agentRun: this._agentRun
|
|
1059
1076
|
};
|
|
1060
1077
|
}
|
|
1061
|
-
countStepsInTree(nodes) {
|
|
1062
|
-
let count = 0;
|
|
1063
|
-
for (const node of nodes) {
|
|
1064
|
-
count++;
|
|
1065
|
-
if (node.children && node.children.length > 0) {
|
|
1066
|
-
count += this.countStepsInTree(node.children);
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
return count;
|
|
1070
|
-
}
|
|
1071
1078
|
calculateTokenStats() {
|
|
1072
1079
|
let totalTokens = 0;
|
|
1073
1080
|
let promptTokens = 0;
|
|
1074
1081
|
let completionTokens = 0;
|
|
1075
1082
|
let totalCost = 0;
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
totalCost += promptResult.result.promptRun?.TotalCost || 0;
|
|
1083
|
+
if (this._agentRun?.Steps) {
|
|
1084
|
+
for (const step of this._agentRun.Steps) {
|
|
1085
|
+
if (step.StepType === 'Prompt' && step.PromptRun) {
|
|
1086
|
+
totalTokens += step.PromptRun.TokensUsedRollup || 0;
|
|
1087
|
+
promptTokens += step.PromptRun.TokensPromptRollup || 0;
|
|
1088
|
+
completionTokens += step.PromptRun.TokensCompletionRollup || 0;
|
|
1089
|
+
totalCost += step.PromptRun.TotalCost || 0;
|
|
1084
1090
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
promptTokens += subAgentResult.result.agentRun.TotalPromptTokensUsed || 0;
|
|
1091
|
-
completionTokens += subAgentResult.result.agentRun.TotalCompletionTokensUsed || 0;
|
|
1092
|
-
totalCost += subAgentResult.result.agentRun.TotalCost || 0;
|
|
1091
|
+
else if (step.StepType === 'Sub-Agent' && step.SubAgentRun) {
|
|
1092
|
+
totalTokens += step.SubAgentRun.TotalTokensUsed || 0;
|
|
1093
|
+
promptTokens += step.SubAgentRun.TotalPromptTokensUsed || 0;
|
|
1094
|
+
completionTokens += step.SubAgentRun.TotalCompletionTokensUsed || 0;
|
|
1095
|
+
totalCost += step.SubAgentRun.TotalCost || 0;
|
|
1093
1096
|
}
|
|
1094
1097
|
}
|
|
1095
1098
|
}
|
|
1096
1099
|
return { totalTokens, promptTokens, completionTokens, totalCost };
|
|
1097
1100
|
}
|
|
1098
|
-
buildExecutionTree() {
|
|
1099
|
-
const executionTree = [];
|
|
1100
|
-
const allEvents = [];
|
|
1101
|
-
let maxProgressStepNumber = 0;
|
|
1102
|
-
for (const progressStep of this._allProgressSteps) {
|
|
1103
|
-
allEvents.push({
|
|
1104
|
-
type: 'progress',
|
|
1105
|
-
timestamp: progressStep.timestamp,
|
|
1106
|
-
data: progressStep
|
|
1107
|
-
});
|
|
1108
|
-
}
|
|
1109
|
-
for (const chainStep of this._executionChain) {
|
|
1110
|
-
allEvents.push({
|
|
1111
|
-
type: 'execution',
|
|
1112
|
-
timestamp: chainStep.startTime,
|
|
1113
|
-
data: chainStep
|
|
1114
|
-
});
|
|
1115
|
-
}
|
|
1116
|
-
allEvents.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
1117
|
-
for (const event of allEvents) {
|
|
1118
|
-
if (event.type === 'progress') {
|
|
1119
|
-
const progressData = event.data;
|
|
1120
|
-
maxProgressStepNumber++;
|
|
1121
|
-
const progressNode = {
|
|
1122
|
-
step: {
|
|
1123
|
-
ID: `progress-${event.timestamp.getTime()}`,
|
|
1124
|
-
StepNumber: maxProgressStepNumber,
|
|
1125
|
-
StepName: progressData.message,
|
|
1126
|
-
StepType: progressData.step || 'progress',
|
|
1127
|
-
Status: 'Completed',
|
|
1128
|
-
StartedAt: event.timestamp,
|
|
1129
|
-
CompletedAt: event.timestamp
|
|
1130
|
-
},
|
|
1131
|
-
inputData: null,
|
|
1132
|
-
outputData: {
|
|
1133
|
-
percentage: progressData.percentage,
|
|
1134
|
-
metadata: progressData.metadata
|
|
1135
|
-
},
|
|
1136
|
-
executionType: progressData.step || 'progress',
|
|
1137
|
-
startTime: event.timestamp,
|
|
1138
|
-
endTime: event.timestamp,
|
|
1139
|
-
durationMs: 0,
|
|
1140
|
-
children: [],
|
|
1141
|
-
depth: progressData.depth || this._runContext?.depth || 0,
|
|
1142
|
-
parentStepId: null,
|
|
1143
|
-
agentHierarchy: progressData.agentHierarchy || this._runContext?.agentHierarchy || []
|
|
1144
|
-
};
|
|
1145
|
-
executionTree.push(progressNode);
|
|
1146
|
-
}
|
|
1147
|
-
else {
|
|
1148
|
-
const chainStep = event.data;
|
|
1149
|
-
const stepEntity = chainStep.stepEntity;
|
|
1150
|
-
let inputData = null;
|
|
1151
|
-
let outputData = null;
|
|
1152
|
-
try {
|
|
1153
|
-
if (stepEntity.InputData) {
|
|
1154
|
-
inputData = JSON.parse(stepEntity.InputData);
|
|
1155
|
-
}
|
|
1156
|
-
if (stepEntity.OutputData) {
|
|
1157
|
-
outputData = JSON.parse(stepEntity.OutputData);
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
catch (e) {
|
|
1161
|
-
inputData = stepEntity.InputData;
|
|
1162
|
-
outputData = stepEntity.OutputData;
|
|
1163
|
-
}
|
|
1164
|
-
const node = {
|
|
1165
|
-
step: stepEntity,
|
|
1166
|
-
inputData,
|
|
1167
|
-
outputData,
|
|
1168
|
-
executionType: chainStep.executionType,
|
|
1169
|
-
startTime: chainStep.startTime,
|
|
1170
|
-
endTime: chainStep.endTime,
|
|
1171
|
-
durationMs: chainStep.durationMs,
|
|
1172
|
-
nextStepDecision: chainStep.nextStepDecision,
|
|
1173
|
-
children: [],
|
|
1174
|
-
depth: this._runContext?.depth || 0,
|
|
1175
|
-
parentStepId: null,
|
|
1176
|
-
agentHierarchy: this._runContext?.agentHierarchy || []
|
|
1177
|
-
};
|
|
1178
|
-
if (chainStep.executionType === 'sub-agent' && chainStep.executionResult?.type === 'sub-agent') {
|
|
1179
|
-
const subAgentResult = chainStep.executionResult.result;
|
|
1180
|
-
if (subAgentResult.executionTree) {
|
|
1181
|
-
node.children = subAgentResult.executionTree.map(childNode => ({
|
|
1182
|
-
...childNode,
|
|
1183
|
-
parentStepId: stepEntity.ID,
|
|
1184
|
-
depth: (this._runContext?.depth || 0) + 1
|
|
1185
|
-
}));
|
|
1186
|
-
this.sortExecutionTreeByStepNumber(node.children);
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
executionTree.push(node);
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
this.sortExecutionTreeByStepNumber(executionTree);
|
|
1193
|
-
return executionTree;
|
|
1194
|
-
}
|
|
1195
|
-
sortExecutionTreeByStepNumber(nodes) {
|
|
1196
|
-
nodes.sort((a, b) => {
|
|
1197
|
-
const aStepNumber = a.step?.StepNumber || 0;
|
|
1198
|
-
const bStepNumber = b.step?.StepNumber || 0;
|
|
1199
|
-
return aStepNumber - bStepNumber;
|
|
1200
|
-
});
|
|
1201
|
-
for (const node of nodes) {
|
|
1202
|
-
if (node.children && node.children.length > 0) {
|
|
1203
|
-
this.sortExecutionTreeByStepNumber(node.children);
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
getNextStepReasoning(nextStep) {
|
|
1208
|
-
switch (nextStep.step) {
|
|
1209
|
-
case 'success':
|
|
1210
|
-
return 'Agent completed successfully';
|
|
1211
|
-
case 'failed':
|
|
1212
|
-
return `Agent failed: ${nextStep.errorMessage || 'Unknown error'}`;
|
|
1213
|
-
case 'retry':
|
|
1214
|
-
return nextStep.retryReason || 'Retrying with additional context';
|
|
1215
|
-
case 'sub-agent':
|
|
1216
|
-
return `Invoking sub-agent: ${nextStep.subAgent?.name}`;
|
|
1217
|
-
case 'actions':
|
|
1218
|
-
return `Executing ${nextStep.actions?.length || 0} action(s)`;
|
|
1219
|
-
case 'chat':
|
|
1220
|
-
return 'User interaction required';
|
|
1221
|
-
default:
|
|
1222
|
-
return 'Unknown next step';
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
getNextStepDetails(nextStep) {
|
|
1226
|
-
switch (nextStep.step) {
|
|
1227
|
-
case 'success':
|
|
1228
|
-
case 'failed':
|
|
1229
|
-
return { type: 'complete', returnValue: nextStep.returnValue };
|
|
1230
|
-
case 'retry':
|
|
1231
|
-
return {
|
|
1232
|
-
type: 'retry',
|
|
1233
|
-
retryReason: nextStep.retryReason || '',
|
|
1234
|
-
retryInstructions: nextStep.retryInstructions || ''
|
|
1235
|
-
};
|
|
1236
|
-
case 'sub-agent':
|
|
1237
|
-
return nextStep.subAgent ? { type: 'sub-agent', subAgent: nextStep.subAgent } : undefined;
|
|
1238
|
-
case 'actions':
|
|
1239
|
-
return nextStep.actions ? { type: 'action', actions: nextStep.actions } : undefined;
|
|
1240
|
-
case 'chat':
|
|
1241
|
-
return { type: 'chat', message: nextStep.userMessage || '' };
|
|
1242
|
-
default:
|
|
1243
|
-
return undefined;
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
1101
|
}
|
|
1247
1102
|
exports.BaseAgent = BaseAgent;
|
|
1248
1103
|
//# sourceMappingURL=base-agent.js.map
|