@memberjunction/ai-agents 3.3.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.
- package/dist/AgentDataPreloader.d.ts +117 -1
- package/dist/AgentDataPreloader.d.ts.map +1 -1
- package/dist/AgentDataPreloader.js +156 -58
- package/dist/AgentDataPreloader.js.map +1 -1
- package/dist/AgentRunner.d.ts +212 -0
- package/dist/AgentRunner.d.ts.map +1 -1
- package/dist/AgentRunner.js +354 -103
- package/dist/AgentRunner.js.map +1 -1
- package/dist/PayloadChangeAnalyzer.d.ts +68 -0
- package/dist/PayloadChangeAnalyzer.d.ts.map +1 -1
- package/dist/PayloadChangeAnalyzer.js +68 -32
- package/dist/PayloadChangeAnalyzer.js.map +1 -1
- package/dist/PayloadFeedbackManager.d.ts +57 -1
- package/dist/PayloadFeedbackManager.d.ts.map +1 -1
- package/dist/PayloadFeedbackManager.js +66 -21
- package/dist/PayloadFeedbackManager.js.map +1 -1
- package/dist/PayloadManager.d.ts +286 -1
- package/dist/PayloadManager.d.ts.map +1 -1
- package/dist/PayloadManager.js +423 -50
- package/dist/PayloadManager.js.map +1 -1
- package/dist/__tests__/action-changes.test.d.ts +13 -0
- package/dist/__tests__/action-changes.test.d.ts.map +1 -1
- package/dist/__tests__/action-changes.test.js +57 -4
- package/dist/__tests__/action-changes.test.js.map +1 -1
- package/dist/__tests__/agent-memory-features.test.d.ts +52 -0
- package/dist/__tests__/agent-memory-features.test.d.ts.map +1 -1
- package/dist/__tests__/agent-memory-features.test.js +96 -13
- package/dist/__tests__/agent-memory-features.test.js.map +1 -1
- package/dist/__tests__/agent-type-prompt-params.test.d.ts +12 -0
- package/dist/__tests__/agent-type-prompt-params.test.d.ts.map +1 -1
- package/dist/__tests__/agent-type-prompt-params.test.js +112 -20
- package/dist/__tests__/agent-type-prompt-params.test.js.map +1 -1
- package/dist/__tests__/chat-handling-option.test.d.ts +26 -0
- package/dist/__tests__/chat-handling-option.test.d.ts.map +1 -1
- package/dist/__tests__/chat-handling-option.test.js +41 -2
- package/dist/__tests__/chat-handling-option.test.js.map +1 -1
- package/dist/agent-context-injector.d.ts +114 -0
- package/dist/agent-context-injector.d.ts.map +1 -1
- package/dist/agent-context-injector.js +138 -19
- package/dist/agent-context-injector.js.map +1 -1
- package/dist/agent-types/base-agent-type.d.ts +354 -0
- package/dist/agent-types/base-agent-type.d.ts.map +1 -1
- package/dist/agent-types/base-agent-type.js +288 -17
- package/dist/agent-types/base-agent-type.js.map +1 -1
- package/dist/agent-types/flow-agent-type.d.ts +328 -2
- package/dist/agent-types/flow-agent-type.d.ts.map +1 -1
- package/dist/agent-types/flow-agent-type.js +503 -63
- package/dist/agent-types/flow-agent-type.js.map +1 -1
- package/dist/agent-types/index.d.ts +14 -3
- package/dist/agent-types/index.d.ts.map +1 -1
- package/dist/agent-types/index.js +14 -23
- package/dist/agent-types/index.js.map +1 -1
- package/dist/agent-types/loop-agent-prompt-params.d.ts +190 -0
- package/dist/agent-types/loop-agent-prompt-params.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-prompt-params.js +23 -6
- package/dist/agent-types/loop-agent-prompt-params.js.map +1 -1
- package/dist/agent-types/loop-agent-response-type.d.ts +62 -0
- package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-response-type.js +3 -2
- package/dist/agent-types/loop-agent-response-type.js.map +1 -1
- package/dist/agent-types/loop-agent-type.d.ts +139 -2
- package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.js +207 -35
- package/dist/agent-types/loop-agent-type.js.map +1 -1
- package/dist/base-agent.d.ts +1344 -1
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +2282 -211
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +24 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -35
- package/dist/index.js.map +1 -1
- package/dist/memory-cleanup-agent.d.ts +53 -1
- package/dist/memory-cleanup-agent.d.ts.map +1 -1
- package/dist/memory-cleanup-agent.js +89 -21
- package/dist/memory-cleanup-agent.js.map +1 -1
- package/dist/memory-manager-agent.d.ts +61 -1
- package/dist/memory-manager-agent.d.ts.map +1 -1
- package/dist/memory-manager-agent.js +260 -116
- package/dist/memory-manager-agent.js.map +1 -1
- package/dist/services/AgentEmbeddingService.d.ts +16 -0
- package/dist/services/AgentEmbeddingService.d.ts.map +1 -0
- package/dist/services/AgentEmbeddingService.js +158 -0
- package/dist/services/AgentEmbeddingService.js.map +1 -0
- package/dist/types/AgentMatchResult.d.ts +18 -0
- package/dist/types/AgentMatchResult.d.ts.map +1 -0
- package/dist/types/AgentMatchResult.js +3 -0
- package/dist/types/AgentMatchResult.js.map +1 -0
- package/dist/types/payload-operations.d.ts +51 -0
- package/dist/types/payload-operations.d.ts.map +1 -1
- package/dist/types/payload-operations.js +54 -15
- package/dist/types/payload-operations.js.map +1 -1
- package/dist/utils/ConversationMessageResolver.d.ts +79 -1
- package/dist/utils/ConversationMessageResolver.d.ts.map +1 -1
- package/dist/utils/ConversationMessageResolver.js +99 -9
- package/dist/utils/ConversationMessageResolver.js.map +1 -1
- package/package.json +20 -19
|
@@ -1,23 +1,160 @@
|
|
|
1
|
-
|
|
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":"
|
|
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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
|
59
|
+
this._evaluator = new SafeExpressionEvaluator();
|
|
18
60
|
}
|
|
19
61
|
async InitializeAgentTypeState(params) {
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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[
|
|
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 (
|
|
271
|
-
return
|
|
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
|
-
|
|
291
|
-
|
|
292
|
-
(0, global_1.RegisterClass)(base_agent_type_1.BaseAgentType, "LoopAgentType")
|
|
465
|
+
LoopAgentType = __decorate([
|
|
466
|
+
RegisterClass(BaseAgentType, "LoopAgentType")
|
|
293
467
|
], LoopAgentType);
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
exports.LoadLoopAgentType = LoadLoopAgentType;
|
|
468
|
+
export { LoopAgentType };
|
|
297
469
|
//# sourceMappingURL=loop-agent-type.js.map
|