@minded-ai/mindedjs 1.0.92-beta-2 → 1.0.92-beta-3

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 (63) hide show
  1. package/dist/agent.js +11 -11
  2. package/dist/agent.js.map +1 -1
  3. package/dist/cli/index.js +12 -12
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/edges/createDirectEdge.js +1 -1
  6. package/dist/edges/createDirectEdge.js.map +1 -1
  7. package/dist/edges/createLogicalRouter.d.ts.map +1 -1
  8. package/dist/edges/createLogicalRouter.js +7 -7
  9. package/dist/edges/createLogicalRouter.js.map +1 -1
  10. package/dist/edges/createPromptRouter.d.ts.map +1 -1
  11. package/dist/edges/createPromptRouter.js +4 -3
  12. package/dist/edges/createPromptRouter.js.map +1 -1
  13. package/dist/edges/edgeFactory.js +2 -2
  14. package/dist/edges/edgeFactory.js.map +1 -1
  15. package/dist/interrupts/InterruptSessionManager.types.d.ts.map +1 -1
  16. package/dist/interrupts/InterruptSessionManager.types.js +2 -1
  17. package/dist/interrupts/InterruptSessionManager.types.js.map +1 -1
  18. package/dist/interrupts/interruptSessionManagerFactory.d.ts.map +1 -1
  19. package/dist/interrupts/interruptSessionManagerFactory.js +3 -0
  20. package/dist/interrupts/interruptSessionManagerFactory.js.map +1 -1
  21. package/dist/nodes/addAppToolNode.js +1 -1
  22. package/dist/nodes/addAppToolNode.js.map +1 -1
  23. package/dist/nodes/addHumanInTheLoopNode.js +1 -1
  24. package/dist/nodes/addHumanInTheLoopNode.js.map +1 -1
  25. package/dist/nodes/addJumpToNode.js +1 -1
  26. package/dist/nodes/addJumpToNode.js.map +1 -1
  27. package/dist/nodes/addPromptNode.d.ts.map +1 -1
  28. package/dist/nodes/addPromptNode.js +8 -3
  29. package/dist/nodes/addPromptNode.js.map +1 -1
  30. package/dist/nodes/addToolNode.js +1 -1
  31. package/dist/nodes/addToolNode.js.map +1 -1
  32. package/dist/nodes/addTriggerNode.js +1 -1
  33. package/dist/nodes/addTriggerNode.js.map +1 -1
  34. package/dist/platform/mindedConnection.d.ts.map +1 -1
  35. package/dist/platform/mindedConnection.js +13 -13
  36. package/dist/platform/mindedConnection.js.map +1 -1
  37. package/dist/playbooks/playbooks.js +4 -4
  38. package/dist/playbooks/playbooks.js.map +1 -1
  39. package/dist/utils/logger.d.ts.map +1 -1
  40. package/dist/utils/logger.js +1 -0
  41. package/dist/utils/logger.js.map +1 -1
  42. package/dist/voice/voiceSession.d.ts.map +1 -1
  43. package/dist/voice/voiceSession.js +10 -2
  44. package/dist/voice/voiceSession.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/agent.ts +11 -11
  47. package/src/cli/index.ts +12 -12
  48. package/src/edges/createDirectEdge.ts +1 -1
  49. package/src/edges/createLogicalRouter.ts +7 -8
  50. package/src/edges/createPromptRouter.ts +4 -3
  51. package/src/edges/edgeFactory.ts +2 -2
  52. package/src/interrupts/InterruptSessionManager.types.ts +2 -1
  53. package/src/interrupts/interruptSessionManagerFactory.ts +3 -0
  54. package/src/nodes/addAppToolNode.ts +1 -1
  55. package/src/nodes/addHumanInTheLoopNode.ts +1 -1
  56. package/src/nodes/addJumpToNode.ts +1 -1
  57. package/src/nodes/addPromptNode.ts +10 -5
  58. package/src/nodes/addToolNode.ts +1 -1
  59. package/src/nodes/addTriggerNode.ts +1 -1
  60. package/src/platform/mindedConnection.ts +13 -13
  61. package/src/playbooks/playbooks.ts +4 -4
  62. package/src/utils/logger.ts +1 -0
  63. package/src/voice/voiceSession.ts +14 -6
@@ -11,8 +11,8 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
11
11
  logger.debug(`Evaluating logical conditions for ${edges.length} edges`);
12
12
 
13
13
  // Separate regular conditions from "else" conditions
14
- const regularEdges = edges.filter(edge => edge.condition.trim() !== 'else');
15
- const elseEdges = edges.filter(edge => edge.condition.trim() === 'else');
14
+ const regularEdges = edges.filter((edge) => edge.condition.trim() !== 'else');
15
+ const elseEdges = edges.filter((edge) => edge.condition.trim() === 'else');
16
16
 
17
17
  // First, evaluate all regular conditions
18
18
  for (const edge of regularEdges) {
@@ -59,17 +59,16 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
59
59
  ]);
60
60
 
61
61
  if (result === true) {
62
- logger.info(`Condition matched for edge ${edge.source} → ${edge.target}`);
62
+ logger.info({ message: `Condition matched for edge ${edge.source} → ${edge.target}` });
63
63
  return edge.target;
64
64
  }
65
-
66
65
  } catch (error) {
67
66
  // Provide detailed error information back to the customer
68
67
  const errorMessage = error instanceof Error ? error.message : String(error);
69
68
  const conditionPreview = edge.condition.length > 100 ? `${edge.condition.substring(0, 100)}...` : edge.condition;
70
69
 
71
70
  logger.error({
72
- msg: `Error evaluating condition for edge ${edge.source} → ${edge.target}`,
71
+ message: `Error evaluating condition for edge ${edge.source} → ${edge.target}`,
73
72
  condition: conditionPreview,
74
73
  error: errorMessage,
75
74
  edgeIndex: edges.indexOf(edge),
@@ -84,15 +83,15 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
84
83
 
85
84
  // If no regular conditions matched, check for "else" conditions
86
85
  if (elseEdges.length > 0) {
87
- logger.info(`No regular conditions matched, evaluating ${elseEdges.length} else condition(s)`);
86
+ logger.info({ message: `No regular conditions matched, evaluating ${elseEdges.length} else condition(s)` });
88
87
  // Return the first "else" condition's target
89
88
  const elseEdge = elseEdges[0];
90
- logger.info(`Else condition matched for edge ${elseEdge.source} → ${elseEdge.target}`);
89
+ logger.info({ message: `Else condition matched for edge ${elseEdge.source} → ${elseEdge.target}`, edge: elseEdge });
91
90
  return elseEdge.target;
92
91
  }
93
92
 
94
93
  // If no conditions matched or all failed, return to the source node
95
- logger.info('No conditions matched');
94
+ logger.info({ message: 'No conditions matched' });
96
95
  return null;
97
96
  };
98
97
  };
@@ -70,11 +70,11 @@ export const createPromptRouter = ({
70
70
  currentNodeName?: string;
71
71
  }) => {
72
72
  return async (state: typeof stateAnnotation.State) => {
73
- logger.info(`Executing prompt router. Edges: ${JSON.stringify(edges)}`);
73
+ logger.info({ message: `Executing prompt router. Edges: ${JSON.stringify(edges)}` });
74
74
 
75
75
  // If canStayInCurrentNode is true and there are no edges, return current node immediately
76
76
  if (canStayInCurrentNode && edges.length === 0 && currentNodeName) {
77
- logger.info(`No edges available and canStayInCurrentNode is true, staying in current node: ${currentNodeName}`);
77
+ logger.info({ message: `No edges available and canStayInCurrentNode is true, staying in current node: ${currentNodeName}` });
78
78
  return currentNodeName;
79
79
  }
80
80
 
@@ -174,13 +174,14 @@ export const createPromptRouter = ({
174
174
 
175
175
  const decision = validatedResponse.nextNodeId === currentNodeName ? 'stay in current node' : validatedResponse.nextNodeId;
176
176
  const reasoning = includeReasoning && 'reasoning' in validatedResponse ? ` - Reasoning: ${validatedResponse.reasoning}` : '';
177
- logger.info({ msg: `Router decision: ${decision}`, reasoning });
177
+ logger.info({ message: `Router decision: ${decision}`, reasoning });
178
178
 
179
179
  return validatedResponse.nextNodeId;
180
180
  } catch (error) {
181
181
  lastError = error instanceof Error ? error : new Error(String(error));
182
182
  logger.warn({
183
183
  message: `Prompt router attempt ${attempts} failed`,
184
+ edge: edges,
184
185
  error: lastError.message,
185
186
  attempt: attempts,
186
187
  maxRetries,
@@ -49,7 +49,7 @@ export const edgeFactory = ({
49
49
  if (result) {
50
50
  return result;
51
51
  } else {
52
- logger.debug('No logical conditions matched, continuing to prompt conditions');
52
+ logger.debug({ message: 'No logical conditions matched, continuing to prompt conditions' });
53
53
  }
54
54
  }
55
55
 
@@ -69,7 +69,7 @@ export const edgeFactory = ({
69
69
 
70
70
  // Fallback: stay at current source node
71
71
  const source = originalNode?.name || sourceNode;
72
- logger.info(`No conditions matched, returning to source: ${source}`);
72
+ logger.info({ message: `No conditions matched, returning to source: ${source}` });
73
73
  return source;
74
74
  };
75
75
  };
@@ -1,5 +1,6 @@
1
1
  import { State } from '../types/LangGraph.types';
2
2
  import { GraphInterrupt } from '@langchain/langgraph';
3
+ import { logger } from '../utils/logger';
3
4
 
4
5
  export enum InterruptType {
5
6
  NEW_TRIGGERS = 'NEW_TRIGGERS',
@@ -52,7 +53,7 @@ export abstract class BaseInterruptSessionManager implements InterruptSessionMan
52
53
  async checkQueueAndInterrupt(sessionId: string, updateStateObject?: Partial<State>): Promise<boolean> {
53
54
  if (await this.hasQueuedMessages(sessionId)) {
54
55
  const queue = await this.getQueuedMessages(sessionId);
55
- console.log({ message: 'Interrupting graph', sessionId, queue, updateStateObject });
56
+ logger.trace({ message: 'graph has queued messagess, interrupting graph', sessionId, queue });
56
57
 
57
58
  // Interrupt the graph with NEW_TRIGGERS flag and optional updateStateObject
58
59
  const interruptPayload: InterruptPayload = { type: InterruptType.NEW_TRIGGERS };
@@ -3,15 +3,18 @@ import { MemoryInterruptSessionManager } from './MemoryInterruptSessionManager';
3
3
  import { MindedInterruptSessionManager } from './MindedInterruptSessionManager';
4
4
  import { MindedConnection } from '../platform/mindedConnection';
5
5
  import { getConfig } from '../platform/config';
6
+ import { logger } from '../utils/logger';
6
7
 
7
8
  export function createInterruptSessionManager(mindedConnection: MindedConnection | null): InterruptSessionManager {
8
9
  const { runLocally } = getConfig();
9
10
  if (runLocally) {
11
+ logger.info({ message: 'Using memory interrupt session manager' });
10
12
  return new MemoryInterruptSessionManager();
11
13
  } else {
12
14
  if (!mindedConnection) {
13
15
  throw new Error('MindedConnection is required for platform interrupt session manager');
14
16
  }
17
+ logger.info({ message: 'Using Minded interrupt session manager' });
15
18
  return new MindedInterruptSessionManager(mindedConnection);
16
19
  }
17
20
  }
@@ -26,7 +26,7 @@ export const addAppToolNode = async ({
26
26
  const cleanedParameters = Object.fromEntries(Object.entries(node.parameters || {}).filter(([, value]) => value !== ''));
27
27
  const appRunnerTool = getAppActionRunnerTool(node.displayName!);
28
28
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
29
- logger.info(`Executing tool node ${appRunnerTool.name}`);
29
+ logger.info({ message: `Executing tool node ${appRunnerTool.name}` });
30
30
 
31
31
  const executeWrapper = async (input: z.infer<typeof appRunnerTool.input>) => {
32
32
  try {
@@ -14,7 +14,7 @@ export const buildHumanInTheLoopNodeName = (nodeName: string) => `${nodeName}${i
14
14
 
15
15
  export const addHumanInTheLoopNode = async ({ graph, attachedToNodeName }: AddHumanInTheLoopNodeParams) => {
16
16
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
17
- logger.info(`Executing "human in the loop" node for the attached node${attachedToNodeName}`);
17
+ logger.info({ message: `Executing "human in the loop" node for the attached node${attachedToNodeName}` });
18
18
 
19
19
  if (state.messages[state.messages.length - 1].getType() === 'ai') {
20
20
  const value = interrupt({ type: InterruptType.HUMAN_IN_THE_LOOP });
@@ -7,7 +7,7 @@ import { createHistoryStep } from '../utils/history';
7
7
 
8
8
  export const addJumpToNode = async ({ graph, node }: { graph: PreCompiledGraph; node: JumpToNode }) => {
9
9
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
10
- logger.info(`Executing jump node ${node.displayName} – jumping to ${node.targetNodeId}`);
10
+ logger.info({ message: `Executing jump node ${node.displayName} – jumping to ${node.targetNodeId}` });
11
11
  // No state modifications are necessary; control flow is handled via edges.
12
12
  return {
13
13
  history: createHistoryStep<HistoryStep>(state.history, {
@@ -14,6 +14,7 @@ import { Agent } from '../agent';
14
14
  import { logger } from '../utils/logger';
15
15
  import { compilePlaybooks } from '../playbooks/playbooks';
16
16
  import { createHistoryStep } from '../utils/history';
17
+ import { v4 as uuidv4 } from 'uuid';
17
18
  const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));
18
19
  type AddPromptNodeParams = {
19
20
  graph: PreCompiledGraph;
@@ -27,7 +28,7 @@ type AddPromptNodeParams = {
27
28
  export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: AddPromptNodeParams) => {
28
29
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
29
30
  await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
30
- logger.info(`Executing prompt node ${node.displayName}`);
31
+ logger.info({ message: `Executing prompt node ${node.displayName}` });
31
32
  const llmToUse = node.llmConfig ? createLlmInstance(node.llmConfig) : llm;
32
33
 
33
34
  const globalTools = tools
@@ -69,13 +70,17 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
69
70
  const toolResult = await matchedTool.invoke(toolCall);
70
71
  console.log('after invoke?');
71
72
  //check for queue after tool call
73
+ const systemMessageId = uuidv4();
74
+
72
75
  await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, {
73
76
  messages: [
74
77
  result,
75
78
  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
+ new SystemMessage({
80
+ id: systemMessageId,
81
+ content:
82
+ 'you called tool when the user send a new message, Consider calling the function again after user message is processed',
83
+ }),
79
84
  ],
80
85
  history: [
81
86
  createHistoryStep<HistoryStep>(state.history, {
@@ -83,7 +88,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
83
88
  nodeId: node.name,
84
89
  nodeDisplayName: node.displayName,
85
90
  raw: toolResult,
86
- messageIds: [toolResult.id!],
91
+ messageIds: [toolResult.id!, systemMessageId],
87
92
  }),
88
93
  ],
89
94
  });
@@ -30,7 +30,7 @@ export const addToolNode = async ({
30
30
  throw new Error(`Tool not found: ${toolNode.toolName} in node ${node.name}`);
31
31
  }
32
32
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
33
- logger.info(`Executing tool node ${toolNode.displayName}`);
33
+ logger.info({ message: `Executing tool node ${toolNode.displayName}` });
34
34
 
35
35
  const tool = langchainTool(() => {}, {
36
36
  name: matchedTool.name,
@@ -7,7 +7,7 @@ import { createHistoryStep } from '../utils/history';
7
7
 
8
8
  export const addTriggerNode = async ({ graph, node }: { graph: PreCompiledGraph; node: TriggerNode }) => {
9
9
  const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
10
- logger.info(`Executing trigger node ${node.displayName}`);
10
+ logger.info({ message: `Executing trigger node ${node.displayName}` });
11
11
  if (node.triggerType === TriggerType.MANUAL) {
12
12
  return {
13
13
  history: createHistoryStep<HistoryStep>(state.history, {
@@ -34,7 +34,7 @@ export class MindedConnection {
34
34
  }
35
35
  };
36
36
 
37
- public awaitEmit = async <T, R>(event: MindedConnectionSocketMessageType, message: T, timeoutMs: number = 5000): Promise<R> => {
37
+ public awaitEmit = async <T, R>(event: MindedConnectionSocketMessageType, message: T, timeoutMs: number = 10000): Promise<R> => {
38
38
  if (!this.socket) {
39
39
  throw new Error('Socket is not connected');
40
40
  }
@@ -75,43 +75,43 @@ export class MindedConnection {
75
75
 
76
76
  const checkReady = () => {
77
77
  if (connected && ready) {
78
- logger.info('\x1b[32mConnection with Minded platform is ready!\x1b[0m');
79
- logger.info('\x1b[32mPress Ctrl+C to exit...');
78
+ logger.info({ message: '\x1b[32mConnection with Minded platform is ready!\x1b[0m' });
79
+ logger.info({ message: '\x1b[32mPress Ctrl+C to exit...' });
80
80
  resolve();
81
81
  }
82
82
  };
83
83
 
84
84
  // Connection event handlers
85
85
  this.socket.on('connect', () => {
86
- logger.info('Socket connected, waiting for server setup...');
86
+ logger.info({ message: 'Socket connected, waiting for server setup...' });
87
87
  connected = true;
88
88
  checkReady();
89
89
  });
90
90
 
91
91
  // Listen for ready event from server
92
92
  this.socket.on('sdk-socket-ready', (data: { agentId: string; orgName: string }) => {
93
- logger.info('Server ready signal received', data);
93
+ logger.info({ message: 'Server ready signal received', data });
94
94
  ready = true;
95
95
  checkReady();
96
96
  });
97
97
 
98
98
  this.socket.on('connect_error', () => {
99
- logger.error('Failed to connect to minded platform');
99
+ logger.error({ message: 'Failed to connect to minded platform' });
100
100
  reject(new Error('Failed to connect to minded platform'));
101
101
  });
102
102
 
103
103
  this.socket.on('disconnect', () => {
104
- logger.info('Disconnected from local debugging socket');
104
+ logger.info({ message: 'Disconnected from local debugging socket' });
105
105
  connected = false;
106
106
  ready = false;
107
107
  });
108
108
 
109
109
  // Listen for error messages from the server
110
110
  this.socket.on('error', async (error: { message: string }) => {
111
- logger.error({ msg: 'Server error:', error });
111
+ logger.error({ message: 'Server error:', error });
112
112
 
113
113
  if (error.message.includes('Invalid token')) {
114
- logger.info('Invalid token');
114
+ logger.info({ message: 'Invalid token' });
115
115
 
116
116
  // Disconnect current socket
117
117
  if (this.socket?.connected) {
@@ -137,7 +137,7 @@ export class MindedConnection {
137
137
  // Handle process termination
138
138
  process.on('SIGINT', () => {
139
139
  if (this.socket?.connected) {
140
- logger.info('\nDisconnecting...');
140
+ logger.info({ message: '\nDisconnecting...' });
141
141
  this.socket.disconnect();
142
142
  }
143
143
  process.exit(0);
@@ -155,16 +155,16 @@ export class MindedConnection {
155
155
 
156
156
  public disconnect() {
157
157
  if (!this.socket) {
158
- logger.warn('No socket connection to disconnect');
158
+ logger.warn({ message: 'No socket connection to disconnect' });
159
159
  return;
160
160
  }
161
161
 
162
162
  if (this.socket.connected) {
163
- logger.info('Disconnecting from Minded platform...');
163
+ logger.info({ message: 'Disconnecting from Minded platform...' });
164
164
  this.socket.disconnect();
165
165
  return;
166
166
  }
167
167
 
168
- logger.warn('Socket is already disconnected');
168
+ logger.warn({ message: 'Socket is already disconnected' });
169
169
  }
170
170
  }
@@ -113,7 +113,7 @@ function loadPlaybooksFromDirectories(directories: string[]): Playbook[] {
113
113
 
114
114
  for (const directory of directories) {
115
115
  if (!fs.existsSync(directory)) {
116
- logger.info(`Playbooks directory does not exist: ${directory}`);
116
+ logger.info({ message: `Playbooks directory does not exist: ${directory}` });
117
117
  continue;
118
118
  }
119
119
 
@@ -126,12 +126,12 @@ function loadPlaybooksFromDirectories(directories: string[]): Playbook[] {
126
126
 
127
127
  if (playbook && playbook.name && playbook.blocks) {
128
128
  playbooks.push(playbook);
129
- logger.info(`Loaded playbook: ${playbook.name} from ${file}`);
129
+ logger.info({ message: `Loaded playbook: ${playbook.name} from ${file}` });
130
130
  } else {
131
- logger.warn(`Invalid playbook structure in ${file}`);
131
+ logger.warn({ message: `Invalid playbook structure in ${file}` });
132
132
  }
133
133
  } catch (error) {
134
- logger.error(`Failed to load playbook file ${file}: ${error}`);
134
+ logger.error({ message: `Failed to load playbook file ${file}: ${error}` });
135
135
  }
136
136
  }
137
137
  }
@@ -12,6 +12,7 @@ export const logger = pino({
12
12
  colorize: true,
13
13
  crlf: true,
14
14
  translateTime: 'SYS:standard',
15
+ messageKey: 'message', // Use 'message' instead of default 'msg'
15
16
  },
16
17
  },
17
18
  formatters: {
@@ -99,10 +99,10 @@ export class VoiceSession {
99
99
  },
100
100
  ...(this.voiceId
101
101
  ? {
102
- tts: {
103
- voice_id: this.voiceId,
104
- },
105
- }
102
+ tts: {
103
+ voice_id: this.voiceId,
104
+ },
105
+ }
106
106
  : {}),
107
107
  } as ConversationInitiationClientData['conversation_config_override'],
108
108
  };
@@ -134,7 +134,11 @@ export class VoiceSession {
134
134
  }, data.ping_event.ping_ms);
135
135
  break;
136
136
  case 'user_transcript':
137
- logger.debug({ message: 'User transcript received', sessionId: this.sessionId, data: data.user_transcription_event.user_transcript });
137
+ logger.debug({
138
+ message: 'User transcript received',
139
+ sessionId: this.sessionId,
140
+ data: data.user_transcription_event.user_transcript,
141
+ });
138
142
  if (this.onMessageCallback) {
139
143
  this.onMessageCallback(
140
144
  data.user_transcription_event.user_transcript,
@@ -189,7 +193,11 @@ export class VoiceSession {
189
193
  break;
190
194
  case 'agent_response_correction':
191
195
  try {
192
- logger.debug({ message: 'Agent response correction received', sessionId: this.sessionId, data: data.agent_response_correction_event });
196
+ logger.debug({
197
+ message: 'Agent response correction received',
198
+ sessionId: this.sessionId,
199
+ data: data.agent_response_correction_event,
200
+ });
193
201
  await this.updateAgentResponse(
194
202
  data.agent_response_correction_event.original_agent_response,
195
203
  data.agent_response_correction_event.corrected_agent_response,