@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.
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +29 -16
- package/dist/agent.js.map +1 -1
- package/dist/browserTask/executeBrowserTask.d.ts +12 -0
- package/dist/browserTask/executeBrowserTask.d.ts.map +1 -0
- package/dist/browserTask/executeBrowserTask.js +181 -0
- package/dist/browserTask/executeBrowserTask.js.map +1 -0
- package/dist/checkpointer/checkpointSaverFactory.js +1 -1
- package/dist/checkpointer/checkpointSaverFactory.js.map +1 -1
- package/dist/cli/index.js +14 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/edges/createDirectEdge.d.ts +2 -1
- package/dist/edges/createDirectEdge.d.ts.map +1 -1
- package/dist/edges/createDirectEdge.js +6 -2
- package/dist/edges/createDirectEdge.js.map +1 -1
- package/dist/edges/createLogicalRouter.d.ts.map +1 -1
- package/dist/edges/createLogicalRouter.js +23 -6
- package/dist/edges/createLogicalRouter.js.map +1 -1
- package/dist/edges/createPromptRouter.d.ts.map +1 -1
- package/dist/edges/createPromptRouter.js +12 -6
- package/dist/edges/createPromptRouter.js.map +1 -1
- package/dist/edges/edgeFactory.d.ts.map +1 -1
- package/dist/edges/edgeFactory.js +8 -3
- package/dist/edges/edgeFactory.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/interrupts/BaseInterruptSessionManager.js +1 -1
- package/dist/interrupts/BaseInterruptSessionManager.js.map +1 -1
- package/dist/interrupts/interruptSessionManagerFactory.js +2 -2
- package/dist/interrupts/interruptSessionManagerFactory.js.map +1 -1
- package/dist/llm/createLlmInstance.d.ts +1 -1
- package/dist/llm/createLlmInstance.d.ts.map +1 -1
- package/dist/llm/createLlmInstance.js +18 -1
- package/dist/llm/createLlmInstance.js.map +1 -1
- package/dist/nodes/addAppToolNode.d.ts.map +1 -1
- package/dist/nodes/addAppToolNode.js +5 -4
- package/dist/nodes/addAppToolNode.js.map +1 -1
- package/dist/nodes/addBrowserTaskNode.d.ts +13 -0
- package/dist/nodes/addBrowserTaskNode.d.ts.map +1 -0
- package/dist/nodes/addBrowserTaskNode.js +232 -0
- package/dist/nodes/addBrowserTaskNode.js.map +1 -0
- package/dist/nodes/addBrowserTaskRunNode.d.ts +13 -0
- package/dist/nodes/addBrowserTaskRunNode.d.ts.map +1 -0
- package/dist/nodes/addBrowserTaskRunNode.js +130 -0
- package/dist/nodes/addBrowserTaskRunNode.js.map +1 -0
- package/dist/nodes/addHumanInTheLoopNode.d.ts.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.js +1 -1
- package/dist/nodes/addHumanInTheLoopNode.js.map +1 -1
- package/dist/nodes/addJumpToNode.d.ts.map +1 -1
- package/dist/nodes/addJumpToNode.js +2 -1
- package/dist/nodes/addJumpToNode.js.map +1 -1
- package/dist/nodes/addJunctionNode.d.ts.map +1 -1
- package/dist/nodes/addJunctionNode.js +1 -0
- package/dist/nodes/addJunctionNode.js.map +1 -1
- package/dist/nodes/addPromptNode.d.ts.map +1 -1
- package/dist/nodes/addPromptNode.js +8 -18
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolNode.js +2 -4
- package/dist/nodes/addToolNode.js.map +1 -1
- package/dist/nodes/addToolRunNode.d.ts.map +1 -1
- package/dist/nodes/addToolRunNode.js +2 -1
- package/dist/nodes/addToolRunNode.js.map +1 -1
- package/dist/nodes/addTriggerNode.d.ts.map +1 -1
- package/dist/nodes/addTriggerNode.js +2 -1
- package/dist/nodes/addTriggerNode.js.map +1 -1
- package/dist/nodes/nodeFactory.d.ts.map +1 -1
- package/dist/nodes/nodeFactory.js +4 -0
- package/dist/nodes/nodeFactory.js.map +1 -1
- package/dist/platform/mindedConnection.js +13 -13
- package/dist/platform/mindedConnection.js.map +1 -1
- package/dist/platform/models/mindedChatOpenAI.d.ts +20 -0
- package/dist/platform/models/mindedChatOpenAI.d.ts.map +1 -0
- package/dist/platform/models/mindedChatOpenAI.js +32 -0
- package/dist/platform/models/mindedChatOpenAI.js.map +1 -0
- package/dist/platform/models/parallelWrapper.d.ts +17 -0
- package/dist/platform/models/parallelWrapper.d.ts.map +1 -0
- package/dist/platform/models/parallelWrapper.js +105 -0
- package/dist/platform/models/parallelWrapper.js.map +1 -0
- package/dist/playbooks/playbooks.js +6 -6
- package/dist/playbooks/playbooks.js.map +1 -1
- package/dist/types/Flows.types.d.ts +18 -3
- package/dist/types/Flows.types.d.ts.map +1 -1
- package/dist/types/Flows.types.js +2 -0
- 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 -0
- package/dist/types/LangGraph.types.d.ts.map +1 -1
- package/dist/types/LangGraph.types.js +5 -0
- package/dist/types/LangGraph.types.js.map +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/voice/voiceSession.d.ts.map +1 -1
- package/dist/voice/voiceSession.js +16 -17
- package/dist/voice/voiceSession.js.map +1 -1
- package/docs/SUMMARY.md +1 -0
- package/docs/low-code-editor/nodes.md +27 -0
- package/docs/low-code-editor/tools.md +32 -0
- package/docs/platform/parallel-llm.md +242 -0
- package/package.json +2 -1
- package/src/agent.ts +30 -18
- package/src/browserTask/executeBrowserTask.ts +213 -0
- package/src/checkpointer/checkpointSaverFactory.ts +1 -1
- package/src/cli/index.ts +14 -14
- package/src/edges/createDirectEdge.ts +7 -2
- package/src/edges/createLogicalRouter.ts +23 -6
- package/src/edges/createPromptRouter.ts +13 -6
- package/src/edges/edgeFactory.ts +20 -4
- package/src/index.ts +6 -0
- package/src/interrupts/BaseInterruptSessionManager.ts +1 -1
- package/src/interrupts/interruptSessionManagerFactory.ts +2 -2
- package/src/llm/createLlmInstance.ts +25 -2
- package/src/nodes/addAppToolNode.ts +5 -4
- package/src/nodes/addBrowserTaskNode.ts +231 -0
- package/src/nodes/addBrowserTaskRunNode.ts +144 -0
- package/src/nodes/addHumanInTheLoopNode.ts +2 -1
- package/src/nodes/addJumpToNode.ts +2 -1
- package/src/nodes/addJunctionNode.ts +1 -0
- package/src/nodes/addPromptNode.ts +8 -19
- package/src/nodes/addToolNode.ts +4 -4
- package/src/nodes/addToolRunNode.ts +3 -1
- package/src/nodes/addTriggerNode.ts +2 -1
- package/src/nodes/nodeFactory.ts +5 -1
- package/src/platform/mindedConnection.ts +13 -13
- package/src/platform/models/mindedChatOpenAI.ts +49 -0
- package/src/platform/models/parallelWrapper.ts +141 -0
- package/src/playbooks/playbooks.ts +6 -6
- package/src/types/Flows.types.ts +17 -1
- package/src/types/LLM.types.ts +5 -5
- package/src/types/LangGraph.types.ts +5 -0
- package/src/utils/logger.ts +1 -1
- package/src/voice/voiceSession.ts +16 -17
- package/src/platform/mindedChatOpenAI.ts +0 -19
package/src/nodes/nodeFactory.ts
CHANGED
|
@@ -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({
|
|
91
|
-
logger.info({
|
|
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({
|
|
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({
|
|
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({
|
|
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({
|
|
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({
|
|
123
|
+
logger.error({ msg: 'Server error:', error });
|
|
124
124
|
|
|
125
125
|
if (error.message.includes('Invalid token')) {
|
|
126
|
-
logger.info({
|
|
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({
|
|
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({
|
|
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({
|
|
170
|
+
logger.warn({ msg: 'No socket connection to disconnect' });
|
|
171
171
|
return;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
if (socket.connected) {
|
|
175
|
-
logger.info({
|
|
175
|
+
logger.info({ msg: 'Disconnecting from Minded platform...' });
|
|
176
176
|
socket.disconnect();
|
|
177
177
|
return;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
logger.warn({
|
|
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({
|
|
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({
|
|
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({
|
|
129
|
+
logger.info({ msg: `Loaded playbook: ${playbook.name} from ${file}` });
|
|
130
130
|
} else {
|
|
131
|
-
logger.warn({
|
|
131
|
+
logger.warn({ msg: `Invalid playbook structure in ${file}` });
|
|
132
132
|
}
|
|
133
133
|
} catch (error) {
|
|
134
|
-
logger.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({
|
|
186
|
+
logger.error({ msg: 'Error compiling playbooks', error });
|
|
187
187
|
return combinedPlaybooks; // Return uncompiled if there's an error
|
|
188
188
|
}
|
|
189
189
|
}
|
package/src/types/Flows.types.ts
CHANGED
|
@@ -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
|
}
|
package/src/types/LLM.types.ts
CHANGED
|
@@ -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,
|
package/src/utils/logger.ts
CHANGED
|
@@ -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({
|
|
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({
|
|
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({
|
|
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({
|
|
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
|
-
|
|
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('
|
|
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({
|
|
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({
|
|
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(
|
|
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.
|
|
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
|
-
|
|
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({
|
|
207
|
+
logger.error({ msg: '[Voice] Error updating agent response', sessionId: this.sessionId, error });
|
|
208
208
|
}
|
|
209
209
|
break;
|
|
210
210
|
default:
|
|
211
|
-
logger.debug({
|
|
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({
|
|
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({
|
|
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
|
-
}
|