@memberjunction/ai-agents 3.4.0 → 4.0.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.
Files changed (97) hide show
  1. package/dist/AgentDataPreloader.d.ts +117 -1
  2. package/dist/AgentDataPreloader.d.ts.map +1 -1
  3. package/dist/AgentDataPreloader.js +156 -58
  4. package/dist/AgentDataPreloader.js.map +1 -1
  5. package/dist/AgentRunner.d.ts +212 -0
  6. package/dist/AgentRunner.d.ts.map +1 -1
  7. package/dist/AgentRunner.js +354 -103
  8. package/dist/AgentRunner.js.map +1 -1
  9. package/dist/PayloadChangeAnalyzer.d.ts +68 -0
  10. package/dist/PayloadChangeAnalyzer.d.ts.map +1 -1
  11. package/dist/PayloadChangeAnalyzer.js +68 -32
  12. package/dist/PayloadChangeAnalyzer.js.map +1 -1
  13. package/dist/PayloadFeedbackManager.d.ts +57 -1
  14. package/dist/PayloadFeedbackManager.d.ts.map +1 -1
  15. package/dist/PayloadFeedbackManager.js +66 -21
  16. package/dist/PayloadFeedbackManager.js.map +1 -1
  17. package/dist/PayloadManager.d.ts +286 -1
  18. package/dist/PayloadManager.d.ts.map +1 -1
  19. package/dist/PayloadManager.js +423 -50
  20. package/dist/PayloadManager.js.map +1 -1
  21. package/dist/__tests__/action-changes.test.d.ts +13 -0
  22. package/dist/__tests__/action-changes.test.d.ts.map +1 -1
  23. package/dist/__tests__/action-changes.test.js +57 -4
  24. package/dist/__tests__/action-changes.test.js.map +1 -1
  25. package/dist/__tests__/agent-memory-features.test.d.ts +52 -0
  26. package/dist/__tests__/agent-memory-features.test.d.ts.map +1 -1
  27. package/dist/__tests__/agent-memory-features.test.js +96 -13
  28. package/dist/__tests__/agent-memory-features.test.js.map +1 -1
  29. package/dist/__tests__/agent-type-prompt-params.test.d.ts +12 -0
  30. package/dist/__tests__/agent-type-prompt-params.test.d.ts.map +1 -1
  31. package/dist/__tests__/agent-type-prompt-params.test.js +112 -20
  32. package/dist/__tests__/agent-type-prompt-params.test.js.map +1 -1
  33. package/dist/__tests__/chat-handling-option.test.d.ts +26 -0
  34. package/dist/__tests__/chat-handling-option.test.d.ts.map +1 -1
  35. package/dist/__tests__/chat-handling-option.test.js +41 -2
  36. package/dist/__tests__/chat-handling-option.test.js.map +1 -1
  37. package/dist/agent-context-injector.d.ts +114 -0
  38. package/dist/agent-context-injector.d.ts.map +1 -1
  39. package/dist/agent-context-injector.js +138 -19
  40. package/dist/agent-context-injector.js.map +1 -1
  41. package/dist/agent-types/base-agent-type.d.ts +354 -0
  42. package/dist/agent-types/base-agent-type.d.ts.map +1 -1
  43. package/dist/agent-types/base-agent-type.js +288 -17
  44. package/dist/agent-types/base-agent-type.js.map +1 -1
  45. package/dist/agent-types/flow-agent-type.d.ts +328 -2
  46. package/dist/agent-types/flow-agent-type.d.ts.map +1 -1
  47. package/dist/agent-types/flow-agent-type.js +503 -63
  48. package/dist/agent-types/flow-agent-type.js.map +1 -1
  49. package/dist/agent-types/index.d.ts +14 -3
  50. package/dist/agent-types/index.d.ts.map +1 -1
  51. package/dist/agent-types/index.js +14 -23
  52. package/dist/agent-types/index.js.map +1 -1
  53. package/dist/agent-types/loop-agent-prompt-params.d.ts +190 -0
  54. package/dist/agent-types/loop-agent-prompt-params.d.ts.map +1 -1
  55. package/dist/agent-types/loop-agent-prompt-params.js +23 -6
  56. package/dist/agent-types/loop-agent-prompt-params.js.map +1 -1
  57. package/dist/agent-types/loop-agent-response-type.d.ts +62 -0
  58. package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
  59. package/dist/agent-types/loop-agent-response-type.js +3 -2
  60. package/dist/agent-types/loop-agent-response-type.js.map +1 -1
  61. package/dist/agent-types/loop-agent-type.d.ts +139 -2
  62. package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
  63. package/dist/agent-types/loop-agent-type.js +207 -35
  64. package/dist/agent-types/loop-agent-type.js.map +1 -1
  65. package/dist/base-agent.d.ts +1344 -1
  66. package/dist/base-agent.d.ts.map +1 -1
  67. package/dist/base-agent.js +2282 -211
  68. package/dist/base-agent.js.map +1 -1
  69. package/dist/index.d.ts +24 -14
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +25 -35
  72. package/dist/index.js.map +1 -1
  73. package/dist/memory-cleanup-agent.d.ts +53 -1
  74. package/dist/memory-cleanup-agent.d.ts.map +1 -1
  75. package/dist/memory-cleanup-agent.js +89 -21
  76. package/dist/memory-cleanup-agent.js.map +1 -1
  77. package/dist/memory-manager-agent.d.ts +61 -1
  78. package/dist/memory-manager-agent.d.ts.map +1 -1
  79. package/dist/memory-manager-agent.js +260 -116
  80. package/dist/memory-manager-agent.js.map +1 -1
  81. package/dist/services/AgentEmbeddingService.d.ts +16 -0
  82. package/dist/services/AgentEmbeddingService.d.ts.map +1 -0
  83. package/dist/services/AgentEmbeddingService.js +158 -0
  84. package/dist/services/AgentEmbeddingService.js.map +1 -0
  85. package/dist/types/AgentMatchResult.d.ts +18 -0
  86. package/dist/types/AgentMatchResult.d.ts.map +1 -0
  87. package/dist/types/AgentMatchResult.js +3 -0
  88. package/dist/types/AgentMatchResult.js.map +1 -0
  89. package/dist/types/payload-operations.d.ts +51 -0
  90. package/dist/types/payload-operations.d.ts.map +1 -1
  91. package/dist/types/payload-operations.js +54 -15
  92. package/dist/types/payload-operations.js.map +1 -1
  93. package/dist/utils/ConversationMessageResolver.d.ts +79 -1
  94. package/dist/utils/ConversationMessageResolver.d.ts.map +1 -1
  95. package/dist/utils/ConversationMessageResolver.js +99 -9
  96. package/dist/utils/ConversationMessageResolver.js.map +1 -1
  97. package/package.json +20 -19
@@ -1,23 +1,160 @@
1
- import { BaseAgentType } from './base-agent-type';
1
+ /**
2
+ * @fileoverview Implementation of the Loop Agent Type for iterative task execution.
3
+ *
4
+ * The LoopAgentType enables agents to operate in a continuous loop, making decisions
5
+ * about task completion and next steps based on the current state. It parses structured
6
+ * JSON responses from the AI model and translates them into BaseAgentNextStep directives.
7
+ *
8
+ * @module @memberjunction/ai-agents
9
+ * @author MemberJunction.com
10
+ * @since 2.49.0
11
+ */
12
+ import { BaseAgentType } from './base-agent-type.js';
2
13
  import { AIPromptRunResult, BaseAgentNextStep, AIPromptParams, ExecuteAgentParams, AgentConfiguration, AgentAction } from '@memberjunction/ai-core-plus';
3
14
  import { AIPromptEntityExtended } from '@memberjunction/ai-core-plus';
15
+ /**
16
+ * Implementation of the Loop Agent Type pattern.
17
+ *
18
+ * This agent type enables iterative execution where the agent continues
19
+ * processing until a task is marked complete. It supports:
20
+ * - Task completion detection
21
+ * - Sub-agent delegation
22
+ * - Action execution
23
+ * - Progress tracking
24
+ * - Error handling
25
+ * - Result accumulation across iterations
26
+ *
27
+ * @class LoopAgentType
28
+ * @extends BaseAgentType
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // The agent will execute in a loop until taskComplete is true
33
+ * const loopAgent = new LoopAgentType();
34
+ * const nextStep = await loopAgent.DetermineNextStep(promptResult);
35
+ *
36
+ * switch (nextStep.step) {
37
+ * case 'success':
38
+ * console.log('Task completed:', nextStep.payload);
39
+ * break;
40
+ * case 'sub-agent':
41
+ * console.log('Delegating to:', nextStep.subAgentName);
42
+ * break;
43
+ * case 'action':
44
+ * console.log('Executing action:', nextStep.actionName);
45
+ * break;
46
+ * }
47
+ * ```
48
+ */
4
49
  export declare class LoopAgentType extends BaseAgentType {
5
50
  private _evaluator;
6
51
  InitializeAgentTypeState<ATS = any, P = any>(params: ExecuteAgentParams<any, P>): Promise<ATS>;
52
+ /**
53
+ * Determines the next step based on the structured response from the AI model.
54
+ *
55
+ * This method parses the JSON response from the loop agent prompt and translates
56
+ * it into appropriate BaseAgentNextStep directives. It handles task completion,
57
+ * sub-agent delegation, action execution, and error conditions.
58
+ *
59
+ * @param {AIPromptRunResult} promptResult - The result from executing the agent's prompt
60
+ * @returns {Promise<BaseAgentNextStep>} The next step to take in the agent execution
61
+ *
62
+ * @throws {Error} Implicitly through failed parsing, but returns failed step instead
63
+ */
7
64
  DetermineNextStep<P = any, ATS = any>(promptResult: AIPromptRunResult | null, params: ExecuteAgentParams<any, P>, payload: P, agentTypeState: ATS): Promise<BaseAgentNextStep<P>>;
65
+ /**
66
+ * Validates that the response conforms to the expected LoopAgentResponse structure.
67
+ *
68
+ * @param {any} response - The response to validate
69
+ * @returns {boolean} True if the response is valid, false otherwise
70
+ *
71
+ * @protected
72
+ */
8
73
  protected isValidLoopResponse(simpleResponse: unknown): {
9
74
  success: boolean;
10
75
  message?: string;
11
76
  };
77
+ /**
78
+ * Injects a payload into the prompt parameters.
79
+ * For LoopAgentType, this could be used to inject previous loop results or context.
80
+ *
81
+ * @param {T} payload - The payload to inject
82
+ * @param {AIPromptParams} prompt - The prompt parameters to update
83
+ * @param {object} agentInfo - Agent identification info (unused by LoopAgentType)
84
+ */
12
85
  InjectPayload<T = any, ATS = any>(payload: T, agentTypeState: ATS, prompt: AIPromptParams, agentInfo: {
13
86
  agentId: string;
14
87
  agentRunId?: string;
15
88
  }): Promise<void>;
89
+ /**
90
+ * Determines the initial step for loop agent types.
91
+ *
92
+ * Loop agents always start with a prompt execution to determine the initial actions.
93
+ *
94
+ * @param {ExecuteAgentParams} params - The full execution parameters
95
+ * @returns {Promise<BaseAgentNextStep<P> | null>} Always returns null to use default behavior
96
+ *
97
+ * @override
98
+ * @since 2.76.0
99
+ */
16
100
  DetermineInitialStep<P = any>(params: ExecuteAgentParams<P>): Promise<BaseAgentNextStep<P> | null>;
101
+ /**
102
+ * Pre-processes steps for loop agent types.
103
+ *
104
+ * Loop agents use the default next step behavior which executes the prompt again.
105
+ *
106
+ * @param {ExecuteAgentParams} params - The full execution parameters
107
+ * @param {BaseAgentNextStep} step - The step that needs to be preprocessed
108
+ * @returns {Promise<BaseAgentNextStep<P> | null>} Always returns null to use default behavior
109
+ *
110
+ * @override
111
+ * @since 2.76.0
112
+ */
17
113
  PreProcessNextStep<P = any, ATS = any>(params: ExecuteAgentParams<P>, step: BaseAgentNextStep<P>, payload: P, agentTypeState: ATS): Promise<BaseAgentNextStep<P> | null>;
114
+ /**
115
+ * Gets the prompt to use for a specific step.
116
+ * Loop agents always use the default prompt from configuration.
117
+ *
118
+ * @param {ExecuteAgentParams} params - The execution parameters (unused)
119
+ * @param {AgentConfiguration} config - The loaded agent configuration
120
+ * @param {BaseAgentNextStep | null} previousDecision - The previous step decision (unused)
121
+ * @returns {Promise<AIPromptEntityExtended | null>} Returns config.childPrompt
122
+ *
123
+ * @override
124
+ * @since 2.76.0
125
+ */
18
126
  GetPromptForStep<P = any, ATS = any>(params: ExecuteAgentParams, config: AgentConfiguration, payload: P, agentTypeState: ATS, previousDecision?: BaseAgentNextStep<P> | null): Promise<AIPromptEntityExtended | null>;
127
+ /**
128
+ * Pre-processes action parameters to resolve conversation references.
129
+ *
130
+ * Loop agents get action parameters directly from the LLM's JSON response.
131
+ * This method resolves any "conversation.*" references in those parameters
132
+ * before the actions are executed.
133
+ *
134
+ * @param {AgentAction[]} actions - The actions that will be executed (modified in place)
135
+ * @param {P} currentPayload - The current payload
136
+ * @param {ATS} agentTypeState - The agent type state
137
+ * @param {BaseAgentNextStep<P>} currentStep - The current step being executed
138
+ * @param {ExecuteAgentParams<P>} params - The execution parameters with conversation messages
139
+ *
140
+ * @returns {Promise<void>} Actions are modified in place
141
+ *
142
+ * @override
143
+ * @since 2.120.0
144
+ */
19
145
  PreProcessActionStep<P = any, ATS = any>(actions: AgentAction[], currentPayload: P, agentTypeState: ATS, currentStep: BaseAgentNextStep<P>, params?: ExecuteAgentParams<P>): Promise<void>;
146
+ /**
147
+ * Recursively resolves conversation references in action parameters.
148
+ *
149
+ * Handles nested objects and arrays, resolving any string values that start
150
+ * with "conversation." using the ConversationMessageResolver.
151
+ *
152
+ * @param {unknown} value - The value to resolve (can be object, array, string, or primitive)
153
+ * @param {ExecuteAgentParams} params - The execution parameters with conversation messages
154
+ * @returns {unknown} The resolved value
155
+ *
156
+ * @private
157
+ */
20
158
  private resolveConversationReferences;
21
159
  }
22
- export declare function LoadLoopAgentType(): void;
23
160
  //# sourceMappingURL=loop-agent-type.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loop-agent-type.d.ts","sourceRoot":"","sources":["../../src/agent-types/loop-agent-type.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEzJ,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAsCtE,qBACa,aAAc,SAAQ,aAAa;IAC5C,OAAO,CAAC,UAAU,CAAiC;IAEtC,wBAAwB,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAkB9F,iBAAiB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAC7C,YAAY,EAAE,iBAAiB,GAAG,IAAI,EACtC,MAAM,EAAE,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,EAClC,OAAO,EAAE,CAAC,EACV,cAAc,EAAE,GAAG,GACpB,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAkJhC,SAAS,CAAC,mBAAmB,CAAC,cAAc,EAAE,OAAO,GAAG;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC;IA2I/E,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EACzC,OAAO,EAAE,CAAC,EACV,cAAc,EAAE,GAAG,EACnB,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GACpD,OAAO,CAAC,IAAI,CAAC;IAoBH,oBAAoB,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAiBlG,kBAAkB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAC9C,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAC7B,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAC1B,OAAO,EAAE,CAAC,EACV,cAAc,EAAE,GAAG,GACpB,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAiB1B,gBAAgB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAC5C,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,CAAC,EACV,cAAc,EAAE,GAAG,EACnB,gBAAgB,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,GAC/C,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAuB5B,oBAAoB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAChD,OAAO,EAAE,WAAW,EAAE,EACtB,cAAc,EAAE,CAAC,EACjB,cAAc,EAAE,GAAG,EACnB,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC,EACjC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC;IAqBhB,OAAO,CAAC,6BAA6B;CAyBxC;AAKD,wBAAgB,iBAAiB,SAEhC"}
1
+ {"version":3,"file":"loop-agent-type.d.ts","sourceRoot":"","sources":["../../src/agent-types/loop-agent-type.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEzJ,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAItE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBACa,aAAc,SAAQ,aAAa;IAC5C,OAAO,CAAC,UAAU,CAAiC;IAEtC,wBAAwB,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAM3G;;;;;;;;;;;OAWG;IACU,iBAAiB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAC7C,YAAY,EAAE,iBAAiB,GAAG,IAAI,EACtC,MAAM,EAAE,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,EAClC,OAAO,EAAE,CAAC,EACV,cAAc,EAAE,GAAG,GACpB,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IA0IhC;;;;;;;OAOG;IACH,SAAS,CAAC,mBAAmB,CAAC,cAAc,EAAE,OAAO,GAAG;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC;IAmI5F;;;;;;;OAOG;IACU,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EACzC,OAAO,EAAE,CAAC,EACV,cAAc,EAAE,GAAG,EACnB,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GACpD,OAAO,CAAC,IAAI,CAAC;IAShB;;;;;;;;;;OAUG;IACU,oBAAoB,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAK/G;;;;;;;;;;;OAWG;IACU,kBAAkB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAC9C,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAC7B,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAC1B,OAAO,EAAE,CAAC,EACV,cAAc,EAAE,GAAG,GACpB,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAKvC;;;;;;;;;;;OAWG;IACU,gBAAgB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAC5C,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,CAAC,EACV,cAAc,EAAE,GAAG,EACnB,gBAAgB,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,GAC/C,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAKzC;;;;;;;;;;;;;;;;;OAiBG;IACU,oBAAoB,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAChD,OAAO,EAAE,WAAW,EAAE,EACtB,cAAc,EAAE,CAAC,EACjB,cAAc,EAAE,GAAG,EACnB,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC,EACjC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC;IAShB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,6BAA6B;CAyBxC"}
@@ -1,50 +1,111 @@
1
- "use strict";
1
+ /**
2
+ * @fileoverview Implementation of the Loop Agent Type for iterative task execution.
3
+ *
4
+ * The LoopAgentType enables agents to operate in a continuous loop, making decisions
5
+ * about task completion and next steps based on the current state. It parses structured
6
+ * JSON responses from the AI model and translates them into BaseAgentNextStep directives.
7
+ *
8
+ * @module @memberjunction/ai-agents
9
+ * @author MemberJunction.com
10
+ * @since 2.49.0
11
+ */
2
12
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
13
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
14
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
15
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
16
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
17
  };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.LoadLoopAgentType = exports.LoopAgentType = void 0;
10
- const global_1 = require("@memberjunction/global");
11
- const base_agent_type_1 = require("./base-agent-type");
12
- const core_1 = require("@memberjunction/core");
13
- const ConversationMessageResolver_1 = require("../utils/ConversationMessageResolver");
14
- let LoopAgentType = class LoopAgentType extends base_agent_type_1.BaseAgentType {
18
+ import { RegisterClass, SafeExpressionEvaluator } from '@memberjunction/global';
19
+ import { BaseAgentType } from './base-agent-type.js';
20
+ import { LogError, LogStatusEx } from '@memberjunction/core';
21
+ import { ConversationMessageResolver } from '../utils/ConversationMessageResolver.js';
22
+ /**
23
+ * Implementation of the Loop Agent Type pattern.
24
+ *
25
+ * This agent type enables iterative execution where the agent continues
26
+ * processing until a task is marked complete. It supports:
27
+ * - Task completion detection
28
+ * - Sub-agent delegation
29
+ * - Action execution
30
+ * - Progress tracking
31
+ * - Error handling
32
+ * - Result accumulation across iterations
33
+ *
34
+ * @class LoopAgentType
35
+ * @extends BaseAgentType
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // The agent will execute in a loop until taskComplete is true
40
+ * const loopAgent = new LoopAgentType();
41
+ * const nextStep = await loopAgent.DetermineNextStep(promptResult);
42
+ *
43
+ * switch (nextStep.step) {
44
+ * case 'success':
45
+ * console.log('Task completed:', nextStep.payload);
46
+ * break;
47
+ * case 'sub-agent':
48
+ * console.log('Delegating to:', nextStep.subAgentName);
49
+ * break;
50
+ * case 'action':
51
+ * console.log('Executing action:', nextStep.actionName);
52
+ * break;
53
+ * }
54
+ * ```
55
+ */
56
+ let LoopAgentType = class LoopAgentType extends BaseAgentType {
15
57
  constructor() {
16
58
  super(...arguments);
17
- this._evaluator = new global_1.SafeExpressionEvaluator();
59
+ this._evaluator = new SafeExpressionEvaluator();
18
60
  }
19
61
  async InitializeAgentTypeState(params) {
20
- return {};
62
+ // Loop agents do not require agent-type specific state initialization
63
+ // but can be extended in the future if needed
64
+ return {}; // Return an empty object for now
21
65
  }
66
+ /**
67
+ * Determines the next step based on the structured response from the AI model.
68
+ *
69
+ * This method parses the JSON response from the loop agent prompt and translates
70
+ * it into appropriate BaseAgentNextStep directives. It handles task completion,
71
+ * sub-agent delegation, action execution, and error conditions.
72
+ *
73
+ * @param {AIPromptRunResult} promptResult - The result from executing the agent's prompt
74
+ * @returns {Promise<BaseAgentNextStep>} The next step to take in the agent execution
75
+ *
76
+ * @throws {Error} Implicitly through failed parsing, but returns failed step instead
77
+ */
22
78
  async DetermineNextStep(promptResult, params, payload, agentTypeState) {
23
79
  try {
80
+ // Ensure we have a successful result
24
81
  if (!promptResult.success || !promptResult.result) {
25
82
  return this.createNextStep('Failed', {
26
83
  errorMessage: promptResult.errorMessage || 'Prompt execution failed'
27
84
  });
28
85
  }
86
+ // Parse the response using the base class utility
29
87
  const response = this.parseJSONResponse(promptResult);
30
88
  if (!response) {
31
89
  return this.createRetryStep('Failed to parse JSON response');
32
90
  }
91
+ // Validate the response structure
33
92
  const validationResult = this.isValidLoopResponse(response);
34
93
  if (!validationResult.success) {
35
94
  return this.createRetryStep(validationResult.message);
36
95
  }
96
+ // Check for Chat nextStep BEFORE checking taskComplete
97
+ // This allows agents to ask for user clarification even when taskComplete=true
37
98
  if (response.nextStep?.type === 'Chat') {
38
99
  if (!response.message) {
39
100
  return this.createRetryStep('Chat type specified but no user message provided');
40
101
  }
41
- (0, core_1.LogStatusEx)({
102
+ LogStatusEx({
42
103
  message: '💬 Loop Agent: Requesting user interaction. Message: ' + response.message,
43
104
  verboseOnly: true
44
105
  });
45
106
  return this.createNextStep('Chat', {
46
107
  message: response.message,
47
- terminate: true,
108
+ terminate: true, // Chat always terminates to return to user
48
109
  payloadChangeRequest: response.payloadChangeRequest,
49
110
  responseForm: response.responseForm,
50
111
  actionableCommands: response.actionableCommands,
@@ -53,8 +114,9 @@ let LoopAgentType = class LoopAgentType extends base_agent_type_1.BaseAgentType
53
114
  confidence: response.confidence
54
115
  });
55
116
  }
117
+ // Check if task is complete
56
118
  if (response.taskComplete) {
57
- (0, core_1.LogStatusEx)({
119
+ LogStatusEx({
58
120
  message: '✅ Loop Agent: Task completed successfully. Message: ' + response.message,
59
121
  verboseOnly: true
60
122
  });
@@ -68,9 +130,11 @@ let LoopAgentType = class LoopAgentType extends base_agent_type_1.BaseAgentType
68
130
  automaticCommands: response.automaticCommands
69
131
  });
70
132
  }
133
+ // Handle when nextStep is not provided but task is not complete
71
134
  if (!response.nextStep) {
72
135
  return this.createRetryStep('Task not complete but no next step provided');
73
136
  }
137
+ // Determine next step based on type
74
138
  const retVal = {
75
139
  payloadChangeRequest: response.payloadChangeRequest,
76
140
  terminate: response.taskComplete,
@@ -115,6 +179,7 @@ let LoopAgentType = class LoopAgentType extends base_agent_type_1.BaseAgentType
115
179
  retVal.errorMessage = 'ForEach type specified but forEach details missing';
116
180
  }
117
181
  else {
182
+ // Return ForEach decision for BaseAgent to execute in next iteration
118
183
  retVal.step = 'ForEach';
119
184
  retVal.forEach = response.nextStep.forEach;
120
185
  }
@@ -125,6 +190,7 @@ let LoopAgentType = class LoopAgentType extends base_agent_type_1.BaseAgentType
125
190
  retVal.errorMessage = 'While type specified but while details missing';
126
191
  }
127
192
  else {
193
+ // Return While decision for BaseAgent to execute in next iteration
128
194
  retVal.step = 'While';
129
195
  retVal.while = response.nextStep.while;
130
196
  }
@@ -137,41 +203,63 @@ let LoopAgentType = class LoopAgentType extends base_agent_type_1.BaseAgentType
137
203
  return retVal;
138
204
  }
139
205
  catch (error) {
140
- (0, core_1.LogError)(`Error in LoopAgentType.DetermineNextStep: ${error.message}`);
206
+ LogError(`Error in LoopAgentType.DetermineNextStep: ${error.message}`);
141
207
  return this.createRetryStep(`Failed to parse loop agent response: ${error.message}`);
142
208
  }
143
209
  }
210
+ /**
211
+ * Validates that the response conforms to the expected LoopAgentResponse structure.
212
+ *
213
+ * @param {any} response - The response to validate
214
+ * @returns {boolean} True if the response is valid, false otherwise
215
+ *
216
+ * @protected
217
+ */
144
218
  isValidLoopResponse(simpleResponse) {
219
+ // Check required fields, first cast the simpleResponse to LoopAgentResponse
220
+ // so we get the benefit of TypeScript's type checking below in this method
145
221
  const response = simpleResponse;
146
222
  if (typeof response !== 'object' || response === null) {
147
223
  return { success: false, message: 'Invalid response format' };
148
224
  }
149
225
  if (!response.taskComplete) {
226
+ // if not provided, default to false to make processing work
150
227
  response.taskComplete = false;
151
228
  }
152
229
  if (typeof response.taskComplete !== 'boolean') {
153
- (0, core_1.LogError)('LoopAgentResponse missing required field: taskComplete');
230
+ LogError('LoopAgentResponse missing required field: taskComplete');
154
231
  return { success: false, message: 'Missing required field: taskComplete' };
155
232
  }
233
+ // nextStep is optional when taskComplete is true
156
234
  if (!response.taskComplete && !response.nextStep) {
157
235
  if (response.message?.trim().length > 0 ||
158
236
  (typeof response.reasoning === 'string' &&
159
237
  response.reasoning?.trim().length > 0)) {
238
+ // in this situation we have a message or reasoning coming back but a malformed response
239
+ // so we can consider it a chat response becuase it is trying to communicate
240
+ // something back, better to provide that back than discarding it entirely
241
+ // possibly we will make this configurable in the future
160
242
  response.nextStep = {
161
243
  type: 'Chat'
162
244
  };
163
245
  if (response.message?.trim().length === 0) {
246
+ // this means reasoning was provided but no message, copy reasoning to message
247
+ // as you shouldn't ever have that but we can handle it gracefully
164
248
  response.message = response.reasoning;
165
249
  }
166
250
  }
167
251
  else if (response.payloadChangeRequest?.newElements ||
168
252
  response.payloadChangeRequest?.updateElements ||
169
253
  response.payloadChangeRequest?.removeElements) {
254
+ // the AI forgot to mark taskComplete as true but provided a payloadChangeRequest
255
+ // with changes to the elements, so we can consider this a valid response
256
+ // and we can consider it attempting to have a taskComplete = true
257
+ // and validation will catch if it didn't actually complete and drive a retry
170
258
  response.message = 'taskComplete set to true automatically due to payloadChangeRequest and no nextStep provided by AI';
171
259
  response.taskComplete = true;
172
260
  }
173
261
  else {
174
- (0, core_1.LogError)('LoopAgentResponse requires nextStep when taskComplete is false');
262
+ LogError('LoopAgentResponse requires nextStep when taskComplete is false');
175
263
  return {
176
264
  success: false,
177
265
  message: `Missing nextStep is a required field when taskComplete is false
@@ -184,98 +272,184 @@ let LoopAgentType = class LoopAgentType extends base_agent_type_1.BaseAgentType
184
272
  };
185
273
  }
186
274
  }
275
+ // Validate nextStep structure if present
187
276
  if (response.nextStep) {
188
277
  const validStepTypes = ['actions', 'sub-agent', 'chat', 'foreach', 'while'];
189
278
  let lcaseType = response.nextStep.type?.toLowerCase().trim();
279
+ // allow the AI to mess up the case, but we need to validate it
280
+ // be smart/lenient about missing types. if type is missing but we have a nextStep.subAgent, default to sub-agent and if type is missing and we have nextStep.actions, default to actions
190
281
  if (!lcaseType && response.nextStep.subAgent) {
191
- response.nextStep.type = 'Sub-Agent';
282
+ response.nextStep.type = 'Sub-Agent'; // update the data structure to have the correct type
192
283
  lcaseType = 'sub-agent';
193
284
  }
194
285
  else if (!lcaseType && response.nextStep.actions && response.nextStep.actions.length > 0) {
195
- response.nextStep.type = 'Actions';
286
+ response.nextStep.type = 'Actions'; // update the data structure to have the correct type
196
287
  lcaseType = 'actions';
197
288
  }
198
289
  else if (!lcaseType && response.nextStep.forEach) {
199
- response.nextStep.type = 'ForEach';
290
+ response.nextStep.type = 'ForEach'; // update the data structure to have the correct type
200
291
  lcaseType = 'foreach';
201
292
  }
202
293
  else if (!lcaseType && response.nextStep.while) {
203
- response.nextStep.type = 'While';
294
+ response.nextStep.type = 'While'; // update the data structure to have the correct type
204
295
  lcaseType = 'while';
205
296
  }
206
297
  if (!validStepTypes.includes(lcaseType)) {
207
298
  const message = `LoopAgentResponse has invalid nextStep.type: ${response.nextStep.type}`;
208
- (0, core_1.LogError)(message);
299
+ LogError(message);
209
300
  return { success: false, message };
210
301
  }
302
+ // Validate specific fields based on type
211
303
  if (lcaseType === 'actions' && !response.nextStep.actions) {
212
304
  const message = 'LoopAgentResponse requires actions array for action type';
213
- (0, core_1.LogError)(message);
305
+ LogError(message);
214
306
  return { success: false, message };
215
307
  }
216
308
  if (lcaseType === 'sub-agent' && !response.nextStep.subAgent) {
217
309
  const message = 'LoopAgentResponse requires subAgent object for sub-agent type';
218
- (0, core_1.LogError)(message);
310
+ LogError(message);
219
311
  return { success: false, message };
220
312
  }
221
313
  if (lcaseType === 'chat' && !response.message) {
314
+ // check to see if we have reasoning, if so, use that, otherwise we have to fail
222
315
  if (!response.reasoning || response.reasoning.trim().length === 0) {
223
316
  const message = 'LoopAgentResponse requires message for chat type';
224
- (0, core_1.LogError)(message);
317
+ LogError(message);
225
318
  return { success: false, message };
226
319
  }
227
320
  else {
321
+ // if we have reasoning, use that as the message
228
322
  response.message = response.reasoning;
229
323
  }
230
324
  }
231
325
  if (lcaseType === 'foreach' && !response.nextStep.forEach) {
232
326
  const message = 'LoopAgentResponse requires forEach object for ForEach type';
233
- (0, core_1.LogError)(message);
327
+ LogError(message);
234
328
  return { success: false, message };
235
329
  }
236
330
  if (lcaseType === 'while' && !response.nextStep.while) {
237
331
  const message = 'LoopAgentResponse requires while object for While type';
238
- (0, core_1.LogError)(message);
332
+ LogError(message);
239
333
  return { success: false, message };
240
334
  }
241
335
  }
242
336
  return { success: true };
243
337
  }
338
+ /**
339
+ * Injects a payload into the prompt parameters.
340
+ * For LoopAgentType, this could be used to inject previous loop results or context.
341
+ *
342
+ * @param {T} payload - The payload to inject
343
+ * @param {AIPromptParams} prompt - The prompt parameters to update
344
+ * @param {object} agentInfo - Agent identification info (unused by LoopAgentType)
345
+ */
244
346
  async InjectPayload(payload, agentTypeState, prompt, agentInfo) {
245
347
  if (!prompt)
246
348
  throw new Error('Prompt parameters are required for payload injection');
247
349
  if (!prompt.data)
248
350
  prompt.data = {};
249
- prompt.data[base_agent_type_1.BaseAgentType.CURRENT_PAYLOAD_PLACEHOLDER] = payload || {};
351
+ prompt.data[BaseAgentType.CURRENT_PAYLOAD_PLACEHOLDER] = payload || {};
250
352
  }
353
+ /**
354
+ * Determines the initial step for loop agent types.
355
+ *
356
+ * Loop agents always start with a prompt execution to determine the initial actions.
357
+ *
358
+ * @param {ExecuteAgentParams} params - The full execution parameters
359
+ * @returns {Promise<BaseAgentNextStep<P> | null>} Always returns null to use default behavior
360
+ *
361
+ * @override
362
+ * @since 2.76.0
363
+ */
251
364
  async DetermineInitialStep(params) {
365
+ // Loop agents always start with a prompt execution
252
366
  return null;
253
367
  }
368
+ /**
369
+ * Pre-processes steps for loop agent types.
370
+ *
371
+ * Loop agents use the default next step behavior which executes the prompt again.
372
+ *
373
+ * @param {ExecuteAgentParams} params - The full execution parameters
374
+ * @param {BaseAgentNextStep} step - The step that needs to be preprocessed
375
+ * @returns {Promise<BaseAgentNextStep<P> | null>} Always returns null to use default behavior
376
+ *
377
+ * @override
378
+ * @since 2.76.0
379
+ */
254
380
  async PreProcessNextStep(params, step, payload, agentTypeState) {
381
+ // Loop agents use default next step behavior (execute prompt)
255
382
  return null;
256
383
  }
384
+ /**
385
+ * Gets the prompt to use for a specific step.
386
+ * Loop agents always use the default prompt from configuration.
387
+ *
388
+ * @param {ExecuteAgentParams} params - The execution parameters (unused)
389
+ * @param {AgentConfiguration} config - The loaded agent configuration
390
+ * @param {BaseAgentNextStep | null} previousDecision - The previous step decision (unused)
391
+ * @returns {Promise<AIPromptEntityExtended | null>} Returns config.childPrompt
392
+ *
393
+ * @override
394
+ * @since 2.76.0
395
+ */
257
396
  async GetPromptForStep(params, config, payload, agentTypeState, previousDecision) {
397
+ // Loop agents always use the default prompt from configuration
258
398
  return config.childPrompt || null;
259
399
  }
400
+ /**
401
+ * Pre-processes action parameters to resolve conversation references.
402
+ *
403
+ * Loop agents get action parameters directly from the LLM's JSON response.
404
+ * This method resolves any "conversation.*" references in those parameters
405
+ * before the actions are executed.
406
+ *
407
+ * @param {AgentAction[]} actions - The actions that will be executed (modified in place)
408
+ * @param {P} currentPayload - The current payload
409
+ * @param {ATS} agentTypeState - The agent type state
410
+ * @param {BaseAgentNextStep<P>} currentStep - The current step being executed
411
+ * @param {ExecuteAgentParams<P>} params - The execution parameters with conversation messages
412
+ *
413
+ * @returns {Promise<void>} Actions are modified in place
414
+ *
415
+ * @override
416
+ * @since 2.120.0
417
+ */
260
418
  async PreProcessActionStep(actions, currentPayload, agentTypeState, currentStep, params) {
419
+ // Resolve conversation references in action parameters
261
420
  for (const action of actions) {
262
421
  if (action.params) {
263
422
  action.params = this.resolveConversationReferences(action.params, params);
264
423
  }
265
424
  }
266
425
  }
426
+ /**
427
+ * Recursively resolves conversation references in action parameters.
428
+ *
429
+ * Handles nested objects and arrays, resolving any string values that start
430
+ * with "conversation." using the ConversationMessageResolver.
431
+ *
432
+ * @param {unknown} value - The value to resolve (can be object, array, string, or primitive)
433
+ * @param {ExecuteAgentParams} params - The execution parameters with conversation messages
434
+ * @returns {unknown} The resolved value
435
+ *
436
+ * @private
437
+ */
267
438
  resolveConversationReferences(value, params) {
268
439
  if (typeof value === 'string') {
440
+ // Check if this is a conversation reference
269
441
  const trimmedValue = value.trim();
270
- if (ConversationMessageResolver_1.ConversationMessageResolver.isConversationReference(trimmedValue) && params?.conversationMessages) {
271
- return ConversationMessageResolver_1.ConversationMessageResolver.resolve(trimmedValue, params.conversationMessages);
442
+ if (ConversationMessageResolver.isConversationReference(trimmedValue) && params?.conversationMessages) {
443
+ return ConversationMessageResolver.resolve(trimmedValue, params.conversationMessages);
272
444
  }
273
445
  return value;
274
446
  }
275
447
  else if (Array.isArray(value)) {
448
+ // Recursively resolve array elements
276
449
  return value.map(item => this.resolveConversationReferences(item, params));
277
450
  }
278
451
  else if (value && typeof value === 'object') {
452
+ // Recursively resolve object properties
279
453
  const resolvedObj = {};
280
454
  for (const [key, val] of Object.entries(value)) {
281
455
  resolvedObj[key] = this.resolveConversationReferences(val, params);
@@ -283,15 +457,13 @@ let LoopAgentType = class LoopAgentType extends base_agent_type_1.BaseAgentType
283
457
  return resolvedObj;
284
458
  }
285
459
  else {
460
+ // Primitives (numbers, booleans, null, undefined) pass through
286
461
  return value;
287
462
  }
288
463
  }
289
464
  };
290
- exports.LoopAgentType = LoopAgentType;
291
- exports.LoopAgentType = LoopAgentType = __decorate([
292
- (0, global_1.RegisterClass)(base_agent_type_1.BaseAgentType, "LoopAgentType")
465
+ LoopAgentType = __decorate([
466
+ RegisterClass(BaseAgentType, "LoopAgentType")
293
467
  ], LoopAgentType);
294
- function LoadLoopAgentType() {
295
- }
296
- exports.LoadLoopAgentType = LoadLoopAgentType;
468
+ export { LoopAgentType };
297
469
  //# sourceMappingURL=loop-agent-type.js.map