@memberjunction/ai-agents 2.123.1 → 2.124.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.
@@ -54,6 +54,7 @@ class BaseAgent {
54
54
  this._subAgentRuns = [];
55
55
  this._payloadManager = new PayloadManager_1.PayloadManager();
56
56
  this._effectiveActions = [];
57
+ this._dynamicActionLimits = {};
57
58
  this._validationRetryCount = 0;
58
59
  this._contextRecoveryAttempts = 0;
59
60
  this.MAX_RECOVERY_ATTEMPTS = 1;
@@ -238,6 +239,8 @@ class BaseAgent {
238
239
  this._validationRetryCount = 0;
239
240
  this._generalValidationRetryCount = 0;
240
241
  this._contextRecoveryAttempts = 0;
242
+ this._effectiveActions = [];
243
+ this._dynamicActionLimits = {};
241
244
  this._messageLifecycleCallback = params.onMessageLifecycle;
242
245
  await this.initializeEngines(params.contextUser);
243
246
  if (params.cancellationToken?.aborted) {
@@ -735,27 +738,29 @@ class BaseAgent {
735
738
  return nextStep;
736
739
  }
737
740
  async validateActionsNextStep(params, nextStep, currentPayload, agentRun, currentStep) {
738
- const curAgentActions = aiengine_1.AIEngine.Instance.AgentActions.filter(aa => aa.AgentID === params.agent.ID && aa.Status === 'Active');
741
+ const effectiveActions = this.getEffectiveActionsForValidation(params.agent.ID);
742
+ const dbAgentActions = aiengine_1.AIEngine.Instance.AgentActions.filter(aa => aa.AgentID === params.agent.ID && aa.Status === 'Active');
739
743
  const missingActions = nextStep.actions?.filter(action => {
740
744
  const actionName = action.name.trim().toLowerCase();
741
- const exactMatch = curAgentActions.find(aa => aa.Action.trim().toLowerCase() === actionName);
745
+ const exactMatch = effectiveActions.find(a => a.Name.trim().toLowerCase() === actionName);
742
746
  if (exactMatch)
743
747
  return false;
744
- const containsMatches = curAgentActions.filter(aa => aa.Action.trim().toLowerCase().includes(actionName));
748
+ const containsMatches = effectiveActions.filter(a => a.Name.trim().toLowerCase().includes(actionName));
745
749
  if (containsMatches.length === 1) {
746
- const correctedName = containsMatches[0].Action;
750
+ const correctedName = containsMatches[0].Name;
747
751
  this.logStatus(`Action name fuzzy matched: '${action.name}' → '${correctedName}'`, true, params);
748
752
  action.name = correctedName;
749
753
  return false;
750
754
  }
751
755
  if (containsMatches.length > 1) {
752
- this.logStatus(`Ambiguous action name '${action.name}' matches ${containsMatches.length} actions: ${containsMatches.map(a => a.Action).join(', ')}`, true, params);
756
+ this.logStatus(`Ambiguous action name '${action.name}' matches ${containsMatches.length} actions: ${containsMatches.map(a => a.Name).join(', ')}`, true, params);
753
757
  }
754
758
  return true;
755
759
  });
756
760
  if (missingActions && missingActions.length > 0) {
757
761
  const missingActionNames = missingActions.map(a => a.name).join(', ');
758
- this.logError(`Actions '${missingActionNames}' not found or not active for agent '${params.agent.Name}'`, {
762
+ const availableActionNames = effectiveActions.map(a => a.Name).join(', ');
763
+ this.logError(`Actions '${missingActionNames}' not found or not active for agent '${params.agent.Name}'. Available actions: ${availableActionNames}`, {
759
764
  agent: params.agent,
760
765
  category: 'ActionExecution'
761
766
  });
@@ -765,17 +770,27 @@ class BaseAgent {
765
770
  return {
766
771
  step: 'Retry',
767
772
  terminate: false,
768
- errorMessage: `Actions '${missingActionNames}' not found or not active`
773
+ errorMessage: `Actions '${missingActionNames}' not found or not active. Available: ${availableActionNames}`
769
774
  };
770
775
  }
771
776
  if (nextStep.actions) {
772
777
  const violatedActions = [];
773
778
  for (const action of nextStep.actions) {
774
- const agentAction = curAgentActions.find(aa => aa.Action.trim().toLowerCase() === action.name.trim().toLowerCase());
775
- if (agentAction && agentAction.MaxExecutionsPerRun != null) {
776
- const executionCount = await this.getActionExecutionCount(agentRun.ID, agentAction.ActionID);
777
- if (executionCount >= agentAction.MaxExecutionsPerRun) {
778
- violatedActions.push(`${action.name} (limit: ${agentAction.MaxExecutionsPerRun}, current: ${executionCount})`);
779
+ const actionEntity = effectiveActions.find(a => a.Name.trim().toLowerCase() === action.name.trim().toLowerCase());
780
+ if (!actionEntity)
781
+ continue;
782
+ const dbAgentAction = dbAgentActions.find(aa => aa.ActionID === actionEntity.ID);
783
+ let maxExecutions = null;
784
+ if (dbAgentAction?.MaxExecutionsPerRun != null) {
785
+ maxExecutions = dbAgentAction.MaxExecutionsPerRun;
786
+ }
787
+ else if (this._dynamicActionLimits[actionEntity.ID] != null) {
788
+ maxExecutions = this._dynamicActionLimits[actionEntity.ID];
789
+ }
790
+ if (maxExecutions != null) {
791
+ const executionCount = await this.getActionExecutionCount(agentRun.ID, actionEntity.ID);
792
+ if (executionCount >= maxExecutions) {
793
+ violatedActions.push(`${action.name} (limit: ${maxExecutions}, current: ${executionCount})`);
779
794
  }
780
795
  }
781
796
  }
@@ -800,6 +815,13 @@ class BaseAgent {
800
815
  }
801
816
  return nextStep;
802
817
  }
818
+ getEffectiveActionsForValidation(agentId) {
819
+ if (this._effectiveActions.length > 0) {
820
+ return this._effectiveActions;
821
+ }
822
+ const agentActions = aiengine_1.AIEngine.Instance.AgentActions.filter(aa => aa.AgentID === agentId && aa.Status === 'Active');
823
+ return actions_1.ActionEngineServer.Instance.Actions.filter(a => agentActions.some(aa => aa.ActionID === a.ID) && a.Status === 'Active');
824
+ }
803
825
  async validateSuccessNextStep(params, nextStep, currentPayload, agentRun, currentStep) {
804
826
  const minViolations = await this.checkMinimumExecutionRequirements(params.agent, agentRun);
805
827
  if (minViolations.length > 0) {
@@ -1620,7 +1642,9 @@ The context is now within limits. Please retry your request with the recovered c
1620
1642
  let actions = actions_1.ActionEngineServer.Instance.Actions.filter(a => agentActions.some(aa => aa.ActionID === a.ID));
1621
1643
  if (actionChanges?.length) {
1622
1644
  const isRoot = this._depth === 0;
1623
- actions = this.applyActionChanges(actions, actionChanges, agent.ID, isRoot);
1645
+ const result = this.applyActionChanges(actions, actionChanges, agent.ID, isRoot);
1646
+ actions = result.actions;
1647
+ this._dynamicActionLimits = result.dynamicLimits;
1624
1648
  }
1625
1649
  const activeActions = actions.filter(a => a.Status === 'Active');
1626
1650
  this._effectiveActions = activeActions;
@@ -1900,6 +1924,7 @@ The context is now within limits. Please retry your request with the recovered c
1900
1924
  }
1901
1925
  applyActionChanges(baseActions, actionChanges, agentId, isRoot) {
1902
1926
  let actions = [...baseActions];
1927
+ const dynamicLimits = {};
1903
1928
  for (const change of actionChanges) {
1904
1929
  if (!this.doesChangeScopeApply(change.scope, agentId, isRoot, change.agentIds)) {
1905
1930
  continue;
@@ -1910,6 +1935,9 @@ The context is now within limits. Please retry your request with the recovered c
1910
1935
  const actionToAdd = actions_1.ActionEngineServer.Instance.Actions.find(a => a.ID === actionId);
1911
1936
  if (actionToAdd) {
1912
1937
  actions.push(actionToAdd);
1938
+ if (change.actionLimits?.[actionId] != null) {
1939
+ dynamicLimits[actionId] = change.actionLimits[actionId];
1940
+ }
1913
1941
  }
1914
1942
  else {
1915
1943
  (0, core_1.LogStatus)(`Action with ID '${actionId}' not found in ActionEngineServer - skipping add`);
@@ -1921,7 +1949,7 @@ The context is now within limits. Please retry your request with the recovered c
1921
1949
  actions = actions.filter(a => !change.actionIds.includes(a.ID));
1922
1950
  }
1923
1951
  }
1924
- return actions;
1952
+ return { actions, dynamicLimits };
1925
1953
  }
1926
1954
  filterActionChangesForSubAgent(actionChanges) {
1927
1955
  if (!actionChanges?.length) {
@@ -3417,18 +3445,22 @@ The context is now within limits. Please retry your request with the recovered c
3417
3445
  return null;
3418
3446
  }
3419
3447
  validateActionInAgent(actionName) {
3420
- const aa = aiengine_1.AIEngine.Instance.AgentActions.filter(aa => aa.AgentID === this._agentRun.AgentID);
3421
- let action = aa.filter(a => a.Agent?.trim().toLowerCase() === actionName.trim().toLowerCase());
3422
- if (!action) {
3423
- const partialAction = aa.filter(a => a.Agent?.trim().toLowerCase().includes(actionName.trim().toLowerCase() || ''));
3424
- if (partialAction.length > 1) {
3425
- return `Ambiguous action '${actionName}' specified`;
3426
- }
3427
- else if (partialAction.length === 0) {
3428
- return `No action '${actionName}' found`;
3429
- }
3448
+ const effectiveActions = this.getEffectiveActionsForValidation(this._agentRun.AgentID);
3449
+ const normalizedName = actionName.trim().toLowerCase();
3450
+ const exactMatch = effectiveActions.find(a => a.Name.trim().toLowerCase() === normalizedName);
3451
+ if (exactMatch) {
3452
+ return null;
3453
+ }
3454
+ const partialMatches = effectiveActions.filter(a => a.Name.trim().toLowerCase().includes(normalizedName));
3455
+ if (partialMatches.length === 1) {
3456
+ return null;
3457
+ }
3458
+ else if (partialMatches.length > 1) {
3459
+ return `Ambiguous action '${actionName}' specified. Matches: ${partialMatches.map(a => a.Name).join(', ')}`;
3460
+ }
3461
+ else {
3462
+ return `No action '${actionName}' found. Available: ${effectiveActions.map(a => a.Name).join(', ')}`;
3430
3463
  }
3431
- return null;
3432
3464
  }
3433
3465
  validateSubAgentInAgent(subAgentName) {
3434
3466
  const relatedAgents = aiengine_1.AIEngine.Instance.AgentRelationships.filter(ar => ar.AgentID === this._agentRun.AgentID);
@@ -3622,22 +3654,23 @@ The context is now within limits. Please retry your request with the recovered c
3622
3654
  });
3623
3655
  }
3624
3656
  findAgentActionForLoop(actionName, agentId, agentName, params) {
3625
- const agentActions = aiengine_1.AIEngine.Instance.AgentActions.filter(aa => aa.AgentID === agentId && aa.Status === 'Active');
3626
- let matched = agentActions.find(aa => aa.Action.trim().toLowerCase() === actionName.trim().toLowerCase());
3627
- if (!matched) {
3628
- const containsMatches = agentActions.filter(aa => aa.Action.trim().toLowerCase().includes(actionName.trim().toLowerCase()));
3657
+ const effectiveActions = this.getEffectiveActionsForValidation(agentId);
3658
+ const normalizedName = actionName.trim().toLowerCase();
3659
+ let matchedAction = effectiveActions.find(a => a.Name.trim().toLowerCase() === normalizedName);
3660
+ if (!matchedAction) {
3661
+ const containsMatches = effectiveActions.filter(a => a.Name.trim().toLowerCase().includes(normalizedName));
3629
3662
  if (containsMatches.length === 1) {
3630
- matched = containsMatches[0];
3631
- this.logStatus(`Action fuzzy matched: '${actionName}' → '${matched.Action}'`, true, params);
3663
+ matchedAction = containsMatches[0];
3664
+ this.logStatus(`Action fuzzy matched: '${actionName}' → '${matchedAction.Name}'`, true, params);
3632
3665
  }
3633
3666
  else if (containsMatches.length > 1) {
3634
- throw new Error(`Ambiguous action '${actionName}'. Matches: ${containsMatches.map(a => a.Action).join(', ')}`);
3667
+ throw new Error(`Ambiguous action '${actionName}'. Matches: ${containsMatches.map(a => a.Name).join(', ')}`);
3635
3668
  }
3636
3669
  else {
3637
- throw new Error(`Action '${actionName}' not found for agent '${agentName}'`);
3670
+ throw new Error(`Action '${actionName}' not found for agent '${agentName}'. Available: ${effectiveActions.map(a => a.Name).join(', ')}`);
3638
3671
  }
3639
3672
  }
3640
- return matched;
3673
+ return { Action: matchedAction.Name };
3641
3674
  }
3642
3675
  createFailedStep(errorMessage, previousDecision) {
3643
3676
  return {