@minded-ai/mindedjs 1.0.95-beta-3 → 1.0.96-beta-1
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 +1 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +41 -75
- package/dist/agent.js.map +1 -1
- package/dist/cli/index.js +12 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/edges/createDirectEdge.js +1 -1
- package/dist/edges/createDirectEdge.js.map +1 -1
- package/dist/edges/createLogicalRouter.d.ts.map +1 -1
- package/dist/edges/createLogicalRouter.js +7 -7
- package/dist/edges/createLogicalRouter.js.map +1 -1
- package/dist/edges/createPromptRouter.d.ts.map +1 -1
- package/dist/edges/createPromptRouter.js +3 -4
- package/dist/edges/createPromptRouter.js.map +1 -1
- package/dist/edges/edgeFactory.js +2 -2
- package/dist/edges/edgeFactory.js.map +1 -1
- package/dist/nodes/addAppToolNode.js +3 -3
- package/dist/nodes/addAppToolNode.js.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.d.ts.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.js +2 -3
- package/dist/nodes/addHumanInTheLoopNode.js.map +1 -1
- package/dist/nodes/addJumpToNode.js +1 -1
- package/dist/nodes/addJumpToNode.js.map +1 -1
- package/dist/nodes/addPromptNode.d.ts.map +1 -1
- package/dist/nodes/addPromptNode.js +1 -45
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolNode.d.ts.map +1 -1
- package/dist/nodes/addToolNode.js +1 -4
- package/dist/nodes/addToolNode.js.map +1 -1
- package/dist/nodes/addToolRunNode.d.ts.map +1 -1
- package/dist/nodes/addToolRunNode.js +0 -1
- package/dist/nodes/addToolRunNode.js.map +1 -1
- package/dist/nodes/addTriggerNode.js +1 -1
- package/dist/nodes/addTriggerNode.js.map +1 -1
- package/dist/platform/mindedConnection.d.ts.map +1 -1
- package/dist/platform/mindedConnection.js +12 -12
- package/dist/platform/mindedConnection.js.map +1 -1
- package/dist/platform/mindedConnectionTypes.d.ts +1 -151
- package/dist/platform/mindedConnectionTypes.d.ts.map +1 -1
- package/dist/platform/mindedConnectionTypes.js +0 -9
- package/dist/platform/mindedConnectionTypes.js.map +1 -1
- package/dist/playbooks/playbooks.js +4 -4
- package/dist/playbooks/playbooks.js.map +1 -1
- package/dist/types/Agent.types.d.ts +0 -2
- package/dist/types/Agent.types.d.ts.map +1 -1
- package/dist/types/Agent.types.js.map +1 -1
- package/dist/types/Flows.types.d.ts +2 -1
- package/dist/types/Flows.types.d.ts.map +1 -1
- package/dist/types/Flows.types.js +1 -0
- package/dist/types/Flows.types.js.map +1 -1
- package/dist/types/LangGraph.types.d.ts +4 -2
- package/dist/types/LangGraph.types.d.ts.map +1 -1
- package/dist/types/LangGraph.types.js +5 -3
- package/dist/types/LangGraph.types.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +0 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/voice/voiceSession.d.ts.map +1 -1
- package/dist/voice/voiceSession.js +3 -2
- package/dist/voice/voiceSession.js.map +1 -1
- package/package.json +1 -1
- package/src/agent.ts +45 -93
- package/src/cli/index.ts +12 -12
- package/src/edges/createDirectEdge.ts +1 -1
- package/src/edges/createLogicalRouter.ts +8 -7
- package/src/edges/createPromptRouter.ts +3 -4
- package/src/edges/edgeFactory.ts +2 -2
- package/src/nodes/addAppToolNode.ts +3 -3
- package/src/nodes/addHumanInTheLoopNode.ts +3 -3
- package/src/nodes/addJumpToNode.ts +1 -1
- package/src/nodes/addPromptNode.ts +6 -50
- package/src/nodes/addToolNode.ts +2 -4
- package/src/nodes/addToolRunNode.ts +1 -1
- package/src/nodes/addTriggerNode.ts +1 -1
- package/src/platform/mindedConnection.ts +25 -15
- package/src/platform/mindedConnectionTypes.ts +1 -188
- package/src/playbooks/playbooks.ts +4 -4
- package/src/types/Agent.types.ts +0 -2
- package/src/types/Flows.types.ts +1 -0
- package/src/types/LangGraph.types.ts +5 -3
- package/src/utils/logger.ts +0 -1
- package/src/voice/voiceSession.ts +4 -7
- package/src/interrupts/BaseInterruptSessionManager.ts +0 -94
- package/src/interrupts/MemoryInterruptSessionManager.ts +0 -57
- package/src/interrupts/MindedInterruptSessionManager.ts +0 -155
- package/src/interrupts/interruptSessionManagerFactory.ts +0 -20
package/src/cli/index.ts
CHANGED
|
@@ -19,7 +19,7 @@ function setToken(token: string): void {
|
|
|
19
19
|
if (!fs.existsSync(envPath)) {
|
|
20
20
|
// Create .env file with the token
|
|
21
21
|
fs.writeFileSync(envPath, tokenLine + '\n');
|
|
22
|
-
logger.info(
|
|
22
|
+
logger.info(`Created ${envPath} and added token`);
|
|
23
23
|
} else {
|
|
24
24
|
// Read existing .env file
|
|
25
25
|
const envContent = fs.readFileSync(envPath, 'utf8');
|
|
@@ -29,12 +29,12 @@ function setToken(token: string): void {
|
|
|
29
29
|
// Replace existing token
|
|
30
30
|
const updatedContent = envContent.replace(/MINDED_CONNECTION_TOKEN=.*/, tokenLine);
|
|
31
31
|
fs.writeFileSync(envPath, updatedContent);
|
|
32
|
-
logger.info(
|
|
32
|
+
logger.info(`Updated MINDED_CONNECTION_TOKEN in ${envPath}`);
|
|
33
33
|
} else {
|
|
34
34
|
// Append token to existing file
|
|
35
35
|
const newContent = envContent.endsWith('\n') ? envContent + tokenLine + '\n' : envContent + '\n' + tokenLine + '\n';
|
|
36
36
|
fs.writeFileSync(envPath, newContent);
|
|
37
|
-
logger.info(
|
|
37
|
+
logger.info(`Added MINDED_CONNECTION_TOKEN to ${envPath}`);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -44,7 +44,7 @@ function generateLambdaHandler(): void {
|
|
|
44
44
|
|
|
45
45
|
// Check if minded.json exists
|
|
46
46
|
if (!fs.existsSync(mindedConfigPath)) {
|
|
47
|
-
logger.error(
|
|
47
|
+
logger.error('minded.json not found in the current directory');
|
|
48
48
|
process.exit(1);
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -54,14 +54,14 @@ function generateLambdaHandler(): void {
|
|
|
54
54
|
const configContent = fs.readFileSync(mindedConfigPath, 'utf8');
|
|
55
55
|
mindedConfig = JSON.parse(configContent);
|
|
56
56
|
} catch (error) {
|
|
57
|
-
logger.error(
|
|
57
|
+
logger.error('Failed to read or parse minded.json:', error);
|
|
58
58
|
process.exit(1);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// Get the agent path
|
|
62
62
|
const agentPath = mindedConfig.agent;
|
|
63
63
|
if (!agentPath) {
|
|
64
|
-
logger.error(
|
|
64
|
+
logger.error('No agent path found in minded.json');
|
|
65
65
|
process.exit(1);
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -91,7 +91,7 @@ function generateLambdaHandler(): void {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
if (!templateContent) {
|
|
94
|
-
logger.error(
|
|
94
|
+
logger.error('Could not find Lambda handler template file');
|
|
95
95
|
process.exit(1);
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -102,10 +102,10 @@ function generateLambdaHandler(): void {
|
|
|
102
102
|
// Write the Lambda handler to index.ts at the root
|
|
103
103
|
const outputPath = path.join(process.cwd(), 'index.ts');
|
|
104
104
|
fs.writeFileSync(outputPath, templateContent);
|
|
105
|
-
logger.info(
|
|
105
|
+
logger.info(`Generated Lambda handler at ${outputPath}`);
|
|
106
106
|
|
|
107
107
|
// Compile the index.ts file using TypeScript
|
|
108
|
-
logger.info(
|
|
108
|
+
logger.info('Compiling the Lambda handler...');
|
|
109
109
|
|
|
110
110
|
try {
|
|
111
111
|
// Read tsconfig.json to get the outDir
|
|
@@ -138,7 +138,7 @@ function generateLambdaHandler(): void {
|
|
|
138
138
|
cwd: process.cwd(),
|
|
139
139
|
});
|
|
140
140
|
|
|
141
|
-
logger.info(
|
|
141
|
+
logger.info(`Successfully compiled Lambda handler to ${outDir}/index.js`);
|
|
142
142
|
} catch (compileError) {
|
|
143
143
|
logger.error({ message: 'Failed to compile Lambda handler', error: compileError });
|
|
144
144
|
}
|
|
@@ -155,14 +155,14 @@ function main() {
|
|
|
155
155
|
if (command === 'token') {
|
|
156
156
|
const token = args[1];
|
|
157
157
|
if (!token) {
|
|
158
|
-
logger.error(
|
|
158
|
+
logger.error('Please provide a token');
|
|
159
159
|
process.exit(1);
|
|
160
160
|
}
|
|
161
161
|
setToken(token);
|
|
162
162
|
} else if (command === 'generate-lambda-ts-handler') {
|
|
163
163
|
generateLambdaHandler();
|
|
164
164
|
} else {
|
|
165
|
-
logger.error(
|
|
165
|
+
logger.error('Unknown command. Available commands: token, generate-lambda-ts-handler');
|
|
166
166
|
process.exit(1);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
@@ -5,7 +5,7 @@ export const createDirectEdge = (edge: StepForwardEdge) => {
|
|
|
5
5
|
return async () => {
|
|
6
6
|
// For direct edges, we just return the target of the first edge
|
|
7
7
|
// since there's no conditional logic needed
|
|
8
|
-
logger.info(
|
|
8
|
+
logger.info(`Executing edge ${JSON.stringify(edge)}`);
|
|
9
9
|
return edge.target;
|
|
10
10
|
};
|
|
11
11
|
};
|
|
@@ -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(
|
|
15
|
-
const elseEdges = edges.filter(
|
|
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,16 +59,17 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
|
|
|
59
59
|
]);
|
|
60
60
|
|
|
61
61
|
if (result === true) {
|
|
62
|
-
logger.info(
|
|
62
|
+
logger.info(`Condition matched for edge ${edge.source} → ${edge.target}`);
|
|
63
63
|
return edge.target;
|
|
64
64
|
}
|
|
65
|
+
|
|
65
66
|
} catch (error) {
|
|
66
67
|
// Provide detailed error information back to the customer
|
|
67
68
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
68
69
|
const conditionPreview = edge.condition.length > 100 ? `${edge.condition.substring(0, 100)}...` : edge.condition;
|
|
69
70
|
|
|
70
71
|
logger.error({
|
|
71
|
-
|
|
72
|
+
msg: `Error evaluating condition for edge ${edge.source} → ${edge.target}`,
|
|
72
73
|
condition: conditionPreview,
|
|
73
74
|
error: errorMessage,
|
|
74
75
|
edgeIndex: edges.indexOf(edge),
|
|
@@ -83,15 +84,15 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
|
|
|
83
84
|
|
|
84
85
|
// If no regular conditions matched, check for "else" conditions
|
|
85
86
|
if (elseEdges.length > 0) {
|
|
86
|
-
logger.info(
|
|
87
|
+
logger.info(`No regular conditions matched, evaluating ${elseEdges.length} else condition(s)`);
|
|
87
88
|
// Return the first "else" condition's target
|
|
88
89
|
const elseEdge = elseEdges[0];
|
|
89
|
-
logger.info(
|
|
90
|
+
logger.info(`Else condition matched for edge ${elseEdge.source} → ${elseEdge.target}`);
|
|
90
91
|
return elseEdge.target;
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
// If no conditions matched or all failed, return to the source node
|
|
94
|
-
logger.info(
|
|
95
|
+
logger.info('No conditions matched');
|
|
95
96
|
return null;
|
|
96
97
|
};
|
|
97
98
|
};
|
|
@@ -70,11 +70,11 @@ export const createPromptRouter = ({
|
|
|
70
70
|
currentNodeName?: string;
|
|
71
71
|
}) => {
|
|
72
72
|
return async (state: typeof stateAnnotation.State) => {
|
|
73
|
-
logger.info(
|
|
73
|
+
logger.info(`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(
|
|
77
|
+
logger.info(`No edges available and canStayInCurrentNode is true, staying in current node: ${currentNodeName}`);
|
|
78
78
|
return currentNodeName;
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -174,14 +174,13 @@ 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({
|
|
177
|
+
logger.info({ msg: `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,
|
|
185
184
|
error: lastError.message,
|
|
186
185
|
attempt: attempts,
|
|
187
186
|
maxRetries,
|
package/src/edges/edgeFactory.ts
CHANGED
|
@@ -49,7 +49,7 @@ export const edgeFactory = ({
|
|
|
49
49
|
if (result) {
|
|
50
50
|
return result;
|
|
51
51
|
} else {
|
|
52
|
-
logger.debug(
|
|
52
|
+
logger.debug('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(
|
|
72
|
+
logger.info(`No conditions matched, returning to source: ${source}`);
|
|
73
73
|
return source;
|
|
74
74
|
};
|
|
75
75
|
};
|
|
@@ -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(
|
|
29
|
+
logger.info(`Executing tool node ${appRunnerTool.name}`);
|
|
30
30
|
|
|
31
31
|
const executeWrapper = async (input: z.infer<typeof appRunnerTool.input>) => {
|
|
32
32
|
try {
|
|
@@ -75,8 +75,8 @@ export const addAppToolNode = async ({
|
|
|
75
75
|
};
|
|
76
76
|
const toolCallMessage = await tool.invoke(AIToolCallMessage.tool_calls[0]);
|
|
77
77
|
AIToolCallMessage.additional_kwargs = {
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
mindedMetadata: {
|
|
79
|
+
nodeType: NodeType.APP_TOOL,
|
|
80
80
|
},
|
|
81
81
|
};
|
|
82
82
|
return {
|
|
@@ -3,7 +3,6 @@ import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
|
3
3
|
import { RunnableLike } from '@langchain/core/runnables';
|
|
4
4
|
import { logger } from '../utils/logger';
|
|
5
5
|
import { internalNodesSuffix } from '../types/Flows.types';
|
|
6
|
-
import { InterruptType } from '../interrupts/BaseInterruptSessionManager';
|
|
7
6
|
|
|
8
7
|
type AddHumanInTheLoopNodeParams = {
|
|
9
8
|
graph: PreCompiledGraph;
|
|
@@ -14,9 +13,10 @@ export const buildHumanInTheLoopNodeName = (nodeName: string) => `${nodeName}${i
|
|
|
14
13
|
|
|
15
14
|
export const addHumanInTheLoopNode = async ({ graph, attachedToNodeName }: AddHumanInTheLoopNodeParams) => {
|
|
16
15
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
17
|
-
logger.info(
|
|
16
|
+
logger.info(`Executing "human in the loop" node for the attached node${attachedToNodeName}`);
|
|
17
|
+
|
|
18
18
|
if (state.messages[state.messages.length - 1].getType() === 'ai') {
|
|
19
|
-
const value = interrupt(
|
|
19
|
+
const value = interrupt('input from human in the loop');
|
|
20
20
|
return value;
|
|
21
21
|
}
|
|
22
22
|
};
|
|
@@ -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(
|
|
10
|
+
logger.info(`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,7 +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
|
-
|
|
17
|
+
|
|
18
18
|
type AddPromptNodeParams = {
|
|
19
19
|
graph: PreCompiledGraph;
|
|
20
20
|
node: PromptNode;
|
|
@@ -26,8 +26,7 @@ type AddPromptNodeParams = {
|
|
|
26
26
|
|
|
27
27
|
export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: AddPromptNodeParams) => {
|
|
28
28
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
29
|
-
|
|
30
|
-
logger.info({ message: `Executing prompt node ${node.displayName}` });
|
|
29
|
+
logger.info(`Executing prompt node ${node.displayName}`);
|
|
31
30
|
const llmToUse = node.llmConfig ? createLlmInstance(node.llmConfig) : llm;
|
|
32
31
|
|
|
33
32
|
const globalTools = tools
|
|
@@ -51,9 +50,9 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
51
50
|
${state.memory ? `# Task context:\n${JSON.stringify(state.memory)}\n\n` : ''}
|
|
52
51
|
${compiledPlaybooks ? `# General guidelines:\n${compiledPlaybooks}\n\n` : ''}
|
|
53
52
|
`;
|
|
54
|
-
|
|
53
|
+
|
|
55
54
|
const result: AIMessage = await llmToUse.bindTools(globalTools).invoke([...state.messages, new SystemMessage(message)]);
|
|
56
|
-
|
|
55
|
+
|
|
57
56
|
// Check if the result contains tool calls
|
|
58
57
|
if (result.tool_calls && result.tool_calls.length > 0) {
|
|
59
58
|
// Execute the tools
|
|
@@ -67,29 +66,6 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
67
66
|
try {
|
|
68
67
|
// Invoke the LangChain tool directly
|
|
69
68
|
const toolResult = await matchedTool.invoke(toolCall);
|
|
70
|
-
//check for queue after tool call
|
|
71
|
-
const systemMessageId = uuidv4();
|
|
72
|
-
|
|
73
|
-
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, {
|
|
74
|
-
messages: [
|
|
75
|
-
result,
|
|
76
|
-
toolResult,
|
|
77
|
-
new SystemMessage({
|
|
78
|
-
id: systemMessageId,
|
|
79
|
-
content:
|
|
80
|
-
'you called tool when the user send a new message, Consider calling the function again after user message is processed',
|
|
81
|
-
}),
|
|
82
|
-
],
|
|
83
|
-
history: [
|
|
84
|
-
createHistoryStep<HistoryStep>(state.history, {
|
|
85
|
-
type: NodeType.TOOL,
|
|
86
|
-
nodeId: node.name,
|
|
87
|
-
nodeDisplayName: node.displayName,
|
|
88
|
-
raw: toolResult,
|
|
89
|
-
messageIds: [toolResult.id!, systemMessageId],
|
|
90
|
-
}),
|
|
91
|
-
],
|
|
92
|
-
});
|
|
93
69
|
const toolStateUpdate = extractToolStateResponse(toolResult);
|
|
94
70
|
// Properly merge memory and other state updates
|
|
95
71
|
stateUpdates = {
|
|
@@ -98,8 +74,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
98
74
|
memory: { ...(stateUpdates as any).memory, ...(toolStateUpdate as any).memory },
|
|
99
75
|
};
|
|
100
76
|
toolResults.push(toolResult);
|
|
101
|
-
} catch (error
|
|
102
|
-
if (error?.name === 'GraphInterrupt') throw error;
|
|
77
|
+
} catch (error) {
|
|
103
78
|
logger.error({ msg: `Error executing tool ${toolCall.name}:`, error });
|
|
104
79
|
const errorMessage = new ToolMessage({
|
|
105
80
|
content: JSON.stringify({ error: error instanceof Error ? error.message : String(error) }),
|
|
@@ -112,30 +87,10 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
112
87
|
}
|
|
113
88
|
}
|
|
114
89
|
|
|
115
|
-
// await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
116
|
-
|
|
117
90
|
// Return the tool call message and tool results with state updates spread at top level
|
|
118
91
|
return {
|
|
119
92
|
...stateUpdates,
|
|
120
93
|
messages: [result, ...toolResults],
|
|
121
|
-
history: [
|
|
122
|
-
createHistoryStep<HistoryStep>(state.history, {
|
|
123
|
-
type: NodeType.TOOL,
|
|
124
|
-
nodeId: node.name,
|
|
125
|
-
nodeDisplayName: node.displayName,
|
|
126
|
-
raw: result,
|
|
127
|
-
messageIds: [result.id!],
|
|
128
|
-
}),
|
|
129
|
-
...toolResults.map((toolResult) =>
|
|
130
|
-
createHistoryStep<HistoryStep>(state.history, {
|
|
131
|
-
type: NodeType.TOOL,
|
|
132
|
-
nodeId: node.name,
|
|
133
|
-
nodeDisplayName: node.displayName,
|
|
134
|
-
raw: toolResult,
|
|
135
|
-
messageIds: [toolResult.id!],
|
|
136
|
-
}),
|
|
137
|
-
),
|
|
138
|
-
],
|
|
139
94
|
};
|
|
140
95
|
}
|
|
141
96
|
|
|
@@ -146,6 +101,7 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
146
101
|
});
|
|
147
102
|
console.log('AI Message', result.content);
|
|
148
103
|
}
|
|
104
|
+
|
|
149
105
|
return {
|
|
150
106
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
151
107
|
type: NodeType.PROMPT_NODE,
|
package/src/nodes/addToolNode.ts
CHANGED
|
@@ -30,8 +30,8 @@ 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
|
-
|
|
34
|
-
|
|
33
|
+
logger.info(`Executing tool node ${toolNode.displayName}`);
|
|
34
|
+
|
|
35
35
|
const tool = langchainTool(() => {}, {
|
|
36
36
|
name: matchedTool.name,
|
|
37
37
|
description: matchedTool.description,
|
|
@@ -56,8 +56,6 @@ export const addToolNode = async ({
|
|
|
56
56
|
tool_choice: tool.name,
|
|
57
57
|
})
|
|
58
58
|
.invoke([...state.messages, new SystemMessage(prompt)]);
|
|
59
|
-
logger.info({ message: 'after llm tool invoke' });
|
|
60
|
-
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
61
59
|
return {
|
|
62
60
|
messages: [AIToolCallMessage],
|
|
63
61
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
@@ -23,7 +23,6 @@ type AddToolRunNodeParams = {
|
|
|
23
23
|
|
|
24
24
|
export const buildToolRunNodeName = (nodeName: string) => `${nodeName}${internalNodesSuffix.TOOL_RUN}`;
|
|
25
25
|
|
|
26
|
-
//you never want to interrupt here because of new triggers, as this node depends on the last message to be the tool call from the addToolNode, interrupting will add human message here
|
|
27
26
|
export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeName, agent }: AddToolRunNodeParams) => {
|
|
28
27
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
29
28
|
const matchedTool = tools.find((tool) => tool.name === toolNode.toolName);
|
|
@@ -55,6 +54,7 @@ export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeNam
|
|
|
55
54
|
|
|
56
55
|
// Push the toolCallMessage into the messages array from toolStateUpdate
|
|
57
56
|
const updatedMessages = [toolCallMessage, ...((toolStateUpdate as any).messages || [])];
|
|
57
|
+
|
|
58
58
|
// Return the full state update from the tool with the updated messages
|
|
59
59
|
return {
|
|
60
60
|
...toolStateUpdate,
|
|
@@ -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(
|
|
10
|
+
logger.info(`Executing trigger node ${node.displayName}`);
|
|
11
11
|
if (node.triggerType === TriggerType.MANUAL) {
|
|
12
12
|
return {
|
|
13
13
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { io, Socket } from 'socket.io-client';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
mindedConnectionSocketMessageType,
|
|
4
|
+
mindedConnectionSocketMessageTypeMap,
|
|
5
|
+
} from './mindedConnectionTypes';
|
|
3
6
|
import { stringify } from 'flatted';
|
|
4
7
|
import { getConfig } from './config';
|
|
5
8
|
import { logger } from '../utils/logger';
|
|
@@ -25,13 +28,20 @@ export const on = <E extends keyof mindedConnectionSocketMessageTypeMap>(
|
|
|
25
28
|
listeners[event].push(callback);
|
|
26
29
|
};
|
|
27
30
|
|
|
28
|
-
export const emit = <E extends keyof mindedConnectionSocketMessageTypeMap>(
|
|
31
|
+
export const emit = <E extends keyof mindedConnectionSocketMessageTypeMap>(
|
|
32
|
+
event: E,
|
|
33
|
+
message: mindedConnectionSocketMessageTypeMap[E]
|
|
34
|
+
) => {
|
|
29
35
|
if (socket) {
|
|
30
36
|
socket.emit(event, message);
|
|
31
37
|
}
|
|
32
38
|
};
|
|
33
39
|
|
|
34
|
-
export const awaitEmit = async <T, R>(
|
|
40
|
+
export const awaitEmit = async <T, R>(
|
|
41
|
+
event: mindedConnectionSocketMessageType,
|
|
42
|
+
message: T,
|
|
43
|
+
timeoutMs: number = 5000
|
|
44
|
+
): Promise<R> => {
|
|
35
45
|
if (!socket) {
|
|
36
46
|
throw new Error('Socket is not connected');
|
|
37
47
|
}
|
|
@@ -87,43 +97,43 @@ const connect = async (token: string): Promise<void> => {
|
|
|
87
97
|
|
|
88
98
|
const checkReady = () => {
|
|
89
99
|
if (connected && ready) {
|
|
90
|
-
logger.info(
|
|
91
|
-
logger.info(
|
|
100
|
+
logger.info('\x1b[32mConnection with Minded platform is ready!\x1b[0m');
|
|
101
|
+
logger.info('\x1b[32mPress Ctrl+C to exit...');
|
|
92
102
|
resolve();
|
|
93
103
|
}
|
|
94
104
|
};
|
|
95
105
|
|
|
96
106
|
// Connection event handlers
|
|
97
107
|
socket.on('connect', () => {
|
|
98
|
-
logger.info(
|
|
108
|
+
logger.info('Socket connected, waiting for server setup...');
|
|
99
109
|
connected = true;
|
|
100
110
|
checkReady();
|
|
101
111
|
});
|
|
102
112
|
|
|
103
113
|
// Listen for ready event from server
|
|
104
114
|
socket.on('sdk-socket-ready', (data: { agentId: string; orgName: string }) => {
|
|
105
|
-
logger.info(
|
|
115
|
+
logger.info('Server ready signal received', data);
|
|
106
116
|
ready = true;
|
|
107
117
|
checkReady();
|
|
108
118
|
});
|
|
109
119
|
|
|
110
120
|
socket.on('connect_error', () => {
|
|
111
|
-
logger.error(
|
|
121
|
+
logger.error('Failed to connect to minded platform');
|
|
112
122
|
reject(new Error('Failed to connect to minded platform'));
|
|
113
123
|
});
|
|
114
124
|
|
|
115
125
|
socket.on('disconnect', () => {
|
|
116
|
-
logger.info(
|
|
126
|
+
logger.info('Disconnected from local debugging socket');
|
|
117
127
|
connected = false;
|
|
118
128
|
ready = false;
|
|
119
129
|
});
|
|
120
130
|
|
|
121
131
|
// Listen for error messages from the server
|
|
122
132
|
socket.on('error', async (error: { message: string }) => {
|
|
123
|
-
logger.error({
|
|
133
|
+
logger.error({ msg: 'Server error:', error });
|
|
124
134
|
|
|
125
135
|
if (error.message.includes('Invalid token')) {
|
|
126
|
-
logger.info(
|
|
136
|
+
logger.info('Invalid token');
|
|
127
137
|
|
|
128
138
|
// Disconnect current socket
|
|
129
139
|
if (socket?.connected) {
|
|
@@ -149,7 +159,7 @@ const connect = async (token: string): Promise<void> => {
|
|
|
149
159
|
// Handle process termination
|
|
150
160
|
process.on('SIGINT', () => {
|
|
151
161
|
if (socket?.connected) {
|
|
152
|
-
logger.info(
|
|
162
|
+
logger.info('\nDisconnecting...');
|
|
153
163
|
socket.disconnect();
|
|
154
164
|
}
|
|
155
165
|
process.exit(0);
|
|
@@ -167,17 +177,17 @@ export const start = async (): Promise<void> => {
|
|
|
167
177
|
|
|
168
178
|
export const disconnect = () => {
|
|
169
179
|
if (!socket) {
|
|
170
|
-
logger.warn(
|
|
180
|
+
logger.warn('No socket connection to disconnect');
|
|
171
181
|
return;
|
|
172
182
|
}
|
|
173
183
|
|
|
174
184
|
if (socket.connected) {
|
|
175
|
-
logger.info(
|
|
185
|
+
logger.info('Disconnecting from Minded platform...');
|
|
176
186
|
socket.disconnect();
|
|
177
187
|
return;
|
|
178
188
|
}
|
|
179
189
|
|
|
180
|
-
logger.warn(
|
|
190
|
+
logger.warn('Socket is already disconnected');
|
|
181
191
|
};
|
|
182
192
|
|
|
183
193
|
export const mindedConnection = {
|