@minded-ai/mindedjs 1.0.24 → 1.0.25

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.
Files changed (88) hide show
  1. package/dist/agent.d.ts +2 -5
  2. package/dist/agent.js +29 -20
  3. package/dist/agent.js.map +1 -1
  4. package/dist/cli/index.js +0 -0
  5. package/dist/edges/createPromptRouter.js +4 -1
  6. package/dist/edges/createPromptRouter.js.map +1 -1
  7. package/dist/events/AgentEvents.d.ts +2 -0
  8. package/dist/events/AgentEvents.js.map +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +3 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/internalTools/appActionRunnerTool.d.ts +25 -0
  13. package/dist/internalTools/appActionRunnerTool.js +30 -0
  14. package/dist/internalTools/appActionRunnerTool.js.map +1 -0
  15. package/dist/nodes/actionRunnerTool.d.ts +11 -0
  16. package/dist/nodes/actionRunnerTool.js +83 -0
  17. package/dist/nodes/actionRunnerTool.js.map +1 -0
  18. package/dist/nodes/addAppTool.d.ts +8 -0
  19. package/dist/nodes/addAppTool.js +12 -0
  20. package/dist/nodes/addAppTool.js.map +1 -0
  21. package/dist/nodes/addAppToolNode.d.ts +8 -0
  22. package/dist/nodes/addAppToolNode.js +14 -0
  23. package/dist/nodes/addAppToolNode.js.map +1 -0
  24. package/dist/nodes/addPromptNode.js +4 -1
  25. package/dist/nodes/addPromptNode.js.map +1 -1
  26. package/dist/nodes/addToolNode.d.ts +4 -4
  27. package/dist/nodes/addToolNode.js +6 -3
  28. package/dist/nodes/addToolNode.js.map +1 -1
  29. package/dist/nodes/addTriggerNode.js.map +1 -1
  30. package/dist/nodes/callTool.d.ts +10 -0
  31. package/dist/nodes/callTool.js +57 -0
  32. package/dist/nodes/callTool.js.map +1 -0
  33. package/dist/nodes/nodeFactory.js +1 -1
  34. package/dist/nodes/nodeFactory.js.map +1 -1
  35. package/dist/nodes/toolNodeRunner.d.ts +15 -0
  36. package/dist/nodes/toolNodeRunner.js +79 -0
  37. package/dist/nodes/toolNodeRunner.js.map +1 -0
  38. package/dist/platform/mindedConnectionTypes.d.ts +1 -0
  39. package/dist/tools/appToolRunner.d.ts +30 -0
  40. package/dist/tools/appToolRunner.js +35 -0
  41. package/dist/tools/appToolRunner.js.map +1 -0
  42. package/dist/tools/parser.d.ts +14 -0
  43. package/dist/tools/parser.js +17 -0
  44. package/dist/tools/parser.js.map +1 -0
  45. package/dist/tools/triggerTypeToDefaultMessage.d.ts +3 -0
  46. package/dist/tools/triggerTypeToDefaultMessage.js +10 -0
  47. package/dist/tools/triggerTypeToDefaultMessage.js.map +1 -0
  48. package/dist/triggers/triggerTypeToDefaultMessage.d.ts +3 -0
  49. package/dist/triggers/triggerTypeToDefaultMessage.js +10 -0
  50. package/dist/triggers/triggerTypeToDefaultMessage.js.map +1 -0
  51. package/dist/types/Agent.types.d.ts +12 -0
  52. package/dist/types/Agent.types.js +6 -0
  53. package/dist/types/Agent.types.js.map +1 -1
  54. package/dist/types/Flows.types.d.ts +15 -3
  55. package/dist/types/LangGraph.types.d.ts +3 -0
  56. package/dist/types/LangGraph.types.js +8 -0
  57. package/dist/types/LangGraph.types.js.map +1 -1
  58. package/dist/types/Tools.types.d.ts +3 -1
  59. package/docs/SUMMARY.md +11 -10
  60. package/docs/core-concepts/triggers.md +89 -0
  61. package/examples/orderRefundAgent/flows/orderRefundFlow.yaml +6 -12
  62. package/package.json +2 -2
  63. package/src/agent.ts +25 -21
  64. package/src/edges/createPromptRouter.ts +13 -7
  65. package/src/events/AgentEvents.ts +2 -1
  66. package/src/index.ts +1 -0
  67. package/src/nodes/addPromptNode.ts +9 -3
  68. package/src/nodes/addToolNode.ts +15 -12
  69. package/src/nodes/addTriggerNode.ts +6 -6
  70. package/src/nodes/nodeFactory.ts +2 -2
  71. package/src/platform/mindedConnectionTypes.ts +1 -0
  72. package/src/triggers/triggerTypeToDefaultMessage.ts +9 -0
  73. package/src/types/Agent.types.ts +15 -0
  74. package/src/types/Flows.types.ts +16 -3
  75. package/src/types/LangGraph.types.ts +9 -1
  76. package/src/types/Tools.types.ts +2 -1
  77. package/test/can-stay-on-node/can-stay-on-node.test.ts +37 -18
  78. package/test/cannot-stay-on-node/cannot-stay-on-node.test.ts +49 -24
  79. package/test/human-in-the-loop-node/human-in-the-loop-node.test.ts +13 -6
  80. package/test/logical-edges/logical-edges.test.ts +13 -4
  81. package/test/no-human-in-the-loop-node/no-human-in-the-loop-node.test.ts +7 -3
  82. package/test/prompt-edges/prompt-edges.test.ts +13 -4
  83. package/test/prompt-node/prompt-node.test.ts +13 -6
  84. package/test/tool-node/tool-node.test.ts +7 -2
  85. package/test/trigger/trigger.test.ts +150 -6
  86. package/dist/types/Triggers.types.d.ts +0 -1
  87. package/dist/types/Triggers.types.js +0 -3
  88. package/dist/types/Triggers.types.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minded-ai/mindedjs",
3
- "version": "1.0.24",
3
+ "version": "1.0.25",
4
4
  "description": "MindedJS is a TypeScript library for building agents.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -49,4 +49,4 @@
49
49
  "uuid": "^11.1.0",
50
50
  "zod": "^3.24.4"
51
51
  }
52
- }
52
+ }
package/src/agent.ts CHANGED
@@ -9,17 +9,18 @@ import { CompiledGraph, PreCompiledGraph, stateAnnotation } from './types/LangGr
9
9
  import { edgeFactory } from './edges/edgeFactory';
10
10
  import { AgentEventRequestPayloads, AgentEventResponsePayloads, AgentEvents } from './events/AgentEvents';
11
11
  import { z } from 'zod';
12
-
13
12
  import { MindedConnection } from './platform/mindedConnection';
14
13
  import { BaseMindedConnectionSocketMessage, MindedConnectionSocketMessageType, OnAppTrigger } from './platform/mindedConnectionTypes';
15
14
  import * as fs from 'fs';
16
15
  import * as path from 'path';
17
16
  import * as yaml from 'js-yaml';
18
- import { MindedSDKConfig } from './types/Agent.types';
17
+ import { MindedSDKConfig, TriggerInvocationHistory } from './types/Agent.types';
19
18
  import { createLlmInstance } from './llm/createLlmInstance';
20
19
  import { config } from 'dotenv';
21
20
  import { resolve } from 'path';
22
21
  import { createCheckpointSaver } from './checkpointer/checkpointSaverFactory';
22
+ import { BaseMessage } from '@langchain/core/messages';
23
+ import triggerTypeToDefaultMessage from './triggers/triggerTypeToDefaultMessage';
23
24
 
24
25
  config({ path: resolve(__dirname, '../.env') });
25
26
 
@@ -63,17 +64,12 @@ export class Agent {
63
64
  this.mindedConnection.start();
64
65
  this.mindedConnection.on(MindedConnectionSocketMessageType.OnAppTrigger, async (message: BaseMindedConnectionSocketMessage) => {
65
66
  const trigger = message as OnAppTrigger;
66
- await this.invoke({
67
- triggerBody: trigger.body,
68
- triggerName: trigger.name,
69
- sessionId: trigger.cnvId,
70
- });
67
+ await this.invoke(trigger);
71
68
  });
72
69
  }
73
70
  this.checkpointer = memorySaver || createCheckpointSaver(this.mindedConnection);
74
71
  this.compiledGraph = this.initializeGraph();
75
72
  }
76
-
77
73
  private loadFlowsFromDirectory(flowsDirectories: string[]): Flow[] {
78
74
  const flows: Flow[] = [];
79
75
  for (const flowsDirectory of flowsDirectories) {
@@ -163,40 +159,48 @@ export class Agent {
163
159
  memory: {} as z.infer<typeof this.memorySchema>,
164
160
  triggerMetadata: null,
165
161
  interruptedNode: null,
162
+ history: [],
163
+ triggerInvocations: [] as Array<TriggerInvocationHistory>,
166
164
  };
167
165
  }
168
166
 
169
- public async invoke({ triggerBody, triggerName, sessionId }: { triggerBody: any; triggerName: string; sessionId?: string }) {
170
- const session = sessionId || uuidv4();
167
+ public async invoke(trigger: OnAppTrigger) {
168
+ const session = trigger.cnvId || uuidv4();
169
+ const triggerName = trigger.name;
170
+ const triggerBody = trigger.body;
171
+ const appName = trigger.appName;
171
172
  const results = await this.emit(AgentEvents.TRIGGER_EVENT, {
172
173
  triggerName,
173
174
  triggerBody,
174
175
  });
175
176
  const handlerResult = results.find((r) => r !== undefined);
176
- if (handlerResult === false) {
177
- console.log(`Disqualified trigger ${triggerName}`);
178
- throw new Error('Disqualified trigger');
177
+ let memoryUpdate = {};
178
+ let messages: Array<BaseMessage> = [];
179
+ if (handlerResult) {
180
+ memoryUpdate = handlerResult.memory || {};
181
+ messages = handlerResult.messages ?? [];
182
+ } else {
183
+ messages = triggerTypeToDefaultMessage[appName]?.[triggerName]?.(triggerBody) ?? [];
179
184
  }
180
- const memoryUpdate = handlerResult?.memory || {};
181
- const messages = handlerResult?.messages ?? [];
185
+ const triggerInvocation = { appName, triggerName, triggerBody };
186
+ const history = [{
187
+ type: 'triggerInvocation',
188
+ ...triggerInvocation
189
+ }];
182
190
  console.log(`Invoking trigger ${triggerName} with session ${session}`);
183
191
  const config = { configurable: { thread_id: session, recursionLimit: 3 } };
184
- // const triggerNode = this.compiledGraph.builder.nodes[triggerName];
185
- // if (!triggerNode) {
186
- // throw new Error(`Trigger node not found: ${triggerName}`);
187
- // }
188
192
  const state = await this.compiledGraph.getState(config);
189
193
  // Resume interruption
190
194
  if (state.tasks?.[0]?.interrupts?.length > 0) {
191
195
  const res = await this.compiledGraph.invoke(
192
196
  new Command({
193
- resume: { memory: memoryUpdate, messages },
197
+ resume: { memory: memoryUpdate, messages, history, triggerInvocations: [triggerInvocation] },
194
198
  }),
195
199
  config,
196
200
  );
197
201
  return res;
198
202
  } else {
199
- const res = await this.compiledGraph.invoke({ messages, memory: memoryUpdate }, config);
203
+ const res = await this.compiledGraph.invoke({ messages, memory: memoryUpdate, history, triggerInvocations: [triggerInvocation] }, config);
200
204
  return res;
201
205
  }
202
206
  }
@@ -4,9 +4,12 @@ import { PromptConditionEdge } from '../types/Flows.types';
4
4
  import { BaseLanguageModel } from '@langchain/core/language_models/base';
5
5
  import { AIMessage } from '@langchain/core/messages';
6
6
  import { stateAnnotation } from '../types/LangGraph.types';
7
+ import { MemorySaver } from '@langchain/langgraph';
8
+ import { v4 as uuidv4 } from 'uuid';
7
9
 
8
10
  export const createPromptRouter = ({ edges, llm }: { edges: PromptConditionEdge[]; llm: BaseLanguageModel }) => {
9
11
  const agent = createReactAgent({
12
+ checkpointer: new MemorySaver(),
10
13
  llm,
11
14
  tools: [],
12
15
  responseFormat: z.object({
@@ -16,10 +19,11 @@ export const createPromptRouter = ({ edges, llm }: { edges: PromptConditionEdge[
16
19
  });
17
20
  return async (state: typeof stateAnnotation.State) => {
18
21
  console.log(`Executing prompt router. Edges: ${JSON.stringify(edges)}`);
19
- const result = await agent.invoke({
20
- messages: [
21
- new AIMessage({
22
- content: `You are a router that decides which node to take in a flow based on the current memory state, history and available node ids.
22
+ const result = await agent.invoke(
23
+ {
24
+ messages: [
25
+ new AIMessage({
26
+ content: `You are a router that decides which node to take in a flow based on the current memory state, history and available node ids.
23
27
 
24
28
  Your task is to analyze the current memory state, history and available nodes and determine the most appropriate next node in the flow, the returned nodeId should be only the id without the prompt.
25
29
 
@@ -35,9 +39,11 @@ ${JSON.stringify(state.messages)}
35
39
 
36
40
  Based on the memory state and available nodes, determine the most appropriate next node id.
37
41
  `,
38
- }),
39
- ],
40
- });
42
+ }),
43
+ ],
44
+ },
45
+ { configurable: { thread_id: uuidv4() } },
46
+ );
41
47
  try {
42
48
  const nextNode = result.structuredResponse.nextNodeId;
43
49
  console.log(`Next node: ${nextNode}`);
@@ -1,4 +1,5 @@
1
1
  import { BaseMessage } from '@langchain/core/messages';
2
+ import { FlowHistory } from '../types/Agent.types';
2
3
 
3
4
  export enum AgentEvents {
4
5
  AI_MESSAGE = 'AI_MESSAGE',
@@ -18,5 +19,5 @@ export type AgentEventRequestPayloads<Memory> = {
18
19
 
19
20
  export type AgentEventResponsePayloads<Memory> = {
20
21
  [AgentEvents.AI_MESSAGE]: void;
21
- [AgentEvents.TRIGGER_EVENT]: { messages?: BaseMessage[]; memory?: Memory } | false;
22
+ [AgentEvents.TRIGGER_EVENT]: { messages?: BaseMessage[]; memory?: Memory, history?: FlowHistory[] } | false;
22
23
  };
package/src/index.ts CHANGED
@@ -20,3 +20,4 @@ export type {
20
20
  } from './types/Flows.types';
21
21
  export { NodeType, TriggerType, EdgeType } from './types/Flows.types';
22
22
  export type { Tool } from './types/Tools.types';
23
+ export { FlowHistoryType, FlowHistory, TriggerInvocationHistory } from './types/Agent.types';
@@ -10,6 +10,8 @@ import { tool as langchainTool } from '@langchain/core/tools';
10
10
  import { AgentEventRequestPayloads, AgentEvents } from '../events/AgentEvents';
11
11
  import { EmitSignature } from '../types/Agent.types';
12
12
  import { createLlmInstance } from '../llm/createLlmInstance';
13
+ import { MemorySaver } from '@langchain/langgraph';
14
+ import { v4 as uuidv4 } from 'uuid';
13
15
 
14
16
  type AddPromptNodeParams = {
15
17
  graph: PreCompiledGraph;
@@ -35,6 +37,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit }: AddPrompt
35
37
  );
36
38
 
37
39
  const agent = createReactAgent({
40
+ checkpointer: new MemorySaver(),
38
41
  llm: llmToUse,
39
42
  tools: globalTools,
40
43
  responseFormat: z.object({
@@ -48,9 +51,12 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit }: AddPrompt
48
51
  - Workflow memory: ${JSON.stringify(state.memory)}
49
52
  - Conversation history: ${state.messages.map((message) => `${message.getType()}: ${message.content}`).join('\n')}
50
53
  `;
51
- const result = await agent.invoke({
52
- messages: [new SystemMessage(message)],
53
- });
54
+ const result = await agent.invoke(
55
+ {
56
+ messages: [new SystemMessage(message)],
57
+ },
58
+ { configurable: { thread_id: uuidv4() } },
59
+ );
54
60
  const lastMessage = result.messages[result.messages.length - 1];
55
61
  if (lastMessage.getType() === 'ai') {
56
62
  await emit(AgentEvents.AI_MESSAGE, {
@@ -1,12 +1,14 @@
1
- import { BaseLanguageModel } from "@langchain/core/language_models/base";
2
- import { ToolNode } from "../types/Flows.types";
3
- import { Tool } from "../types/Tools.types";
4
- import { tool as langchainTool } from "@langchain/core/tools";
5
- import { PreCompiledGraph, stateAnnotation } from "../types/LangGraph.types";
6
- import { AIMessage, BaseMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
7
- import { createReactAgent } from "@langchain/langgraph/prebuilt";
8
- import { RunnableLike } from "@langchain/core/runnables";
9
- import { z } from "zod";
1
+ import { BaseLanguageModel } from '@langchain/core/language_models/base';
2
+ import { ToolNode } from '../types/Flows.types';
3
+ import { Tool } from '../types/Tools.types';
4
+ import { tool as langchainTool } from '@langchain/core/tools';
5
+ import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
6
+ import { AIMessage, BaseMessage, SystemMessage, ToolMessage } from '@langchain/core/messages';
7
+ import { createReactAgent } from '@langchain/langgraph/prebuilt';
8
+ import { RunnableLike } from '@langchain/core/runnables';
9
+ import { z } from 'zod';
10
+ import { MemorySaver } from '@langchain/langgraph';
11
+ import { v4 as uuidv4 } from 'uuid';
10
12
 
11
13
  export const addToolNode = async <Memory>({
12
14
  graph,
@@ -30,7 +32,7 @@ export const addToolNode = async <Memory>({
30
32
 
31
33
  const executeWrapper = async (input: z.infer<typeof matchedTool.input>) => {
32
34
  try {
33
- const response = await matchedTool.execute({ input, memory: state.memory });
35
+ const response = await matchedTool.execute({ input, memory: state.memory, triggerInvocations: state.triggerInvocations });
34
36
  return response || {};
35
37
  } catch (error) {
36
38
  console.error('Error executing tool', error);
@@ -51,17 +53,18 @@ export const addToolNode = async <Memory>({
51
53
  ${toolNode.prompt && `Tool execution instructions: ${toolNode.prompt}`}
52
54
  `;
53
55
  const toolCallingAgent = createReactAgent({
56
+ checkpointer: new MemorySaver(),
54
57
  llm,
55
58
  tools: [tool],
56
59
  });
57
- const response = await toolCallingAgent.invoke({ messages: [new SystemMessage(prompt)] });
60
+ const response = await toolCallingAgent.invoke({ messages: [new SystemMessage(prompt)] }, { configurable: { thread_id: uuidv4() } });
58
61
  const toolCallMessage = getLastToolCallMessage(response.messages);
59
62
  const toolResponseMessage = getLastToolMessage(response.messages);
60
63
  if (!toolCallMessage || !toolResponseMessage) {
61
64
  throw new Error('Tool call or tool response message not found');
62
65
  }
63
66
  const toolMemory = extractToolMemoryResponse<Memory>(toolResponseMessage);
64
- return { memory: toolMemory, messages: [toolCallMessage, toolResponseMessage] };
67
+ return { memory: toolMemory, messages: [toolCallMessage, toolResponseMessage], triggerInvocations: state.triggerInvocations };
65
68
  } catch (error) {
66
69
  console.error('Error executing tool node', error);
67
70
  throw error;
@@ -3,10 +3,10 @@ import { TriggerNode } from '../types/Flows.types';
3
3
  import { PreCompiledGraph } from '../types/LangGraph.types';
4
4
 
5
5
  export const addTriggerNode = async ({ graph, node }: { graph: PreCompiledGraph; node: TriggerNode }) => {
6
- const callback: RunnableLike = async () => {
7
- console.log(`Executing trigger node ${node.name}`);
8
- return;
9
- };
6
+ const callback: RunnableLike = async () => {
7
+ console.log(`Executing trigger node ${node.name}`);
8
+ return;
9
+ };
10
10
 
11
- graph.addNode(node.name, callback);
12
- };
11
+ graph.addNode(node.name, callback);
12
+ };
@@ -3,14 +3,14 @@ import { AppToolNode, JunctionNode, Node, NodeType } from '../types/Flows.types'
3
3
  import { PreCompiledGraph } from '../types/LangGraph.types';
4
4
  import { Tool } from '../types/Tools.types';
5
5
  import { BaseLanguageModel } from '@langchain/core/language_models/base';
6
- import { addTriggerNode } from './addTriggerNode';
7
6
  import { addToolNode } from './addToolNode';
8
7
  import { addPromptNode } from './addPromptNode';
9
8
  import { AgentEventRequestPayloads } from '../events/AgentEvents';
10
9
  import { EmitSignature } from '../types/Agent.types';
10
+ import { addTriggerNode } from './addTriggerNode';
11
11
 
12
12
  const addJunctionNode = ({ graph, node }: { graph: PreCompiledGraph; node: JunctionNode }) => {
13
- const callback: RunnableLike = async () => {};
13
+ const callback: RunnableLike = async () => { };
14
14
  graph.addNode(node.name, callback);
15
15
  };
16
16
 
@@ -28,6 +28,7 @@ export interface OnAppTrigger extends BaseMindedConnectionSocketMessage {
28
28
  agentId: string;
29
29
  body: Record<string, any>;
30
30
  cnvId: string;
31
+ appName: string;
31
32
  }
32
33
 
33
34
  export interface OnCheckpointPut extends BaseMindedConnectionSocketMessage {
@@ -0,0 +1,9 @@
1
+ import { BaseMessage, HumanMessage } from "@langchain/core/messages";
2
+
3
+ const triggerTypeToDefaultMessage: Record<string, Record<string, (triggerBody: any) => Array<BaseMessage>>> = {
4
+ ["Slack"]: {
5
+ "New Direct Message (Instant)": (triggerBody: any) => [new HumanMessage({ content: triggerBody.text })],
6
+ }
7
+ };
8
+
9
+ export default triggerTypeToDefaultMessage;
@@ -8,3 +8,18 @@ export type MindedSDKConfig = {
8
8
  llm: LLMConfig;
9
9
  tools: string[];
10
10
  }
11
+
12
+ export enum FlowHistoryType {
13
+ TRIGGER_INVOCATION = 'triggerInvocation',
14
+ }
15
+
16
+ export interface FlowHistory {
17
+ type: FlowHistoryType;
18
+ }
19
+
20
+ export interface TriggerInvocationHistory extends FlowHistory {
21
+ type: FlowHistoryType.TRIGGER_INVOCATION;
22
+ appName?: string;
23
+ triggerName: string;
24
+ triggerBody: any;
25
+ };
@@ -36,9 +36,19 @@ export interface BaseTriggerNode extends BaseNode {
36
36
  type: NodeType.TRIGGER;
37
37
  }
38
38
 
39
- export interface AppTriggerNode extends BaseTriggerNode {
39
+ export interface BaseAppNode {
40
+ appName: string;
41
+ appImgSrc: string;
42
+ account?: string;
43
+ mockDataInstructions?: string;
44
+ textSentToModel?: string;
45
+ }
46
+
47
+ export interface AppTriggerNode extends BaseTriggerNode, BaseAppNode {
40
48
  triggerType: TriggerType.APP;
41
49
  appTriggerId: string;
50
+ appTriggerName: string;
51
+ promptInstructions?: string;
42
52
  }
43
53
 
44
54
  export interface WebhookTriggerNode extends BaseTriggerNode {
@@ -67,9 +77,12 @@ export interface ToolNode extends BaseNode {
67
77
  prompt: string;
68
78
  }
69
79
 
70
- export interface AppToolNode extends BaseNode {
80
+ export interface AppToolNode extends BaseNode, BaseAppNode {
71
81
  type: NodeType.APP_TOOL;
72
- prompt: string;
82
+ prompt?: string;
83
+ actionName: string;
84
+ actionKey: string;
85
+ parameters?: Record<string, 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null'>;
73
86
  }
74
87
 
75
88
  export type Node = TriggerNode | JunctionNode | ToolNode | AppToolNode | PromptNode;
@@ -1,5 +1,6 @@
1
1
  import { BaseMessage } from '@langchain/core/messages';
2
2
  import { Annotation, CompiledStateGraph, StateGraph } from '@langchain/langgraph';
3
+ import { FlowHistory, TriggerInvocationHistory } from './Agent.types';
3
4
 
4
5
  export const stateAnnotation = Annotation.Root({
5
6
  messages: Annotation<Array<BaseMessage>>({
@@ -10,7 +11,10 @@ export const stateAnnotation = Annotation.Root({
10
11
  default: () => ({}),
11
12
  reducer: (a, b) => ({ ...a, ...b }),
12
13
  }),
13
-
14
+ triggerInvocations: Annotation<Array<TriggerInvocationHistory>>({
15
+ default: () => [],
16
+ reducer: (a, b) => a.concat(b),
17
+ }),
14
18
  triggerMetadata: Annotation<{
15
19
  name: string;
16
20
  triggerBody: any;
@@ -19,6 +23,10 @@ export const stateAnnotation = Annotation.Root({
19
23
  default: () => null,
20
24
  reducer: (a, b) => b,
21
25
  }),
26
+ history: Annotation<Array<FlowHistory>>({
27
+ default: () => [],
28
+ reducer: (a, b) => a.concat(b),
29
+ }),
22
30
  });
23
31
 
24
32
  export type CompiledGraph = CompiledStateGraph<any, any, string>;
@@ -1,9 +1,10 @@
1
1
  import { z } from 'zod';
2
+ import { FlowHistory } from './Agent.types';
2
3
 
3
4
  export interface Tool<Input extends z.ZodSchema, Memory> {
4
5
  name: string;
5
6
  description: string;
6
7
  input: Input;
7
8
  isGlobal?: boolean;
8
- execute: ({ input, memory }: { input: z.infer<Input>; memory: Memory }) => Promise<{ memory?: Partial<Memory>, result?: any } | void>;
9
+ execute: ({ input, memory, triggerInvocations }: { input: z.infer<Input>; memory: Memory; triggerInvocations?: Array<FlowHistory> }) => Promise<{ memory?: Partial<Memory>, result?: any } | void>;
9
10
  }
@@ -5,6 +5,7 @@ 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';
8
9
 
9
10
  const memorySchema = z.object({
10
11
  success: z.boolean(),
@@ -65,11 +66,14 @@ describe('Can Stay On Node', function () {
65
66
 
66
67
  // First invocation - triggers the flow and reaches the human-in-the-loop pause
67
68
  const result1 = await agent.invoke({
68
- triggerBody: {
69
+ name: 'Trigger',
70
+ body: {
69
71
  message: 'Initial input for processing',
70
72
  },
71
- triggerName: 'Trigger',
72
- sessionId,
73
+ cnvId: sessionId,
74
+ agentId: 'test',
75
+ appName: 'test',
76
+ type: MindedConnectionSocketMessageType.OnAppTrigger,
73
77
  });
74
78
 
75
79
  // Should pause at human-in-the-loop, not reach success tool yet
@@ -78,11 +82,14 @@ describe('Can Stay On Node', function () {
78
82
 
79
83
  // Second invocation - provide "stay" instruction
80
84
  const result2 = await agent.invoke({
81
- triggerBody: {
85
+ name: 'Trigger',
86
+ body: {
82
87
  message: 'stay',
83
88
  },
84
- triggerName: 'Trigger',
85
- sessionId,
89
+ cnvId: sessionId,
90
+ agentId: 'test',
91
+ appName: 'test',
92
+ type: MindedConnectionSocketMessageType.OnAppTrigger,
86
93
  });
87
94
 
88
95
  // Should stay on the node, pause again, not reach success tool
@@ -91,11 +98,14 @@ describe('Can Stay On Node', function () {
91
98
 
92
99
  // Third invocation - provide another "stay" instruction
93
100
  const result3 = await agent.invoke({
94
- triggerBody: {
101
+ name: 'Trigger',
102
+ body: {
95
103
  message: 'stay',
96
104
  },
97
- triggerName: 'Trigger',
98
- sessionId,
105
+ cnvId: sessionId,
106
+ agentId: 'test',
107
+ appName: 'test',
108
+ type: MindedConnectionSocketMessageType.OnAppTrigger,
99
109
  });
100
110
 
101
111
  // Should still stay on the node, pause again
@@ -104,11 +114,14 @@ describe('Can Stay On Node', function () {
104
114
 
105
115
  // Fourth invocation - provide "continue" instruction
106
116
  const result4 = await agent.invoke({
107
- triggerBody: {
117
+ name: 'Trigger',
118
+ body: {
108
119
  message: 'continue',
109
120
  },
110
- triggerName: 'Trigger',
111
- sessionId,
121
+ cnvId: sessionId,
122
+ agentId: 'test',
123
+ appName: 'test',
124
+ type: MindedConnectionSocketMessageType.OnAppTrigger,
112
125
  });
113
126
 
114
127
  // Should now move to success tool and complete
@@ -122,11 +135,14 @@ describe('Can Stay On Node', function () {
122
135
 
123
136
  // First invocation - triggers the flow and reaches the human-in-the-loop pause
124
137
  const result1 = await agent.invoke({
125
- triggerBody: {
138
+ name: 'Trigger',
139
+ body: {
126
140
  message: 'Initial input for processing',
127
141
  },
128
- triggerName: 'Trigger',
129
- sessionId,
142
+ cnvId: sessionId,
143
+ agentId: 'test',
144
+ appName: 'test',
145
+ type: MindedConnectionSocketMessageType.OnAppTrigger,
130
146
  });
131
147
 
132
148
  // Should pause at human-in-the-loop, not reach success tool yet
@@ -135,11 +151,14 @@ describe('Can Stay On Node', function () {
135
151
 
136
152
  // Second invocation - provide "continue" instruction
137
153
  const result2 = await agent.invoke({
138
- triggerBody: {
154
+ name: 'Trigger',
155
+ body: {
139
156
  message: 'continue',
140
157
  },
141
- triggerName: 'Trigger',
142
- sessionId,
158
+ cnvId: sessionId,
159
+ agentId: 'test',
160
+ appName: 'test',
161
+ type: MindedConnectionSocketMessageType.OnAppTrigger,
143
162
  });
144
163
 
145
164
  // Should now move to success tool and complete