@minded-ai/mindedjs 1.0.102 → 1.0.103-beta-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +4 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +76 -30
- package/dist/agent.js.map +1 -1
- package/dist/checkpointer/checkpointSaverFactory.js +1 -1
- package/dist/checkpointer/checkpointSaverFactory.js.map +1 -1
- package/dist/cli/index.js +12 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/edges/createDirectEdge.d.ts +1 -2
- package/dist/edges/createDirectEdge.d.ts.map +1 -1
- package/dist/edges/createDirectEdge.js +2 -6
- package/dist/edges/createDirectEdge.js.map +1 -1
- package/dist/edges/createLogicalRouter.d.ts.map +1 -1
- package/dist/edges/createLogicalRouter.js +6 -23
- package/dist/edges/createLogicalRouter.js.map +1 -1
- package/dist/edges/createPromptRouter.d.ts.map +1 -1
- package/dist/edges/createPromptRouter.js +6 -12
- package/dist/edges/createPromptRouter.js.map +1 -1
- package/dist/edges/edgeFactory.d.ts.map +1 -1
- package/dist/edges/edgeFactory.js +3 -8
- package/dist/edges/edgeFactory.js.map +1 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -6
- package/dist/index.js.map +1 -1
- package/dist/interrupts/BaseInterruptSessionManager.d.ts +51 -0
- package/dist/interrupts/BaseInterruptSessionManager.d.ts.map +1 -0
- package/dist/interrupts/BaseInterruptSessionManager.js +39 -0
- package/dist/interrupts/BaseInterruptSessionManager.js.map +1 -0
- package/dist/interrupts/InterruptSessionManager.types.d.ts +36 -0
- package/dist/interrupts/InterruptSessionManager.types.d.ts.map +1 -0
- package/dist/interrupts/InterruptSessionManager.types.js +40 -0
- package/dist/interrupts/InterruptSessionManager.types.js.map +1 -0
- package/dist/interrupts/MemoryInterruptSessionManager.d.ts +14 -0
- package/dist/interrupts/MemoryInterruptSessionManager.d.ts.map +1 -0
- package/dist/interrupts/MemoryInterruptSessionManager.js +56 -0
- package/dist/interrupts/MemoryInterruptSessionManager.js.map +1 -0
- package/dist/interrupts/MindedInterruptSessionManager.d.ts +13 -0
- package/dist/interrupts/MindedInterruptSessionManager.d.ts.map +1 -0
- package/dist/interrupts/MindedInterruptSessionManager.js +156 -0
- package/dist/interrupts/MindedInterruptSessionManager.js.map +1 -0
- package/dist/interrupts/interruptSessionManagerFactory.d.ts +3 -0
- package/dist/interrupts/interruptSessionManagerFactory.d.ts.map +1 -0
- package/dist/interrupts/interruptSessionManagerFactory.js +56 -0
- package/dist/interrupts/interruptSessionManagerFactory.js.map +1 -0
- package/dist/llm/createLlmInstance.d.ts +1 -1
- package/dist/llm/createLlmInstance.d.ts.map +1 -1
- package/dist/llm/createLlmInstance.js +1 -18
- package/dist/llm/createLlmInstance.js.map +1 -1
- package/dist/nodes/addAppToolNode.d.ts.map +1 -1
- package/dist/nodes/addAppToolNode.js +4 -5
- package/dist/nodes/addAppToolNode.js.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.d.ts.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.js +3 -2
- package/dist/nodes/addHumanInTheLoopNode.js.map +1 -1
- package/dist/nodes/addJumpToNode.d.ts.map +1 -1
- package/dist/nodes/addJumpToNode.js +1 -2
- package/dist/nodes/addJumpToNode.js.map +1 -1
- package/dist/nodes/addJunctionNode.d.ts.map +1 -1
- package/dist/nodes/addJunctionNode.js +0 -1
- package/dist/nodes/addJunctionNode.js.map +1 -1
- package/dist/nodes/addPromptNode.d.ts.map +1 -1
- package/dist/nodes/addPromptNode.js +61 -7
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolNode.js +4 -2
- package/dist/nodes/addToolNode.js.map +1 -1
- package/dist/nodes/addToolRunNode.d.ts.map +1 -1
- package/dist/nodes/addToolRunNode.js +2 -2
- package/dist/nodes/addToolRunNode.js.map +1 -1
- package/dist/nodes/addTriggerNode.d.ts.map +1 -1
- package/dist/nodes/addTriggerNode.js +1 -2
- package/dist/nodes/addTriggerNode.js.map +1 -1
- package/dist/nodes/nodeFactory.d.ts.map +1 -1
- package/dist/nodes/nodeFactory.js +0 -4
- package/dist/nodes/nodeFactory.js.map +1 -1
- package/dist/platform/mindedChatOpenAI.d.ts +5 -0
- package/dist/platform/mindedChatOpenAI.d.ts.map +1 -0
- package/dist/platform/{models/mindedChatOpenAI.js → mindedChatOpenAI.js} +1 -10
- package/dist/platform/mindedChatOpenAI.js.map +1 -0
- package/dist/platform/mindedConnection.d.ts.map +1 -1
- package/dist/platform/mindedConnection.js +12 -12
- package/dist/platform/mindedConnection.js.map +1 -1
- package/dist/platform/mindedConnectionTypes.d.ts +151 -1
- package/dist/platform/mindedConnectionTypes.d.ts.map +1 -1
- package/dist/platform/mindedConnectionTypes.js +9 -0
- package/dist/platform/mindedConnectionTypes.js.map +1 -1
- package/dist/playbooks/playbooks.js +4 -4
- package/dist/playbooks/playbooks.js.map +1 -1
- package/dist/types/Agent.types.d.ts +2 -0
- package/dist/types/Agent.types.d.ts.map +1 -1
- package/dist/types/Agent.types.js.map +1 -1
- package/dist/types/Flows.types.d.ts +3 -18
- package/dist/types/Flows.types.d.ts.map +1 -1
- package/dist/types/Flows.types.js +0 -2
- package/dist/types/Flows.types.js.map +1 -1
- package/dist/types/LLM.types.d.ts.map +1 -1
- package/dist/types/LLM.types.js +1 -1
- package/dist/types/LLM.types.js.map +1 -1
- package/dist/types/LangGraph.types.d.ts +2 -4
- package/dist/types/LangGraph.types.d.ts.map +1 -1
- package/dist/types/LangGraph.types.js +2 -5
- package/dist/types/LangGraph.types.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +2 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/voice/voiceSession.d.ts.map +1 -1
- package/dist/voice/voiceSession.js +17 -16
- package/dist/voice/voiceSession.js.map +1 -1
- package/docs/SUMMARY.md +0 -1
- package/docs/getting-started/installation.md +0 -42
- package/docs/low-code-editor/nodes.md +0 -27
- package/docs/low-code-editor/tools.md +0 -32
- package/package.json +2 -3
- package/src/agent.ts +93 -32
- package/src/checkpointer/checkpointSaverFactory.ts +1 -1
- package/src/cli/index.ts +12 -12
- package/src/edges/createDirectEdge.ts +2 -7
- package/src/edges/createLogicalRouter.ts +6 -23
- package/src/edges/createPromptRouter.ts +6 -13
- package/src/edges/edgeFactory.ts +4 -20
- package/src/index.ts +0 -6
- package/src/interrupts/BaseInterruptSessionManager.ts +94 -0
- package/src/interrupts/MemoryInterruptSessionManager.ts +57 -0
- package/src/interrupts/MindedInterruptSessionManager.ts +155 -0
- package/src/interrupts/interruptSessionManagerFactory.ts +20 -0
- package/src/llm/createLlmInstance.ts +2 -25
- package/src/nodes/addAppToolNode.ts +4 -5
- package/src/nodes/addHumanInTheLoopNode.ts +3 -3
- package/src/nodes/addJumpToNode.ts +1 -2
- package/src/nodes/addJunctionNode.ts +0 -1
- package/src/nodes/addPromptNode.ts +65 -10
- package/src/nodes/addToolNode.ts +4 -4
- package/src/nodes/addToolRunNode.ts +2 -4
- package/src/nodes/addTriggerNode.ts +1 -2
- package/src/nodes/nodeFactory.ts +1 -5
- package/src/platform/mindedChatOpenAI.ts +19 -0
- package/src/platform/mindedConnection.ts +15 -25
- package/src/platform/mindedConnectionTypes.ts +188 -1
- package/src/playbooks/playbooks.ts +4 -4
- package/src/types/Agent.types.ts +2 -0
- package/src/types/Flows.types.ts +1 -17
- package/src/types/LLM.types.ts +5 -5
- package/src/types/LangGraph.types.ts +2 -5
- package/src/utils/logger.ts +2 -1
- package/src/voice/voiceSession.ts +17 -16
- package/dist/browserTask/executeBrowserTask.d.ts +0 -12
- package/dist/browserTask/executeBrowserTask.d.ts.map +0 -1
- package/dist/browserTask/executeBrowserTask.js +0 -181
- package/dist/browserTask/executeBrowserTask.js.map +0 -1
- package/dist/nodes/addBrowserTaskNode.d.ts +0 -13
- package/dist/nodes/addBrowserTaskNode.d.ts.map +0 -1
- package/dist/nodes/addBrowserTaskNode.js +0 -230
- package/dist/nodes/addBrowserTaskNode.js.map +0 -1
- package/dist/nodes/addBrowserTaskRunNode.d.ts +0 -13
- package/dist/nodes/addBrowserTaskRunNode.d.ts.map +0 -1
- package/dist/nodes/addBrowserTaskRunNode.js +0 -126
- package/dist/nodes/addBrowserTaskRunNode.js.map +0 -1
- package/dist/platform/models/mindedChatOpenAI.d.ts +0 -20
- package/dist/platform/models/mindedChatOpenAI.d.ts.map +0 -1
- package/dist/platform/models/mindedChatOpenAI.js.map +0 -1
- package/dist/platform/models/parallelWrapper.d.ts +0 -17
- package/dist/platform/models/parallelWrapper.d.ts.map +0 -1
- package/dist/platform/models/parallelWrapper.js +0 -105
- package/dist/platform/models/parallelWrapper.js.map +0 -1
- package/docs/platform/parallel-llm.md +0 -242
- package/src/browserTask/executeBrowserTask.ts +0 -213
- package/src/nodes/addBrowserTaskNode.ts +0 -229
- package/src/nodes/addBrowserTaskRunNode.ts +0 -142
- package/src/platform/models/mindedChatOpenAI.ts +0 -49
- package/src/platform/models/parallelWrapper.ts +0 -141
|
@@ -1,229 +0,0 @@
|
|
|
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
|
-
taskId,
|
|
175
|
-
liveUrl: taskDetails.live_url,
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
return {
|
|
181
|
-
history: createHistoryStep<HistoryStep>(state.history, {
|
|
182
|
-
type: NodeType.BROWSER_TASK,
|
|
183
|
-
nodeId: node.name,
|
|
184
|
-
nodeDisplayName: node.displayName,
|
|
185
|
-
raw: { taskId, liveUrl: taskDetails.live_url, inputParams },
|
|
186
|
-
messageIds: [toolCallingMessage.id!],
|
|
187
|
-
}),
|
|
188
|
-
messages: [toolCallingMessage],
|
|
189
|
-
};
|
|
190
|
-
} catch (error: any) {
|
|
191
|
-
logger.error(`Error creating browser task node ${node.displayName}: ${error}`);
|
|
192
|
-
|
|
193
|
-
const errorMessageId = uuidv4();
|
|
194
|
-
const errorToolCallId = uuidv4();
|
|
195
|
-
|
|
196
|
-
const toolCallingMessage = new AIMessage({
|
|
197
|
-
id: errorMessageId,
|
|
198
|
-
content: '',
|
|
199
|
-
tool_calls: [
|
|
200
|
-
{
|
|
201
|
-
id: errorToolCallId,
|
|
202
|
-
name: 'browser-task',
|
|
203
|
-
args: {
|
|
204
|
-
error: error.message,
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
],
|
|
208
|
-
additional_kwargs: {
|
|
209
|
-
mindedMetadata: {
|
|
210
|
-
nodeType: NodeType.BROWSER_TASK,
|
|
211
|
-
error: error.message,
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
return {
|
|
217
|
-
history: createHistoryStep<HistoryStep>(state.history, {
|
|
218
|
-
type: NodeType.BROWSER_TASK,
|
|
219
|
-
nodeId: node.name,
|
|
220
|
-
nodeDisplayName: node.displayName,
|
|
221
|
-
raw: error,
|
|
222
|
-
messageIds: [errorMessageId],
|
|
223
|
-
}),
|
|
224
|
-
messages: [toolCallingMessage],
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
graph.addNode(node.name, callback);
|
|
229
|
-
};
|
|
@@ -1,142 +0,0 @@
|
|
|
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
|
-
|
|
30
|
-
const toolCall = toolCallObj.tool_calls[0];
|
|
31
|
-
const { taskId, ...inputParams } = toolCall.args;
|
|
32
|
-
|
|
33
|
-
if (!taskId) {
|
|
34
|
-
throw new Error('Task ID not found in tool call arguments');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
// Wait for task completion
|
|
39
|
-
const completedTask = await waitForCompletion(taskId);
|
|
40
|
-
logger.debug({ msg: 'Browser task completed', taskId, output: completedTask.output });
|
|
41
|
-
|
|
42
|
-
// Create tool message with the result
|
|
43
|
-
const toolMessage = new ToolMessage({
|
|
44
|
-
id: uuidv4(),
|
|
45
|
-
content: JSON.stringify({
|
|
46
|
-
result: completedTask.output || 'Task completed successfully',
|
|
47
|
-
steps: completedTask.steps || [],
|
|
48
|
-
inputParams: inputParams,
|
|
49
|
-
}),
|
|
50
|
-
name: 'browser-task',
|
|
51
|
-
tool_call_id: toolCall.id,
|
|
52
|
-
status: 'success',
|
|
53
|
-
additional_kwargs: {
|
|
54
|
-
mindedMetadata: {
|
|
55
|
-
nodeType: NodeType.BROWSER_TASK,
|
|
56
|
-
taskId,
|
|
57
|
-
steps: completedTask.steps,
|
|
58
|
-
inputParams: inputParams,
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Update the AI message with steps using the message reducer pattern
|
|
64
|
-
const updatedAIMessage = new AIMessage({
|
|
65
|
-
id: toolCallObj.id,
|
|
66
|
-
content: toolCallObj.content,
|
|
67
|
-
tool_calls: toolCallObj.tool_calls,
|
|
68
|
-
additional_kwargs: {
|
|
69
|
-
...toolCallObj.additional_kwargs,
|
|
70
|
-
mindedMetadata: {
|
|
71
|
-
...toolCallObj.additional_kwargs?.mindedMetadata,
|
|
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
|
-
taskId,
|
|
105
|
-
error: error.message,
|
|
106
|
-
inputParams: inputParams,
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// Update the AI message with error status
|
|
112
|
-
const updatedAIMessage = new AIMessage({
|
|
113
|
-
id: toolCallObj.id,
|
|
114
|
-
content: toolCallObj.content,
|
|
115
|
-
tool_calls: toolCallObj.tool_calls,
|
|
116
|
-
additional_kwargs: {
|
|
117
|
-
...toolCallObj.additional_kwargs,
|
|
118
|
-
mindedMetadata: {
|
|
119
|
-
...toolCallObj.additional_kwargs?.mindedMetadata,
|
|
120
|
-
status: 'failed',
|
|
121
|
-
error: error.message,
|
|
122
|
-
},
|
|
123
|
-
update: true,
|
|
124
|
-
},
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
messages: [errorToolMessage, updatedAIMessage],
|
|
129
|
-
history: createHistoryStep<HistoryStep>(state.history, {
|
|
130
|
-
type: NodeType.BROWSER_TASK,
|
|
131
|
-
nodeId: browserTaskNode.name,
|
|
132
|
-
nodeDisplayName: browserTaskNode.displayName,
|
|
133
|
-
raw: error,
|
|
134
|
-
messageIds: [],
|
|
135
|
-
}),
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
graph.addNode(buildBrowserTaskRunNodeName(attachedToNodeName), callback);
|
|
141
|
-
graph.addEdge(attachedToNodeName as any, buildBrowserTaskRunNodeName(attachedToNodeName) as any);
|
|
142
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,141 +0,0 @@
|
|
|
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
|
-
}
|