@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
@@ -87,43 +87,43 @@ const connect = async (token: string): Promise<void> => {
87
87
 
88
88
  const checkReady = () => {
89
89
  if (connected && ready) {
90
- logger.info({ message: '\x1b[32mConnection with Minded platform is ready!\x1b[0m' });
91
- logger.info({ message: '\x1b[32mPress Ctrl+C to exit...' });
90
+ logger.info({ msg: '\x1b[32mConnection with Minded platform is ready!\x1b[0m' });
91
+ logger.info({ msg: '\x1b[32mPress Ctrl+C to exit...' });
92
92
  resolve();
93
93
  }
94
94
  };
95
95
 
96
96
  // Connection event handlers
97
97
  socket.on('connect', () => {
98
- logger.info({ message: 'Socket connected, waiting for server setup...' });
98
+ logger.info({ msg: 'Socket connected, waiting for server setup...' });
99
99
  connected = true;
100
100
  checkReady();
101
101
  });
102
102
 
103
103
  // Listen for ready event from server
104
104
  socket.on('sdk-socket-ready', (data: { agentId: string; orgName: string }) => {
105
- logger.info({ message: 'Server ready signal received', data });
105
+ logger.info({ msg: 'Server ready signal received', data });
106
106
  ready = true;
107
107
  checkReady();
108
108
  });
109
109
 
110
110
  socket.on('connect_error', () => {
111
- logger.error({ message: 'Failed to connect to minded platform' });
111
+ logger.error({ msg: 'Failed to connect to minded platform' });
112
112
  reject(new Error('Failed to connect to minded platform'));
113
113
  });
114
114
 
115
115
  socket.on('disconnect', () => {
116
- logger.info({ message: 'Disconnected from local debugging socket' });
116
+ logger.info({ msg: 'Disconnected from local debugging socket' });
117
117
  connected = false;
118
118
  ready = false;
119
119
  });
120
120
 
121
121
  // Listen for error messages from the server
122
122
  socket.on('error', async (error: { message: string }) => {
123
- logger.error({ message: 'Server error:', error });
123
+ logger.error({ msg: 'Server error:', error });
124
124
 
125
125
  if (error.message.includes('Invalid token')) {
126
- logger.info({ message: 'Invalid token' });
126
+ logger.info({ msg: 'Invalid token' });
127
127
 
128
128
  // Disconnect current socket
129
129
  if (socket?.connected) {
@@ -142,14 +142,14 @@ const connect = async (token: string): Promise<void> => {
142
142
  listener(message, callback);
143
143
  });
144
144
  } else {
145
- console.warn({ message: 'No listeners found for event', event });
145
+ console.warn({ msg: 'No listeners found for event', event });
146
146
  }
147
147
  });
148
148
 
149
149
  // Handle process termination
150
150
  process.on('SIGINT', () => {
151
151
  if (socket?.connected) {
152
- logger.info({ message: '\nDisconnecting...' });
152
+ logger.info({ msg: '\nDisconnecting...' });
153
153
  socket.disconnect();
154
154
  }
155
155
  process.exit(0);
@@ -167,17 +167,17 @@ export const start = async (): Promise<void> => {
167
167
 
168
168
  export const disconnect = () => {
169
169
  if (!socket) {
170
- logger.warn({ message: 'No socket connection to disconnect' });
170
+ logger.warn({ msg: 'No socket connection to disconnect' });
171
171
  return;
172
172
  }
173
173
 
174
174
  if (socket.connected) {
175
- logger.info({ message: 'Disconnecting from Minded platform...' });
175
+ logger.info({ msg: 'Disconnecting from Minded platform...' });
176
176
  socket.disconnect();
177
177
  return;
178
178
  }
179
179
 
180
- logger.warn({ message: 'Socket is already disconnected' });
180
+ logger.warn({ msg: 'Socket is already disconnected' });
181
181
  };
182
182
 
183
183
  export const mindedConnection = {
@@ -42,6 +42,8 @@ export enum mindedConnectionSocketMessageType {
42
42
  INTERRUPT_SESSION_DEQUEUE = 'interrupt-session-dequeue',
43
43
  INTERRUPT_SESSION_HAS_MESSAGES = 'interrupt-session-has-messages',
44
44
  INTERRUPT_SESSION_GET_MESSAGES = 'interrupt-session-get-messages',
45
+ INTERRUPT_SESSION_INTERRUPT = 'interrupt-session-interrupt',
46
+ INTERRUPT_SESSION_IS_INTERRUPTED = 'interrupt-session-is-interrupted',
45
47
  }
46
48
 
47
49
  export type mindedConnectionSocketMessageTypeMap = {
@@ -0,0 +1,49 @@
1
+ import { ChatOpenAI, ChatOpenAIFields } from '@langchain/openai';
2
+ import { getConfig } from '../config';
3
+
4
+ export interface BaseParallelChatFields {
5
+ /**
6
+ * Number of parallel requests to make. Defaults to 1 (no parallelization).
7
+ * When > 1, multiple identical requests are sent and the fastest response is used.
8
+ */
9
+ numParallelRequests?: number;
10
+
11
+ /**
12
+ * Whether to log timing information for parallel requests
13
+ */
14
+ logTimings?: boolean;
15
+ }
16
+
17
+ export interface MindedChatOpenAIFields extends ChatOpenAIFields, BaseParallelChatFields {}
18
+
19
+ export class MindedChatOpenAI extends ChatOpenAI {
20
+ private numParallelRequests: number;
21
+ private logTimings: boolean;
22
+
23
+ constructor(fields?: MindedChatOpenAIFields) {
24
+ const { token, baseUrl } = getConfig();
25
+ const mindedBaseUrl = `${baseUrl}/sdk/llmGateway/chatOpenAI`;
26
+ if (!token) {
27
+ throw new Error('Minded token not found');
28
+ }
29
+
30
+ // Store parallel configuration
31
+ const numParallelRequests = fields?.numParallelRequests || 1;
32
+ const logTimings = fields?.logTimings || false;
33
+
34
+ super({
35
+ ...fields,
36
+ apiKey: token,
37
+ configuration: {
38
+ baseURL: mindedBaseUrl,
39
+ defaultHeaders: {
40
+ 'X-Parallel-Requests': numParallelRequests.toString(),
41
+ 'X-Log-Timings': logTimings.toString(),
42
+ },
43
+ },
44
+ });
45
+
46
+ this.numParallelRequests = numParallelRequests;
47
+ this.logTimings = logTimings;
48
+ }
49
+ }
@@ -0,0 +1,141 @@
1
+ import { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import { BaseMessage } from '@langchain/core/messages';
3
+ import { ChatGenerationChunk, ChatResult } from '@langchain/core/outputs';
4
+ import { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
5
+ import { logger } from '../../utils/logger';
6
+
7
+ export interface BaseParallelChatFields {
8
+ /**
9
+ * Number of parallel requests to make. Defaults to 1 (no parallelization).
10
+ * When > 1, multiple identical requests are sent and the fastest response is used.
11
+ */
12
+ numParallelRequests?: number;
13
+
14
+ /**
15
+ * Whether to log timing information for parallel requests
16
+ */
17
+ logTimings?: boolean;
18
+ }
19
+
20
+ /**
21
+ * Creates a wrapped version of a chat model with parallel request capabilities
22
+ */
23
+ export function createParallelWrapper<T extends BaseChatModel>(model: T, fields?: BaseParallelChatFields): T {
24
+ const numParallelRequests = fields?.numParallelRequests || 1;
25
+ const logTimings = fields?.logTimings || false;
26
+
27
+ // If parallel requests are disabled, return the original model
28
+ if (numParallelRequests <= 1) {
29
+ return model;
30
+ }
31
+
32
+ // Helper function that returns a promise that resolves with the second fulfilled promise
33
+ const promiseSecondFulfillment = <T>(promises: Promise<T>[]): Promise<T> => {
34
+ return new Promise((resolve) => {
35
+ let fulfillCount = 0;
36
+
37
+ for (const p of promises) {
38
+ Promise.resolve(p)
39
+ .then((value) => {
40
+ fulfillCount++;
41
+ if (fulfillCount === 2) {
42
+ resolve(value);
43
+ }
44
+ })
45
+ .catch(() => {
46
+ // Ignoring rejections for second fulfillment tracking
47
+ });
48
+ }
49
+ });
50
+ };
51
+
52
+ // Store original methods
53
+ const originalGenerate = model._generate.bind(model);
54
+ const originalStream = model._streamResponseChunks.bind(model);
55
+
56
+ // Override _generate
57
+ model._generate = async function (messages: BaseMessage[], options?: any, runManager?: CallbackManagerForLLMRun): Promise<ChatResult> {
58
+ const startTime = Date.now();
59
+
60
+ // Create array of identical requests
61
+ const requests = Array.from({ length: numParallelRequests }, () => originalGenerate(messages, options, runManager));
62
+
63
+ let fastestRequestTime = 0;
64
+ let secondFastestRequestTime = 0;
65
+
66
+ // Race all requests and return the fastest
67
+ const racePromise = Promise.race(requests).then((result) => {
68
+ fastestRequestTime = (Date.now() - startTime) / 1000.0;
69
+
70
+ if (logTimings) {
71
+ logger.debug({
72
+ msg: '[Model] Fastest request completed',
73
+ requestTime: fastestRequestTime,
74
+ numParallelRequests: numParallelRequests,
75
+ });
76
+ }
77
+
78
+ return result;
79
+ });
80
+
81
+ // Track second fastest if we have 3+ requests
82
+ if (requests.length >= 3) {
83
+ promiseSecondFulfillment(requests)
84
+ .then(() => {
85
+ secondFastestRequestTime = (Date.now() - startTime) / 1000.0;
86
+ })
87
+ .catch(() => {
88
+ // Ignore errors in timing tracking
89
+ });
90
+ }
91
+
92
+ // Track all completion times if we have 2+ requests
93
+ if (requests.length >= 2 && logTimings) {
94
+ Promise.all(requests)
95
+ .then(() => {
96
+ const allFinishTime = (Date.now() - startTime) / 1000.0;
97
+ const timeSaved = allFinishTime - fastestRequestTime;
98
+ const timeSavedFromSecond = secondFastestRequestTime > 0 ? secondFastestRequestTime - fastestRequestTime : 0;
99
+
100
+ logger.debug({
101
+ msg: '[Model] Time saved using parallel requests',
102
+ fastestRequestTime,
103
+ secondFastestRequestTime: secondFastestRequestTime || 'N/A',
104
+ allFinishTime,
105
+ timeSaved,
106
+ timeSavedFromSecond,
107
+ numParallelRequests: numParallelRequests,
108
+ });
109
+ })
110
+ .catch(() => {
111
+ // Ignore errors in timing tracking
112
+ });
113
+ }
114
+
115
+ return racePromise;
116
+ };
117
+
118
+ // Override _streamResponseChunks
119
+ model._streamResponseChunks = async function* (
120
+ messages: BaseMessage[],
121
+ options?: any,
122
+ runManager?: CallbackManagerForLLMRun,
123
+ ): AsyncGenerator<ChatGenerationChunk> {
124
+ // For streaming, we'll use the original implementation
125
+ // Parallel streaming is more complex and may not provide the same benefits
126
+ if (numParallelRequests > 1 && logTimings) {
127
+ logger.debug({
128
+ msg: '[Model] Streaming mode - using single request',
129
+ reason: 'Parallel streaming not implemented',
130
+ });
131
+ }
132
+
133
+ yield* originalStream(messages, options, runManager);
134
+ };
135
+
136
+ // Add properties for testing
137
+ (model as any).numParallelRequests = numParallelRequests;
138
+ (model as any).logTimings = logTimings;
139
+
140
+ return model;
141
+ }
@@ -71,7 +71,7 @@ function editorJsToMarkdown(blocks: OutputBlockData[]): string {
71
71
  }
72
72
  }
73
73
  } catch (error) {
74
- logger.error({ message: 'Error converting EditorJS blocks to markdown', error, block });
74
+ logger.error({ msg: 'Error converting EditorJS blocks to markdown', error, block });
75
75
  throw error;
76
76
  }
77
77
  })
@@ -113,7 +113,7 @@ function loadPlaybooksFromDirectories(directories: string[]): Playbook[] {
113
113
 
114
114
  for (const directory of directories) {
115
115
  if (!fs.existsSync(directory)) {
116
- logger.info({ message: `Playbooks directory does not exist: ${directory}` });
116
+ logger.info({ msg: `Playbooks directory does not exist: ${directory}` });
117
117
  continue;
118
118
  }
119
119
 
@@ -126,12 +126,12 @@ function loadPlaybooksFromDirectories(directories: string[]): Playbook[] {
126
126
 
127
127
  if (playbook && playbook.name && playbook.blocks) {
128
128
  playbooks.push(playbook);
129
- logger.info({ message: `Loaded playbook: ${playbook.name} from ${file}` });
129
+ logger.info({ msg: `Loaded playbook: ${playbook.name} from ${file}` });
130
130
  } else {
131
- logger.warn({ message: `Invalid playbook structure in ${file}` });
131
+ logger.warn({ msg: `Invalid playbook structure in ${file}` });
132
132
  }
133
133
  } catch (error) {
134
- logger.error({ message: `Failed to load playbook file ${file}: ${error}` });
134
+ logger.error({ msg: `Failed to load playbook file ${file}: ${error}` });
135
135
  }
136
136
  }
137
137
  }
@@ -183,7 +183,7 @@ export function compilePlaybooks(playbooks: Playbook[], params: Record<string, a
183
183
 
184
184
  return compiledPlaybooks;
185
185
  } catch (error) {
186
- logger.error({ message: 'Error compiling playbooks', error });
186
+ logger.error({ msg: 'Error compiling playbooks', error });
187
187
  return combinedPlaybooks; // Return uncompiled if there's an error
188
188
  }
189
189
  }
@@ -11,6 +11,7 @@ export enum NodeType {
11
11
  APP_TOOL = 'appTool',
12
12
  PROMPT_NODE = 'promptNode',
13
13
  JUMP_TO_NODE = 'jumpToNode',
14
+ BROWSER_TASK = 'browserTask',
14
15
  }
15
16
 
16
17
  export enum EdgeType {
@@ -58,6 +59,8 @@ export interface AppTriggerNode extends BaseTriggerNode, BaseAppNode {
58
59
 
59
60
  export interface WebhookTriggerNode extends BaseTriggerNode {
60
61
  triggerType: TriggerType.WEBHOOK;
62
+ autoTrigger?: boolean;
63
+ defaultPayload?: string;
61
64
  }
62
65
 
63
66
  export interface VoiceTriggerNode extends BaseTriggerNode {
@@ -87,6 +90,18 @@ export interface JumpToNode extends BaseNode {
87
90
  targetNodeId: string;
88
91
  }
89
92
 
93
+ export interface BrowserTaskNode extends BaseNode {
94
+ type: NodeType.BROWSER_TASK;
95
+ prompt: string;
96
+ model?: string;
97
+ inputSchema?: {
98
+ name: string;
99
+ type: 'string' | 'number';
100
+ description?: string;
101
+ required?: boolean;
102
+ }[];
103
+ }
104
+
90
105
  export type TriggerNode = AppTriggerNode | WebhookTriggerNode | ManualTriggerNode | VoiceTriggerNode;
91
106
 
92
107
  export interface JunctionNode extends BaseNode {
@@ -109,7 +124,7 @@ export interface AppToolNode extends BaseNode, BaseAppNode {
109
124
  actionKey: string;
110
125
  }
111
126
 
112
- export type Node = TriggerNode | JunctionNode | ToolNode | AppToolNode | PromptNode | JumpToNode;
127
+ export type Node = TriggerNode | JunctionNode | ToolNode | AppToolNode | PromptNode | JumpToNode | BrowserTaskNode;
113
128
 
114
129
  export interface BaseEdge {
115
130
  source: string;
@@ -181,4 +196,5 @@ export enum KnownTriggerNames {
181
196
  export enum internalNodesSuffix {
182
197
  HUMAN_IN_THE_LOOP = '_humanInTheLoop',
183
198
  TOOL_RUN = '_toolRun',
199
+ BROWSER_TASK_RUN = '_browserTaskRun',
184
200
  }
@@ -1,10 +1,10 @@
1
1
  import { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';
2
- import { MindedChatOpenAI } from '../platform/mindedChatOpenAI';
2
+ import { MindedChatOpenAI } from '../platform/models/mindedChatOpenAI';
3
3
 
4
4
  export type LLMConfig = {
5
- name: string,
6
- properties: Record<string, any>
7
- }
5
+ name: string;
6
+ properties: Record<string, any>;
7
+ };
8
8
 
9
9
  export type LLMProvider = 'ChatOpenAI' | 'AzureChatOpenAI' | 'MindedChatOpenAI';
10
10
 
@@ -12,4 +12,4 @@ export const LLMProviders: Record<LLMProvider, any> = {
12
12
  ChatOpenAI: ChatOpenAI,
13
13
  AzureChatOpenAI: AzureChatOpenAI,
14
14
  MindedChatOpenAI,
15
- }
15
+ };
@@ -13,6 +13,7 @@ export const createStateAnnotation = <Memory = any>() =>
13
13
  const index = res.findIndex((m) => m.id && m.id === message.id);
14
14
  if (index !== -1) {
15
15
  res[index].content = message.content;
16
+ res[index].additional_kwargs = { ...res[index].additional_kwargs, ...message.additional_kwargs };
16
17
  }
17
18
  } else {
18
19
  res.push(message);
@@ -32,6 +33,10 @@ export const createStateAnnotation = <Memory = any>() =>
32
33
  sessionId: Annotation<string>({
33
34
  reducer: (a, b) => b || a,
34
35
  }),
36
+ goto: Annotation<string | null | undefined>({
37
+ default: () => null,
38
+ reducer: (a, b) => b,
39
+ }),
35
40
  sessionType: Annotation<SessionType>({
36
41
  default: () => SessionType.TEXT,
37
42
  reducer: (a, b) => b || a,
@@ -4,7 +4,7 @@ dotenv.config();
4
4
 
5
5
  // Create a Pino logger with a custom log format
6
6
  export const logger = pino({
7
- level: process.env.LOG_LEVEL || 'info',
7
+ level: process.env.LOG_LEVEL || 'trace',
8
8
  base: null,
9
9
  transport: {
10
10
  target: 'pino-pretty',
@@ -12,7 +12,6 @@ export const logger = pino({
12
12
  colorize: true,
13
13
  crlf: true,
14
14
  translateTime: 'SYS:standard',
15
- messageKey: 'message', // Use 'message' instead of default 'msg'
16
15
  },
17
16
  },
18
17
  formatters: {
@@ -25,7 +25,7 @@ export class VoiceSession {
25
25
  private onDisconnectCallback?: () => void;
26
26
 
27
27
  constructor({ agent, sessionId, firstMessage, voiceId }: { agent: Agent; sessionId: string; firstMessage: string; voiceId?: string }) {
28
- logger.debug({ message: 'Starting voice session', sessionId, firstMessage, voiceId });
28
+ logger.debug({ msg: '[Voice] Starting voice session', sessionId, firstMessage, voiceId });
29
29
  this.agent = agent;
30
30
  this.sessionId = sessionId;
31
31
  this.firstMessage = firstMessage;
@@ -51,7 +51,6 @@ export class VoiceSession {
51
51
  apiKey: elevenLabsKey,
52
52
  });
53
53
 
54
- logger.debug({ message: 'Connecting to ElevenLabs', sessionId: this.sessionId });
55
54
  this.elevenLabsSocket = new WebSocket(signedUrl);
56
55
  this.setupSocketHandlers();
57
56
  }
@@ -90,7 +89,7 @@ export class VoiceSession {
90
89
  const socket = this.elevenLabsSocket!; // non-null assertion once, we ensured it's assigned in init()
91
90
 
92
91
  socket.onopen = () => {
93
- logger.debug({ message: 'Connected to ElevenLabs', sessionId: this.sessionId });
92
+ logger.debug({ msg: '[Voice] Connected to ElevenLabs', sessionId: this.sessionId });
94
93
  const initiationData: ConversationInitiationClientData = {
95
94
  type: 'conversation_initiation_client_data',
96
95
  conversation_config_override: {
@@ -116,13 +115,13 @@ export class VoiceSession {
116
115
  };
117
116
 
118
117
  socket.onclose = () => {
119
- logger.debug({ message: 'Disconnected from ElevenLabs, removing voice session', sessionId: this.sessionId });
118
+ logger.debug({ msg: '[Voice] Disconnected from ElevenLabs, removing voice session', sessionId: this.sessionId });
120
119
  this.onDisconnectCallback?.();
121
120
  this.agent.voiceSessions.delete(this.sessionId);
122
121
  };
123
122
 
124
123
  socket.onerror = (err: unknown) => {
125
- logger.error({ message: '[ElevenLabsVoice] socket error', sessionId: this.sessionId, error: err });
124
+ logger.error({ msg: '[Voice] socket error', sessionId: this.sessionId, error: err });
126
125
  };
127
126
 
128
127
  socket.onmessage = async (event: any) => {
@@ -136,7 +135,7 @@ export class VoiceSession {
136
135
  break;
137
136
  case 'user_transcript':
138
137
  logger.debug({
139
- message: 'User transcript received',
138
+ msg: '[Voice] Received user transcript',
140
139
  sessionId: this.sessionId,
141
140
  data: data.user_transcription_event.user_transcript,
142
141
  });
@@ -148,6 +147,7 @@ export class VoiceSession {
148
147
  }
149
148
  break;
150
149
  case 'agent_response':
150
+ logger.debug({ msg: '[Voice] Received agent response' });
151
151
  if (this.onMessageCallback) {
152
152
  this.onMessageCallback(
153
153
  data.agent_response_event.agent_response,
@@ -156,8 +156,9 @@ export class VoiceSession {
156
156
  }
157
157
  break;
158
158
  case 'interruption':
159
- logger.debug('Interruption received');
159
+ logger.debug({ msg: '[Voice] Received interruption' });
160
160
  this.onInterruptionCallback?.();
161
+ this.agent.interruptSessionManager.interrupt(this.sessionId);
161
162
  // Send interruption event to dashboard if connected
162
163
  if (getConfig().dashboardConnected) {
163
164
  try {
@@ -167,12 +168,12 @@ export class VoiceSession {
167
168
  timestamp: Date.now(),
168
169
  });
169
170
  } catch (error) {
170
- logger.error({ message: '[ElevenLabsVoice] Error sending interruption to dashboard', sessionId: this.sessionId, error });
171
+ logger.error({ msg: '[Voice] Error sending interruption to dashboard', sessionId: this.sessionId, error });
171
172
  }
172
173
  }
173
174
  break;
174
175
  case 'audio':
175
- logger.debug({ message: 'Agent audio received', sessionId: this.sessionId });
176
+ logger.debug({ msg: '[Voice] Received audio response to user', sessionId: this.sessionId });
176
177
  if (this.onAudioCallback) {
177
178
  this.onAudioCallback(data.audio_event.audio_base_64);
178
179
  }
@@ -185,17 +186,17 @@ export class VoiceSession {
185
186
  type: mindedConnectionSocketMessageType.DASHBOARD_VOICE_AGENT_AUDIO,
186
187
  });
187
188
  } catch (error) {
188
- logger.error(`[ElevenLabsVoice] Error sending audio to dashboard: ${error}`);
189
+ logger.error({ msg: '[Voice] Error sending audio to dashboard', sessionId: this.sessionId, error });
189
190
  }
190
191
  }
191
192
  break;
192
193
  case 'conversation_initiation_metadata':
193
- logger.debug({ message: 'ElevenLabs conversation initiation metadata', sessionId: this.sessionId, data });
194
+ logger.trace({ msg: '[Voice] ElevenLabs conversation initiation metadata', sessionId: this.sessionId, data });
194
195
  break;
195
196
  case 'agent_response_correction':
196
197
  try {
197
198
  logger.debug({
198
- message: 'Agent response correction received',
199
+ msg: '[Voice] Received agent response correction',
199
200
  sessionId: this.sessionId,
200
201
  data: data.agent_response_correction_event,
201
202
  });
@@ -203,19 +204,18 @@ export class VoiceSession {
203
204
  data.agent_response_correction_event.original_agent_response,
204
205
  data.agent_response_correction_event.corrected_agent_response,
205
206
  );
206
- } catch (error) {
207
- logger.error({ message: '[ElevenLabsVoice] Error updating agent response', sessionId: this.sessionId, error });
207
+ } catch (error: any) {
208
+ logger.error({ msg: '[Voice] Error updating agent response', sessionId: this.sessionId, error: error.message });
208
209
  }
209
210
  break;
210
211
  default:
211
- logger.debug({ message: 'Received unknown message from ElevenLabs', sessionId: this.sessionId, data });
212
+ logger.debug({ msg: '[Voice] Received unknown message from ElevenLabs', sessionId: this.sessionId, data });
212
213
  break;
213
214
  }
214
215
  };
215
216
  }
216
217
 
217
218
  private async addFirstMessageToState(): Promise<void> {
218
- logger.debug({ message: 'Adding first message to state', sessionId: this.sessionId, firstMessage: this.firstMessage });
219
219
  const graphState = await this.agent.compiledGraph.getState(this.agent.getLangraphConfig(this.sessionId));
220
220
  if (!graphState.values.messages?.length) {
221
221
  await this.agent.compiledGraph.updateState(this.agent.getLangraphConfig(this.sessionId), {
@@ -227,8 +227,9 @@ export class VoiceSession {
227
227
 
228
228
  private async updateAgentResponse(originalAgentResponse: string, correctedAgentResponse: string): Promise<void> {
229
229
  const graphState = await this.agent.compiledGraph.getState(this.agent.getLangraphConfig(this.sessionId));
230
+ const cleanedOriginalAgentResponse = originalAgentResponse.replace('... ', '');
230
231
  const agentMessage: AIMessage | null = graphState.values.messages.find(
231
- (message: BaseMessage) => message.content === originalAgentResponse && message instanceof AIMessage,
232
+ (message: BaseMessage) => message.content === cleanedOriginalAgentResponse && message instanceof AIMessage,
232
233
  );
233
234
  if (agentMessage) {
234
235
  agentMessage.content = correctedAgentResponse;
@@ -240,12 +241,12 @@ export class VoiceSession {
240
241
  overrideStartFromNodeId: currentNodeId,
241
242
  });
242
243
  } else {
243
- logger.warn({ message: 'Agent message not found for correction', sessionId: this.sessionId, originalAgentResponse });
244
+ logger.warn({ msg: '[Voice] Agent message not found for correction', sessionId: this.sessionId, originalAgentResponse });
244
245
  }
245
246
  }
246
247
 
247
248
  public hangup(): void {
248
- logger.info({ message: 'Hanging up voice session', sessionId: this.sessionId });
249
+ logger.info({ msg: '[Voice] Hanging up voice session', sessionId: this.sessionId });
249
250
  this.onDisconnectCallback?.();
250
251
  this.elevenLabsSocket?.close();
251
252
  }
@@ -1,19 +0,0 @@
1
- import { ChatOpenAI, ChatOpenAIFields } from "@langchain/openai";
2
- import { getConfig } from "./config";
3
-
4
- export class MindedChatOpenAI extends ChatOpenAI {
5
- constructor(fields?: ChatOpenAIFields) {
6
- const { token, baseUrl } = getConfig();
7
- const mindedBaseUrl = `${baseUrl}/sdk/llmGateway/chatOpenAI`;
8
- if (!token) {
9
- throw new Error('Minded token not found');
10
- }
11
- super({
12
- ...fields,
13
- apiKey: token,
14
- configuration: {
15
- baseURL: mindedBaseUrl,
16
- },
17
- });
18
- }
19
- }