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

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 (136) hide show
  1. package/dist/agent.d.ts.map +1 -1
  2. package/dist/agent.js +29 -16
  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.js +1 -1
  30. package/dist/interrupts/BaseInterruptSessionManager.js.map +1 -1
  31. package/dist/interrupts/interruptSessionManagerFactory.js +2 -2
  32. package/dist/interrupts/interruptSessionManagerFactory.js.map +1 -1
  33. package/dist/llm/createLlmInstance.d.ts +1 -1
  34. package/dist/llm/createLlmInstance.d.ts.map +1 -1
  35. package/dist/llm/createLlmInstance.js +18 -1
  36. package/dist/llm/createLlmInstance.js.map +1 -1
  37. package/dist/nodes/addAppToolNode.d.ts.map +1 -1
  38. package/dist/nodes/addAppToolNode.js +5 -4
  39. package/dist/nodes/addAppToolNode.js.map +1 -1
  40. package/dist/nodes/addBrowserTaskNode.d.ts +13 -0
  41. package/dist/nodes/addBrowserTaskNode.d.ts.map +1 -0
  42. package/dist/nodes/addBrowserTaskNode.js +232 -0
  43. package/dist/nodes/addBrowserTaskNode.js.map +1 -0
  44. package/dist/nodes/addBrowserTaskRunNode.d.ts +13 -0
  45. package/dist/nodes/addBrowserTaskRunNode.d.ts.map +1 -0
  46. package/dist/nodes/addBrowserTaskRunNode.js +130 -0
  47. package/dist/nodes/addBrowserTaskRunNode.js.map +1 -0
  48. package/dist/nodes/addHumanInTheLoopNode.d.ts.map +1 -1
  49. package/dist/nodes/addHumanInTheLoopNode.js +1 -1
  50. package/dist/nodes/addHumanInTheLoopNode.js.map +1 -1
  51. package/dist/nodes/addJumpToNode.d.ts.map +1 -1
  52. package/dist/nodes/addJumpToNode.js +2 -1
  53. package/dist/nodes/addJumpToNode.js.map +1 -1
  54. package/dist/nodes/addJunctionNode.d.ts.map +1 -1
  55. package/dist/nodes/addJunctionNode.js +1 -0
  56. package/dist/nodes/addJunctionNode.js.map +1 -1
  57. package/dist/nodes/addPromptNode.d.ts.map +1 -1
  58. package/dist/nodes/addPromptNode.js +8 -18
  59. package/dist/nodes/addPromptNode.js.map +1 -1
  60. package/dist/nodes/addToolNode.js +2 -4
  61. package/dist/nodes/addToolNode.js.map +1 -1
  62. package/dist/nodes/addToolRunNode.d.ts.map +1 -1
  63. package/dist/nodes/addToolRunNode.js +2 -1
  64. package/dist/nodes/addToolRunNode.js.map +1 -1
  65. package/dist/nodes/addTriggerNode.d.ts.map +1 -1
  66. package/dist/nodes/addTriggerNode.js +2 -1
  67. package/dist/nodes/addTriggerNode.js.map +1 -1
  68. package/dist/nodes/nodeFactory.d.ts.map +1 -1
  69. package/dist/nodes/nodeFactory.js +4 -0
  70. package/dist/nodes/nodeFactory.js.map +1 -1
  71. package/dist/platform/mindedConnection.js +13 -13
  72. package/dist/platform/mindedConnection.js.map +1 -1
  73. package/dist/platform/models/mindedChatOpenAI.d.ts +20 -0
  74. package/dist/platform/models/mindedChatOpenAI.d.ts.map +1 -0
  75. package/dist/platform/models/mindedChatOpenAI.js +32 -0
  76. package/dist/platform/models/mindedChatOpenAI.js.map +1 -0
  77. package/dist/platform/models/parallelWrapper.d.ts +17 -0
  78. package/dist/platform/models/parallelWrapper.d.ts.map +1 -0
  79. package/dist/platform/models/parallelWrapper.js +105 -0
  80. package/dist/platform/models/parallelWrapper.js.map +1 -0
  81. package/dist/playbooks/playbooks.js +6 -6
  82. package/dist/playbooks/playbooks.js.map +1 -1
  83. package/dist/types/Flows.types.d.ts +18 -3
  84. package/dist/types/Flows.types.d.ts.map +1 -1
  85. package/dist/types/Flows.types.js +2 -0
  86. package/dist/types/Flows.types.js.map +1 -1
  87. package/dist/types/LLM.types.d.ts.map +1 -1
  88. package/dist/types/LLM.types.js +1 -1
  89. package/dist/types/LLM.types.js.map +1 -1
  90. package/dist/types/LangGraph.types.d.ts +2 -0
  91. package/dist/types/LangGraph.types.d.ts.map +1 -1
  92. package/dist/types/LangGraph.types.js +5 -0
  93. package/dist/types/LangGraph.types.js.map +1 -1
  94. package/dist/utils/logger.js +1 -1
  95. package/dist/utils/logger.js.map +1 -1
  96. package/dist/voice/voiceSession.d.ts.map +1 -1
  97. package/dist/voice/voiceSession.js +16 -17
  98. package/dist/voice/voiceSession.js.map +1 -1
  99. package/docs/SUMMARY.md +1 -0
  100. package/docs/low-code-editor/nodes.md +27 -0
  101. package/docs/low-code-editor/tools.md +32 -0
  102. package/docs/platform/parallel-llm.md +242 -0
  103. package/package.json +2 -1
  104. package/src/agent.ts +30 -18
  105. package/src/browserTask/executeBrowserTask.ts +213 -0
  106. package/src/checkpointer/checkpointSaverFactory.ts +1 -1
  107. package/src/cli/index.ts +14 -14
  108. package/src/edges/createDirectEdge.ts +7 -2
  109. package/src/edges/createLogicalRouter.ts +23 -6
  110. package/src/edges/createPromptRouter.ts +13 -6
  111. package/src/edges/edgeFactory.ts +20 -4
  112. package/src/index.ts +6 -0
  113. package/src/interrupts/BaseInterruptSessionManager.ts +1 -1
  114. package/src/interrupts/interruptSessionManagerFactory.ts +2 -2
  115. package/src/llm/createLlmInstance.ts +25 -2
  116. package/src/nodes/addAppToolNode.ts +5 -4
  117. package/src/nodes/addBrowserTaskNode.ts +231 -0
  118. package/src/nodes/addBrowserTaskRunNode.ts +144 -0
  119. package/src/nodes/addHumanInTheLoopNode.ts +2 -1
  120. package/src/nodes/addJumpToNode.ts +2 -1
  121. package/src/nodes/addJunctionNode.ts +1 -0
  122. package/src/nodes/addPromptNode.ts +8 -19
  123. package/src/nodes/addToolNode.ts +4 -4
  124. package/src/nodes/addToolRunNode.ts +3 -1
  125. package/src/nodes/addTriggerNode.ts +2 -1
  126. package/src/nodes/nodeFactory.ts +5 -1
  127. package/src/platform/mindedConnection.ts +13 -13
  128. package/src/platform/models/mindedChatOpenAI.ts +49 -0
  129. package/src/platform/models/parallelWrapper.ts +141 -0
  130. package/src/playbooks/playbooks.ts +6 -6
  131. package/src/types/Flows.types.ts +17 -1
  132. package/src/types/LLM.types.ts +5 -5
  133. package/src/types/LangGraph.types.ts +5 -0
  134. package/src/utils/logger.ts +1 -1
  135. package/src/voice/voiceSession.ts +16 -17
  136. package/src/platform/mindedChatOpenAI.ts +0 -19
@@ -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
+ };
@@ -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 = {
@@ -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',
@@ -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,7 +156,7 @@ 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
161
  // Send interruption event to dashboard if connected
162
162
  if (getConfig().dashboardConnected) {
@@ -167,12 +167,12 @@ export class VoiceSession {
167
167
  timestamp: Date.now(),
168
168
  });
169
169
  } catch (error) {
170
- logger.error({ message: '[ElevenLabsVoice] Error sending interruption to dashboard', sessionId: this.sessionId, error });
170
+ logger.error({ msg: '[Voice] Error sending interruption to dashboard', sessionId: this.sessionId, error });
171
171
  }
172
172
  }
173
173
  break;
174
174
  case 'audio':
175
- logger.debug({ message: 'Agent audio received', sessionId: this.sessionId });
175
+ logger.debug({ msg: '[Voice] Received audio response to user', sessionId: this.sessionId });
176
176
  if (this.onAudioCallback) {
177
177
  this.onAudioCallback(data.audio_event.audio_base_64);
178
178
  }
@@ -185,17 +185,17 @@ export class VoiceSession {
185
185
  type: mindedConnectionSocketMessageType.DASHBOARD_VOICE_AGENT_AUDIO,
186
186
  });
187
187
  } catch (error) {
188
- logger.error(`[ElevenLabsVoice] Error sending audio to dashboard: ${error}`);
188
+ logger.error({ msg: '[Voice] Error sending audio to dashboard', sessionId: this.sessionId, error });
189
189
  }
190
190
  }
191
191
  break;
192
192
  case 'conversation_initiation_metadata':
193
- logger.debug({ message: 'ElevenLabs conversation initiation metadata', sessionId: this.sessionId, data });
193
+ logger.trace({ msg: '[Voice] ElevenLabs conversation initiation metadata', sessionId: this.sessionId, data });
194
194
  break;
195
195
  case 'agent_response_correction':
196
196
  try {
197
197
  logger.debug({
198
- message: 'Agent response correction received',
198
+ msg: '[Voice] Received agent response correction',
199
199
  sessionId: this.sessionId,
200
200
  data: data.agent_response_correction_event,
201
201
  });
@@ -204,18 +204,17 @@ export class VoiceSession {
204
204
  data.agent_response_correction_event.corrected_agent_response,
205
205
  );
206
206
  } catch (error) {
207
- logger.error({ message: '[ElevenLabsVoice] Error updating agent response', sessionId: this.sessionId, error });
207
+ logger.error({ msg: '[Voice] Error updating agent response', sessionId: this.sessionId, error });
208
208
  }
209
209
  break;
210
210
  default:
211
- logger.debug({ message: 'Received unknown message from ElevenLabs', sessionId: this.sessionId, data });
211
+ logger.debug({ msg: '[Voice] Received unknown message from ElevenLabs', sessionId: this.sessionId, data });
212
212
  break;
213
213
  }
214
214
  };
215
215
  }
216
216
 
217
217
  private async addFirstMessageToState(): Promise<void> {
218
- logger.debug({ message: 'Adding first message to state', sessionId: this.sessionId, firstMessage: this.firstMessage });
219
218
  const graphState = await this.agent.compiledGraph.getState(this.agent.getLangraphConfig(this.sessionId));
220
219
  if (!graphState.values.messages?.length) {
221
220
  await this.agent.compiledGraph.updateState(this.agent.getLangraphConfig(this.sessionId), {
@@ -240,12 +239,12 @@ export class VoiceSession {
240
239
  overrideStartFromNodeId: currentNodeId,
241
240
  });
242
241
  } else {
243
- logger.warn({ message: 'Agent message not found for correction', sessionId: this.sessionId, originalAgentResponse });
242
+ logger.warn({ msg: '[Voice] Agent message not found for correction', sessionId: this.sessionId, originalAgentResponse });
244
243
  }
245
244
  }
246
245
 
247
246
  public hangup(): void {
248
- logger.info({ message: 'Hanging up voice session', sessionId: this.sessionId });
247
+ logger.info({ msg: '[Voice] Hanging up voice session', sessionId: this.sessionId });
249
248
  this.onDisconnectCallback?.();
250
249
  this.elevenLabsSocket?.close();
251
250
  }
@@ -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
- }