@minded-ai/mindedjs 2.0.0-beta1 → 2.0.1-beta-1

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 (146) hide show
  1. package/dist/agent.js +2 -2
  2. package/dist/agent.js.map +1 -1
  3. package/dist/browserTask/README.md +419 -0
  4. package/dist/browserTask/browserAgent.py +632 -0
  5. package/dist/browserTask/captcha_isolated.png +0 -0
  6. package/dist/browserTask/executeBrowserTask.ts +79 -0
  7. package/dist/browserTask/requirements.txt +8 -0
  8. package/dist/browserTask/setup.sh +144 -0
  9. package/dist/cli/index.js +0 -0
  10. package/dist/internalTools/retell.js +17 -7
  11. package/dist/internalTools/retell.js.map +1 -1
  12. package/dist/internalTools/sendPlaceholderMessage.js +17 -7
  13. package/dist/internalTools/sendPlaceholderMessage.js.map +1 -1
  14. package/dist/interrupts/BaseInterruptSessionManager.d.ts +1 -1
  15. package/dist/interrupts/BaseInterruptSessionManager.d.ts.map +1 -1
  16. package/dist/nodes/addPromptNode.d.ts.map +1 -1
  17. package/dist/nodes/addPromptNode.js +250 -93
  18. package/dist/nodes/addPromptNode.js.map +1 -1
  19. package/dist/playbooks/playbooks.d.ts +1 -1
  20. package/dist/playbooks/playbooks.d.ts.map +1 -1
  21. package/dist/playbooks/playbooks.js +1 -1
  22. package/dist/playbooks/playbooks.js.map +1 -1
  23. package/dist/utils/extractStateMemoryResponse.d.ts +4 -0
  24. package/dist/utils/extractStateMemoryResponse.d.ts.map +1 -1
  25. package/dist/utils/extractStateMemoryResponse.js +89 -87
  26. package/dist/utils/extractStateMemoryResponse.js.map +1 -1
  27. package/docs/low-code-editor/tools.md +37 -43
  28. package/docs/sdk/events.md +40 -38
  29. package/docs/sdk/memory.md +27 -24
  30. package/package.json +1 -1
  31. package/src/agent.ts +2 -2
  32. package/src/interrupts/BaseInterruptSessionManager.ts +1 -1
  33. package/src/nodes/addPromptNode.ts +283 -94
  34. package/src/playbooks/playbooks.ts +2 -2
  35. package/dist/guidelines/guidelinesManager.d.ts +0 -37
  36. package/dist/guidelines/guidelinesManager.d.ts.map +0 -1
  37. package/dist/guidelines/guidelinesManager.js +0 -172
  38. package/dist/guidelines/guidelinesManager.js.map +0 -1
  39. package/dist/internalTools/documentExtraction.d.ts +0 -69
  40. package/dist/internalTools/documentExtraction.d.ts.map +0 -1
  41. package/dist/internalTools/documentExtraction.js +0 -65
  42. package/dist/internalTools/documentExtraction.js.map +0 -1
  43. package/dist/internalTools/managedDocumentParser/managedDocumentParser.d.ts +0 -10
  44. package/dist/internalTools/managedDocumentParser/managedDocumentParser.d.ts.map +0 -1
  45. package/dist/internalTools/managedDocumentParser/managedDocumentParser.js +0 -80
  46. package/dist/internalTools/managedDocumentParser/managedDocumentParser.js.map +0 -1
  47. package/dist/pii-gateway/gateway.d.ts +0 -17
  48. package/dist/pii-gateway/gateway.d.ts.map +0 -1
  49. package/dist/pii-gateway/gateway.js +0 -77
  50. package/dist/pii-gateway/gateway.js.map +0 -1
  51. package/dist/pii-gateway/index.d.ts +0 -4
  52. package/dist/pii-gateway/index.d.ts.map +0 -1
  53. package/dist/pii-gateway/index.js +0 -14
  54. package/dist/pii-gateway/index.js.map +0 -1
  55. package/dist/pii-gateway/proxy.d.ts +0 -80
  56. package/dist/pii-gateway/proxy.d.ts.map +0 -1
  57. package/dist/pii-gateway/proxy.js +0 -106
  58. package/dist/pii-gateway/proxy.js.map +0 -1
  59. package/dist/pii-gateway/types.d.ts +0 -27
  60. package/dist/pii-gateway/types.d.ts.map +0 -1
  61. package/dist/pii-gateway/types.js +0 -3
  62. package/dist/pii-gateway/types.js.map +0 -1
  63. package/dist/platform/mindedChatOpenAI.d.ts +0 -5
  64. package/dist/platform/mindedChatOpenAI.d.ts.map +0 -1
  65. package/dist/platform/mindedChatOpenAI.js +0 -23
  66. package/dist/platform/mindedChatOpenAI.js.map +0 -1
  67. package/dist/platform/mindedUtils.d.ts +0 -1
  68. package/dist/platform/mindedUtils.d.ts.map +0 -1
  69. package/dist/platform/mindedUtils.js +0 -2
  70. package/dist/platform/mindedUtils.js.map +0 -1
  71. package/dist/platform/parallelAzureChatOpenAI.d.ts +0 -39
  72. package/dist/platform/parallelAzureChatOpenAI.d.ts.map +0 -1
  73. package/dist/platform/parallelAzureChatOpenAI.js +0 -114
  74. package/dist/platform/parallelAzureChatOpenAI.js.map +0 -1
  75. package/dist/platform/parallelChatOpenAI.d.ts +0 -38
  76. package/dist/platform/parallelChatOpenAI.d.ts.map +0 -1
  77. package/dist/platform/parallelChatOpenAI.js +0 -111
  78. package/dist/platform/parallelChatOpenAI.js.map +0 -1
  79. package/dist/platform/parallelMindedChatOpenAI.d.ts +0 -39
  80. package/dist/platform/parallelMindedChatOpenAI.d.ts.map +0 -1
  81. package/dist/platform/parallelMindedChatOpenAI.js +0 -111
  82. package/dist/platform/parallelMindedChatOpenAI.js.map +0 -1
  83. package/dist/platform/piiGateway/proxy.d.ts +0 -20
  84. package/dist/platform/piiGateway/proxy.d.ts.map +0 -1
  85. package/dist/platform/piiGateway/proxy.js +0 -24
  86. package/dist/platform/piiGateway/proxy.js.map +0 -1
  87. package/dist/types/Agent.d.ts +0 -2
  88. package/dist/types/Agent.d.ts.map +0 -1
  89. package/dist/types/Agent.js +0 -18
  90. package/dist/types/Agent.js.map +0 -1
  91. package/dist/types/Flows.d.ts +0 -2
  92. package/dist/types/Flows.d.ts.map +0 -1
  93. package/dist/types/Flows.js +0 -18
  94. package/dist/types/Flows.js.map +0 -1
  95. package/dist/types/LLM.d.ts +0 -2
  96. package/dist/types/LLM.d.ts.map +0 -1
  97. package/dist/types/LLM.js +0 -18
  98. package/dist/types/LLM.js.map +0 -1
  99. package/dist/types/LangGraph.d.ts +0 -2
  100. package/dist/types/LangGraph.d.ts.map +0 -1
  101. package/dist/types/LangGraph.js +0 -18
  102. package/dist/types/LangGraph.js.map +0 -1
  103. package/dist/types/Platform.d.ts +0 -2
  104. package/dist/types/Platform.d.ts.map +0 -1
  105. package/dist/types/Platform.js +0 -18
  106. package/dist/types/Platform.js.map +0 -1
  107. package/dist/types/Tools.d.ts +0 -2
  108. package/dist/types/Tools.d.ts.map +0 -1
  109. package/dist/types/Tools.js +0 -18
  110. package/dist/types/Tools.js.map +0 -1
  111. package/dist/types/Triggers.d.ts +0 -2
  112. package/dist/types/Triggers.d.ts.map +0 -1
  113. package/dist/types/Triggers.js +0 -18
  114. package/dist/types/Triggers.js.map +0 -1
  115. package/dist/types/Triggers.types.d.ts +0 -25
  116. package/dist/types/Triggers.types.d.ts.map +0 -1
  117. package/dist/types/Triggers.types.js +0 -3
  118. package/dist/types/Triggers.types.js.map +0 -1
  119. package/dist/types/Voice.d.ts +0 -2
  120. package/dist/types/Voice.d.ts.map +0 -1
  121. package/dist/types/Voice.js +0 -18
  122. package/dist/types/Voice.js.map +0 -1
  123. package/dist/types/index.d.ts +0 -9
  124. package/dist/types/index.d.ts.map +0 -1
  125. package/dist/types/index.js +0 -25
  126. package/dist/types/index.js.map +0 -1
  127. package/dist/utils/LogicalConditionDebugger.d.ts +0 -57
  128. package/dist/utils/LogicalConditionDebugger.d.ts.map +0 -1
  129. package/dist/utils/LogicalConditionDebugger.js +0 -143
  130. package/dist/utils/LogicalConditionDebugger.js.map +0 -1
  131. package/dist/utils/documentProcessor.d.ts +0 -87
  132. package/dist/utils/documentProcessor.d.ts.map +0 -1
  133. package/dist/utils/documentProcessor.js +0 -726
  134. package/dist/utils/documentProcessor.js.map +0 -1
  135. package/dist/utils/extractToolGuidelineParams.d.ts +0 -4
  136. package/dist/utils/extractToolGuidelineParams.d.ts.map +0 -1
  137. package/dist/utils/extractToolGuidelineParams.js +0 -20
  138. package/dist/utils/extractToolGuidelineParams.js.map +0 -1
  139. package/dist/utils/extractToolMemoryResponse.d.ts +0 -4
  140. package/dist/utils/extractToolMemoryResponse.d.ts.map +0 -1
  141. package/dist/utils/extractToolMemoryResponse.js +0 -16
  142. package/dist/utils/extractToolMemoryResponse.js.map +0 -1
  143. package/dist/utils/parseAttachments.d.ts +0 -14
  144. package/dist/utils/parseAttachments.d.ts.map +0 -1
  145. package/dist/utils/parseAttachments.js +0 -54
  146. package/dist/utils/parseAttachments.js.map +0 -1
package/src/agent.ts CHANGED
@@ -424,7 +424,7 @@ export class Agent {
424
424
  // Try to acquire lock atomically (unless bypassing session check)
425
425
  if (!bypassSessionCheck && !(await this.interruptSessionManager.lock(sessionId))) {
426
426
  // Could not acquire lock, session is being processed - enqueue the message
427
- logger.info({ msg: 'Enqueuing message', sessionId, triggerBody, triggerName, appName });
427
+ logger.debug({ msg: 'Enqueuing message', sessionId, triggerBody, triggerName, appName });
428
428
  await this.interruptSessionManager.enqueueMessage(sessionId, {
429
429
  triggerBody,
430
430
  triggerName,
@@ -560,7 +560,7 @@ export class Agent {
560
560
  if (nextMessage.appName) {
561
561
  invokeParams.appName = nextMessage.appName;
562
562
  }
563
- logger.info({ msg: 'Invoking next message in the queue', invokeParams });
563
+ logger.debug({ msg: 'Invoking next message in the queue', invokeParams });
564
564
  return await this.invoke(invokeParams);
565
565
  }
566
566
 
@@ -32,7 +32,7 @@ export interface InterruptSessionManager {
32
32
  enqueueMessage(sessionId: string, message: QueuedMessage): void | Promise<void>;
33
33
  dequeueAll(sessionId: string): QueuedMessage[] | Promise<QueuedMessage[]>;
34
34
  dequeue(sessionId: string): QueuedMessage | null | Promise<QueuedMessage | null>;
35
- checkQueueAndInterrupt(sessionId: string, updateStateObject?: Partial<State>): Promise<boolean>;
35
+ checkQueueAndInterrupt(sessionId: string, updateStateObject?: State): Promise<boolean>;
36
36
  }
37
37
 
38
38
  export abstract class BaseInterruptSessionManager implements InterruptSessionManager {
@@ -58,134 +58,323 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
58
58
  state.messages.unshift(systemMessage);
59
59
  }
60
60
 
61
- const startTime = Date.now();
62
- const result: AIMessage = await llmToUse.bindTools(scopedTools).invoke(state.messages);
63
- const endTime = Date.now();
64
- await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
65
- logger.debug({
66
- msg: '[Model] Model execution time',
67
- executionTimeMs: endTime - startTime,
68
- sessionId: state.sessionId,
69
- node: node.displayName,
70
- });
71
- // Check if the result contains tool calls
72
- if (result.tool_calls && result.tool_calls.length > 0) {
73
- // Execute the tools
74
- const toolResults = [];
75
-
76
- for (const toolCall of result.tool_calls) {
77
- const matchedTool = scopedTools.find((t) => t.name === toolCall.name);
78
- logger.info({
79
- msg: `[Model] Calling tool inside prompt node`,
80
- tool: matchedTool?.name,
61
+ // Check if we should use the agentic loop (only when humanInTheLoop is true)
62
+ const useAgenticLoop = node.humanInTheLoop === true;
63
+
64
+ /**
65
+ * When humanInTheLoop is true: Run an agentic loop that continues invoking the LLM
66
+ * after tool calls until we get a final AI message without tool calls.
67
+ *
68
+ * When humanInTheLoop is false: Return immediately after tool execution without
69
+ * additional LLM invocations.
70
+ */
71
+ const newMessages: any[] = [];
72
+ const newHistory: any[] = [];
73
+ let currentMessages = [...state.messages];
74
+ let finalAIMessage: AIMessage | null = null;
75
+ let loopCount = 0;
76
+ const MAX_LOOP_ITERATIONS = 10;
77
+
78
+ while (true) {
79
+ loopCount++;
80
+
81
+ // Break if we've reached the maximum number of iterations
82
+ if (loopCount > MAX_LOOP_ITERATIONS) {
83
+ logger.warn({
84
+ msg: '[Model] Reached maximum loop iterations, breaking agentic loop',
85
+ loopCount,
81
86
  sessionId: state.sessionId,
82
87
  node: node.displayName,
83
88
  });
84
- if (matchedTool) {
85
- try {
86
- // Invoke the LangChain tool directly
87
- const startTime = Date.now();
88
- const toolResult = await matchedTool.invoke(toolCall);
89
- const endTime = Date.now();
90
- logger.debug({
91
- msg: `[Tool] Tool result inside prompt node`,
92
- tool: matchedTool?.name,
93
- result: toolResult,
94
- executionTimeMs: endTime - startTime,
95
- sessionId: state.sessionId,
96
- node: node.displayName,
97
- });
98
- //check for queue after tool call
99
- const systemMessageId = uuidv4();
100
-
101
- await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, {
102
- messages: [
103
- result,
104
- toolResult,
105
- new SystemMessage({
106
- id: systemMessageId,
107
- content:
108
- 'you called tool when the user send a new message, Consider calling the function again after user message is processed',
109
- }),
110
- ],
111
- history: [
89
+ break;
90
+ }
91
+ const startTime = Date.now();
92
+
93
+ const result: AIMessage = await llmToUse.bindTools(scopedTools).invoke([new SystemMessage(compiledPrompt), ...currentMessages]);
94
+
95
+ // Always pass accumulated state to interrupt manager
96
+ // Pass the accumulated messages from this prompt node execution
97
+ // If empty, pass undefined to avoid empty state updates
98
+ const interruptState =
99
+ newMessages.length > 0 || newHistory.length > 0
100
+ ? {
101
+ ...state,
102
+ messages: [...state.messages, ...newMessages],
103
+ history: [...state.history, ...newHistory],
104
+ }
105
+ : undefined;
106
+ await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, interruptState);
107
+
108
+ const endTime = Date.now();
109
+
110
+ logger.debug({
111
+ msg: '[Model] Model execution time',
112
+ executionTimeMs: endTime - startTime,
113
+ sessionId: state.sessionId,
114
+ node: node.displayName,
115
+ });
116
+
117
+ // Check if the result contains tool calls
118
+ if (result.tool_calls && result.tool_calls.length > 0) {
119
+ // Add the tool call message
120
+ newMessages.push(result);
121
+ newHistory.push(
122
+ createHistoryStep<HistoryStep>(state.history, {
123
+ type: NodeType.TOOL,
124
+ nodeId: node.name,
125
+ nodeDisplayName: node.displayName,
126
+ raw: result,
127
+ messageIds: [result.id!],
128
+ }),
129
+ );
130
+
131
+ // Execute the tools
132
+ // Track how many tool responses we've added for validation
133
+ const toolResponseStartIndex = newMessages.length;
134
+
135
+ // Ensure we process ALL tool calls, even if some fail
136
+ for (const toolCall of result.tool_calls) {
137
+ const matchedTool = scopedTools.find((t) => t.name === toolCall.name);
138
+ logger.info({
139
+ msg: `[Model] Calling tool inside prompt node`,
140
+ tool: matchedTool?.name || toolCall.name,
141
+ toolCallId: toolCall.id,
142
+ sessionId: state.sessionId,
143
+ node: node.displayName,
144
+ });
145
+
146
+ if (matchedTool) {
147
+ try {
148
+ // Invoke the LangChain tool directly
149
+ const toolStartTime = Date.now();
150
+ const toolResult = await matchedTool.invoke(toolCall);
151
+ const toolEndTime = Date.now();
152
+
153
+ logger.debug({
154
+ msg: `[Tool] Tool result inside prompt node`,
155
+ tool: matchedTool?.name,
156
+ result: toolResult,
157
+ executionTimeMs: toolEndTime - toolStartTime,
158
+ sessionId: state.sessionId,
159
+ node: node.displayName,
160
+ });
161
+
162
+ // Add the tool result directly to allMessages
163
+ newMessages.push(toolResult);
164
+
165
+ // Check for queue after tool call
166
+ const systemMessageId = uuidv4();
167
+ await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, {
168
+ ...state,
169
+ messages: [
170
+ ...state.messages,
171
+ ...newMessages,
172
+ new SystemMessage({
173
+ id: systemMessageId,
174
+ content:
175
+ 'you called tool when the user send a new message, Consider calling the function again after user message is processed',
176
+ }),
177
+ ],
178
+ history: [
179
+ ...state.history,
180
+ ...newHistory,
181
+ createHistoryStep<HistoryStep>(state.history, {
182
+ type: NodeType.TOOL,
183
+ nodeId: node.name,
184
+ nodeDisplayName: node.displayName,
185
+ raw: toolResult,
186
+ messageIds: [toolResult.id!, systemMessageId],
187
+ }),
188
+ ],
189
+ });
190
+
191
+ // In v2.0, tools update state by reference, no need to extract state updates
192
+
193
+ newHistory.push(
112
194
  createHistoryStep<HistoryStep>(state.history, {
113
195
  type: NodeType.TOOL,
114
196
  nodeId: node.name,
115
197
  nodeDisplayName: node.displayName,
116
198
  raw: toolResult,
117
- messageIds: [toolResult.id!, systemMessageId],
199
+ messageIds: [toolResult.id!],
118
200
  }),
119
- ],
120
- });
121
- toolResults.push(toolResult);
122
- } catch (err: any) {
123
- if (err?.name === 'GraphInterrupt') throw err;
201
+ );
202
+ } catch (err: any) {
203
+ if (err?.name === 'GraphInterrupt') throw err;
204
+ logger.error({
205
+ msg: `[Tool] Error executing tool inside prompt node`,
206
+ tool: toolCall.name,
207
+ err,
208
+ sessionId: state.sessionId,
209
+ node: node.displayName,
210
+ });
211
+ const errorMessage = new ToolMessage({
212
+ content: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }),
213
+ tool_call_id: toolCall.id!,
214
+ });
215
+
216
+ // Add the error message directly to allMessages
217
+ newMessages.push(errorMessage);
218
+
219
+ // Check for queue after tool error
220
+ const errorSystemMessageId = uuidv4();
221
+ await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, {
222
+ ...state,
223
+ messages: [
224
+ ...state.messages,
225
+ ...newMessages,
226
+ new SystemMessage({
227
+ id: errorSystemMessageId,
228
+ content: 'Tool execution failed. Consider handling the error or calling another function if needed.',
229
+ }),
230
+ ],
231
+ history: [
232
+ ...state.history,
233
+ ...newHistory,
234
+ createHistoryStep<HistoryStep>(state.history, {
235
+ type: NodeType.TOOL,
236
+ nodeId: node.name,
237
+ nodeDisplayName: node.displayName,
238
+ raw: errorMessage,
239
+ messageIds: [errorMessage.id!, errorSystemMessageId],
240
+ }),
241
+ ],
242
+ });
243
+ newHistory.push(
244
+ createHistoryStep<HistoryStep>(state.history, {
245
+ type: NodeType.TOOL,
246
+ nodeId: node.name,
247
+ nodeDisplayName: node.displayName,
248
+ raw: errorMessage,
249
+ messageIds: [errorMessage.id!],
250
+ }),
251
+ );
252
+ }
253
+ } else {
124
254
  logger.error({
125
- msg: `[Tool] Error executing tool inside prompt node`,
255
+ msg: `[Tool] Model called tool but it was not found inside prompt node`,
126
256
  tool: toolCall.name,
127
- err,
257
+ toolCallId: toolCall.id,
128
258
  sessionId: state.sessionId,
129
259
  node: node.displayName,
130
260
  });
131
- const errorMessage = new ToolMessage({
132
- content: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }),
133
- tool_call_id: toolCall.id!,
261
+
262
+ // IMPORTANT: Create an error message for the missing tool with the correct tool_call_id
263
+ const missingToolMessage = new ToolMessage({
264
+ content: JSON.stringify({ error: `Tool '${toolCall.name}' not found` }),
265
+ tool_call_id: toolCall.id!, // This MUST match the tool_call_id from the AI message
266
+ name: toolCall.name,
134
267
  });
135
- toolResults.push(errorMessage);
268
+
269
+ newMessages.push(missingToolMessage);
270
+ newHistory.push(
271
+ createHistoryStep<HistoryStep>(state.history, {
272
+ type: NodeType.TOOL,
273
+ nodeId: node.name,
274
+ nodeDisplayName: node.displayName,
275
+ raw: missingToolMessage,
276
+ messageIds: [missingToolMessage.id!],
277
+ }),
278
+ );
136
279
  }
137
- } else {
280
+ }
281
+
282
+ // Validate that we have responses for ALL tool calls
283
+ const toolResponseCount = newMessages.length - toolResponseStartIndex;
284
+ if (toolResponseCount !== result.tool_calls.length) {
138
285
  logger.error({
139
- msg: `[Tool] Model called tool but it was not found inside prompt node`,
140
- tool: toolCall.name,
286
+ msg: '[Model] Tool response count mismatch',
287
+ expectedCount: result.tool_calls.length,
288
+ actualCount: toolResponseCount,
289
+ toolCallIds: result.tool_calls.map((tc) => tc.id),
141
290
  sessionId: state.sessionId,
142
291
  node: node.displayName,
143
292
  });
144
293
  }
294
+
295
+ // If humanInTheLoop is false, return immediately after tool execution
296
+ if (!useAgenticLoop) {
297
+ // In v2.0, modify state directly
298
+ state.messages.push(...newMessages);
299
+ state.history.push(...newHistory);
300
+ return state;
301
+ }
302
+
303
+ // Otherwise, prepare for next iteration
304
+ // allMessages now contains all the new messages from this iteration
305
+ currentMessages = [...state.messages, ...newMessages];
306
+
307
+ // Continue the loop to see what the model wants to do next
308
+ continue;
309
+ } else {
310
+ // We got an AI message without tool calls - this is our final response
311
+ finalAIMessage = result;
312
+ break;
313
+ }
314
+ }
315
+
316
+ // Process the final AI message if we have one
317
+ if (finalAIMessage) {
318
+ // Add the final AI message to our messages first
319
+ newMessages.push(finalAIMessage);
320
+
321
+ if (finalAIMessage.getType() === 'ai') {
322
+ logger.info({
323
+ msg: `[Model] Response`,
324
+ content: finalAIMessage.content,
325
+ sessionId: state.sessionId,
326
+ node: node.displayName,
327
+ });
328
+
329
+ // First add all messages to state
330
+ state.messages.push(...newMessages);
331
+
332
+ // In v2.0, emit AI_MESSAGE for handlers to process
333
+ // Handlers will modify state directly by reference
334
+ await emit(AgentEvents.AI_MESSAGE, {
335
+ message: finalAIMessage.content as string,
336
+ state: state,
337
+ });
145
338
  }
146
339
 
147
- state.messages.push(result, ...toolResults);
148
- state.history.push(
340
+ // Set goto to null
341
+ state.goto = null;
342
+
343
+ newHistory.push(
149
344
  createHistoryStep<HistoryStep>(state.history, {
150
- type: NodeType.TOOL,
345
+ type: NodeType.PROMPT_NODE,
151
346
  nodeId: node.name,
152
347
  nodeDisplayName: node.displayName,
153
- raw: result,
154
- messageIds: [result.id!],
348
+ raw: finalAIMessage.content,
349
+ messageIds: [finalAIMessage.id!],
155
350
  }),
156
- ...toolResults.map((toolResult) =>
157
- createHistoryStep<HistoryStep>(state.history, {
158
- type: NodeType.TOOL,
159
- nodeId: node.name,
160
- nodeDisplayName: node.displayName,
161
- raw: toolResult,
162
- messageIds: [toolResult.id!],
163
- }),
164
- ),
165
351
  );
352
+
353
+ // History is added to state
354
+ state.history.push(...newHistory);
355
+
166
356
  return state;
167
357
  }
168
358
 
169
- // Model text response
170
- state.goto = null;
171
- state.messages.push(result);
359
+ // If we hit the loop limit without a final AI message, return what we have
360
+ if (loopCount > MAX_LOOP_ITERATIONS && newMessages.length > 0) {
361
+ logger.warn({
362
+ msg: '[Model] Returning accumulated messages after hitting loop limit',
363
+ messageCount: newMessages.length,
364
+ sessionId: state.sessionId,
365
+ node: node.displayName,
366
+ });
172
367
 
173
- if (result.getType() === 'ai') {
174
- logger.info({ msg: `[Model] Response`, content: result.content, sessionId: state.sessionId, node: node.displayName });
175
- await emit(AgentEvents.AI_MESSAGE, { message: result.content as string, state });
368
+ state.goto = null;
369
+ // In v2.0, modify state directly
370
+ state.messages.push(...newMessages);
371
+ state.history.push(...newHistory);
372
+
373
+ return state;
176
374
  }
177
375
 
178
- state.history.push(
179
- createHistoryStep<HistoryStep>(state.history, {
180
- type: NodeType.PROMPT_NODE,
181
- nodeId: node.name,
182
- nodeDisplayName: node.displayName,
183
- raw: result.content,
184
- messageIds: [result.id!],
185
- }),
186
- );
187
-
188
- return state;
376
+ // This should only be reached in unexpected cases
377
+ throw new Error('Unexpected state: no messages generated in prompt node');
189
378
  };
190
379
  graph.addNode(node.name, callback);
191
380
  };
@@ -183,9 +183,9 @@ function getAllYamlFiles(dir: string): string[] {
183
183
  /**
184
184
  * Combine playbooks into a single string
185
185
  */
186
- export function combinePlaybooks(playbooks: Playbook[]): string | undefined {
186
+ export function combinePlaybooks(playbooks: Playbook[]): string | null {
187
187
  if (playbooks.length === 0) {
188
- return undefined;
188
+ return null;
189
189
  }
190
190
 
191
191
  // Combine all playbooks into sections
@@ -1,37 +0,0 @@
1
- import { MindedConnection } from '../platform/mindedConnection';
2
- export interface Guideline {
3
- id: string;
4
- name: string;
5
- content: string;
6
- index?: number;
7
- }
8
- export declare class GuidelinesManager {
9
- private guidelines;
10
- private mindedConnection;
11
- constructor(mindedConnection: MindedConnection | null);
12
- /**
13
- * Load guidelines from directories or platform
14
- */
15
- loadGuidelines(guidelinesDirectories?: string[]): Promise<Guideline[]>;
16
- /**
17
- * Load guidelines from local directories
18
- */
19
- private loadGuidelinesFromDirectories;
20
- /**
21
- * Recursively get all YAML files in a directory
22
- */
23
- private getAllYamlFiles;
24
- /**
25
- * Compile guidelines into a single string with EJS and placeholders
26
- */
27
- compileGuidelines(params?: Record<string, any>): string;
28
- /**
29
- * Replace placeholders in {key} format
30
- */
31
- private replacePlaceholders;
32
- /**
33
- * Get raw guidelines without compilation
34
- */
35
- getGuidelines(): Guideline[];
36
- }
37
- //# sourceMappingURL=guidelinesManager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guidelinesManager.d.ts","sourceRoot":"","sources":["../../src/guidelines/guidelinesManager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAKhE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,gBAAgB,CAA0B;gBAEtC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI;IAIrD;;OAEG;IACU,cAAc,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IA+BnF;;OAEG;IACH,OAAO,CAAC,6BAA6B;IA+BrC;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;OAEG;IACI,iBAAiB,CAAC,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,MAAM;IA0BlE;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;OAEG;IACI,aAAa,IAAI,SAAS,EAAE;CAGpC"}
@@ -1,172 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.GuidelinesManager = void 0;
37
- const fs = __importStar(require("fs"));
38
- const path = __importStar(require("path"));
39
- const yaml = __importStar(require("js-yaml"));
40
- const ejs = __importStar(require("ejs"));
41
- const mindedConnectionTypes_1 = require("../platform/mindedConnectionTypes");
42
- const config_1 = require("../platform/config");
43
- const logger_1 = require("../utils/logger");
44
- class GuidelinesManager {
45
- constructor(mindedConnection) {
46
- this.guidelines = [];
47
- this.mindedConnection = mindedConnection;
48
- }
49
- /**
50
- * Load guidelines from directories or platform
51
- */
52
- async loadGuidelines(guidelinesDirectories) {
53
- const { env, isDeployed } = (0, config_1.getConfig)();
54
- if (['sandbox-staging', 'sandbox'].includes(env) && isDeployed && this.mindedConnection) {
55
- // Load from platform
56
- const response = await this.mindedConnection.awaitEmit(mindedConnectionTypes_1.MindedConnectionSocketMessageType.GET_GUIDELINES, {});
57
- if (response === null || response === void 0 ? void 0 : response.error) {
58
- throw new Error(`Failed to load guidelines from platform: ${response.error}`);
59
- }
60
- this.guidelines = (response === null || response === void 0 ? void 0 : response.guidelines) || [];
61
- }
62
- else if (guidelinesDirectories) {
63
- // Load from directories
64
- this.guidelines = this.loadGuidelinesFromDirectories(guidelinesDirectories);
65
- }
66
- // Sort guidelines by index if available
67
- this.guidelines.sort((a, b) => {
68
- if (a.index !== undefined && b.index !== undefined) {
69
- return a.index - b.index;
70
- }
71
- return 0;
72
- });
73
- return this.guidelines;
74
- }
75
- /**
76
- * Load guidelines from local directories
77
- */
78
- loadGuidelinesFromDirectories(directories) {
79
- const guidelines = [];
80
- for (const directory of directories) {
81
- if (!fs.existsSync(directory)) {
82
- logger_1.logger.info(`Guidelines directory does not exist: ${directory}`);
83
- continue;
84
- }
85
- const files = this.getAllYamlFiles(directory);
86
- for (const file of files) {
87
- try {
88
- const fileContent = fs.readFileSync(file, 'utf8');
89
- const guideline = yaml.load(fileContent);
90
- if (guideline && guideline.name && guideline.content) {
91
- guidelines.push(guideline);
92
- logger_1.logger.info(`Loaded guideline: ${guideline.name} from ${file}`);
93
- }
94
- else {
95
- logger_1.logger.warn(`Invalid guideline structure in ${file}`);
96
- }
97
- }
98
- catch (error) {
99
- logger_1.logger.error(`Failed to load guideline file ${file}: ${error}`);
100
- }
101
- }
102
- }
103
- return guidelines;
104
- }
105
- /**
106
- * Recursively get all YAML files in a directory
107
- */
108
- getAllYamlFiles(dir) {
109
- const files = [];
110
- const entries = fs.readdirSync(dir, { withFileTypes: true });
111
- for (const entry of entries) {
112
- const fullPath = path.join(dir, entry.name);
113
- if (entry.isDirectory()) {
114
- files.push(...this.getAllYamlFiles(fullPath));
115
- }
116
- else if (entry.name.endsWith('.yaml') || entry.name.endsWith('.yml')) {
117
- files.push(fullPath);
118
- }
119
- }
120
- return files;
121
- }
122
- /**
123
- * Compile guidelines into a single string with EJS and placeholders
124
- */
125
- compileGuidelines(params = {}) {
126
- if (this.guidelines.length === 0) {
127
- return '';
128
- }
129
- // Combine all guidelines into sections
130
- const sections = this.guidelines.map((guideline) => {
131
- return `# ${guideline.name}\n${guideline.content}`;
132
- });
133
- const combinedGuidelines = sections.join('\n\n');
134
- try {
135
- // First, render with EJS
136
- let compiledGuidelines = ejs.render(combinedGuidelines, params);
137
- // Then, replace placeholders in {} format
138
- compiledGuidelines = this.replacePlaceholders(compiledGuidelines, params);
139
- return compiledGuidelines;
140
- }
141
- catch (error) {
142
- logger_1.logger.error({ message: 'Error compiling guidelines', error });
143
- return combinedGuidelines; // Return uncompiled if there's an error
144
- }
145
- }
146
- /**
147
- * Replace placeholders in {key} format
148
- */
149
- replacePlaceholders(text, params) {
150
- return text.replace(/\{([^}]+)\}/g, (match, key) => {
151
- const keys = key.split('.');
152
- let value = params;
153
- for (const k of keys) {
154
- if (value && typeof value === 'object' && k in value) {
155
- value = value[k];
156
- }
157
- else {
158
- return match; // Return original if key not found
159
- }
160
- }
161
- return String(value);
162
- });
163
- }
164
- /**
165
- * Get raw guidelines without compilation
166
- */
167
- getGuidelines() {
168
- return this.guidelines;
169
- }
170
- }
171
- exports.GuidelinesManager = GuidelinesManager;
172
- //# sourceMappingURL=guidelinesManager.js.map