@minded-ai/mindedjs 1.0.102 → 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 +4 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +68 -9
- package/dist/agent.js.map +1 -1
- package/dist/cli/index.js +14 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/edges/edgeFactory.js +2 -2
- package/dist/edges/edgeFactory.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/nodes/addAppToolNode.js +1 -1
- package/dist/nodes/addBrowserTaskNode.d.ts.map +1 -1
- package/dist/nodes/addBrowserTaskNode.js +2 -0
- package/dist/nodes/addBrowserTaskNode.js.map +1 -1
- package/dist/nodes/addBrowserTaskRunNode.d.ts.map +1 -1
- package/dist/nodes/addBrowserTaskRunNode.js +7 -3
- package/dist/nodes/addBrowserTaskRunNode.js.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.d.ts.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.js +2 -1
- package/dist/nodes/addHumanInTheLoopNode.js.map +1 -1
- package/dist/nodes/addJumpToNode.js +1 -1
- package/dist/nodes/addJumpToNode.js.map +1 -1
- package/dist/nodes/addPromptNode.d.ts.map +1 -1
- package/dist/nodes/addPromptNode.js +45 -1
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolRunNode.d.ts.map +1 -1
- package/dist/nodes/addToolRunNode.js +1 -0
- package/dist/nodes/addToolRunNode.js.map +1 -1
- package/dist/platform/mindedChatOpenAI.d.ts +5 -0
- package/dist/platform/mindedChatOpenAI.d.ts.map +1 -0
- package/dist/platform/mindedChatOpenAI.js +23 -0
- 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 +6 -6
- 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/LangGraph.types.d.ts +2 -2
- package/dist/types/LangGraph.types.d.ts.map +1 -1
- package/dist/types/LangGraph.types.js +3 -1
- package/dist/types/LangGraph.types.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +1 -0
- package/dist/utils/logger.js.map +1 -1
- package/docs/getting-started/installation.md +0 -42
- package/package.json +2 -2
- package/src/agent.ts +86 -13
- package/src/cli/index.ts +14 -14
- package/src/edges/edgeFactory.ts +2 -2
- 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/nodes/addAppToolNode.ts +1 -1
- package/src/nodes/addBrowserTaskNode.ts +3 -1
- package/src/nodes/addBrowserTaskRunNode.ts +8 -6
- package/src/nodes/addHumanInTheLoopNode.ts +2 -1
- package/src/nodes/addJumpToNode.ts +1 -1
- package/src/nodes/addPromptNode.ts +50 -6
- package/src/nodes/addToolRunNode.ts +1 -1
- package/src/platform/mindedConnection.ts +15 -25
- package/src/platform/mindedConnectionTypes.ts +188 -1
- package/src/playbooks/playbooks.ts +6 -6
- package/src/types/Agent.types.ts +2 -0
- package/src/types/LangGraph.types.ts +3 -1
- package/src/utils/logger.ts +1 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { BaseInterruptSessionManager, QueuedMessage } from './BaseInterruptSessionManager';
|
|
2
|
+
import * as mindedConnection from '../platform/mindedConnection';
|
|
3
|
+
import {
|
|
4
|
+
mindedConnectionSocketMessageType,
|
|
5
|
+
InterruptSessionIsProcessedRequest,
|
|
6
|
+
InterruptSessionIsProcessedResponse,
|
|
7
|
+
InterruptSessionLockRequest,
|
|
8
|
+
InterruptSessionLockResponse,
|
|
9
|
+
InterruptSessionReleaseRequest,
|
|
10
|
+
InterruptSessionReleaseResponse,
|
|
11
|
+
InterruptSessionEnqueueRequest,
|
|
12
|
+
InterruptSessionEnqueueResponse,
|
|
13
|
+
InterruptSessionDequeueAllRequest,
|
|
14
|
+
InterruptSessionDequeueAllResponse,
|
|
15
|
+
InterruptSessionDequeueRequest,
|
|
16
|
+
InterruptSessionDequeueResponse,
|
|
17
|
+
InterruptSessionHasMessagesRequest,
|
|
18
|
+
InterruptSessionHasMessagesResponse,
|
|
19
|
+
InterruptSessionGetMessagesRequest,
|
|
20
|
+
InterruptSessionGetMessagesResponse,
|
|
21
|
+
} from '../platform/mindedConnectionTypes';
|
|
22
|
+
|
|
23
|
+
export class MindedInterruptSessionManager extends BaseInterruptSessionManager {
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async isProcessed(sessionId: string): Promise<boolean> {
|
|
29
|
+
try {
|
|
30
|
+
const response = await mindedConnection.awaitEmit<InterruptSessionIsProcessedRequest, InterruptSessionIsProcessedResponse>(
|
|
31
|
+
mindedConnectionSocketMessageType.INTERRUPT_SESSION_IS_PROCESSED,
|
|
32
|
+
{
|
|
33
|
+
type: mindedConnectionSocketMessageType.INTERRUPT_SESSION_IS_PROCESSED,
|
|
34
|
+
sessionId,
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
return response.isProcessed ?? false;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error('Error checking if session is processed:', error);
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async lock(sessionId: string): Promise<boolean> {
|
|
45
|
+
try {
|
|
46
|
+
const response = await mindedConnection.awaitEmit<InterruptSessionLockRequest, InterruptSessionLockResponse>(
|
|
47
|
+
mindedConnectionSocketMessageType.INTERRUPT_SESSION_LOCK,
|
|
48
|
+
{
|
|
49
|
+
type: mindedConnectionSocketMessageType.INTERRUPT_SESSION_LOCK,
|
|
50
|
+
sessionId,
|
|
51
|
+
},
|
|
52
|
+
);
|
|
53
|
+
return response.lockAcquired ?? false;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('Error locking session:', error);
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async release(sessionId: string): Promise<void> {
|
|
61
|
+
try {
|
|
62
|
+
await mindedConnection.awaitEmit<InterruptSessionReleaseRequest, InterruptSessionReleaseResponse>(
|
|
63
|
+
mindedConnectionSocketMessageType.INTERRUPT_SESSION_RELEASE,
|
|
64
|
+
{
|
|
65
|
+
type: mindedConnectionSocketMessageType.INTERRUPT_SESSION_RELEASE,
|
|
66
|
+
sessionId,
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error('Error releasing session:', error);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async enqueueMessage(sessionId: string, message: QueuedMessage): Promise<void> {
|
|
76
|
+
try {
|
|
77
|
+
await mindedConnection.awaitEmit<InterruptSessionEnqueueRequest, InterruptSessionEnqueueResponse>(
|
|
78
|
+
mindedConnectionSocketMessageType.INTERRUPT_SESSION_ENQUEUE,
|
|
79
|
+
{
|
|
80
|
+
type: mindedConnectionSocketMessageType.INTERRUPT_SESSION_ENQUEUE,
|
|
81
|
+
sessionId,
|
|
82
|
+
message,
|
|
83
|
+
},
|
|
84
|
+
);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error('Error enqueuing message:', error);
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async dequeueAll(sessionId: string): Promise<QueuedMessage[]> {
|
|
92
|
+
try {
|
|
93
|
+
const response = await mindedConnection.awaitEmit<InterruptSessionDequeueAllRequest, InterruptSessionDequeueAllResponse>(
|
|
94
|
+
mindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE_ALL,
|
|
95
|
+
{
|
|
96
|
+
type: mindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE_ALL,
|
|
97
|
+
sessionId,
|
|
98
|
+
},
|
|
99
|
+
);
|
|
100
|
+
return response.messages ?? [];
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error('Error dequeuing all messages:', error);
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async dequeue(sessionId: string): Promise<QueuedMessage | null> {
|
|
108
|
+
try {
|
|
109
|
+
const response = await mindedConnection.awaitEmit<InterruptSessionDequeueRequest, InterruptSessionDequeueResponse>(
|
|
110
|
+
mindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE,
|
|
111
|
+
{
|
|
112
|
+
type: mindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE,
|
|
113
|
+
sessionId,
|
|
114
|
+
},
|
|
115
|
+
);
|
|
116
|
+
return response.message ?? null;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error('Error dequeuing message:', error);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Implementation of abstract methods from BaseInterruptSessionManager
|
|
124
|
+
protected async hasQueuedMessages(sessionId: string): Promise<boolean> {
|
|
125
|
+
try {
|
|
126
|
+
const response = await mindedConnection.awaitEmit<InterruptSessionHasMessagesRequest, InterruptSessionHasMessagesResponse>(
|
|
127
|
+
mindedConnectionSocketMessageType.INTERRUPT_SESSION_HAS_MESSAGES,
|
|
128
|
+
{
|
|
129
|
+
type: mindedConnectionSocketMessageType.INTERRUPT_SESSION_HAS_MESSAGES,
|
|
130
|
+
sessionId,
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
return response.hasMessages ?? false;
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error('Error checking if session has messages:', error);
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
protected async getQueuedMessages(sessionId: string): Promise<QueuedMessage[]> {
|
|
141
|
+
try {
|
|
142
|
+
const response = await mindedConnection.awaitEmit<InterruptSessionGetMessagesRequest, InterruptSessionGetMessagesResponse>(
|
|
143
|
+
mindedConnectionSocketMessageType.INTERRUPT_SESSION_GET_MESSAGES,
|
|
144
|
+
{
|
|
145
|
+
type: mindedConnectionSocketMessageType.INTERRUPT_SESSION_GET_MESSAGES,
|
|
146
|
+
sessionId,
|
|
147
|
+
},
|
|
148
|
+
);
|
|
149
|
+
return response.messages ?? [];
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error('Error getting queued messages:', error);
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { InterruptSessionManager } from './BaseInterruptSessionManager';
|
|
2
|
+
import { MemoryInterruptSessionManager } from './MemoryInterruptSessionManager';
|
|
3
|
+
import { MindedInterruptSessionManager } from './MindedInterruptSessionManager';
|
|
4
|
+
import * as mindedConnection from '../platform/mindedConnection';
|
|
5
|
+
import { getConfig } from '../platform/config';
|
|
6
|
+
import { logger } from '../utils/logger';
|
|
7
|
+
|
|
8
|
+
export function createInterruptSessionManager(): InterruptSessionManager {
|
|
9
|
+
const { runLocally } = getConfig();
|
|
10
|
+
if (runLocally) {
|
|
11
|
+
logger.info({ msg: 'Using memory interrupt session manager' });
|
|
12
|
+
return new MemoryInterruptSessionManager();
|
|
13
|
+
} else {
|
|
14
|
+
if (!mindedConnection.isConnected()) {
|
|
15
|
+
throw new Error('MindedConnection is required for platform interrupt session manager');
|
|
16
|
+
}
|
|
17
|
+
logger.info({ msg: 'Using Minded interrupt session manager' });
|
|
18
|
+
return new MindedInterruptSessionManager();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -76,7 +76,7 @@ export const addAppToolNode = async ({
|
|
|
76
76
|
const toolCallMessage = await tool.invoke(AIToolCallMessage.tool_calls[0]);
|
|
77
77
|
AIToolCallMessage.additional_kwargs = {
|
|
78
78
|
mindedMetadata: {
|
|
79
|
-
nodeType: NodeType.APP_TOOL
|
|
79
|
+
nodeType: NodeType.APP_TOOL,
|
|
80
80
|
},
|
|
81
81
|
};
|
|
82
82
|
return {
|
|
@@ -92,7 +92,7 @@ export const addBrowserTaskNode = async ({ graph, node, agent, llm }: AddBrowser
|
|
|
92
92
|
const zodSchema = z.object(schemaFields);
|
|
93
93
|
|
|
94
94
|
// Create langchain tool
|
|
95
|
-
const tool = langchainTool(() => {
|
|
95
|
+
const tool = langchainTool(() => {}, {
|
|
96
96
|
name: 'browser-task',
|
|
97
97
|
description: node.prompt,
|
|
98
98
|
schema: zodSchema,
|
|
@@ -171,6 +171,7 @@ ${state.memory ? `# Task context:\n${JSON.stringify(state.memory)}\n\n` : ''}
|
|
|
171
171
|
additional_kwargs: {
|
|
172
172
|
mindedMetadata: {
|
|
173
173
|
nodeType: NodeType.BROWSER_TASK,
|
|
174
|
+
nodeDisplayName: node.displayName,
|
|
174
175
|
taskId,
|
|
175
176
|
liveUrl: taskDetails.live_url,
|
|
176
177
|
},
|
|
@@ -208,6 +209,7 @@ ${state.memory ? `# Task context:\n${JSON.stringify(state.memory)}\n\n` : ''}
|
|
|
208
209
|
additional_kwargs: {
|
|
209
210
|
mindedMetadata: {
|
|
210
211
|
nodeType: NodeType.BROWSER_TASK,
|
|
212
|
+
nodeDisplayName: node.displayName,
|
|
211
213
|
error: error.message,
|
|
212
214
|
},
|
|
213
215
|
},
|
|
@@ -26,15 +26,13 @@ export const addBrowserTaskRunNode = async ({ graph, browserTaskNode, attachedTo
|
|
|
26
26
|
if (!toolCallObj.tool_calls) {
|
|
27
27
|
throw new Error('Tool call not found');
|
|
28
28
|
}
|
|
29
|
-
|
|
30
29
|
const toolCall = toolCallObj.tool_calls[0];
|
|
31
30
|
const { taskId, ...inputParams } = toolCall.args;
|
|
32
|
-
|
|
33
|
-
if (!taskId) {
|
|
34
|
-
throw new Error('Task ID not found in tool call arguments');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
31
|
try {
|
|
32
|
+
if (!taskId) {
|
|
33
|
+
throw new Error('Task ID not found in tool call arguments');
|
|
34
|
+
}
|
|
35
|
+
|
|
38
36
|
// Wait for task completion
|
|
39
37
|
const completedTask = await waitForCompletion(taskId);
|
|
40
38
|
logger.debug({ msg: 'Browser task completed', taskId, output: completedTask.output });
|
|
@@ -53,6 +51,7 @@ export const addBrowserTaskRunNode = async ({ graph, browserTaskNode, attachedTo
|
|
|
53
51
|
additional_kwargs: {
|
|
54
52
|
mindedMetadata: {
|
|
55
53
|
nodeType: NodeType.BROWSER_TASK,
|
|
54
|
+
nodeDisplayName: browserTaskNode.displayName,
|
|
56
55
|
taskId,
|
|
57
56
|
steps: completedTask.steps,
|
|
58
57
|
inputParams: inputParams,
|
|
@@ -69,6 +68,7 @@ export const addBrowserTaskRunNode = async ({ graph, browserTaskNode, attachedTo
|
|
|
69
68
|
...toolCallObj.additional_kwargs,
|
|
70
69
|
mindedMetadata: {
|
|
71
70
|
...toolCallObj.additional_kwargs?.mindedMetadata,
|
|
71
|
+
nodeDisplayName: browserTaskNode.displayName,
|
|
72
72
|
steps: completedTask.steps,
|
|
73
73
|
status: 'completed',
|
|
74
74
|
},
|
|
@@ -101,6 +101,7 @@ export const addBrowserTaskRunNode = async ({ graph, browserTaskNode, attachedTo
|
|
|
101
101
|
additional_kwargs: {
|
|
102
102
|
mindedMetadata: {
|
|
103
103
|
nodeType: NodeType.BROWSER_TASK,
|
|
104
|
+
nodeDisplayName: browserTaskNode.displayName,
|
|
104
105
|
taskId,
|
|
105
106
|
error: error.message,
|
|
106
107
|
inputParams: inputParams,
|
|
@@ -117,6 +118,7 @@ export const addBrowserTaskRunNode = async ({ graph, browserTaskNode, attachedTo
|
|
|
117
118
|
...toolCallObj.additional_kwargs,
|
|
118
119
|
mindedMetadata: {
|
|
119
120
|
...toolCallObj.additional_kwargs?.mindedMetadata,
|
|
121
|
+
nodeDisplayName: browserTaskNode.displayName,
|
|
120
122
|
status: 'failed',
|
|
121
123
|
error: error.message,
|
|
122
124
|
},
|
|
@@ -3,6 +3,7 @@ import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
|
3
3
|
import { RunnableLike } from '@langchain/core/runnables';
|
|
4
4
|
import { logger } from '../utils/logger';
|
|
5
5
|
import { internalNodesSuffix } from '../types/Flows.types';
|
|
6
|
+
import { InterruptType } from '../interrupts/BaseInterruptSessionManager';
|
|
6
7
|
|
|
7
8
|
type AddHumanInTheLoopNodeParams = {
|
|
8
9
|
graph: PreCompiledGraph;
|
|
@@ -16,7 +17,7 @@ export const addHumanInTheLoopNode = async ({ graph, attachedToNodeName }: AddHu
|
|
|
16
17
|
logger.debug({ msg: `[Node] Waiting for human input`, node: attachedToNodeName });
|
|
17
18
|
|
|
18
19
|
if (state.messages[state.messages.length - 1].getType() === 'ai') {
|
|
19
|
-
const value = interrupt(
|
|
20
|
+
const value = interrupt({ type: InterruptType.HUMAN_IN_THE_LOOP });
|
|
20
21
|
return value;
|
|
21
22
|
}
|
|
22
23
|
};
|
|
@@ -7,7 +7,7 @@ import { createHistoryStep } from '../utils/history';
|
|
|
7
7
|
|
|
8
8
|
export const addJumpToNode = async ({ graph, node }: { graph: PreCompiledGraph; node: JumpToNode }) => {
|
|
9
9
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
10
|
-
logger.info(`Executing jump node ${node.displayName} – jumping to ${node.targetNodeId}`);
|
|
10
|
+
logger.info({ msg: `Executing jump node ${node.displayName} – jumping to ${node.targetNodeId}` });
|
|
11
11
|
// No state modifications are necessary; control flow is handled via edges.
|
|
12
12
|
return {
|
|
13
13
|
goto: null,
|
|
@@ -14,7 +14,7 @@ import { Agent } from '../agent';
|
|
|
14
14
|
import { logger } from '../utils/logger';
|
|
15
15
|
import { compilePlaybooks } from '../playbooks/playbooks';
|
|
16
16
|
import { createHistoryStep } from '../utils/history';
|
|
17
|
-
|
|
17
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
18
18
|
type AddPromptNodeParams = {
|
|
19
19
|
graph: PreCompiledGraph;
|
|
20
20
|
node: PromptNode;
|
|
@@ -26,7 +26,8 @@ type AddPromptNodeParams = {
|
|
|
26
26
|
|
|
27
27
|
export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: AddPromptNodeParams) => {
|
|
28
28
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
29
|
-
|
|
29
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
30
|
+
logger.info({ msg: `[Node] Executing prompt node`, node: node.displayName });
|
|
30
31
|
const llmToUse = node.llmConfig ? createLlmInstance(node.llmConfig) : llm;
|
|
31
32
|
|
|
32
33
|
const globalTools = tools
|
|
@@ -50,9 +51,9 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
50
51
|
${state.memory ? `# Task context:\n${JSON.stringify(state.memory)}\n\n` : ''}
|
|
51
52
|
${compiledPlaybooks ? `# General guidelines:\n${compiledPlaybooks}\n\n` : ''}
|
|
52
53
|
`;
|
|
53
|
-
|
|
54
|
+
// await wait(5000);
|
|
54
55
|
const result: AIMessage = await llmToUse.bindTools(globalTools).invoke([...state.messages, new SystemMessage(message)]);
|
|
55
|
-
|
|
56
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
56
57
|
// Check if the result contains tool calls
|
|
57
58
|
if (result.tool_calls && result.tool_calls.length > 0) {
|
|
58
59
|
// Execute the tools
|
|
@@ -67,6 +68,29 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
67
68
|
// Invoke the LangChain tool directly
|
|
68
69
|
const toolResult = await matchedTool.invoke(toolCall);
|
|
69
70
|
logger.debug({ msg: `[Tool] Tool result`, tool: matchedTool?.name, result: toolResult });
|
|
71
|
+
//check for queue after tool call
|
|
72
|
+
const systemMessageId = uuidv4();
|
|
73
|
+
|
|
74
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, {
|
|
75
|
+
messages: [
|
|
76
|
+
result,
|
|
77
|
+
toolResult,
|
|
78
|
+
new SystemMessage({
|
|
79
|
+
id: systemMessageId,
|
|
80
|
+
content:
|
|
81
|
+
'you called tool when the user send a new message, Consider calling the function again after user message is processed',
|
|
82
|
+
}),
|
|
83
|
+
],
|
|
84
|
+
history: [
|
|
85
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
86
|
+
type: NodeType.TOOL,
|
|
87
|
+
nodeId: node.name,
|
|
88
|
+
nodeDisplayName: node.displayName,
|
|
89
|
+
raw: toolResult,
|
|
90
|
+
messageIds: [toolResult.id!, systemMessageId],
|
|
91
|
+
}),
|
|
92
|
+
],
|
|
93
|
+
});
|
|
70
94
|
const toolStateUpdate = extractToolStateResponse(toolResult);
|
|
71
95
|
// Properly merge memory and other state updates
|
|
72
96
|
stateUpdates = {
|
|
@@ -75,7 +99,8 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
75
99
|
memory: { ...(stateUpdates as any).memory, ...(toolStateUpdate as any).memory },
|
|
76
100
|
};
|
|
77
101
|
toolResults.push(toolResult);
|
|
78
|
-
} catch (error) {
|
|
102
|
+
} catch (error: any) {
|
|
103
|
+
if (error?.name === 'GraphInterrupt') throw error;
|
|
79
104
|
logger.error({ msg: `[Tool] Error executing tool`, tool: toolCall.name, error });
|
|
80
105
|
const errorMessage = new ToolMessage({
|
|
81
106
|
content: JSON.stringify({ error: error instanceof Error ? error.message : String(error) }),
|
|
@@ -88,10 +113,30 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
88
113
|
}
|
|
89
114
|
}
|
|
90
115
|
|
|
116
|
+
// await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
117
|
+
|
|
91
118
|
// Return the tool call message and tool results with state updates spread at top level
|
|
92
119
|
return {
|
|
93
120
|
...stateUpdates,
|
|
94
121
|
messages: [result, ...toolResults],
|
|
122
|
+
history: [
|
|
123
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
124
|
+
type: NodeType.TOOL,
|
|
125
|
+
nodeId: node.name,
|
|
126
|
+
nodeDisplayName: node.displayName,
|
|
127
|
+
raw: result,
|
|
128
|
+
messageIds: [result.id!],
|
|
129
|
+
}),
|
|
130
|
+
...toolResults.map((toolResult) =>
|
|
131
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
132
|
+
type: NodeType.TOOL,
|
|
133
|
+
nodeId: node.name,
|
|
134
|
+
nodeDisplayName: node.displayName,
|
|
135
|
+
raw: toolResult,
|
|
136
|
+
messageIds: [toolResult.id!],
|
|
137
|
+
}),
|
|
138
|
+
),
|
|
139
|
+
],
|
|
95
140
|
};
|
|
96
141
|
}
|
|
97
142
|
|
|
@@ -102,7 +147,6 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
102
147
|
});
|
|
103
148
|
logger.info({ msg: `[Model] Response`, content: result.content });
|
|
104
149
|
}
|
|
105
|
-
|
|
106
150
|
return {
|
|
107
151
|
goto: null,
|
|
108
152
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
@@ -23,6 +23,7 @@ type AddToolRunNodeParams = {
|
|
|
23
23
|
|
|
24
24
|
export const buildToolRunNodeName = (nodeName: string) => `${nodeName}${internalNodesSuffix.TOOL_RUN}`;
|
|
25
25
|
|
|
26
|
+
//you never want to interrupt here because of new triggers, as this node depends on the last message to be the tool call from the addToolNode, interrupting will add human message here
|
|
26
27
|
export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeName, agent }: AddToolRunNodeParams) => {
|
|
27
28
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
28
29
|
const matchedTool = tools.find((tool) => tool.name === toolNode.toolName);
|
|
@@ -54,7 +55,6 @@ export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeNam
|
|
|
54
55
|
|
|
55
56
|
// Push the toolCallMessage into the messages array from toolStateUpdate
|
|
56
57
|
const updatedMessages = [toolCallMessage, ...((toolStateUpdate as any).messages || [])];
|
|
57
|
-
|
|
58
58
|
// Return the full state update from the tool with the updated messages
|
|
59
59
|
|
|
60
60
|
return {
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { io, Socket } from 'socket.io-client';
|
|
2
|
-
import {
|
|
3
|
-
mindedConnectionSocketMessageType,
|
|
4
|
-
mindedConnectionSocketMessageTypeMap,
|
|
5
|
-
} from './mindedConnectionTypes';
|
|
2
|
+
import { mindedConnectionSocketMessageType, mindedConnectionSocketMessageTypeMap } from './mindedConnectionTypes';
|
|
6
3
|
import { stringify } from 'flatted';
|
|
7
4
|
import { getConfig } from './config';
|
|
8
5
|
import { logger } from '../utils/logger';
|
|
@@ -28,20 +25,13 @@ export const on = <E extends keyof mindedConnectionSocketMessageTypeMap>(
|
|
|
28
25
|
listeners[event].push(callback);
|
|
29
26
|
};
|
|
30
27
|
|
|
31
|
-
export const emit = <E extends keyof mindedConnectionSocketMessageTypeMap>(
|
|
32
|
-
event: E,
|
|
33
|
-
message: mindedConnectionSocketMessageTypeMap[E]
|
|
34
|
-
) => {
|
|
28
|
+
export const emit = <E extends keyof mindedConnectionSocketMessageTypeMap>(event: E, message: mindedConnectionSocketMessageTypeMap[E]) => {
|
|
35
29
|
if (socket) {
|
|
36
30
|
socket.emit(event, message);
|
|
37
31
|
}
|
|
38
32
|
};
|
|
39
33
|
|
|
40
|
-
export const awaitEmit = async <T, R>(
|
|
41
|
-
event: mindedConnectionSocketMessageType,
|
|
42
|
-
message: T,
|
|
43
|
-
timeoutMs: number = 5000
|
|
44
|
-
): Promise<R> => {
|
|
34
|
+
export const awaitEmit = async <T, R>(event: mindedConnectionSocketMessageType, message: T, timeoutMs: number = 5000): Promise<R> => {
|
|
45
35
|
if (!socket) {
|
|
46
36
|
throw new Error('Socket is not connected');
|
|
47
37
|
}
|
|
@@ -97,33 +87,33 @@ const connect = async (token: string): Promise<void> => {
|
|
|
97
87
|
|
|
98
88
|
const checkReady = () => {
|
|
99
89
|
if (connected && ready) {
|
|
100
|
-
logger.info('\x1b[32mConnection with Minded platform is ready!\x1b[0m');
|
|
101
|
-
logger.info('\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...' });
|
|
102
92
|
resolve();
|
|
103
93
|
}
|
|
104
94
|
};
|
|
105
95
|
|
|
106
96
|
// Connection event handlers
|
|
107
97
|
socket.on('connect', () => {
|
|
108
|
-
logger.info('Socket connected, waiting for server setup...');
|
|
98
|
+
logger.info({ msg: 'Socket connected, waiting for server setup...' });
|
|
109
99
|
connected = true;
|
|
110
100
|
checkReady();
|
|
111
101
|
});
|
|
112
102
|
|
|
113
103
|
// Listen for ready event from server
|
|
114
104
|
socket.on('sdk-socket-ready', (data: { agentId: string; orgName: string }) => {
|
|
115
|
-
logger.info('Server ready signal received', data);
|
|
105
|
+
logger.info({ msg: 'Server ready signal received', data });
|
|
116
106
|
ready = true;
|
|
117
107
|
checkReady();
|
|
118
108
|
});
|
|
119
109
|
|
|
120
110
|
socket.on('connect_error', () => {
|
|
121
|
-
logger.error('Failed to connect to minded platform');
|
|
111
|
+
logger.error({ msg: 'Failed to connect to minded platform' });
|
|
122
112
|
reject(new Error('Failed to connect to minded platform'));
|
|
123
113
|
});
|
|
124
114
|
|
|
125
115
|
socket.on('disconnect', () => {
|
|
126
|
-
logger.info('Disconnected from local debugging socket');
|
|
116
|
+
logger.info({ msg: 'Disconnected from local debugging socket' });
|
|
127
117
|
connected = false;
|
|
128
118
|
ready = false;
|
|
129
119
|
});
|
|
@@ -133,7 +123,7 @@ const connect = async (token: string): Promise<void> => {
|
|
|
133
123
|
logger.error({ msg: 'Server error:', error });
|
|
134
124
|
|
|
135
125
|
if (error.message.includes('Invalid token')) {
|
|
136
|
-
logger.info('Invalid token');
|
|
126
|
+
logger.info({ msg: 'Invalid token' });
|
|
137
127
|
|
|
138
128
|
// Disconnect current socket
|
|
139
129
|
if (socket?.connected) {
|
|
@@ -152,14 +142,14 @@ const connect = async (token: string): Promise<void> => {
|
|
|
152
142
|
listener(message, callback);
|
|
153
143
|
});
|
|
154
144
|
} else {
|
|
155
|
-
console.warn({
|
|
145
|
+
console.warn({ msg: 'No listeners found for event', event });
|
|
156
146
|
}
|
|
157
147
|
});
|
|
158
148
|
|
|
159
149
|
// Handle process termination
|
|
160
150
|
process.on('SIGINT', () => {
|
|
161
151
|
if (socket?.connected) {
|
|
162
|
-
logger.info('\nDisconnecting...');
|
|
152
|
+
logger.info({ msg: '\nDisconnecting...' });
|
|
163
153
|
socket.disconnect();
|
|
164
154
|
}
|
|
165
155
|
process.exit(0);
|
|
@@ -177,17 +167,17 @@ export const start = async (): Promise<void> => {
|
|
|
177
167
|
|
|
178
168
|
export const disconnect = () => {
|
|
179
169
|
if (!socket) {
|
|
180
|
-
logger.warn('No socket connection to disconnect');
|
|
170
|
+
logger.warn({ msg: 'No socket connection to disconnect' });
|
|
181
171
|
return;
|
|
182
172
|
}
|
|
183
173
|
|
|
184
174
|
if (socket.connected) {
|
|
185
|
-
logger.info('Disconnecting from Minded platform...');
|
|
175
|
+
logger.info({ msg: 'Disconnecting from Minded platform...' });
|
|
186
176
|
socket.disconnect();
|
|
187
177
|
return;
|
|
188
178
|
}
|
|
189
179
|
|
|
190
|
-
logger.warn('Socket is already disconnected');
|
|
180
|
+
logger.warn({ msg: 'Socket is already disconnected' });
|
|
191
181
|
};
|
|
192
182
|
|
|
193
183
|
export const mindedConnection = {
|