@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.
@@ -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._executionChain = [];
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._runContext?.agentHierarchy || [],
30
- depth: this._runContext?.depth || 0
65
+ agentHierarchy: this._agentHierarchy || [],
66
+ depth: this._depth || 0
31
67
  });
32
- originalCallback(progress);
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
- return await this.finalizeAgentRun(executionResult.finalStep.step, executionResult.finalStep.returnValue, params.contextUser);
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
- finalStep: 'failed',
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(agentType, systemPrompt, childPrompt, params) {
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
- (0, core_1.LogStatus)(`🎯 Agent '${params.agent.Name}' configured to use its own prompt for model selection`);
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
- (0, core_1.LogStatus)(`🎯 Using runtime override: ${params.override.modelId || 'model'} ${params.override.vendorId ? `from vendor ${params.override.vendorId}` : ''}`);
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
- let agentTypeInstance;
194
- try {
195
- agentTypeInstance = await this.getAgentTypeInstance(agentType);
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 getAgentTypeInstance(agentType) {
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
- const engine = aiengine_1.AIEngine.Instance;
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._runContext?.agentHierarchy,
343
- parentDepth: this._runContext?.depth,
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.errorMessage || 'Unknown error'}`);
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._runContext = {
475
- currentStepIndex: 0,
476
- parentRunStack: [],
477
- agentHierarchy: params.parentAgentHierarchy
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('validation', 'Agent Validation', contextUser);
494
- const executionResult = {
495
- type: 'validation',
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('validation', 'Agent Validation', contextUser);
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._runContext.currentStepIndex + 1;
536
+ stepEntity.StepNumber = (this._agentRun.Steps?.length || 0) + 1;
547
537
  stepEntity.StepType = stepType;
548
538
  stepEntity.StepName = this.formatHierarchicalMessage(stepName);
549
- stepEntity.TargetID = targetId || null;
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._runContext.agentHierarchy,
558
- depth: this._runContext.depth,
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._runContext.currentStepIndex++;
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._runContext && this._runContext.depth > 0) {
590
- const breadcrumb = this._runContext.agentHierarchy
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 'retry':
618
+ case 'Retry':
603
619
  return await this.executePromptStep(params, config, previousDecision);
604
- case 'sub-agent':
605
- return await this.executeSubAgentStep(params, previousDecision.subAgent);
606
- case 'actions':
607
- return await this.executeActionsStep(params, previousDecision.actions);
608
- case 'chat':
609
- return await this.executeChatStep(params, previousDecision.userMessage);
610
- case 'success':
611
- return {
612
- terminate: true,
613
- step: 'success',
614
- returnValue: previousDecision.returnValue
615
- };
616
- case 'failed':
617
- return {
618
- terminate: true,
619
- step: 'failed',
620
- returnValue: previousDecision.returnValue
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, retryContext) {
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: !!retryContext,
632
- retryContext: retryContext ? {
633
- reason: retryContext.retryReason,
634
- instructions: retryContext.retryInstructions
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('prompt', 'Execute Agent Prompt', params.contextUser, config.childPrompt?.ID, inputData);
664
+ const stepEntity = await this.createStepEntity('Prompt', 'Execute Agent Prompt', params.contextUser, config.childPrompt?.ID, inputData);
640
665
  try {
641
- const isRetry = !!retryContext;
666
+ const isRetry = !!previousDecision;
642
667
  const promptMessage = isRetry
643
- ? `Running ${params.agent.Name} with context from ${retryContext.retryReason || 'previous actions'}`
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 promptParams = await this.preparePromptParams(config.agentType, config.systemPrompt, config.childPrompt, params);
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
- await stepEntity.Save();
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: cancelledResult.finalStep,
677
- returnValue: cancelledResult.returnValue,
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: nextStepDecision.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 === 'chat') {
737
+ if (nextStep.step === 'Chat') {
722
738
  return { ...nextStep, terminate: true };
723
739
  }
724
- else if (nextStep.step === 'success' || nextStep.step === 'failed') {
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
- throw error;
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, subAgentRequest) {
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
- subAgentId: subAgentRequest.id,
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
- subAgentId: subAgentRequest.id,
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._runContext?.agentHierarchy
782
+ parentAgentHierarchy: this._agentHierarchy
762
783
  };
763
- const stepEntity = await this.createStepEntity('subagent', `Execute Sub-Agent: ${subAgentRequest.name}`, params.contextUser, subAgentRequest.id, inputData);
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
- const subAgentResult = await this.ExecuteSubAgent(params, subAgentRequest);
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
- await stepEntity.Save();
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.finalStep,
801
- returnValue: subAgentResult.returnValue,
802
- errorMessage: subAgentResult.errorMessage,
831
+ finalStep: subAgentResult.agentRun?.FinalStep,
832
+ payload: subAgentResult.payload,
833
+ errorMessage: subAgentResult.agentRun?.ErrorMessage,
803
834
  agentRunId: subAgentResult.agentRun?.ID,
804
- stepCount: this.countStepsInTree(subAgentResult.executionTree)
835
+ stepCount: subAgentResult.agentRun?.Steps?.length || 0
805
836
  },
806
837
  shouldTerminate: shouldTerminate,
807
- nextStep: nextStepDecision.decision
838
+ nextStep: shouldTerminate ? 'success' : 'retry'
808
839
  };
809
- await this.finalizeStepEntity(stepEntity, subAgentResult.success, subAgentResult.errorMessage, outputData);
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: subAgentRequest.id,
844
+ subAgentId: subAgentEntity.ID,
813
845
  success: subAgentResult.success,
814
- finalStep: subAgentResult.finalStep,
815
- returnValue: subAgentResult.returnValue,
816
- errorMessage: subAgentResult.errorMessage || null
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 ? 'success' : 'failed',
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
- throw error;
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, actions) {
837
- if (params.cancellationToken?.aborted) {
838
- throw new Error('Cancelled before action execution');
839
- }
840
- let progressMessage;
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
- else {
857
- progressMessage = `Executing ${actions.length} actions:`;
858
- actions.forEach(action => {
859
- progressMessage += `\n\n• **${action.name}**`;
860
- if (action.params && Object.keys(action.params).length > 0) {
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
- params.onProgress?.({
874
- step: 'action_execution',
875
- percentage: 50,
876
- message: this.formatHierarchicalMessage(progressMessage),
877
- metadata: {
878
- actionCount: actions.length,
879
- actionNames: actions.map(a => a.name)
880
- },
881
- displayMode: 'live'
882
- });
883
- const actionMessage = actions.length === 1
884
- ? `I'm executing the "${actions[0].name}" action...`
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 executionResult = {
901
- type: 'action',
902
- actionId: action.id,
903
- actionName: action.name,
904
- result: actionResult
905
- };
906
- const nextStepDecision = {
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
- await this.finalizeStepEntity(stepEntity, actionResult.Success, actionResult.Success ? undefined : actionResult.Message, outputData);
929
- return { success: true, result: actionResult, action, stepEntity };
930
- }
931
- catch (error) {
932
- await this.finalizeStepEntity(stepEntity, false, error.message);
933
- return { success: false, result: actionResult, error: error.message, action, stepEntity };
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
- const actionResults = await Promise.all(actionPromises);
937
- if (params.cancellationToken?.aborted) {
938
- throw new Error('Cancelled after action execution');
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
- const actionSummaries = actionResults.map(result => {
941
- const actionResult = result.success ? result.result : null;
996
+ catch (e) {
942
997
  return {
943
- actionName: result.action.name,
944
- actionId: result.action.id,
945
- params: result.result?.Params || {},
946
- success: result.success,
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, userMessage) {
969
- const startTime = new Date();
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: 'chat',
1009
+ step: 'Chat',
992
1010
  terminate: true,
993
- returnValue: userMessage,
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
- finalStep: 'failed',
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
- finalStep: 'failed',
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, returnValue, contextUser) {
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 === 'success';
1045
- this._agentRun.Result = returnValue ? JSON.stringify(returnValue) : null;
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 === 'success' || finalStep === 'chat',
1055
- finalStep,
1056
- returnValue,
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
- for (const step of this._executionChain) {
1077
- if (step.executionType === 'prompt' && step.executionResult.type === 'prompt') {
1078
- const promptResult = step.executionResult;
1079
- if (promptResult.result) {
1080
- totalTokens += promptResult.result.tokensUsed || 0;
1081
- promptTokens += promptResult.result.promptTokens || 0;
1082
- completionTokens += promptResult.result.completionTokens || 0;
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
- else if (step.executionType === 'sub-agent' && step.executionResult.type === 'sub-agent') {
1087
- const subAgentResult = step.executionResult;
1088
- if (subAgentResult.result?.agentRun) {
1089
- totalTokens += subAgentResult.result.agentRun.TotalTokensUsed || 0;
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