@minded-ai/mindedjs 1.0.23 → 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 (96) hide show
  1. package/dist/agent.d.ts +2 -5
  2. package/dist/agent.js +41 -25
  3. package/dist/agent.js.map +1 -1
  4. package/dist/checkpointer/checkpointSaverFactory.js +1 -1
  5. package/dist/checkpointer/checkpointSaverFactory.js.map +1 -1
  6. package/dist/cli/index.js +0 -0
  7. package/dist/edges/createPromptRouter.js +4 -1
  8. package/dist/edges/createPromptRouter.js.map +1 -1
  9. package/dist/events/AgentEvents.d.ts +2 -0
  10. package/dist/events/AgentEvents.js.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +3 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/internalTools/appActionRunnerTool.d.ts +25 -0
  15. package/dist/internalTools/appActionRunnerTool.js +30 -0
  16. package/dist/internalTools/appActionRunnerTool.js.map +1 -0
  17. package/dist/nodes/actionRunnerTool.d.ts +11 -0
  18. package/dist/nodes/actionRunnerTool.js +83 -0
  19. package/dist/nodes/actionRunnerTool.js.map +1 -0
  20. package/dist/nodes/addAppTool.d.ts +8 -0
  21. package/dist/nodes/addAppTool.js +12 -0
  22. package/dist/nodes/addAppTool.js.map +1 -0
  23. package/dist/nodes/addAppToolNode.d.ts +8 -0
  24. package/dist/nodes/addAppToolNode.js +14 -0
  25. package/dist/nodes/addAppToolNode.js.map +1 -0
  26. package/dist/nodes/addPromptNode.js +4 -1
  27. package/dist/nodes/addPromptNode.js.map +1 -1
  28. package/dist/nodes/addToolNode.d.ts +4 -4
  29. package/dist/nodes/addToolNode.js +6 -3
  30. package/dist/nodes/addToolNode.js.map +1 -1
  31. package/dist/nodes/addTriggerNode.js.map +1 -1
  32. package/dist/nodes/callTool.d.ts +10 -0
  33. package/dist/nodes/callTool.js +57 -0
  34. package/dist/nodes/callTool.js.map +1 -0
  35. package/dist/nodes/nodeFactory.js +1 -1
  36. package/dist/nodes/nodeFactory.js.map +1 -1
  37. package/dist/nodes/toolNodeRunner.d.ts +15 -0
  38. package/dist/nodes/toolNodeRunner.js +79 -0
  39. package/dist/nodes/toolNodeRunner.js.map +1 -0
  40. package/dist/platform/mindedConnection.js +1 -0
  41. package/dist/platform/mindedConnection.js.map +1 -1
  42. package/dist/platform/mindedConnectionTypes.d.ts +1 -0
  43. package/dist/tools/appToolRunner.d.ts +30 -0
  44. package/dist/tools/appToolRunner.js +35 -0
  45. package/dist/tools/appToolRunner.js.map +1 -0
  46. package/dist/tools/parser.d.ts +14 -0
  47. package/dist/tools/parser.js +17 -0
  48. package/dist/tools/parser.js.map +1 -0
  49. package/dist/tools/triggerTypeToDefaultMessage.d.ts +3 -0
  50. package/dist/tools/triggerTypeToDefaultMessage.js +10 -0
  51. package/dist/tools/triggerTypeToDefaultMessage.js.map +1 -0
  52. package/dist/triggers/triggerTypeToDefaultMessage.d.ts +3 -0
  53. package/dist/triggers/triggerTypeToDefaultMessage.js +10 -0
  54. package/dist/triggers/triggerTypeToDefaultMessage.js.map +1 -0
  55. package/dist/types/Agent.types.d.ts +12 -0
  56. package/dist/types/Agent.types.js +6 -0
  57. package/dist/types/Agent.types.js.map +1 -1
  58. package/dist/types/Flows.types.d.ts +15 -3
  59. package/dist/types/LangGraph.types.d.ts +3 -0
  60. package/dist/types/LangGraph.types.js +8 -0
  61. package/dist/types/LangGraph.types.js.map +1 -1
  62. package/dist/types/Tools.types.d.ts +3 -1
  63. package/docs/SUMMARY.md +11 -10
  64. package/docs/core-concepts/nodes.md +18 -0
  65. package/docs/core-concepts/tools.md +21 -1
  66. package/docs/core-concepts/triggers.md +89 -0
  67. package/examples/orderRefundAgent/flows/orderRefundFlow.yaml +6 -12
  68. package/package.json +2 -2
  69. package/src/agent.ts +37 -26
  70. package/src/checkpointer/checkpointSaverFactory.ts +1 -1
  71. package/src/edges/createPromptRouter.ts +13 -7
  72. package/src/events/AgentEvents.ts +2 -1
  73. package/src/index.ts +1 -0
  74. package/src/nodes/addPromptNode.ts +9 -3
  75. package/src/nodes/addToolNode.ts +15 -12
  76. package/src/nodes/addTriggerNode.ts +6 -6
  77. package/src/nodes/nodeFactory.ts +2 -2
  78. package/src/platform/mindedConnection.ts +1 -0
  79. package/src/platform/mindedConnectionTypes.ts +1 -0
  80. package/src/triggers/triggerTypeToDefaultMessage.ts +9 -0
  81. package/src/types/Agent.types.ts +15 -0
  82. package/src/types/Flows.types.ts +16 -3
  83. package/src/types/LangGraph.types.ts +9 -1
  84. package/src/types/Tools.types.ts +2 -1
  85. package/test/can-stay-on-node/can-stay-on-node.test.ts +37 -18
  86. package/test/cannot-stay-on-node/cannot-stay-on-node.test.ts +49 -24
  87. package/test/human-in-the-loop-node/human-in-the-loop-node.test.ts +13 -6
  88. package/test/logical-edges/logical-edges.test.ts +13 -4
  89. package/test/no-human-in-the-loop-node/no-human-in-the-loop-node.test.ts +7 -3
  90. package/test/prompt-edges/prompt-edges.test.ts +13 -4
  91. package/test/prompt-node/prompt-node.test.ts +13 -6
  92. package/test/tool-node/tool-node.test.ts +7 -2
  93. package/test/trigger/trigger.test.ts +150 -6
  94. package/dist/types/Triggers.types.d.ts +0 -1
  95. package/dist/types/Triggers.types.js +0 -3
  96. package/dist/types/Triggers.types.js.map +0 -1
@@ -0,0 +1,89 @@
1
+ # Triggers
2
+
3
+ Triggers are the entry points into your agent's flows. They serve as the initial contact point between external systems and your agent, handling incoming events and initializing conversations with appropriate context and memory.
4
+
5
+ ## Trigger Types
6
+
7
+ Currently, MindedJS supports a single type of trigger:
8
+
9
+ - **App Triggers**: Triggered by specific applications (e.g., Slack, Zendesk)
10
+ - Each app trigger is identified by a unique `appTriggerId`
11
+ - Triggers can be customized to handle app-specific data formats
12
+ - Supports automatic message conversion for certain apps (e.g., Slack messages)
13
+
14
+ ### Trigger Invocation History
15
+
16
+ When a trigger is invoked, it creates a comprehensive record of the event that is:
17
+
18
+ 1. Added to the flow history for tracking and debugging
19
+ 2. Passed to subsequent tool calls via the `triggerInvocations` parameter
20
+ 3. Preserved throughout the flow's execution
21
+
22
+ This history allows tools to:
23
+
24
+ - Access the original trigger context
25
+ - Make decisions based on the triggering event
26
+ - Maintain conversation continuity
27
+ - Debug flow execution
28
+
29
+ Example:
30
+
31
+ ```typescript
32
+ const tool: Tool = {
33
+ name: 'myTool',
34
+ execute: async ({ input, triggerInvocations }) => {
35
+ // Access trigger information
36
+ const trigger = triggerInvocations[0];
37
+ console.log(`Triggered by ${trigger.appName}: ${trigger.triggerName}`);
38
+ },
39
+ };
40
+ ```
41
+
42
+ ### Default Message Behavior
43
+
44
+ MindedJS provides intelligent message handling for different trigger types through the `triggerTypeToDefaultMessage` mapping. This system:
45
+
46
+ - Automatically converts trigger data into appropriate message formats
47
+ - Maintains conversation context without manual intervention
48
+ - Supports different message types for different applications
49
+
50
+ Currently supported default messages:
51
+
52
+ - **Slack**: For "New Direct Message (Instant)" triggers, the message text is automatically converted to a human message
53
+
54
+ Example:
55
+
56
+ ```typescript
57
+ // Slack trigger will automatically add a human message
58
+ const slackResult = await agent.invoke({
59
+ name: 'New Direct Message (Instant)',
60
+ body: { text: 'Hello from Slack' },
61
+ appName: 'Slack',
62
+ // ... other required fields
63
+ });
64
+
65
+ // Other triggers won't add any messages by default
66
+ const otherResult = await agent.invoke({
67
+ name: 'SomeOtherTrigger',
68
+ body: { text: 'Hello' },
69
+ appName: 'OtherApp',
70
+ // ... other required fields
71
+ });
72
+ ```
73
+
74
+ ### Validate Trigger Input
75
+
76
+ ```typescript
77
+ // ✅ Good - Input validation
78
+ agent.on(AgentEvents.TRIGGER_EVENT, async ({ triggerName, triggerBody }) => {
79
+ if (!triggerBody.customerId || !triggerBody.message) {
80
+ return false; // Disqualify invalid triggers
81
+ }
82
+ // Process valid trigger
83
+ });
84
+
85
+ // ❌ Avoid - No validation
86
+ agent.on(AgentEvents.TRIGGER_EVENT, async ({ triggerBody }) => {
87
+ // Process without validation
88
+ });
89
+ ```
@@ -1,14 +1,5 @@
1
1
  name: 'Order refund flow'
2
2
  nodes:
3
- - type: 'trigger'
4
- triggerType: 'manual'
5
- name: 'New Direct Message (Instant)'
6
- - type: 'tool'
7
- name: 'Refund order'
8
- toolName: 'refundOrder'
9
- - type: 'tool'
10
- name: 'Escalate conversation'
11
- toolName: 'escalateConversation'
12
3
  - type: 'promptNode'
13
4
  name: 'Prompt'
14
5
  humanInTheLoop: true
@@ -18,10 +9,13 @@ nodes:
18
9
  name: 'AzureChatOpenAI'
19
10
  properties:
20
11
  model: 'gpt-4o'
12
+ - type: 'tool'
13
+ name: 'Refund order'
14
+ toolName: 'refundOrder'
15
+ - type: 'tool'
16
+ name: 'Escalate conversation'
17
+ toolName: 'escalateConversation'
21
18
  edges:
22
- - source: 'New Direct Message (Instant)'
23
- target: 'Prompt'
24
- type: 'stepForward'
25
19
  - source: 'Prompt'
26
20
  target: 'Refund order'
27
21
  type: 'promptCondition'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minded-ai/mindedjs",
3
- "version": "1.0.23",
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) {
@@ -140,11 +136,18 @@ export class Agent {
140
136
 
141
137
  // Add edges
142
138
  edgeFactory({ graph, edges, nodes: nodesObject, llm: this.llm });
143
- nodes.forEach((node) => {
144
- if (node.type === NodeType.TRIGGER) {
145
- graph.addEdge('__start__', node.name as any);
146
- }
147
- });
139
+
140
+ // Add edge from start to first node if no triggers exist
141
+ const hasTrigger = nodes.some((node) => node.type === NodeType.TRIGGER);
142
+ if (!hasTrigger && nodes.length > 0) {
143
+ graph.addEdge('__start__', nodes[0].name as any);
144
+ } else {
145
+ nodes.forEach((node) => {
146
+ if (node.type === NodeType.TRIGGER) {
147
+ graph.addEdge('__start__', node.name as any);
148
+ }
149
+ });
150
+ }
148
151
 
149
152
  // Compile the graph
150
153
  return graph.compile({ checkpointer: this.checkpointer }) as CompiledGraph;
@@ -156,40 +159,48 @@ export class Agent {
156
159
  memory: {} as z.infer<typeof this.memorySchema>,
157
160
  triggerMetadata: null,
158
161
  interruptedNode: null,
162
+ history: [],
163
+ triggerInvocations: [] as Array<TriggerInvocationHistory>,
159
164
  };
160
165
  }
161
166
 
162
- public async invoke({ triggerBody, triggerName, sessionId }: { triggerBody: any; triggerName: string; sessionId?: string }) {
163
- 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;
164
172
  const results = await this.emit(AgentEvents.TRIGGER_EVENT, {
165
173
  triggerName,
166
174
  triggerBody,
167
175
  });
168
176
  const handlerResult = results.find((r) => r !== undefined);
169
- if (handlerResult === false) {
170
- console.log(`Disqualified trigger ${triggerName}`);
171
- 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) ?? [];
172
184
  }
173
- const memoryUpdate = handlerResult?.memory || {};
174
- const messages = handlerResult?.messages ?? [];
185
+ const triggerInvocation = { appName, triggerName, triggerBody };
186
+ const history = [{
187
+ type: 'triggerInvocation',
188
+ ...triggerInvocation
189
+ }];
175
190
  console.log(`Invoking trigger ${triggerName} with session ${session}`);
176
191
  const config = { configurable: { thread_id: session, recursionLimit: 3 } };
177
- // const triggerNode = this.compiledGraph.builder.nodes[triggerName];
178
- // if (!triggerNode) {
179
- // throw new Error(`Trigger node not found: ${triggerName}`);
180
- // }
181
192
  const state = await this.compiledGraph.getState(config);
182
193
  // Resume interruption
183
194
  if (state.tasks?.[0]?.interrupts?.length > 0) {
184
195
  const res = await this.compiledGraph.invoke(
185
196
  new Command({
186
- resume: { memory: memoryUpdate, messages },
197
+ resume: { memory: memoryUpdate, messages, history, triggerInvocations: [triggerInvocation] },
187
198
  }),
188
199
  config,
189
200
  );
190
201
  return res;
191
202
  } else {
192
- const res = await this.compiledGraph.invoke({ messages, memory: memoryUpdate }, config);
203
+ const res = await this.compiledGraph.invoke({ messages, memory: memoryUpdate, history, triggerInvocations: [triggerInvocation] }, config);
193
204
  return res;
194
205
  }
195
206
  }
@@ -13,6 +13,6 @@ export function createCheckpointSaver(mindedConnection: MindedConnection | null)
13
13
  return new MemorySaver();
14
14
  }
15
15
 
16
- console.log(`Using remote checkpoint saver}`);
16
+ console.log(`Using remote checkpoint saver`);
17
17
  return new MindedCheckpointSaver(mindedConnection);
18
18
  }
@@ -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
 
@@ -136,6 +136,7 @@ export class MindedConnection {
136
136
  console.error('Server error:', error.message);
137
137
 
138
138
  if (error.message.includes('Invalid token')) {
139
+ console.log('Invalid token');
139
140
  // Delete saved token on connection error
140
141
  if (fs.existsSync(this.tokenPath)) {
141
142
  fs.unlinkSync(this.tokenPath);
@@ -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
  }