@minded-ai/mindedjs 1.0.91 → 1.0.92-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 +93 -12
- package/dist/agent.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- 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 +39 -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 +51 -0
- package/dist/interrupts/MemoryInterruptSessionManager.js.map +1 -0
- package/dist/interrupts/MindedInterruptSessionManager.d.ts +15 -0
- package/dist/interrupts/MindedInterruptSessionManager.d.ts.map +1 -0
- package/dist/interrupts/MindedInterruptSessionManager.js +121 -0
- package/dist/interrupts/MindedInterruptSessionManager.js.map +1 -0
- package/dist/interrupts/interruptSessionManagerFactory.d.ts +4 -0
- package/dist/interrupts/interruptSessionManagerFactory.d.ts.map +1 -0
- package/dist/interrupts/interruptSessionManagerFactory.js +19 -0
- package/dist/interrupts/interruptSessionManagerFactory.js.map +1 -0
- package/dist/nodes/addAppToolNode.d.ts.map +1 -1
- package/dist/nodes/addAppToolNode.js +2 -2
- package/dist/nodes/addAppToolNode.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.d.ts.map +1 -1
- package/dist/nodes/addJumpToNode.js +2 -2
- package/dist/nodes/addJumpToNode.js.map +1 -1
- package/dist/nodes/addJunctionNode.d.ts +7 -0
- package/dist/nodes/addJunctionNode.d.ts.map +1 -0
- package/dist/nodes/addJunctionNode.js +20 -0
- package/dist/nodes/addJunctionNode.js.map +1 -0
- package/dist/nodes/addPromptNode.d.ts.map +1 -1
- package/dist/nodes/addPromptNode.js +42 -2
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolNode.d.ts.map +1 -1
- package/dist/nodes/addToolNode.js +2 -2
- package/dist/nodes/addToolNode.js.map +1 -1
- package/dist/nodes/addToolRunNode.d.ts.map +1 -1
- package/dist/nodes/addToolRunNode.js +1 -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 +2 -5
- package/dist/nodes/nodeFactory.js.map +1 -1
- package/dist/platform/mindedConnectionTypes.d.ts +82 -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/types/Agent.types.d.ts +11 -13
- package/dist/types/Agent.types.d.ts.map +1 -1
- package/dist/types/Agent.types.js +1 -10
- 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/package.json +2 -2
- package/src/agent.ts +119 -21
- package/src/index.ts +0 -1
- package/src/interrupts/InterruptSessionManager.types.ts +79 -0
- package/src/interrupts/MemoryInterruptSessionManager.ts +56 -0
- package/src/interrupts/MindedInterruptSessionManager.ts +157 -0
- package/src/interrupts/interruptSessionManagerFactory.ts +17 -0
- package/src/nodes/addAppToolNode.ts +3 -3
- package/src/nodes/addHumanInTheLoopNode.ts +2 -1
- package/src/nodes/addJumpToNode.ts +3 -3
- package/src/nodes/addJunctionNode.ts +19 -0
- package/src/nodes/addPromptNode.ts +48 -7
- package/src/nodes/addToolNode.ts +2 -3
- package/src/nodes/addToolRunNode.ts +2 -3
- package/src/nodes/addTriggerNode.ts +3 -3
- package/src/nodes/nodeFactory.ts +2 -7
- package/src/platform/mindedConnectionTypes.ts +100 -0
- package/src/types/Agent.types.ts +12 -15
- package/src/types/LangGraph.types.ts +3 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { State } from '../types/LangGraph.types';
|
|
2
|
+
import { logger } from '../utils/logger';
|
|
3
|
+
import { BaseInterruptSessionManager, QueuedMessage, InterruptType, InterruptPayload } from './InterruptSessionManager.types';
|
|
4
|
+
import { GraphInterrupt, interrupt } from '@langchain/langgraph';
|
|
5
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
6
|
+
|
|
7
|
+
export class MemoryInterruptSessionManager extends BaseInterruptSessionManager {
|
|
8
|
+
private sessionProcessing: Map<string, boolean> = new Map();
|
|
9
|
+
private sessionMessageQueues: Map<string, QueuedMessage[]> = new Map();
|
|
10
|
+
|
|
11
|
+
isProcessed(sessionId: string): boolean {
|
|
12
|
+
return this.sessionProcessing.get(sessionId) || false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
lock(sessionId: string): void {
|
|
16
|
+
this.sessionProcessing.set(sessionId, true);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
release(sessionId: string): void {
|
|
20
|
+
this.sessionProcessing.set(sessionId, false);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
enqueueMessage(sessionId: string, message: QueuedMessage): void {
|
|
24
|
+
if (!this.sessionMessageQueues.has(sessionId)) {
|
|
25
|
+
this.sessionMessageQueues.set(sessionId, []);
|
|
26
|
+
}
|
|
27
|
+
this.sessionMessageQueues.get(sessionId)!.push(message);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
dequeueAll(sessionId: string): QueuedMessage[] {
|
|
31
|
+
const messages = this.sessionMessageQueues.get(sessionId) || [];
|
|
32
|
+
const result = [...messages];
|
|
33
|
+
this.sessionMessageQueues.set(sessionId, []);
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
dequeue(sessionId: string): QueuedMessage | null {
|
|
38
|
+
const messages = this.sessionMessageQueues.get(sessionId) || [];
|
|
39
|
+
if (messages.length === 0) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const firstMessage = messages.shift()!;
|
|
43
|
+
this.sessionMessageQueues.set(sessionId, messages);
|
|
44
|
+
return firstMessage;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Implementation of abstract methods from BaseInterruptSessionManager
|
|
48
|
+
protected hasQueuedMessages(sessionId: string): boolean {
|
|
49
|
+
const queue = this.sessionMessageQueues.get(sessionId) || [];
|
|
50
|
+
return queue.length > 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
protected getQueuedMessages(sessionId: string): QueuedMessage[] {
|
|
54
|
+
return this.sessionMessageQueues.get(sessionId) || [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { BaseInterruptSessionManager, QueuedMessage } from './InterruptSessionManager.types';
|
|
2
|
+
import { 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
|
+
private mindedConnection: MindedConnection;
|
|
25
|
+
|
|
26
|
+
constructor(mindedConnection: MindedConnection) {
|
|
27
|
+
super();
|
|
28
|
+
this.mindedConnection = mindedConnection;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async isProcessed(sessionId: string): Promise<boolean> {
|
|
32
|
+
try {
|
|
33
|
+
const response = await this.mindedConnection.awaitEmit<InterruptSessionIsProcessedRequest, InterruptSessionIsProcessedResponse>(
|
|
34
|
+
MindedConnectionSocketMessageType.INTERRUPT_SESSION_IS_PROCESSED,
|
|
35
|
+
{
|
|
36
|
+
type: MindedConnectionSocketMessageType.INTERRUPT_SESSION_IS_PROCESSED,
|
|
37
|
+
sessionId,
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
return response.isProcessed ?? false;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('Error checking if session is processed:', error);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async lock(sessionId: string): Promise<void> {
|
|
48
|
+
try {
|
|
49
|
+
await this.mindedConnection.awaitEmit<InterruptSessionLockRequest, InterruptSessionLockResponse>(
|
|
50
|
+
MindedConnectionSocketMessageType.INTERRUPT_SESSION_LOCK,
|
|
51
|
+
{
|
|
52
|
+
type: MindedConnectionSocketMessageType.INTERRUPT_SESSION_LOCK,
|
|
53
|
+
sessionId,
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error('Error locking session:', error);
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async release(sessionId: string): Promise<void> {
|
|
63
|
+
try {
|
|
64
|
+
await this.mindedConnection.awaitEmit<InterruptSessionReleaseRequest, InterruptSessionReleaseResponse>(
|
|
65
|
+
MindedConnectionSocketMessageType.INTERRUPT_SESSION_RELEASE,
|
|
66
|
+
{
|
|
67
|
+
type: MindedConnectionSocketMessageType.INTERRUPT_SESSION_RELEASE,
|
|
68
|
+
sessionId,
|
|
69
|
+
},
|
|
70
|
+
);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error('Error releasing session:', error);
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async enqueueMessage(sessionId: string, message: QueuedMessage): Promise<void> {
|
|
78
|
+
try {
|
|
79
|
+
await this.mindedConnection.awaitEmit<InterruptSessionEnqueueRequest, InterruptSessionEnqueueResponse>(
|
|
80
|
+
MindedConnectionSocketMessageType.INTERRUPT_SESSION_ENQUEUE,
|
|
81
|
+
{
|
|
82
|
+
type: MindedConnectionSocketMessageType.INTERRUPT_SESSION_ENQUEUE,
|
|
83
|
+
sessionId,
|
|
84
|
+
message,
|
|
85
|
+
},
|
|
86
|
+
);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error('Error enqueuing message:', error);
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async dequeueAll(sessionId: string): Promise<QueuedMessage[]> {
|
|
94
|
+
try {
|
|
95
|
+
const response = await this.mindedConnection.awaitEmit<InterruptSessionDequeueAllRequest, InterruptSessionDequeueAllResponse>(
|
|
96
|
+
MindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE_ALL,
|
|
97
|
+
{
|
|
98
|
+
type: MindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE_ALL,
|
|
99
|
+
sessionId,
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
return response.messages ?? [];
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('Error dequeuing all messages:', error);
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async dequeue(sessionId: string): Promise<QueuedMessage | null> {
|
|
110
|
+
try {
|
|
111
|
+
const response = await this.mindedConnection.awaitEmit<InterruptSessionDequeueRequest, InterruptSessionDequeueResponse>(
|
|
112
|
+
MindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE,
|
|
113
|
+
{
|
|
114
|
+
type: MindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE,
|
|
115
|
+
sessionId,
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
return response.message ?? null;
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error('Error dequeuing message:', error);
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Implementation of abstract methods from BaseInterruptSessionManager
|
|
126
|
+
protected async hasQueuedMessages(sessionId: string): Promise<boolean> {
|
|
127
|
+
try {
|
|
128
|
+
const response = await this.mindedConnection.awaitEmit<InterruptSessionHasMessagesRequest, InterruptSessionHasMessagesResponse>(
|
|
129
|
+
MindedConnectionSocketMessageType.INTERRUPT_SESSION_HAS_MESSAGES,
|
|
130
|
+
{
|
|
131
|
+
type: MindedConnectionSocketMessageType.INTERRUPT_SESSION_HAS_MESSAGES,
|
|
132
|
+
sessionId,
|
|
133
|
+
},
|
|
134
|
+
);
|
|
135
|
+
return response.hasMessages ?? false;
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error('Error checking if session has messages:', error);
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
protected async getQueuedMessages(sessionId: string): Promise<QueuedMessage[]> {
|
|
143
|
+
try {
|
|
144
|
+
const response = await this.mindedConnection.awaitEmit<InterruptSessionGetMessagesRequest, InterruptSessionGetMessagesResponse>(
|
|
145
|
+
MindedConnectionSocketMessageType.INTERRUPT_SESSION_GET_MESSAGES,
|
|
146
|
+
{
|
|
147
|
+
type: MindedConnectionSocketMessageType.INTERRUPT_SESSION_GET_MESSAGES,
|
|
148
|
+
sessionId,
|
|
149
|
+
},
|
|
150
|
+
);
|
|
151
|
+
return response.messages ?? [];
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error('Error getting queued messages:', error);
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { InterruptSessionManager } from './InterruptSessionManager.types';
|
|
2
|
+
import { MemoryInterruptSessionManager } from './MemoryInterruptSessionManager';
|
|
3
|
+
import { MindedInterruptSessionManager } from './MindedInterruptSessionManager';
|
|
4
|
+
import { MindedConnection } from '../platform/mindedConnection';
|
|
5
|
+
import { getConfig } from '../platform/config';
|
|
6
|
+
|
|
7
|
+
export function createInterruptSessionManager(mindedConnection: MindedConnection | null): InterruptSessionManager {
|
|
8
|
+
const { runLocally } = getConfig();
|
|
9
|
+
if (runLocally) {
|
|
10
|
+
return new MemoryInterruptSessionManager();
|
|
11
|
+
} else {
|
|
12
|
+
if (!mindedConnection) {
|
|
13
|
+
throw new Error('MindedConnection is required for platform interrupt session manager');
|
|
14
|
+
}
|
|
15
|
+
return new MindedInterruptSessionManager(mindedConnection);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppToolNode } from '../types/Flows.types';
|
|
1
|
+
import { AppToolNode, NodeType } from '../types/Flows.types';
|
|
2
2
|
import { tool as langchainTool } from '@langchain/core/tools';
|
|
3
3
|
import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
4
4
|
import { SystemMessage } from '@langchain/core/messages';
|
|
@@ -6,7 +6,7 @@ import { RunnableLike } from '@langchain/core/runnables';
|
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
import { LLMProviders } from '../types/LLM.types';
|
|
8
8
|
import { getAppActionRunnerTool } from '../internalTools/appActionRunnerTool';
|
|
9
|
-
import { AppActionInvocationHistoryStep
|
|
9
|
+
import { AppActionInvocationHistoryStep } from '../types/Agent.types';
|
|
10
10
|
import { Agent } from '../agent';
|
|
11
11
|
import { logger } from '../utils/logger';
|
|
12
12
|
import { compilePlaybooks } from '../playbooks/playbooks';
|
|
@@ -82,7 +82,7 @@ export const addAppToolNode = async ({
|
|
|
82
82
|
return {
|
|
83
83
|
messages: [AIToolCallMessage, toolCallMessage],
|
|
84
84
|
history: createHistoryStep<AppActionInvocationHistoryStep>(state.history, {
|
|
85
|
-
type:
|
|
85
|
+
type: NodeType.APP_TOOL,
|
|
86
86
|
nodeId: node.name,
|
|
87
87
|
nodeDisplayName: node.displayName!,
|
|
88
88
|
raw: AIToolCallMessage.tool_calls[0],
|
|
@@ -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/InterruptSessionManager.types';
|
|
6
7
|
|
|
7
8
|
type AddHumanInTheLoopNodeParams = {
|
|
8
9
|
graph: PreCompiledGraph;
|
|
@@ -16,7 +17,7 @@ export const addHumanInTheLoopNode = async ({ graph, attachedToNodeName }: AddHu
|
|
|
16
17
|
logger.info(`Executing "human in the loop" node for the attached 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
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RunnableLike } from '@langchain/core/runnables';
|
|
2
2
|
import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
3
|
-
import { JumpToNode } from '../types/Flows.types';
|
|
3
|
+
import { JumpToNode, NodeType } from '../types/Flows.types';
|
|
4
4
|
import { logger } from '../utils/logger';
|
|
5
|
-
import {
|
|
5
|
+
import { HistoryStep } from '../types/Agent.types';
|
|
6
6
|
import { createHistoryStep } from '../utils/history';
|
|
7
7
|
|
|
8
8
|
export const addJumpToNode = async ({ graph, node }: { graph: PreCompiledGraph; node: JumpToNode }) => {
|
|
@@ -11,7 +11,7 @@ export const addJumpToNode = async ({ graph, node }: { graph: PreCompiledGraph;
|
|
|
11
11
|
// No state modifications are necessary; control flow is handled via edges.
|
|
12
12
|
return {
|
|
13
13
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
14
|
-
type:
|
|
14
|
+
type: NodeType.JUMP_TO_NODE,
|
|
15
15
|
nodeId: node.name,
|
|
16
16
|
nodeDisplayName: node.displayName,
|
|
17
17
|
raw: '',
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { JunctionNode, NodeType } from '../types/Flows.types';
|
|
2
|
+
import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
3
|
+
import { RunnableLike } from '@langchain/core/runnables';
|
|
4
|
+
import { createHistoryStep } from '../utils/history';
|
|
5
|
+
import { HistoryStep } from '../types/Agent.types';
|
|
6
|
+
|
|
7
|
+
export const addJunctionNode = ({ graph, node }: { graph: PreCompiledGraph; node: JunctionNode }) => {
|
|
8
|
+
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
9
|
+
return {
|
|
10
|
+
history: createHistoryStep<HistoryStep>(state.history, {
|
|
11
|
+
type: NodeType.JUNCTION,
|
|
12
|
+
nodeId: node.name,
|
|
13
|
+
nodeDisplayName: node.displayName,
|
|
14
|
+
raw: '',
|
|
15
|
+
}),
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
graph.addNode(node.name, callback);
|
|
19
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RunnableLike } from '@langchain/core/runnables';
|
|
2
|
-
import { PromptNode } from '../types/Flows.types';
|
|
2
|
+
import { NodeType, PromptNode } from '../types/Flows.types';
|
|
3
3
|
import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { BaseLanguageModel } from '@langchain/core/language_models/base';
|
|
@@ -7,14 +7,14 @@ import { SystemMessage, AIMessage, ToolMessage } from '@langchain/core/messages'
|
|
|
7
7
|
import { Tool } from '../types/Tools.types';
|
|
8
8
|
import { tool as langchainTool } from '@langchain/core/tools';
|
|
9
9
|
import { AgentEventRequestPayloads, AgentEvents } from '../events/AgentEvents';
|
|
10
|
-
import { EmitSignature,
|
|
10
|
+
import { EmitSignature, HistoryStep } from '../types/Agent.types';
|
|
11
11
|
import { createLlmInstance } from '../llm/createLlmInstance';
|
|
12
12
|
import extractToolStateResponse from '../utils/extractStateMemoryResponse';
|
|
13
13
|
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
|
+
const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
18
18
|
type AddPromptNodeParams = {
|
|
19
19
|
graph: PreCompiledGraph;
|
|
20
20
|
node: PromptNode;
|
|
@@ -26,6 +26,7 @@ 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
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
29
30
|
logger.info(`Executing prompt node ${node.displayName}`);
|
|
30
31
|
const llmToUse = node.llmConfig ? createLlmInstance(node.llmConfig) : llm;
|
|
31
32
|
|
|
@@ -52,7 +53,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
52
53
|
`;
|
|
53
54
|
|
|
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
|
|
@@ -66,6 +67,26 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
66
67
|
try {
|
|
67
68
|
// Invoke the LangChain tool directly
|
|
68
69
|
const toolResult = await matchedTool.invoke(toolCall);
|
|
70
|
+
console.log('after invoke?');
|
|
71
|
+
//check for queue after tool call
|
|
72
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, {
|
|
73
|
+
messages: [
|
|
74
|
+
result,
|
|
75
|
+
toolResult,
|
|
76
|
+
new SystemMessage(
|
|
77
|
+
'you called tool when the user send a new message, Consider calling the function again after user message is processed',
|
|
78
|
+
),
|
|
79
|
+
],
|
|
80
|
+
history: [
|
|
81
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
82
|
+
type: NodeType.TOOL,
|
|
83
|
+
nodeId: node.name,
|
|
84
|
+
nodeDisplayName: node.displayName,
|
|
85
|
+
raw: toolResult,
|
|
86
|
+
messageIds: [toolResult.id!],
|
|
87
|
+
}),
|
|
88
|
+
],
|
|
89
|
+
});
|
|
69
90
|
const toolStateUpdate = extractToolStateResponse(toolResult);
|
|
70
91
|
// Properly merge memory and other state updates
|
|
71
92
|
stateUpdates = {
|
|
@@ -74,7 +95,8 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
74
95
|
memory: { ...(stateUpdates as any).memory, ...(toolStateUpdate as any).memory },
|
|
75
96
|
};
|
|
76
97
|
toolResults.push(toolResult);
|
|
77
|
-
} catch (error) {
|
|
98
|
+
} catch (error: any) {
|
|
99
|
+
if (error?.name === 'GraphInterrupt') throw error;
|
|
78
100
|
logger.error({ msg: `Error executing tool ${toolCall.name}:`, error });
|
|
79
101
|
const errorMessage = new ToolMessage({
|
|
80
102
|
content: JSON.stringify({ error: error instanceof Error ? error.message : String(error) }),
|
|
@@ -87,10 +109,30 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
87
109
|
}
|
|
88
110
|
}
|
|
89
111
|
|
|
112
|
+
// await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
113
|
+
|
|
90
114
|
// Return the tool call message and tool results with state updates spread at top level
|
|
91
115
|
return {
|
|
92
116
|
...stateUpdates,
|
|
93
117
|
messages: [result, ...toolResults],
|
|
118
|
+
history: [
|
|
119
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
120
|
+
type: NodeType.TOOL,
|
|
121
|
+
nodeId: node.name,
|
|
122
|
+
nodeDisplayName: node.displayName,
|
|
123
|
+
raw: result,
|
|
124
|
+
messageIds: [result.id!],
|
|
125
|
+
}),
|
|
126
|
+
...toolResults.map((toolResult) =>
|
|
127
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
128
|
+
type: NodeType.TOOL,
|
|
129
|
+
nodeId: node.name,
|
|
130
|
+
nodeDisplayName: node.displayName,
|
|
131
|
+
raw: toolResult,
|
|
132
|
+
messageIds: [toolResult.id!],
|
|
133
|
+
}),
|
|
134
|
+
),
|
|
135
|
+
],
|
|
94
136
|
};
|
|
95
137
|
}
|
|
96
138
|
|
|
@@ -101,10 +143,9 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
101
143
|
});
|
|
102
144
|
console.log('AI Message', result.content);
|
|
103
145
|
}
|
|
104
|
-
|
|
105
146
|
return {
|
|
106
147
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
107
|
-
type:
|
|
148
|
+
type: NodeType.PROMPT_NODE,
|
|
108
149
|
nodeId: node.name,
|
|
109
150
|
nodeDisplayName: node.displayName,
|
|
110
151
|
raw: result.content,
|
package/src/nodes/addToolNode.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ToolNode } from '../types/Flows.types';
|
|
1
|
+
import { NodeType, ToolNode } from '../types/Flows.types';
|
|
2
2
|
import { Tool } from '../types/Tools.types';
|
|
3
3
|
import { tool as langchainTool } from '@langchain/core/tools';
|
|
4
4
|
import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
@@ -10,7 +10,6 @@ import { Agent } from '../agent';
|
|
|
10
10
|
import { compilePlaybooks } from '../playbooks/playbooks';
|
|
11
11
|
import { createHistoryStep } from '../utils/history';
|
|
12
12
|
import { HistoryStep } from '../types/Agent.types';
|
|
13
|
-
import { HistoryStepType } from '../types/Agent.types';
|
|
14
13
|
|
|
15
14
|
export const addToolNode = async ({
|
|
16
15
|
graph,
|
|
@@ -60,7 +59,7 @@ export const addToolNode = async ({
|
|
|
60
59
|
return {
|
|
61
60
|
messages: [AIToolCallMessage],
|
|
62
61
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
63
|
-
type:
|
|
62
|
+
type: NodeType.TOOL,
|
|
64
63
|
nodeId: node.name,
|
|
65
64
|
nodeDisplayName: node.displayName,
|
|
66
65
|
raw: AIToolCallMessage.tool_calls?.[0] || '',
|
|
@@ -2,7 +2,7 @@ import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
|
2
2
|
import { RunnableLike } from '@langchain/core/runnables';
|
|
3
3
|
import { Tool } from '../types/Tools.types';
|
|
4
4
|
import { LLMProviders } from '../types/LLM.types';
|
|
5
|
-
import { internalNodesSuffix, ToolNode } from '../types/Flows.types';
|
|
5
|
+
import { internalNodesSuffix, NodeType, ToolNode } from '../types/Flows.types';
|
|
6
6
|
import { tool as langchainTool } from '@langchain/core/tools';
|
|
7
7
|
import { ToolMessage } from '@langchain/core/messages';
|
|
8
8
|
import { z } from 'zod';
|
|
@@ -11,7 +11,6 @@ import { Agent } from '../agent';
|
|
|
11
11
|
import { logger } from '../utils/logger';
|
|
12
12
|
import { createHistoryStep } from '../utils/history';
|
|
13
13
|
import { HistoryStep } from '../types/Agent.types';
|
|
14
|
-
import { HistoryStepType } from '../types/Agent.types';
|
|
15
14
|
|
|
16
15
|
type AddToolRunNodeParams = {
|
|
17
16
|
graph: PreCompiledGraph;
|
|
@@ -61,7 +60,7 @@ export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeNam
|
|
|
61
60
|
...toolStateUpdate,
|
|
62
61
|
messages: updatedMessages,
|
|
63
62
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
64
|
-
type:
|
|
63
|
+
type: NodeType.TOOL,
|
|
65
64
|
nodeId: toolNode.name,
|
|
66
65
|
nodeDisplayName: toolNode.displayName,
|
|
67
66
|
raw: toolCallMessage,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RunnableLike } from '@langchain/core/runnables';
|
|
2
|
-
import { TriggerNode, TriggerType } from '../types/Flows.types';
|
|
2
|
+
import { NodeType, TriggerNode, TriggerType } from '../types/Flows.types';
|
|
3
3
|
import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
4
4
|
import { logger } from '../utils/logger';
|
|
5
|
-
import { HistoryStep
|
|
5
|
+
import { HistoryStep } from '../types/Agent.types';
|
|
6
6
|
import { createHistoryStep } from '../utils/history';
|
|
7
7
|
|
|
8
8
|
export const addTriggerNode = async ({ graph, node }: { graph: PreCompiledGraph; node: TriggerNode }) => {
|
|
@@ -11,7 +11,7 @@ export const addTriggerNode = async ({ graph, node }: { graph: PreCompiledGraph;
|
|
|
11
11
|
if (node.triggerType === TriggerType.MANUAL) {
|
|
12
12
|
return {
|
|
13
13
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
14
|
-
type:
|
|
14
|
+
type: NodeType.TRIGGER,
|
|
15
15
|
nodeId: node.name,
|
|
16
16
|
nodeDisplayName: node.displayName,
|
|
17
17
|
raw: '',
|
package/src/nodes/nodeFactory.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { JunctionNode, Node, NodeType } from '../types/Flows.types';
|
|
1
|
+
import { Node, NodeType } from '../types/Flows.types';
|
|
3
2
|
import { PreCompiledGraph } from '../types/LangGraph.types';
|
|
4
3
|
import { Tool } from '../types/Tools.types';
|
|
5
4
|
import { addToolNode } from './addToolNode';
|
|
@@ -11,11 +10,7 @@ import { addTriggerNode } from './addTriggerNode';
|
|
|
11
10
|
import { LLMProviders } from '../types/LLM.types';
|
|
12
11
|
import { Agent } from '../agent';
|
|
13
12
|
import { addJumpToNode } from './addJumpToNode';
|
|
14
|
-
|
|
15
|
-
const addJunctionNode = ({ graph, node }: { graph: PreCompiledGraph; node: JunctionNode }) => {
|
|
16
|
-
const callback: RunnableLike = async () => { };
|
|
17
|
-
graph.addNode(node.name, callback);
|
|
18
|
-
};
|
|
13
|
+
import { addJunctionNode } from './addJunctionNode';
|
|
19
14
|
|
|
20
15
|
export const nodeFactory = ({
|
|
21
16
|
graph,
|
|
@@ -32,6 +32,15 @@ export enum MindedConnectionSocketMessageType {
|
|
|
32
32
|
TIMER_RESET = 'timer-reset',
|
|
33
33
|
TIMER_CANCEL = 'timer-cancel',
|
|
34
34
|
TIMER_TRIGGER = 'timer-trigger',
|
|
35
|
+
// Interrupt Session Management
|
|
36
|
+
INTERRUPT_SESSION_IS_PROCESSED = 'interrupt-session-is-processed',
|
|
37
|
+
INTERRUPT_SESSION_LOCK = 'interrupt-session-lock',
|
|
38
|
+
INTERRUPT_SESSION_RELEASE = 'interrupt-session-release',
|
|
39
|
+
INTERRUPT_SESSION_ENQUEUE = 'interrupt-session-enqueue',
|
|
40
|
+
INTERRUPT_SESSION_DEQUEUE_ALL = 'interrupt-session-dequeue-all',
|
|
41
|
+
INTERRUPT_SESSION_DEQUEUE = 'interrupt-session-dequeue',
|
|
42
|
+
INTERRUPT_SESSION_HAS_MESSAGES = 'interrupt-session-has-messages',
|
|
43
|
+
INTERRUPT_SESSION_GET_MESSAGES = 'interrupt-session-get-messages',
|
|
35
44
|
}
|
|
36
45
|
|
|
37
46
|
export type MindedConnectionSocketMessageTypeMap = {
|
|
@@ -55,6 +64,15 @@ export type MindedConnectionSocketMessageTypeMap = {
|
|
|
55
64
|
[MindedConnectionSocketMessageType.TIMER_RESET]: TimerResetRequest;
|
|
56
65
|
[MindedConnectionSocketMessageType.TIMER_CANCEL]: TimerCancelRequest;
|
|
57
66
|
[MindedConnectionSocketMessageType.TIMER_TRIGGER]: TimerTriggerRequest;
|
|
67
|
+
// Interrupt Session Management
|
|
68
|
+
[MindedConnectionSocketMessageType.INTERRUPT_SESSION_IS_PROCESSED]: InterruptSessionIsProcessedRequest;
|
|
69
|
+
[MindedConnectionSocketMessageType.INTERRUPT_SESSION_LOCK]: InterruptSessionLockRequest;
|
|
70
|
+
[MindedConnectionSocketMessageType.INTERRUPT_SESSION_RELEASE]: InterruptSessionReleaseRequest;
|
|
71
|
+
[MindedConnectionSocketMessageType.INTERRUPT_SESSION_ENQUEUE]: InterruptSessionEnqueueRequest;
|
|
72
|
+
[MindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE_ALL]: InterruptSessionDequeueAllRequest;
|
|
73
|
+
[MindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE]: InterruptSessionDequeueRequest;
|
|
74
|
+
[MindedConnectionSocketMessageType.INTERRUPT_SESSION_HAS_MESSAGES]: InterruptSessionHasMessagesRequest;
|
|
75
|
+
[MindedConnectionSocketMessageType.INTERRUPT_SESSION_GET_MESSAGES]: InterruptSessionGetMessagesRequest;
|
|
58
76
|
};
|
|
59
77
|
|
|
60
78
|
export interface BaseMindedConnectionSocketMessage {
|
|
@@ -178,3 +196,85 @@ export interface TimerTriggerRequest extends BaseMindedConnectionSocketMessage {
|
|
|
178
196
|
timerName: string;
|
|
179
197
|
eventArgs: Record<string, any>;
|
|
180
198
|
}
|
|
199
|
+
|
|
200
|
+
// Interrupt Session Management Interfaces
|
|
201
|
+
export interface InterruptSessionIsProcessedRequest extends BaseMindedConnectionSocketMessage {
|
|
202
|
+
sessionId: string;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface InterruptSessionIsProcessedResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
206
|
+
isProcessed?: boolean;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export interface InterruptSessionLockRequest extends BaseMindedConnectionSocketMessage {
|
|
210
|
+
sessionId: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface InterruptSessionLockResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
214
|
+
success?: boolean;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface InterruptSessionReleaseRequest extends BaseMindedConnectionSocketMessage {
|
|
218
|
+
sessionId: string;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export interface InterruptSessionReleaseResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
222
|
+
success?: boolean;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface InterruptSessionEnqueueRequest extends BaseMindedConnectionSocketMessage {
|
|
226
|
+
sessionId: string;
|
|
227
|
+
message: {
|
|
228
|
+
triggerBody: any;
|
|
229
|
+
triggerName: string;
|
|
230
|
+
appName?: string;
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface InterruptSessionEnqueueResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
235
|
+
success?: boolean;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export interface InterruptSessionDequeueAllRequest extends BaseMindedConnectionSocketMessage {
|
|
239
|
+
sessionId: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export interface InterruptSessionDequeueAllResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
243
|
+
messages?: Array<{
|
|
244
|
+
triggerBody: any;
|
|
245
|
+
triggerName: string;
|
|
246
|
+
appName?: string;
|
|
247
|
+
}>;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface InterruptSessionDequeueRequest extends BaseMindedConnectionSocketMessage {
|
|
251
|
+
sessionId: string;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export interface InterruptSessionDequeueResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
255
|
+
message?: {
|
|
256
|
+
triggerBody: any;
|
|
257
|
+
triggerName: string;
|
|
258
|
+
appName?: string;
|
|
259
|
+
} | null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface InterruptSessionHasMessagesRequest extends BaseMindedConnectionSocketMessage {
|
|
263
|
+
sessionId: string;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export interface InterruptSessionHasMessagesResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
267
|
+
hasMessages?: boolean;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface InterruptSessionGetMessagesRequest extends BaseMindedConnectionSocketMessage {
|
|
271
|
+
sessionId: string;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export interface InterruptSessionGetMessagesResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
275
|
+
messages?: Array<{
|
|
276
|
+
triggerBody: any;
|
|
277
|
+
triggerName: string;
|
|
278
|
+
appName?: string;
|
|
279
|
+
}>;
|
|
280
|
+
}
|