@minded-ai/mindedjs 1.0.103-beta-1 → 1.0.103-beta-4

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 (155) hide show
  1. package/dist/agent.d.ts.map +1 -1
  2. package/dist/agent.js +44 -31
  3. package/dist/agent.js.map +1 -1
  4. package/dist/browserTask/executeBrowserTask.d.ts +12 -0
  5. package/dist/browserTask/executeBrowserTask.d.ts.map +1 -0
  6. package/dist/browserTask/executeBrowserTask.js +181 -0
  7. package/dist/browserTask/executeBrowserTask.js.map +1 -0
  8. package/dist/checkpointer/checkpointSaverFactory.js +1 -1
  9. package/dist/checkpointer/checkpointSaverFactory.js.map +1 -1
  10. package/dist/cli/index.js +14 -14
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/edges/createDirectEdge.d.ts +2 -1
  13. package/dist/edges/createDirectEdge.d.ts.map +1 -1
  14. package/dist/edges/createDirectEdge.js +6 -2
  15. package/dist/edges/createDirectEdge.js.map +1 -1
  16. package/dist/edges/createLogicalRouter.d.ts.map +1 -1
  17. package/dist/edges/createLogicalRouter.js +23 -6
  18. package/dist/edges/createLogicalRouter.js.map +1 -1
  19. package/dist/edges/createPromptRouter.d.ts.map +1 -1
  20. package/dist/edges/createPromptRouter.js +12 -6
  21. package/dist/edges/createPromptRouter.js.map +1 -1
  22. package/dist/edges/edgeFactory.d.ts.map +1 -1
  23. package/dist/edges/edgeFactory.js +8 -3
  24. package/dist/edges/edgeFactory.js.map +1 -1
  25. package/dist/index.d.ts +4 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +6 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/interrupts/BaseInterruptSessionManager.d.ts +4 -0
  30. package/dist/interrupts/BaseInterruptSessionManager.d.ts.map +1 -1
  31. package/dist/interrupts/BaseInterruptSessionManager.js +1 -1
  32. package/dist/interrupts/BaseInterruptSessionManager.js.map +1 -1
  33. package/dist/interrupts/MemoryInterruptSessionManager.d.ts +2 -0
  34. package/dist/interrupts/MemoryInterruptSessionManager.d.ts.map +1 -1
  35. package/dist/interrupts/MemoryInterruptSessionManager.js +6 -0
  36. package/dist/interrupts/MemoryInterruptSessionManager.js.map +1 -1
  37. package/dist/interrupts/MindedInterruptSessionManager.d.ts +2 -0
  38. package/dist/interrupts/MindedInterruptSessionManager.d.ts.map +1 -1
  39. package/dist/interrupts/MindedInterruptSessionManager.js +26 -0
  40. package/dist/interrupts/MindedInterruptSessionManager.js.map +1 -1
  41. package/dist/interrupts/interruptSessionManagerFactory.js +2 -2
  42. package/dist/interrupts/interruptSessionManagerFactory.js.map +1 -1
  43. package/dist/llm/createLlmInstance.d.ts +1 -1
  44. package/dist/llm/createLlmInstance.d.ts.map +1 -1
  45. package/dist/llm/createLlmInstance.js +18 -1
  46. package/dist/llm/createLlmInstance.js.map +1 -1
  47. package/dist/nodes/addAppToolNode.d.ts.map +1 -1
  48. package/dist/nodes/addAppToolNode.js +5 -4
  49. package/dist/nodes/addAppToolNode.js.map +1 -1
  50. package/dist/nodes/addBrowserTaskNode.d.ts +13 -0
  51. package/dist/nodes/addBrowserTaskNode.d.ts.map +1 -0
  52. package/dist/nodes/addBrowserTaskNode.js +232 -0
  53. package/dist/nodes/addBrowserTaskNode.js.map +1 -0
  54. package/dist/nodes/addBrowserTaskRunNode.d.ts +13 -0
  55. package/dist/nodes/addBrowserTaskRunNode.d.ts.map +1 -0
  56. package/dist/nodes/addBrowserTaskRunNode.js +130 -0
  57. package/dist/nodes/addBrowserTaskRunNode.js.map +1 -0
  58. package/dist/nodes/addHumanInTheLoopNode.d.ts.map +1 -1
  59. package/dist/nodes/addHumanInTheLoopNode.js +1 -1
  60. package/dist/nodes/addHumanInTheLoopNode.js.map +1 -1
  61. package/dist/nodes/addJumpToNode.d.ts.map +1 -1
  62. package/dist/nodes/addJumpToNode.js +2 -1
  63. package/dist/nodes/addJumpToNode.js.map +1 -1
  64. package/dist/nodes/addJunctionNode.d.ts.map +1 -1
  65. package/dist/nodes/addJunctionNode.js +1 -0
  66. package/dist/nodes/addJunctionNode.js.map +1 -1
  67. package/dist/nodes/addPromptNode.d.ts.map +1 -1
  68. package/dist/nodes/addPromptNode.js +7 -17
  69. package/dist/nodes/addPromptNode.js.map +1 -1
  70. package/dist/nodes/addToolNode.d.ts.map +1 -1
  71. package/dist/nodes/addToolNode.js +2 -2
  72. package/dist/nodes/addToolNode.js.map +1 -1
  73. package/dist/nodes/addToolRunNode.d.ts.map +1 -1
  74. package/dist/nodes/addToolRunNode.js +2 -1
  75. package/dist/nodes/addToolRunNode.js.map +1 -1
  76. package/dist/nodes/addTriggerNode.d.ts.map +1 -1
  77. package/dist/nodes/addTriggerNode.js +2 -1
  78. package/dist/nodes/addTriggerNode.js.map +1 -1
  79. package/dist/nodes/nodeFactory.d.ts.map +1 -1
  80. package/dist/nodes/nodeFactory.js +4 -0
  81. package/dist/nodes/nodeFactory.js.map +1 -1
  82. package/dist/platform/mindedConnection.js +13 -13
  83. package/dist/platform/mindedConnection.js.map +1 -1
  84. package/dist/platform/mindedConnectionTypes.d.ts +3 -1
  85. package/dist/platform/mindedConnectionTypes.d.ts.map +1 -1
  86. package/dist/platform/mindedConnectionTypes.js +2 -0
  87. package/dist/platform/mindedConnectionTypes.js.map +1 -1
  88. package/dist/platform/models/mindedChatOpenAI.d.ts +20 -0
  89. package/dist/platform/models/mindedChatOpenAI.d.ts.map +1 -0
  90. package/dist/platform/models/mindedChatOpenAI.js +32 -0
  91. package/dist/platform/models/mindedChatOpenAI.js.map +1 -0
  92. package/dist/platform/models/parallelWrapper.d.ts +17 -0
  93. package/dist/platform/models/parallelWrapper.d.ts.map +1 -0
  94. package/dist/platform/models/parallelWrapper.js +105 -0
  95. package/dist/platform/models/parallelWrapper.js.map +1 -0
  96. package/dist/playbooks/playbooks.js +6 -6
  97. package/dist/playbooks/playbooks.js.map +1 -1
  98. package/dist/types/Flows.types.d.ts +18 -3
  99. package/dist/types/Flows.types.d.ts.map +1 -1
  100. package/dist/types/Flows.types.js +2 -0
  101. package/dist/types/Flows.types.js.map +1 -1
  102. package/dist/types/LLM.types.d.ts.map +1 -1
  103. package/dist/types/LLM.types.js +1 -1
  104. package/dist/types/LLM.types.js.map +1 -1
  105. package/dist/types/LangGraph.types.d.ts +2 -0
  106. package/dist/types/LangGraph.types.d.ts.map +1 -1
  107. package/dist/types/LangGraph.types.js +5 -0
  108. package/dist/types/LangGraph.types.js.map +1 -1
  109. package/dist/utils/logger.d.ts.map +1 -1
  110. package/dist/utils/logger.js +1 -2
  111. package/dist/utils/logger.js.map +1 -1
  112. package/dist/voice/voiceSession.d.ts.map +1 -1
  113. package/dist/voice/voiceSession.js +19 -18
  114. package/dist/voice/voiceSession.js.map +1 -1
  115. package/docs/SUMMARY.md +1 -0
  116. package/docs/low-code-editor/nodes.md +27 -0
  117. package/docs/low-code-editor/tools.md +32 -0
  118. package/docs/platform/parallel-llm.md +242 -0
  119. package/package.json +2 -1
  120. package/src/agent.ts +45 -33
  121. package/src/browserTask/executeBrowserTask.ts +213 -0
  122. package/src/checkpointer/checkpointSaverFactory.ts +1 -1
  123. package/src/cli/index.ts +14 -14
  124. package/src/edges/createDirectEdge.ts +7 -2
  125. package/src/edges/createLogicalRouter.ts +23 -6
  126. package/src/edges/createPromptRouter.ts +13 -6
  127. package/src/edges/edgeFactory.ts +20 -4
  128. package/src/index.ts +6 -0
  129. package/src/interrupts/BaseInterruptSessionManager.ts +5 -2
  130. package/src/interrupts/MemoryInterruptSessionManager.ts +8 -0
  131. package/src/interrupts/MindedInterruptSessionManager.ts +25 -0
  132. package/src/interrupts/interruptSessionManagerFactory.ts +2 -2
  133. package/src/llm/createLlmInstance.ts +25 -2
  134. package/src/nodes/addAppToolNode.ts +5 -4
  135. package/src/nodes/addBrowserTaskNode.ts +231 -0
  136. package/src/nodes/addBrowserTaskRunNode.ts +144 -0
  137. package/src/nodes/addHumanInTheLoopNode.ts +2 -1
  138. package/src/nodes/addJumpToNode.ts +2 -1
  139. package/src/nodes/addJunctionNode.ts +1 -0
  140. package/src/nodes/addPromptNode.ts +8 -16
  141. package/src/nodes/addToolNode.ts +3 -2
  142. package/src/nodes/addToolRunNode.ts +3 -1
  143. package/src/nodes/addTriggerNode.ts +2 -1
  144. package/src/nodes/nodeFactory.ts +5 -1
  145. package/src/platform/mindedConnection.ts +13 -13
  146. package/src/platform/mindedConnectionTypes.ts +2 -0
  147. package/src/platform/models/mindedChatOpenAI.ts +49 -0
  148. package/src/platform/models/parallelWrapper.ts +141 -0
  149. package/src/playbooks/playbooks.ts +6 -6
  150. package/src/types/Flows.types.ts +17 -1
  151. package/src/types/LLM.types.ts +5 -5
  152. package/src/types/LangGraph.types.ts +5 -0
  153. package/src/utils/logger.ts +1 -2
  154. package/src/voice/voiceSession.ts +20 -19
  155. package/src/platform/mindedChatOpenAI.ts +0 -19
@@ -26,14 +26,14 @@ export const addAppToolNode = async ({
26
26
  const cleanedParameters = Object.fromEntries(Object.entries(node.parameters || {}).filter(([, value]) => value !== ''));
27
27
  const appRunnerTool = getAppActionRunnerTool(node.displayName!);
28
28
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
29
- logger.info({ message: `Executing tool node ${appRunnerTool.name}` });
29
+ logger.debug({ msg: `[Node] Executing tool node`, node: appRunnerTool.name });
30
30
 
31
31
  const executeWrapper = async (input: z.infer<typeof appRunnerTool.input>) => {
32
32
  try {
33
33
  const response = await appRunnerTool.execute({ input, state, agent });
34
34
  return response || {};
35
35
  } catch (error) {
36
- logger.error({ msg: 'Error executing tool', error });
36
+ logger.error({ msg: `[Node] Error executing tool`, error, node: node.name });
37
37
  throw error;
38
38
  }
39
39
  };
@@ -75,11 +75,12 @@ export const addAppToolNode = async ({
75
75
  };
76
76
  const toolCallMessage = await tool.invoke(AIToolCallMessage.tool_calls[0]);
77
77
  AIToolCallMessage.additional_kwargs = {
78
- appActionInvocation: {
79
- nodeTitle: node.name,
78
+ mindedMetadata: {
79
+ nodeType: NodeType.APP_TOOL,
80
80
  },
81
81
  };
82
82
  return {
83
+ goto: null,
83
84
  messages: [AIToolCallMessage, toolCallMessage],
84
85
  history: createHistoryStep<AppActionInvocationHistoryStep>(state.history, {
85
86
  type: NodeType.APP_TOOL,
@@ -0,0 +1,231 @@
1
+ import { RunnableLike } from '@langchain/core/runnables';
2
+ import { BrowserTaskNode, NodeType } from '../types/Flows.types';
3
+ import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
4
+ import { HistoryStep } from '../types/Agent.types';
5
+ import { logger } from '../utils/logger';
6
+ import { createHistoryStep } from '../utils/history';
7
+ import { AIMessage, SystemMessage } from '@langchain/core/messages';
8
+ import { v4 as uuidv4 } from 'uuid';
9
+ import { Agent } from '../agent';
10
+ import { createCloudTask, waitForLiveUrl } from '../browserTask/executeBrowserTask';
11
+ import { tool as langchainTool } from '@langchain/core/tools';
12
+ import { z } from 'zod';
13
+ import { LLMProviders } from '../types/LLM.types';
14
+ import { compilePlaybooks } from '../playbooks/playbooks';
15
+ import * as ejs from 'ejs';
16
+
17
+ /**
18
+ * Compile prompt with parameters using EJS and placeholder replacement
19
+ */
20
+ function compilePrompt(prompt: string, params: Record<string, any> = {}): string {
21
+ try {
22
+ // First, render with EJS
23
+ let compiledPrompt = ejs.render(prompt, params);
24
+
25
+ // Then, replace placeholders in {} format
26
+ compiledPrompt = replacePlaceholders(compiledPrompt, params);
27
+
28
+ return compiledPrompt;
29
+ } catch (error) {
30
+ logger.error({ message: 'Error compiling prompt', error });
31
+ return prompt; // Return uncompiled if there's an error
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Replace placeholders in {key} format
37
+ */
38
+ function replacePlaceholders(text: string, params: Record<string, any>): string {
39
+ return text.replace(/\{([^}]+)\}/g, (match, key) => {
40
+ const keys = key.split('.');
41
+ let value: any = params;
42
+
43
+ for (const k of keys) {
44
+ if (value && typeof value === 'object' && k in value) {
45
+ value = value[k];
46
+ } else {
47
+ return match; // Return original if key not found
48
+ }
49
+ }
50
+
51
+ return String(value);
52
+ });
53
+ }
54
+
55
+ type AddBrowserTaskNodeParams = {
56
+ graph: PreCompiledGraph;
57
+ node: BrowserTaskNode;
58
+ agent: Agent;
59
+ llm: (typeof LLMProviders)[keyof typeof LLMProviders];
60
+ };
61
+
62
+ export const addBrowserTaskNode = async ({ graph, node, agent, llm }: AddBrowserTaskNodeParams) => {
63
+ const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
64
+ logger.info({ msg: `Executing browser task node ${node.displayName}`, prompt: node.prompt });
65
+
66
+ // Create Zod schema from inputSchema
67
+ const schemaFields: Record<string, z.ZodTypeAny> = {};
68
+ if (node.inputSchema) {
69
+ for (const field of node.inputSchema) {
70
+ let fieldSchema: z.ZodTypeAny;
71
+
72
+ if (field.type === 'string') {
73
+ fieldSchema = z.string();
74
+ } else if (field.type === 'number') {
75
+ fieldSchema = z.number();
76
+ } else {
77
+ fieldSchema = z.string(); // Default to string
78
+ }
79
+
80
+ if (field.description) {
81
+ fieldSchema = fieldSchema.describe(field.description);
82
+ }
83
+
84
+ if (field.required === false) {
85
+ fieldSchema = fieldSchema.optional();
86
+ }
87
+
88
+ schemaFields[field.name] = fieldSchema;
89
+ }
90
+ }
91
+
92
+ const zodSchema = z.object(schemaFields);
93
+
94
+ // Create langchain tool
95
+ const tool = langchainTool(() => {}, {
96
+ name: 'browser-task',
97
+ description: node.prompt,
98
+ schema: zodSchema,
99
+ });
100
+
101
+ // Get compiled playbooks
102
+ const playbookParams = {
103
+ ...state.memory,
104
+ state,
105
+ currentTime: new Date().toISOString(),
106
+ };
107
+ const compiledPlaybooks = compilePlaybooks(agent.playbooks, playbookParams) || '';
108
+
109
+ const systemPrompt = `${compiledPlaybooks ? compiledPlaybooks + '\n\n' : ''}
110
+ Additional context:
111
+ - workflow memory: ${JSON.stringify(state.memory)}`;
112
+
113
+ try {
114
+ // Use LLM to generate tool call
115
+ const AIToolCallMessage: AIMessage = await llm
116
+ .bindTools([tool], {
117
+ tool_choice: tool.name,
118
+ })
119
+ .invoke([...state.messages, new SystemMessage(systemPrompt)]);
120
+
121
+ if (!AIToolCallMessage.tool_calls || AIToolCallMessage.tool_calls.length === 0) {
122
+ throw new Error('No tool calls generated by LLM');
123
+ }
124
+
125
+ const toolCall = AIToolCallMessage.tool_calls[0];
126
+ const inputParams = toolCall.args || {};
127
+
128
+ // Prepare parameters for prompt compilation
129
+ const promptParams = {
130
+ input: inputParams,
131
+ state,
132
+ currentTime: new Date().toISOString(),
133
+ };
134
+
135
+ // Compile the prompt with parameters
136
+ const compiledPrompt = compilePrompt(node.prompt, promptParams);
137
+
138
+ // Build the full prompt with compiled content
139
+ const fullPrompt = `
140
+ Follow the instructions. Any retrieved data should be printed as string and not saved to a file.
141
+
142
+ # Task instructions:
143
+ ${compiledPrompt}
144
+
145
+ ${Object.keys(inputParams).length > 0 ? `# Input parameters:\n${JSON.stringify(inputParams, null, 2)}\n\n` : ''}
146
+ ${state.memory ? `# Task context:\n${JSON.stringify(state.memory)}\n\n` : ''}
147
+ `;
148
+
149
+ // Create the browser task in the cloud
150
+ const taskId = await createCloudTask(fullPrompt, node.model);
151
+ logger.debug({ msg: 'Browser task created', taskId });
152
+
153
+ // Wait for live_url to become available
154
+ const taskDetails = await waitForLiveUrl(taskId);
155
+ logger.debug({ msg: 'Live URL available', taskId, liveUrl: taskDetails.live_url });
156
+
157
+ // Update the tool call with taskId and other metadata
158
+ const updatedToolCall = {
159
+ ...toolCall,
160
+ args: {
161
+ ...inputParams,
162
+ taskId,
163
+ prompt: fullPrompt,
164
+ },
165
+ };
166
+
167
+ const toolCallingMessage = new AIMessage({
168
+ id: AIToolCallMessage.id,
169
+ content: AIToolCallMessage.content,
170
+ tool_calls: [updatedToolCall],
171
+ additional_kwargs: {
172
+ mindedMetadata: {
173
+ nodeType: NodeType.BROWSER_TASK,
174
+ nodeDisplayName: node.displayName,
175
+ taskId,
176
+ liveUrl: taskDetails.live_url,
177
+ },
178
+ },
179
+ });
180
+
181
+ return {
182
+ history: createHistoryStep<HistoryStep>(state.history, {
183
+ type: NodeType.BROWSER_TASK,
184
+ nodeId: node.name,
185
+ nodeDisplayName: node.displayName,
186
+ raw: { taskId, liveUrl: taskDetails.live_url, inputParams },
187
+ messageIds: [toolCallingMessage.id!],
188
+ }),
189
+ messages: [toolCallingMessage],
190
+ };
191
+ } catch (error: any) {
192
+ logger.error(`Error creating browser task node ${node.displayName}: ${error}`);
193
+
194
+ const errorMessageId = uuidv4();
195
+ const errorToolCallId = uuidv4();
196
+
197
+ const toolCallingMessage = new AIMessage({
198
+ id: errorMessageId,
199
+ content: '',
200
+ tool_calls: [
201
+ {
202
+ id: errorToolCallId,
203
+ name: 'browser-task',
204
+ args: {
205
+ error: error.message,
206
+ },
207
+ },
208
+ ],
209
+ additional_kwargs: {
210
+ mindedMetadata: {
211
+ nodeType: NodeType.BROWSER_TASK,
212
+ nodeDisplayName: node.displayName,
213
+ error: error.message,
214
+ },
215
+ },
216
+ });
217
+
218
+ return {
219
+ history: createHistoryStep<HistoryStep>(state.history, {
220
+ type: NodeType.BROWSER_TASK,
221
+ nodeId: node.name,
222
+ nodeDisplayName: node.displayName,
223
+ raw: error,
224
+ messageIds: [errorMessageId],
225
+ }),
226
+ messages: [toolCallingMessage],
227
+ };
228
+ }
229
+ };
230
+ graph.addNode(node.name, callback);
231
+ };
@@ -0,0 +1,144 @@
1
+ import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
2
+ import { RunnableLike } from '@langchain/core/runnables';
3
+ import { internalNodesSuffix, NodeType, BrowserTaskNode } from '../types/Flows.types';
4
+ import { ToolMessage, AIMessage } from '@langchain/core/messages';
5
+ import { Agent } from '../agent';
6
+ import { logger } from '../utils/logger';
7
+ import { createHistoryStep } from '../utils/history';
8
+ import { HistoryStep } from '../types/Agent.types';
9
+ import { v4 as uuidv4 } from 'uuid';
10
+ import { waitForCompletion } from '../browserTask/executeBrowserTask';
11
+
12
+ type AddBrowserTaskRunNodeParams = {
13
+ graph: PreCompiledGraph;
14
+ browserTaskNode: BrowserTaskNode;
15
+ attachedToNodeName: string;
16
+ agent: Agent;
17
+ };
18
+
19
+ export const buildBrowserTaskRunNodeName = (nodeName: string) => `${nodeName}${internalNodesSuffix.BROWSER_TASK_RUN}`;
20
+
21
+ export const addBrowserTaskRunNode = async ({ graph, browserTaskNode, attachedToNodeName }: AddBrowserTaskRunNodeParams) => {
22
+ const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
23
+ logger.info(`Executing browser task run node for ${browserTaskNode.displayName}`);
24
+
25
+ const toolCallObj = state.messages[state.messages.length - 1] as any;
26
+ if (!toolCallObj.tool_calls) {
27
+ throw new Error('Tool call not found');
28
+ }
29
+ const toolCall = toolCallObj.tool_calls[0];
30
+ const { taskId, ...inputParams } = toolCall.args;
31
+ try {
32
+ if (!taskId) {
33
+ throw new Error('Task ID not found in tool call arguments');
34
+ }
35
+
36
+ // Wait for task completion
37
+ const completedTask = await waitForCompletion(taskId);
38
+ logger.debug({ msg: 'Browser task completed', taskId, output: completedTask.output });
39
+
40
+ // Create tool message with the result
41
+ const toolMessage = new ToolMessage({
42
+ id: uuidv4(),
43
+ content: JSON.stringify({
44
+ result: completedTask.output || 'Task completed successfully',
45
+ steps: completedTask.steps || [],
46
+ inputParams: inputParams,
47
+ }),
48
+ name: 'browser-task',
49
+ tool_call_id: toolCall.id,
50
+ status: 'success',
51
+ additional_kwargs: {
52
+ mindedMetadata: {
53
+ nodeType: NodeType.BROWSER_TASK,
54
+ nodeDisplayName: browserTaskNode.displayName,
55
+ taskId,
56
+ steps: completedTask.steps,
57
+ inputParams: inputParams,
58
+ },
59
+ },
60
+ });
61
+
62
+ // Update the AI message with steps using the message reducer pattern
63
+ const updatedAIMessage = new AIMessage({
64
+ id: toolCallObj.id,
65
+ content: toolCallObj.content,
66
+ tool_calls: toolCallObj.tool_calls,
67
+ additional_kwargs: {
68
+ ...toolCallObj.additional_kwargs,
69
+ mindedMetadata: {
70
+ ...toolCallObj.additional_kwargs?.mindedMetadata,
71
+ nodeDisplayName: browserTaskNode.displayName,
72
+ steps: completedTask.steps,
73
+ status: 'completed',
74
+ },
75
+ update: true, // This triggers the message reducer to update the existing message
76
+ },
77
+ });
78
+
79
+ return {
80
+ messages: [toolMessage, updatedAIMessage],
81
+ history: createHistoryStep<HistoryStep>(state.history, {
82
+ type: NodeType.BROWSER_TASK,
83
+ nodeId: browserTaskNode.name,
84
+ nodeDisplayName: browserTaskNode.displayName,
85
+ raw: completedTask,
86
+ messageIds: [],
87
+ }),
88
+ };
89
+ } catch (error: any) {
90
+ logger.error({ msg: 'Error executing browser task run node', error });
91
+
92
+ const errorToolMessage = new ToolMessage({
93
+ id: uuidv4(),
94
+ content: JSON.stringify({
95
+ error: error instanceof Error ? error.message : error.toString(),
96
+ inputParams: inputParams,
97
+ }),
98
+ status: 'error',
99
+ name: 'browser-task',
100
+ tool_call_id: toolCall.id,
101
+ additional_kwargs: {
102
+ mindedMetadata: {
103
+ nodeType: NodeType.BROWSER_TASK,
104
+ nodeDisplayName: browserTaskNode.displayName,
105
+ taskId,
106
+ error: error.message,
107
+ inputParams: inputParams,
108
+ },
109
+ },
110
+ });
111
+
112
+ // Update the AI message with error status
113
+ const updatedAIMessage = new AIMessage({
114
+ id: toolCallObj.id,
115
+ content: toolCallObj.content,
116
+ tool_calls: toolCallObj.tool_calls,
117
+ additional_kwargs: {
118
+ ...toolCallObj.additional_kwargs,
119
+ mindedMetadata: {
120
+ ...toolCallObj.additional_kwargs?.mindedMetadata,
121
+ nodeDisplayName: browserTaskNode.displayName,
122
+ status: 'failed',
123
+ error: error.message,
124
+ },
125
+ update: true,
126
+ },
127
+ });
128
+
129
+ return {
130
+ messages: [errorToolMessage, updatedAIMessage],
131
+ history: createHistoryStep<HistoryStep>(state.history, {
132
+ type: NodeType.BROWSER_TASK,
133
+ nodeId: browserTaskNode.name,
134
+ nodeDisplayName: browserTaskNode.displayName,
135
+ raw: error,
136
+ messageIds: [],
137
+ }),
138
+ };
139
+ }
140
+ };
141
+
142
+ graph.addNode(buildBrowserTaskRunNodeName(attachedToNodeName), callback);
143
+ graph.addEdge(attachedToNodeName as any, buildBrowserTaskRunNodeName(attachedToNodeName) as any);
144
+ };
@@ -14,7 +14,8 @@ export const buildHumanInTheLoopNodeName = (nodeName: string) => `${nodeName}${i
14
14
 
15
15
  export const addHumanInTheLoopNode = async ({ graph, attachedToNodeName }: AddHumanInTheLoopNodeParams) => {
16
16
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
17
- logger.info({ message: `Executing "human in the loop" node for the attached node${attachedToNodeName}` });
17
+ logger.debug({ msg: `[Node] Waiting for human input`, node: attachedToNodeName });
18
+
18
19
  if (state.messages[state.messages.length - 1].getType() === 'ai') {
19
20
  const value = interrupt({ type: InterruptType.HUMAN_IN_THE_LOOP });
20
21
  return value;
@@ -7,9 +7,10 @@ import { createHistoryStep } from '../utils/history';
7
7
 
8
8
  export const addJumpToNode = async ({ graph, node }: { graph: PreCompiledGraph; node: JumpToNode }) => {
9
9
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
10
- logger.info({ message: `Executing jump node ${node.displayName} – jumping to ${node.targetNodeId}` });
10
+ logger.info({ msg: `Executing jump node ${node.displayName} – jumping to ${node.targetNodeId}` });
11
11
  // No state modifications are necessary; control flow is handled via edges.
12
12
  return {
13
+ goto: null,
13
14
  history: createHistoryStep<HistoryStep>(state.history, {
14
15
  type: NodeType.JUMP_TO_NODE,
15
16
  nodeId: node.name,
@@ -7,6 +7,7 @@ import { HistoryStep } from '../types/Agent.types';
7
7
  export const addJunctionNode = ({ graph, node }: { graph: PreCompiledGraph; node: JunctionNode }) => {
8
8
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
9
9
  return {
10
+ goto: null,
10
11
  history: createHistoryStep<HistoryStep>(state.history, {
11
12
  type: NodeType.JUNCTION,
12
13
  nodeId: node.name,
@@ -14,10 +14,9 @@ import { Agent } from '../agent';
14
14
  import { logger } from '../utils/logger';
15
15
  import { compilePlaybooks } from '../playbooks/playbooks';
16
16
  import { createHistoryStep } from '../utils/history';
17
+ import { v4 as uuidv4 } from 'uuid';
17
18
  import { wait } from '../utils/wait';
18
19
  import { sendPlaceholderMessage } from '../internalTools/sendPlaceholderMessage';
19
- import { v4 as uuidv4 } from 'uuid';
20
-
21
20
  type AddPromptNodeParams = {
22
21
  graph: PreCompiledGraph;
23
22
  node: PromptNode;
@@ -31,7 +30,7 @@ let shouldWait = true;
31
30
  export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: AddPromptNodeParams) => {
32
31
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
33
32
  await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
34
- logger.info({ message: `Executing prompt node ${node.displayName}` });
33
+ logger.info({ msg: `[Node] Executing prompt node`, node: node.displayName });
35
34
  const llmToUse = node.llmConfig ? createLlmInstance(node.llmConfig) : llm;
36
35
 
37
36
  const globalTools = tools
@@ -55,16 +54,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
55
54
  ${state.memory ? `# Task context:\n${JSON.stringify(state.memory)}\n\n` : ''}
56
55
  ${compiledPlaybooks ? `# General guidelines:\n${compiledPlaybooks}\n\n` : ''}
57
56
  `;
58
- if (true) {
59
- logger.info({ msg: `waiting 15 seconds` });
60
- shouldWait = false;
61
57
 
62
- await sendPlaceholderMessage({ sessionId: state.sessionId, message: 'just a moment please... ' });
63
- await wait(10000);
64
- logger.info({ msg: `done waiting 15 seconds` });
65
- } else {
66
- logger.info({ msg: `not waiting` });
67
- }
68
58
  const result: AIMessage = await llmToUse.bindTools(globalTools).invoke([...state.messages, new SystemMessage(message)]);
69
59
  await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
70
60
  // Check if the result contains tool calls
@@ -75,11 +65,12 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
75
65
 
76
66
  for (const toolCall of result.tool_calls) {
77
67
  const matchedTool = globalTools.find((t) => t.name === toolCall.name);
78
- logger.info({ msg: `Model called tool ${matchedTool?.name}` });
68
+ logger.info({ msg: `[Model] Calling tool`, tool: matchedTool?.name });
79
69
  if (matchedTool) {
80
70
  try {
81
71
  // Invoke the LangChain tool directly
82
72
  const toolResult = await matchedTool.invoke(toolCall);
73
+ logger.debug({ msg: `[Tool] Tool result`, tool: matchedTool?.name, result: toolResult });
83
74
  //check for queue after tool call
84
75
  const systemMessageId = uuidv4();
85
76
 
@@ -113,7 +104,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
113
104
  toolResults.push(toolResult);
114
105
  } catch (error: any) {
115
106
  if (error?.name === 'GraphInterrupt') throw error;
116
- logger.error({ msg: `Error executing tool ${toolCall.name}:`, error });
107
+ logger.error({ msg: `[Tool] Error executing tool`, tool: toolCall.name, error });
117
108
  const errorMessage = new ToolMessage({
118
109
  content: JSON.stringify({ error: error instanceof Error ? error.message : String(error) }),
119
110
  tool_call_id: toolCall.id!,
@@ -121,7 +112,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
121
112
  toolResults.push(errorMessage);
122
113
  }
123
114
  } else {
124
- logger.error({ msg: `Model tried to call tool ${toolCall.name} but it was not found` });
115
+ logger.error({ msg: `[Tool] Model called tool but it was not found`, tool: toolCall.name });
125
116
  }
126
117
  }
127
118
 
@@ -157,9 +148,10 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
157
148
  message: result.content as string,
158
149
  state,
159
150
  });
160
- console.log('AI Message', result.content);
151
+ logger.info({ msg: `[Model] Response`, content: result.content });
161
152
  }
162
153
  return {
154
+ goto: null,
163
155
  history: createHistoryStep<HistoryStep>(state.history, {
164
156
  type: NodeType.PROMPT_NODE,
165
157
  nodeId: node.name,
@@ -31,7 +31,8 @@ export const addToolNode = async ({
31
31
  }
32
32
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
33
33
  await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
34
- logger.info({ message: `Executing tool node ${toolNode.displayName}` });
34
+ logger.debug({ msg: `[Node] Executing tool node`, node: toolNode.displayName });
35
+
35
36
  const tool = langchainTool(() => {}, {
36
37
  name: matchedTool.name,
37
38
  description: matchedTool.description,
@@ -56,9 +57,9 @@ export const addToolNode = async ({
56
57
  tool_choice: tool.name,
57
58
  })
58
59
  .invoke([...state.messages, new SystemMessage(prompt)]);
59
- logger.info({ message: 'after llm tool invoke' });
60
60
  await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
61
61
  return {
62
+ goto: null,
62
63
  messages: [AIToolCallMessage],
63
64
  history: createHistoryStep<HistoryStep>(state.history, {
64
65
  type: NodeType.TOOL,
@@ -36,7 +36,7 @@ export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeNam
36
36
  const response = await matchedTool.execute({ input, state, agent });
37
37
  return response || {};
38
38
  } catch (error) {
39
- logger.error({ msg: 'Error executing tool', error });
39
+ logger.error({ msg: '[Tool] Error executing tool', error, node: toolNode.displayName });
40
40
  throw error;
41
41
  }
42
42
  };
@@ -56,7 +56,9 @@ export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeNam
56
56
  // Push the toolCallMessage into the messages array from toolStateUpdate
57
57
  const updatedMessages = [toolCallMessage, ...((toolStateUpdate as any).messages || [])];
58
58
  // Return the full state update from the tool with the updated messages
59
+
59
60
  return {
61
+ goto: null,
60
62
  ...toolStateUpdate,
61
63
  messages: updatedMessages,
62
64
  history: createHistoryStep<HistoryStep>(state.history, {
@@ -7,9 +7,10 @@ import { createHistoryStep } from '../utils/history';
7
7
 
8
8
  export const addTriggerNode = async ({ graph, node }: { graph: PreCompiledGraph; node: TriggerNode }) => {
9
9
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
10
- logger.info({ message: `Executing trigger node ${node.displayName}` });
10
+ logger.debug({ msg: `[Trigger] Executing trigger node`, node: node.displayName });
11
11
  if (node.triggerType === TriggerType.MANUAL) {
12
12
  return {
13
+ goto: null,
13
14
  history: createHistoryStep<HistoryStep>(state.history, {
14
15
  type: NodeType.TRIGGER,
15
16
  nodeId: node.name,
@@ -11,6 +11,7 @@ import { LLMProviders } from '../types/LLM.types';
11
11
  import { Agent } from '../agent';
12
12
  import { addJumpToNode } from './addJumpToNode';
13
13
  import { addJunctionNode } from './addJunctionNode';
14
+ import { addBrowserTaskNode } from './addBrowserTaskNode';
14
15
 
15
16
  export const nodeFactory = ({
16
17
  graph,
@@ -47,7 +48,10 @@ export const nodeFactory = ({
47
48
  case NodeType.JUMP_TO_NODE:
48
49
  addJumpToNode({ graph, node });
49
50
  break;
51
+ case NodeType.BROWSER_TASK:
52
+ addBrowserTaskNode({ graph, node, agent, llm });
53
+ break;
50
54
  default:
51
55
  throw new Error(`Unsupported node type: ${nodeType}`);
52
56
  }
53
- };
57
+ };