@minded-ai/mindedjs 1.0.25 → 1.0.27
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 +5 -2
- package/dist/agent.js +20 -29
- package/dist/agent.js.map +1 -1
- package/dist/cli/index.js +0 -0
- package/dist/edges/createPromptRouter.js +1 -4
- package/dist/edges/createPromptRouter.js.map +1 -1
- package/dist/events/AgentEvents.d.ts +0 -2
- package/dist/events/AgentEvents.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/nodes/addPromptNode.js +1 -4
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolNode.d.ts +4 -4
- package/dist/nodes/addToolNode.js +3 -6
- package/dist/nodes/addToolNode.js.map +1 -1
- package/dist/nodes/addTriggerNode.js.map +1 -1
- package/dist/nodes/nodeFactory.js +1 -1
- package/dist/nodes/nodeFactory.js.map +1 -1
- package/dist/platform/mindedConnectionTypes.d.ts +0 -1
- package/dist/types/Agent.types.d.ts +0 -12
- package/dist/types/Agent.types.js +0 -6
- package/dist/types/Agent.types.js.map +1 -1
- package/dist/types/Flows.types.d.ts +3 -15
- package/dist/types/LangGraph.types.d.ts +0 -3
- package/dist/types/LangGraph.types.js +0 -8
- package/dist/types/LangGraph.types.js.map +1 -1
- package/dist/types/Tools.types.d.ts +1 -3
- package/dist/types/Triggers.types.d.ts +1 -0
- package/dist/types/Triggers.types.js +3 -0
- package/dist/types/Triggers.types.js.map +1 -0
- package/docs/SUMMARY.md +1 -0
- package/docs/core-concepts/edges.md +84 -27
- package/docs/core-concepts/events.md +12 -8
- package/docs/core-concepts/triggers.md +4 -6
- package/docs/getting-started/environment-configuration.md +117 -0
- package/docs/getting-started/installation.md +9 -3
- package/examples/orderRefundAgent/orderRefundAgent.ts +1 -1
- package/package.json +1 -1
- package/src/agent.ts +28 -14
- package/src/edges/createDirectEdge.ts +1 -2
- package/src/edges/edgeFactory.ts +76 -51
- package/src/events/AgentEvents.ts +1 -0
- package/src/nodes/addPromptNode.ts +2 -1
- package/src/platform/config.ts +42 -0
- package/src/platform/mindedChatOpenAI.ts +16 -0
- package/src/platform/mindedConnection.ts +4 -3
- package/src/types/LLM.types.ts +4 -2
- package/src/types/LangGraph.types.ts +0 -4
- package/test/can-stay-on-node/can-stay-on-node.test.ts +18 -31
- package/test/cannot-stay-on-node/cannot-stay-on-node.test.ts +24 -41
- package/test/edge-priority/edge-priority.test.ts +182 -0
- package/test/edge-priority/flows/all-three-edges/test-flow.yaml +35 -0
- package/test/edge-priority/flows/logical-prompt-edges/test-flow.yaml +26 -0
- package/test/edge-priority/flows/stepforward-logical-edges/test-flow.yaml +25 -0
- package/test/edge-priority/flows/stepforward-prompt-edges/test-flow.yaml +25 -0
- package/test/human-in-the-loop-node/human-in-the-loop-node.test.ts +6 -11
- package/test/logical-edges/logical-edges.test.ts +4 -11
- package/test/no-human-in-the-loop-node/no-human-in-the-loop-node.test.ts +3 -6
- package/test/prompt-edges/prompt-edges.test.ts +4 -11
- package/test/prompt-node/prompt-node.test.ts +6 -11
- package/test/tool-node/tool-node.test.ts +2 -6
- package/test/trigger/trigger.test.ts +10 -26
- package/dist/internalTools/appActionRunnerTool.d.ts +0 -25
- package/dist/internalTools/appActionRunnerTool.js +0 -30
- package/dist/internalTools/appActionRunnerTool.js.map +0 -1
- package/dist/nodes/actionRunnerTool.d.ts +0 -11
- package/dist/nodes/actionRunnerTool.js +0 -83
- package/dist/nodes/actionRunnerTool.js.map +0 -1
- package/dist/nodes/addAppTool.d.ts +0 -8
- package/dist/nodes/addAppTool.js +0 -12
- package/dist/nodes/addAppTool.js.map +0 -1
- package/dist/nodes/addAppToolNode.d.ts +0 -8
- package/dist/nodes/addAppToolNode.js +0 -14
- package/dist/nodes/addAppToolNode.js.map +0 -1
- package/dist/nodes/callTool.d.ts +0 -10
- package/dist/nodes/callTool.js +0 -57
- package/dist/nodes/callTool.js.map +0 -1
- package/dist/nodes/toolNodeRunner.d.ts +0 -15
- package/dist/nodes/toolNodeRunner.js +0 -79
- package/dist/nodes/toolNodeRunner.js.map +0 -1
- package/dist/tools/appToolRunner.d.ts +0 -30
- package/dist/tools/appToolRunner.js +0 -35
- package/dist/tools/appToolRunner.js.map +0 -1
- package/dist/tools/parser.d.ts +0 -14
- package/dist/tools/parser.js +0 -17
- package/dist/tools/parser.js.map +0 -1
- package/dist/tools/triggerTypeToDefaultMessage.d.ts +0 -3
- package/dist/tools/triggerTypeToDefaultMessage.js +0 -10
- package/dist/tools/triggerTypeToDefaultMessage.js.map +0 -1
- package/dist/triggers/triggerTypeToDefaultMessage.d.ts +0 -3
- package/dist/triggers/triggerTypeToDefaultMessage.js +0 -10
- package/dist/triggers/triggerTypeToDefaultMessage.js.map +0 -1
- package/src/platform/analytics.ts +0 -16
- package/src/platform/mindedRequest.ts +0 -29
package/src/edges/edgeFactory.ts
CHANGED
|
@@ -6,9 +6,10 @@ import { createLogicalRouter } from './createLogicalRouter';
|
|
|
6
6
|
import { createDirectEdge } from './createDirectEdge';
|
|
7
7
|
import { addHumanInTheLoopNode, buildHumanInTheLoopNodeName } from '../nodes/addHumanInTheLoopNode';
|
|
8
8
|
|
|
9
|
-
type
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
type EdgesBySource = {
|
|
10
|
+
stepForward?: StepForwardEdge;
|
|
11
|
+
logical: LogicalConditionEdge[];
|
|
12
|
+
prompt: PromptConditionEdge[];
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
export const edgeFactory = ({
|
|
@@ -23,63 +24,87 @@ export const edgeFactory = ({
|
|
|
23
24
|
llm: BaseLanguageModel;
|
|
24
25
|
}) => {
|
|
25
26
|
/**
|
|
26
|
-
*
|
|
27
|
-
* This elegant abstraction handles both prompt and logical edges uniformly
|
|
27
|
+
* Creates a combined router that handles edge priority: step forward > logical > prompt
|
|
28
28
|
*/
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
const createCombinedRouter = (sourceNode: string, edgesBySource: EdgesBySource) => {
|
|
30
|
+
return async (state: any) => {
|
|
31
|
+
// Priority 1: Step forward edge (max 1)
|
|
32
|
+
if (edgesBySource.stepForward) {
|
|
33
|
+
const directRouter = createDirectEdge(edgesBySource.stepForward);
|
|
34
|
+
return await directRouter();
|
|
35
|
+
}
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
// Priority 2: Logical condition edges
|
|
38
|
+
if (edgesBySource.logical.length > 0) {
|
|
39
|
+
const logicalRouter = createLogicalRouter({ edges: edgesBySource.logical });
|
|
40
|
+
const result = await logicalRouter(state);
|
|
41
|
+
if (result && result !== edgesBySource.logical[0].source) {
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
36
45
|
|
|
37
|
-
//
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
46
|
+
// Priority 3: Prompt condition edges
|
|
47
|
+
if (edgesBySource.prompt.length > 0) {
|
|
48
|
+
const promptRouter = createPromptRouter({ edges: edgesBySource.prompt, llm });
|
|
49
|
+
return await promptRouter(state);
|
|
41
50
|
}
|
|
42
51
|
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
target: source,
|
|
48
|
-
type: EdgeType.PROMPT_CONDITION,
|
|
49
|
-
prompt: 'stay at current node if still relevant',
|
|
50
|
-
} as T;
|
|
52
|
+
// Fallback: stay at current source node
|
|
53
|
+
return sourceNode;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Processes all edges for a specific source node with enhanced capabilities
|
|
59
|
+
*/
|
|
60
|
+
const processEdgesForNode = (source: string, edgesBySource: EdgesBySource): void => {
|
|
61
|
+
let effectiveSource = source;
|
|
62
|
+
|
|
63
|
+
// Handle human-in-the-loop enhancement
|
|
64
|
+
if (nodes[source]?.humanInTheLoop) {
|
|
65
|
+
addHumanInTheLoopNode({ graph, attachedToNodeName: source });
|
|
66
|
+
effectiveSource = buildHumanInTheLoopNodeName(source);
|
|
67
|
+
}
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
// Handle stay-on-node capability
|
|
70
|
+
if (nodes[source]?.canStayOnNode) {
|
|
71
|
+
const stayEdge: PromptConditionEdge = {
|
|
72
|
+
source,
|
|
73
|
+
target: source,
|
|
74
|
+
type: EdgeType.PROMPT_CONDITION,
|
|
75
|
+
prompt: 'stay at current node if still relevant',
|
|
76
|
+
};
|
|
77
|
+
edgesBySource.prompt.push(stayEdge);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Create and add the combined conditional edge
|
|
81
|
+
const combinedRouter = createCombinedRouter(effectiveSource, edgesBySource);
|
|
82
|
+
graph.addConditionalEdges(effectiveSource as any, combinedRouter);
|
|
57
83
|
};
|
|
58
84
|
|
|
59
|
-
//
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
85
|
+
// Get all unique source nodes and categorize their edges in a single pass
|
|
86
|
+
const edgesBySource = edges.reduce((acc, edge) => {
|
|
87
|
+
if (!acc[edge.source]) {
|
|
88
|
+
acc[edge.source] = {
|
|
89
|
+
stepForward: undefined,
|
|
90
|
+
logical: [],
|
|
91
|
+
prompt: [],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (edge.type === EdgeType.STEP_FORWARD) {
|
|
96
|
+
acc[edge.source].stepForward = edge as StepForwardEdge;
|
|
97
|
+
} else if (edge.type === EdgeType.LOGICAL_CONDITION) {
|
|
98
|
+
acc[edge.source].logical.push(edge as LogicalConditionEdge);
|
|
99
|
+
} else if (edge.type === EdgeType.PROMPT_CONDITION) {
|
|
100
|
+
acc[edge.source].prompt.push(edge as PromptConditionEdge);
|
|
101
|
+
}
|
|
67
102
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (promptEdges.length > 0) {
|
|
71
|
-
processEdges({
|
|
72
|
-
edges: promptEdges,
|
|
73
|
-
router: createPromptRouter,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
103
|
+
return acc;
|
|
104
|
+
}, {} as Record<string, EdgesBySource>);
|
|
76
105
|
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
edges: logicalEdges,
|
|
82
|
-
router: createLogicalRouter,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
106
|
+
// Process edges for each source node
|
|
107
|
+
Object.entries(edgesBySource).forEach(([source, categorizedEdges]) => {
|
|
108
|
+
processEdgesForNode(source, categorizedEdges);
|
|
109
|
+
});
|
|
85
110
|
};
|
|
@@ -22,7 +22,7 @@ type AddPromptNodeParams = {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
export const addPromptNode = async ({ graph, node, llm, tools, emit }: AddPromptNodeParams) => {
|
|
25
|
-
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
25
|
+
const callback: RunnableLike = async (state: typeof stateAnnotation.State, { configurable }) => {
|
|
26
26
|
console.log(`Executing prompt node ${node.name}`);
|
|
27
27
|
const llmToUse = node.llmConfig ? createLlmInstance(node.llmConfig) : llm;
|
|
28
28
|
|
|
@@ -62,6 +62,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit }: AddPrompt
|
|
|
62
62
|
await emit(AgentEvents.AI_MESSAGE, {
|
|
63
63
|
message: lastMessage.content as string,
|
|
64
64
|
memory: state.memory,
|
|
65
|
+
sessionId: configurable.thread_id,
|
|
65
66
|
});
|
|
66
67
|
}
|
|
67
68
|
return {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
type MindedConfig = {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
env: Environment;
|
|
4
|
+
token: string;
|
|
5
|
+
runLocally: boolean;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type Environment = 'development' | 'sandbox' | 'production' | 'test';
|
|
9
|
+
|
|
10
|
+
export const getConfig = (): MindedConfig => {
|
|
11
|
+
const environment = (process.env.NODE_ENV as Environment) || 'sandbox';
|
|
12
|
+
switch (environment) {
|
|
13
|
+
case 'test':
|
|
14
|
+
return {
|
|
15
|
+
baseUrl: 'http://localhost:8888',
|
|
16
|
+
env: 'test',
|
|
17
|
+
token: process.env.MINDED_CONNECTION_TOKEN || '',
|
|
18
|
+
runLocally: true,
|
|
19
|
+
};
|
|
20
|
+
case 'development':
|
|
21
|
+
return {
|
|
22
|
+
baseUrl: 'http://localhost:8888',
|
|
23
|
+
env: 'development',
|
|
24
|
+
token: process.env.MINDED_CONNECTION_TOKEN || '',
|
|
25
|
+
runLocally: process.env.RUN_LOCALLY === 'true',
|
|
26
|
+
};
|
|
27
|
+
case 'sandbox':
|
|
28
|
+
return {
|
|
29
|
+
baseUrl: 'https://dashboard-api.minded.com',
|
|
30
|
+
env: 'sandbox',
|
|
31
|
+
token: process.env.MINDED_CONNECTION_TOKEN || '',
|
|
32
|
+
runLocally: false,
|
|
33
|
+
};
|
|
34
|
+
case 'production':
|
|
35
|
+
return {
|
|
36
|
+
baseUrl: 'https://api.minded.com',
|
|
37
|
+
env: 'production',
|
|
38
|
+
token: process.env.MINDED_CONNECTION_TOKEN || '',
|
|
39
|
+
runLocally: false,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
super({
|
|
9
|
+
...fields,
|
|
10
|
+
apiKey: token,
|
|
11
|
+
configuration: {
|
|
12
|
+
baseURL: mindedBaseUrl,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -4,6 +4,7 @@ import { BaseMindedConnectionSocketMessage, MindedConnectionSocketMessageType }
|
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
import { stringify } from 'flatted';
|
|
7
|
+
import { getConfig } from './config';
|
|
7
8
|
|
|
8
9
|
export class MindedConnection {
|
|
9
10
|
private socket: Socket | null = null;
|
|
@@ -14,7 +15,7 @@ export class MindedConnection {
|
|
|
14
15
|
} = {};
|
|
15
16
|
|
|
16
17
|
constructor() {
|
|
17
|
-
if (!
|
|
18
|
+
if (!getConfig().token && !this.getSavedToken()) {
|
|
18
19
|
this.initializeReadline();
|
|
19
20
|
}
|
|
20
21
|
}
|
|
@@ -46,7 +47,7 @@ export class MindedConnection {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
private async getMindedToken(): Promise<string> {
|
|
49
|
-
const envToken =
|
|
50
|
+
const envToken = getConfig().token;
|
|
50
51
|
if (envToken) {
|
|
51
52
|
this.saveToken(envToken);
|
|
52
53
|
return envToken;
|
|
@@ -110,7 +111,7 @@ export class MindedConnection {
|
|
|
110
111
|
};
|
|
111
112
|
|
|
112
113
|
private async connect(token: string) {
|
|
113
|
-
this.socket = io(
|
|
114
|
+
this.socket = io(getConfig().baseUrl, {
|
|
114
115
|
path: '/minded-connect',
|
|
115
116
|
query: {
|
|
116
117
|
token,
|
package/src/types/LLM.types.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';
|
|
2
|
+
import { MindedChatOpenAI } from '../platform/mindedChatOpenAI';
|
|
2
3
|
|
|
3
4
|
export type LLMConfig = {
|
|
4
5
|
name: string,
|
|
5
6
|
properties: Record<string, any>
|
|
6
7
|
}
|
|
7
8
|
|
|
8
|
-
export type LLMProvider = 'ChatOpenAI' | 'AzureChatOpenAI';
|
|
9
|
+
export type LLMProvider = 'ChatOpenAI' | 'AzureChatOpenAI' | 'MindedChatOpenAI';
|
|
9
10
|
|
|
10
|
-
export const LLMProviders = {
|
|
11
|
+
export const LLMProviders: Record<LLMProvider, any> = {
|
|
11
12
|
ChatOpenAI: ChatOpenAI,
|
|
12
13
|
AzureChatOpenAI: AzureChatOpenAI,
|
|
14
|
+
MindedChatOpenAI,
|
|
13
15
|
}
|
|
@@ -19,10 +19,6 @@ export const stateAnnotation = Annotation.Root({
|
|
|
19
19
|
name: string;
|
|
20
20
|
triggerBody: any;
|
|
21
21
|
} | null>,
|
|
22
|
-
interruptedNode: Annotation<string | null>({
|
|
23
|
-
default: () => null,
|
|
24
|
-
reducer: (a, b) => b,
|
|
25
|
-
}),
|
|
26
22
|
history: Annotation<Array<FlowHistory>>({
|
|
27
23
|
default: () => [],
|
|
28
24
|
reducer: (a, b) => a.concat(b),
|
|
@@ -5,7 +5,6 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { AgentEvents } from '../../src/events/AgentEvents';
|
|
7
7
|
import { HumanMessage } from '@langchain/core/messages';
|
|
8
|
-
import { MindedConnectionSocketMessageType } from '../../src/platform/mindedConnectionTypes';
|
|
9
8
|
|
|
10
9
|
const memorySchema = z.object({
|
|
11
10
|
success: z.boolean(),
|
|
@@ -66,14 +65,12 @@ describe('Can Stay On Node', function () {
|
|
|
66
65
|
|
|
67
66
|
// First invocation - triggers the flow and reaches the human-in-the-loop pause
|
|
68
67
|
const result1 = await agent.invoke({
|
|
69
|
-
|
|
70
|
-
body: {
|
|
68
|
+
triggerBody: {
|
|
71
69
|
message: 'Initial input for processing',
|
|
72
70
|
},
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
triggerName: 'Trigger',
|
|
72
|
+
sessionId: sessionId,
|
|
75
73
|
appName: 'test',
|
|
76
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
77
74
|
});
|
|
78
75
|
|
|
79
76
|
// Should pause at human-in-the-loop, not reach success tool yet
|
|
@@ -82,14 +79,12 @@ describe('Can Stay On Node', function () {
|
|
|
82
79
|
|
|
83
80
|
// Second invocation - provide "stay" instruction
|
|
84
81
|
const result2 = await agent.invoke({
|
|
85
|
-
|
|
86
|
-
body: {
|
|
82
|
+
triggerBody: {
|
|
87
83
|
message: 'stay',
|
|
88
84
|
},
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
triggerName: 'Trigger',
|
|
86
|
+
sessionId: sessionId,
|
|
91
87
|
appName: 'test',
|
|
92
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
93
88
|
});
|
|
94
89
|
|
|
95
90
|
// Should stay on the node, pause again, not reach success tool
|
|
@@ -98,14 +93,12 @@ describe('Can Stay On Node', function () {
|
|
|
98
93
|
|
|
99
94
|
// Third invocation - provide another "stay" instruction
|
|
100
95
|
const result3 = await agent.invoke({
|
|
101
|
-
|
|
102
|
-
body: {
|
|
96
|
+
triggerBody: {
|
|
103
97
|
message: 'stay',
|
|
104
98
|
},
|
|
105
|
-
|
|
106
|
-
|
|
99
|
+
triggerName: 'Trigger',
|
|
100
|
+
sessionId: sessionId,
|
|
107
101
|
appName: 'test',
|
|
108
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
109
102
|
});
|
|
110
103
|
|
|
111
104
|
// Should still stay on the node, pause again
|
|
@@ -114,14 +107,12 @@ describe('Can Stay On Node', function () {
|
|
|
114
107
|
|
|
115
108
|
// Fourth invocation - provide "continue" instruction
|
|
116
109
|
const result4 = await agent.invoke({
|
|
117
|
-
|
|
118
|
-
body: {
|
|
110
|
+
triggerBody: {
|
|
119
111
|
message: 'continue',
|
|
120
112
|
},
|
|
121
|
-
|
|
122
|
-
|
|
113
|
+
triggerName: 'Trigger',
|
|
114
|
+
sessionId: sessionId,
|
|
123
115
|
appName: 'test',
|
|
124
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
125
116
|
});
|
|
126
117
|
|
|
127
118
|
// Should now move to success tool and complete
|
|
@@ -135,14 +126,12 @@ describe('Can Stay On Node', function () {
|
|
|
135
126
|
|
|
136
127
|
// First invocation - triggers the flow and reaches the human-in-the-loop pause
|
|
137
128
|
const result1 = await agent.invoke({
|
|
138
|
-
|
|
139
|
-
body: {
|
|
129
|
+
triggerBody: {
|
|
140
130
|
message: 'Initial input for processing',
|
|
141
131
|
},
|
|
142
|
-
|
|
143
|
-
|
|
132
|
+
triggerName: 'Trigger',
|
|
133
|
+
sessionId: sessionId,
|
|
144
134
|
appName: 'test',
|
|
145
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
146
135
|
});
|
|
147
136
|
|
|
148
137
|
// Should pause at human-in-the-loop, not reach success tool yet
|
|
@@ -151,14 +140,12 @@ describe('Can Stay On Node', function () {
|
|
|
151
140
|
|
|
152
141
|
// Second invocation - provide "continue" instruction
|
|
153
142
|
const result2 = await agent.invoke({
|
|
154
|
-
|
|
155
|
-
body: {
|
|
143
|
+
triggerBody: {
|
|
156
144
|
message: 'continue',
|
|
157
145
|
},
|
|
158
|
-
|
|
159
|
-
|
|
146
|
+
triggerName: 'Trigger',
|
|
147
|
+
sessionId: sessionId,
|
|
160
148
|
appName: 'test',
|
|
161
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
162
149
|
});
|
|
163
150
|
|
|
164
151
|
// Should now move to success tool and complete
|
|
@@ -5,7 +5,6 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { AgentEvents } from '../../src/events/AgentEvents';
|
|
7
7
|
import { HumanMessage } from '@langchain/core/messages';
|
|
8
|
-
import { MindedConnectionSocketMessageType } from '../../src/platform/mindedConnectionTypes';
|
|
9
8
|
|
|
10
9
|
const memorySchema = z.object({
|
|
11
10
|
success: z.boolean(),
|
|
@@ -80,14 +79,12 @@ describe('Cannot Stay On Node', function () {
|
|
|
80
79
|
|
|
81
80
|
// First invocation - triggers the flow and reaches the human-in-the-loop pause
|
|
82
81
|
const result1 = await agent.invoke({
|
|
83
|
-
|
|
84
|
-
body: {
|
|
82
|
+
triggerBody: {
|
|
85
83
|
message: 'Initial input for processing',
|
|
86
84
|
},
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
triggerName: 'Trigger',
|
|
86
|
+
sessionId: sessionId,
|
|
89
87
|
appName: 'test',
|
|
90
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
91
88
|
});
|
|
92
89
|
|
|
93
90
|
// Should pause at human-in-the-loop, not reach any tool yet
|
|
@@ -97,14 +94,12 @@ describe('Cannot Stay On Node', function () {
|
|
|
97
94
|
|
|
98
95
|
// Second invocation - explicitly request to stay on the node
|
|
99
96
|
const result2 = await agent.invoke({
|
|
100
|
-
|
|
101
|
-
body: {
|
|
97
|
+
triggerBody: {
|
|
102
98
|
message: 'You must stay at the node! Do not move to the next step. Stay here and continue processing on this same node.',
|
|
103
99
|
},
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
triggerName: 'Trigger',
|
|
101
|
+
sessionId: sessionId,
|
|
106
102
|
appName: 'test',
|
|
107
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
108
103
|
});
|
|
109
104
|
|
|
110
105
|
// Should NOT stay on the node - should move to one of the target nodes
|
|
@@ -119,14 +114,12 @@ describe('Cannot Stay On Node', function () {
|
|
|
119
114
|
|
|
120
115
|
// First invocation - initial trigger
|
|
121
116
|
const result1 = await agent.invoke({
|
|
122
|
-
|
|
123
|
-
body: {
|
|
117
|
+
triggerBody: {
|
|
124
118
|
message: 'Start processing',
|
|
125
119
|
},
|
|
126
|
-
|
|
127
|
-
|
|
120
|
+
triggerName: 'Trigger',
|
|
121
|
+
sessionId: sessionId,
|
|
128
122
|
appName: 'test',
|
|
129
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
130
123
|
});
|
|
131
124
|
|
|
132
125
|
expect(result1.memory.success).to.not.equal(true);
|
|
@@ -134,14 +127,12 @@ describe('Cannot Stay On Node', function () {
|
|
|
134
127
|
|
|
135
128
|
// Second invocation - request main workflow
|
|
136
129
|
const result2 = await agent.invoke({
|
|
137
|
-
|
|
138
|
-
body: {
|
|
130
|
+
triggerBody: {
|
|
139
131
|
message: 'Proceed with the main workflow',
|
|
140
132
|
},
|
|
141
|
-
|
|
142
|
-
|
|
133
|
+
triggerName: 'Trigger',
|
|
134
|
+
sessionId: sessionId,
|
|
143
135
|
appName: 'test',
|
|
144
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
145
136
|
});
|
|
146
137
|
|
|
147
138
|
// Should move to success node
|
|
@@ -156,14 +147,12 @@ describe('Cannot Stay On Node', function () {
|
|
|
156
147
|
|
|
157
148
|
// First invocation - initial trigger
|
|
158
149
|
const result1 = await agent.invoke({
|
|
159
|
-
|
|
160
|
-
body: {
|
|
150
|
+
triggerBody: {
|
|
161
151
|
message: 'Begin workflow',
|
|
162
152
|
},
|
|
163
|
-
|
|
164
|
-
|
|
153
|
+
triggerName: 'Trigger',
|
|
154
|
+
sessionId: sessionId,
|
|
165
155
|
appName: 'test',
|
|
166
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
167
156
|
});
|
|
168
157
|
|
|
169
158
|
expect(result1.memory.success).to.not.equal(true);
|
|
@@ -171,14 +160,12 @@ describe('Cannot Stay On Node', function () {
|
|
|
171
160
|
|
|
172
161
|
// Second invocation - request alternative approach
|
|
173
162
|
const result2 = await agent.invoke({
|
|
174
|
-
|
|
175
|
-
body: {
|
|
163
|
+
triggerBody: {
|
|
176
164
|
message: 'I want an alternative approach instead',
|
|
177
165
|
},
|
|
178
|
-
|
|
179
|
-
|
|
166
|
+
triggerName: 'Trigger',
|
|
167
|
+
sessionId: sessionId,
|
|
180
168
|
appName: 'test',
|
|
181
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
182
169
|
});
|
|
183
170
|
|
|
184
171
|
// Should move to alternative node
|
|
@@ -193,14 +180,12 @@ describe('Cannot Stay On Node', function () {
|
|
|
193
180
|
|
|
194
181
|
// First invocation - initial trigger
|
|
195
182
|
const result1 = await agent.invoke({
|
|
196
|
-
|
|
197
|
-
body: {
|
|
183
|
+
triggerBody: {
|
|
198
184
|
message: 'Process this data',
|
|
199
185
|
},
|
|
200
|
-
|
|
201
|
-
|
|
186
|
+
triggerName: 'Trigger',
|
|
187
|
+
sessionId: sessionId,
|
|
202
188
|
appName: 'test',
|
|
203
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
204
189
|
});
|
|
205
190
|
|
|
206
191
|
expect(result1.memory.success).to.not.equal(true);
|
|
@@ -208,15 +193,13 @@ describe('Cannot Stay On Node', function () {
|
|
|
208
193
|
|
|
209
194
|
// Second invocation - very strong request to stay
|
|
210
195
|
const result2 = await agent.invoke({
|
|
211
|
-
|
|
212
|
-
body: {
|
|
196
|
+
triggerBody: {
|
|
213
197
|
message:
|
|
214
198
|
'STAY! Do not proceed! You must remain on this current node and not move forward. Keep processing here. Do not go to any other node.',
|
|
215
199
|
},
|
|
216
|
-
|
|
217
|
-
|
|
200
|
+
triggerName: 'Trigger',
|
|
201
|
+
sessionId: sessionId,
|
|
218
202
|
appName: 'test',
|
|
219
|
-
type: MindedConnectionSocketMessageType.OnAppTrigger,
|
|
220
203
|
});
|
|
221
204
|
|
|
222
205
|
// Should still be forced to move to one of the available target nodes
|