@minded-ai/mindedjs 1.0.121 → 1.0.122-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 +4 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +69 -9
- package/dist/agent.js.map +1 -1
- package/dist/browserTask/README.md +419 -0
- package/dist/browserTask/browserAgent.py +632 -0
- package/dist/browserTask/captcha_isolated.png +0 -0
- package/dist/browserTask/executeBrowserTask.ts +79 -0
- package/dist/browserTask/requirements.txt +8 -0
- package/dist/browserTask/setup.sh +144 -0
- package/dist/cli/index.js +14 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/edges/edgeFactory.js +2 -2
- package/dist/edges/edgeFactory.js.map +1 -1
- package/dist/internalTools/retell.d.ts +12 -0
- package/dist/internalTools/retell.d.ts.map +1 -0
- package/dist/internalTools/retell.js +54 -0
- package/dist/internalTools/retell.js.map +1 -0
- package/dist/internalTools/sendPlaceholderMessage.d.ts +14 -0
- package/dist/internalTools/sendPlaceholderMessage.d.ts.map +1 -0
- package/dist/internalTools/sendPlaceholderMessage.js +61 -0
- package/dist/internalTools/sendPlaceholderMessage.js.map +1 -0
- package/dist/interrupts/BaseInterruptSessionManager.d.ts +52 -0
- package/dist/interrupts/BaseInterruptSessionManager.d.ts.map +1 -0
- package/dist/interrupts/BaseInterruptSessionManager.js +40 -0
- package/dist/interrupts/BaseInterruptSessionManager.js.map +1 -0
- package/dist/interrupts/MemoryInterruptSessionManager.d.ts +14 -0
- package/dist/interrupts/MemoryInterruptSessionManager.d.ts.map +1 -0
- package/dist/interrupts/MemoryInterruptSessionManager.js +60 -0
- package/dist/interrupts/MemoryInterruptSessionManager.js.map +1 -0
- package/dist/interrupts/MindedInterruptSessionManager.d.ts +13 -0
- package/dist/interrupts/MindedInterruptSessionManager.d.ts.map +1 -0
- package/dist/interrupts/MindedInterruptSessionManager.js +151 -0
- package/dist/interrupts/MindedInterruptSessionManager.js.map +1 -0
- package/dist/interrupts/interruptSessionManagerFactory.d.ts +3 -0
- package/dist/interrupts/interruptSessionManagerFactory.d.ts.map +1 -0
- package/dist/interrupts/interruptSessionManagerFactory.js +46 -0
- package/dist/interrupts/interruptSessionManagerFactory.js.map +1 -0
- package/dist/nodes/addAppToolNode.js +1 -1
- package/dist/nodes/addAppToolNode.js.map +1 -1
- package/dist/nodes/addBrowserTaskNode.js +2 -2
- package/dist/nodes/addBrowserTaskNode.js.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.d.ts.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.js +2 -1
- 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 +88 -7
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolNode.d.ts.map +1 -1
- package/dist/nodes/addToolNode.js +5 -1
- package/dist/nodes/addToolNode.js.map +1 -1
- package/dist/nodes/addToolRunNode.d.ts.map +1 -1
- package/dist/nodes/addToolRunNode.js +1 -0
- package/dist/nodes/addToolRunNode.js.map +1 -1
- package/dist/nodes/compilePrompt.d.ts.map +1 -1
- package/dist/nodes/compilePrompt.js +1 -0
- package/dist/nodes/compilePrompt.js.map +1 -1
- package/dist/platform/mindedConnection.js +12 -12
- package/dist/platform/mindedConnection.js.map +1 -1
- package/dist/platform/mindedConnectionTypes.d.ts +151 -1
- package/dist/platform/mindedConnectionTypes.d.ts.map +1 -1
- package/dist/platform/mindedConnectionTypes.js +9 -0
- package/dist/platform/mindedConnectionTypes.js.map +1 -1
- package/dist/playbooks/playbooks.d.ts.map +1 -1
- package/dist/playbooks/playbooks.js +33 -12
- package/dist/playbooks/playbooks.js.map +1 -1
- package/dist/types/Agent.types.d.ts +2 -0
- package/dist/types/Agent.types.d.ts.map +1 -1
- package/dist/types/Agent.types.js.map +1 -1
- package/dist/types/LangGraph.types.d.ts +2 -2
- package/dist/types/LangGraph.types.d.ts.map +1 -1
- package/dist/types/LangGraph.types.js +3 -1
- package/dist/types/LangGraph.types.js.map +1 -1
- package/dist/voice/voiceSession.d.ts.map +1 -1
- package/dist/voice/voiceSession.js +9 -1
- package/dist/voice/voiceSession.js.map +1 -1
- package/docs/low-code-editor/nodes.md +21 -12
- package/docs/low-code-editor/playbooks.md +50 -32
- package/package.json +1 -1
- package/src/agent.ts +93 -19
- package/src/cli/index.ts +14 -14
- package/src/edges/edgeFactory.ts +2 -2
- package/src/interrupts/BaseInterruptSessionManager.ts +96 -0
- package/src/interrupts/MemoryInterruptSessionManager.ts +63 -0
- package/src/interrupts/MindedInterruptSessionManager.ts +162 -0
- package/src/interrupts/interruptSessionManagerFactory.ts +20 -0
- package/src/nodes/addAppToolNode.ts +1 -1
- package/src/nodes/addBrowserTaskNode.ts +3 -3
- package/src/nodes/addHumanInTheLoopNode.ts +2 -1
- package/src/nodes/addJumpToNode.ts +1 -1
- package/src/nodes/addPromptNode.ts +95 -11
- package/src/nodes/addToolNode.ts +6 -2
- package/src/nodes/addToolRunNode.ts +1 -1
- package/src/nodes/compilePrompt.ts +2 -2
- package/src/platform/mindedConnection.ts +12 -12
- package/src/platform/mindedConnectionTypes.ts +187 -0
- package/src/playbooks/playbooks.ts +36 -13
- package/src/types/Agent.types.ts +2 -0
- package/src/types/LangGraph.types.ts +3 -1
- package/src/voice/voiceSession.ts +9 -1
|
@@ -54,7 +54,7 @@ export const addBrowserTaskNode = async ({ graph, node, agent, llm }: AddBrowser
|
|
|
54
54
|
const zodSchema = z.object(schemaFields);
|
|
55
55
|
|
|
56
56
|
// Create langchain tool
|
|
57
|
-
const tool = langchainTool(() => {
|
|
57
|
+
const tool = langchainTool(() => {}, {
|
|
58
58
|
name: 'browser-task',
|
|
59
59
|
description: node.prompt,
|
|
60
60
|
schema: zodSchema,
|
|
@@ -81,8 +81,8 @@ export const addBrowserTaskNode = async ({ graph, node, agent, llm }: AddBrowser
|
|
|
81
81
|
// Prepare parameters for prompt compilation
|
|
82
82
|
const promptParams = {
|
|
83
83
|
input: inputParams,
|
|
84
|
-
state,
|
|
85
|
-
currentTime: new Date().toISOString(),
|
|
84
|
+
memory: state.memory,
|
|
85
|
+
system: { currentTime: new Date().toISOString() },
|
|
86
86
|
};
|
|
87
87
|
|
|
88
88
|
// Compile the prompt with parameters
|
|
@@ -3,6 +3,7 @@ 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';
|
|
6
7
|
|
|
7
8
|
type AddHumanInTheLoopNodeParams = {
|
|
8
9
|
graph: PreCompiledGraph;
|
|
@@ -16,7 +17,7 @@ export const addHumanInTheLoopNode = async ({ graph, attachedToNodeName }: AddHu
|
|
|
16
17
|
logger.debug({ msg: `[Node] Waiting for human input`, node: attachedToNodeName });
|
|
17
18
|
|
|
18
19
|
if (state.messages[state.messages.length - 1].getType() === 'ai') {
|
|
19
|
-
const value = interrupt(
|
|
20
|
+
const value = interrupt({ type: InterruptType.HUMAN_IN_THE_LOOP });
|
|
20
21
|
return value;
|
|
21
22
|
}
|
|
22
23
|
};
|
|
@@ -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({ msg: `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
|
goto: node.targetNodeId,
|
|
@@ -15,7 +15,7 @@ import { logger } from '../utils/logger';
|
|
|
15
15
|
import { combinePlaybooks } from '../playbooks/playbooks';
|
|
16
16
|
import { createHistoryStep } from '../utils/history';
|
|
17
17
|
import { compilePrompt } from './compilePrompt';
|
|
18
|
-
|
|
18
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
19
19
|
type AddPromptNodeParams = {
|
|
20
20
|
graph: PreCompiledGraph;
|
|
21
21
|
node: PromptNode;
|
|
@@ -27,7 +27,8 @@ type AddPromptNodeParams = {
|
|
|
27
27
|
|
|
28
28
|
export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: AddPromptNodeParams) => {
|
|
29
29
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
30
|
-
|
|
30
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
31
|
+
logger.info({ msg: `[Node] Executing prompt node`, node: node.displayName });
|
|
31
32
|
const llmToUse = node.llmConfig ? createLlmInstance(node.llmConfig) : llm;
|
|
32
33
|
|
|
33
34
|
const globalTools = tools
|
|
@@ -42,15 +43,15 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
42
43
|
|
|
43
44
|
const combinedPlaybooks = combinePlaybooks(agent.playbooks) || '';
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const compiledPrompt = compilePrompt(
|
|
46
|
+
// Get edges for the current node and format them
|
|
47
|
+
const edges = agent.flows?.flatMap((flow: any) => flow.edges) || [];
|
|
48
|
+
const nodeEdges = edges.filter((edge: any) => edge.source === node.name);
|
|
49
|
+
const currentPromptNode = getCurrentPromptNode(node, nodeEdges);
|
|
50
|
+
const systemMessage = combinedPlaybooks + '\n\n' + currentPromptNode;
|
|
51
|
+
const compiledPrompt = compilePrompt(systemMessage, { memory: state.memory, system: { currentTime: new Date().toISOString() } });
|
|
51
52
|
|
|
52
53
|
const startTime = Date.now();
|
|
53
|
-
const result: AIMessage = await llmToUse.bindTools(globalTools).invoke([
|
|
54
|
+
const result: AIMessage = await llmToUse.bindTools(globalTools).invoke([new SystemMessage(compiledPrompt), ...state.messages]);
|
|
54
55
|
const endTime = Date.now();
|
|
55
56
|
logger.debug({ msg: '[Model] Model execution time', executionTimeMs: endTime - startTime });
|
|
56
57
|
// Check if the result contains tool calls
|
|
@@ -69,6 +70,29 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
69
70
|
const toolResult = await matchedTool.invoke(toolCall);
|
|
70
71
|
const endTime = Date.now();
|
|
71
72
|
logger.debug({ msg: `[Tool] Tool result`, tool: matchedTool?.name, result: toolResult, executionTimeMs: endTime - startTime });
|
|
73
|
+
//check for queue after tool call
|
|
74
|
+
const systemMessageId = uuidv4();
|
|
75
|
+
|
|
76
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, {
|
|
77
|
+
messages: [
|
|
78
|
+
result,
|
|
79
|
+
toolResult,
|
|
80
|
+
new SystemMessage({
|
|
81
|
+
id: systemMessageId,
|
|
82
|
+
content:
|
|
83
|
+
'you called tool when the user send a new message, Consider calling the function again after user message is processed',
|
|
84
|
+
}),
|
|
85
|
+
],
|
|
86
|
+
history: [
|
|
87
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
88
|
+
type: NodeType.TOOL,
|
|
89
|
+
nodeId: node.name,
|
|
90
|
+
nodeDisplayName: node.displayName,
|
|
91
|
+
raw: toolResult,
|
|
92
|
+
messageIds: [toolResult.id!, systemMessageId],
|
|
93
|
+
}),
|
|
94
|
+
],
|
|
95
|
+
});
|
|
72
96
|
const toolStateUpdate = extractToolStateResponse(toolResult);
|
|
73
97
|
// Properly merge memory and other state updates
|
|
74
98
|
stateUpdates = {
|
|
@@ -77,7 +101,8 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
77
101
|
memory: { ...(stateUpdates as any).memory, ...(toolStateUpdate as any).memory },
|
|
78
102
|
};
|
|
79
103
|
toolResults.push(toolResult);
|
|
80
|
-
} catch (error) {
|
|
104
|
+
} catch (error: any) {
|
|
105
|
+
if (error?.name === 'GraphInterrupt') throw error;
|
|
81
106
|
logger.error({ msg: `[Tool] Error executing tool`, tool: toolCall.name, error });
|
|
82
107
|
const errorMessage = new ToolMessage({
|
|
83
108
|
content: JSON.stringify({ error: error instanceof Error ? error.message : String(error) }),
|
|
@@ -90,10 +115,30 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
90
115
|
}
|
|
91
116
|
}
|
|
92
117
|
|
|
118
|
+
// await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
119
|
+
|
|
93
120
|
// Return the tool call message and tool results with state updates spread at top level
|
|
94
121
|
return {
|
|
95
122
|
...stateUpdates,
|
|
96
123
|
messages: [result, ...toolResults],
|
|
124
|
+
history: [
|
|
125
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
126
|
+
type: NodeType.TOOL,
|
|
127
|
+
nodeId: node.name,
|
|
128
|
+
nodeDisplayName: node.displayName,
|
|
129
|
+
raw: result,
|
|
130
|
+
messageIds: [result.id!],
|
|
131
|
+
}),
|
|
132
|
+
...toolResults.map((toolResult) =>
|
|
133
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
134
|
+
type: NodeType.TOOL,
|
|
135
|
+
nodeId: node.name,
|
|
136
|
+
nodeDisplayName: node.displayName,
|
|
137
|
+
raw: toolResult,
|
|
138
|
+
messageIds: [toolResult.id!],
|
|
139
|
+
}),
|
|
140
|
+
),
|
|
141
|
+
],
|
|
97
142
|
};
|
|
98
143
|
}
|
|
99
144
|
|
|
@@ -104,7 +149,6 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
104
149
|
});
|
|
105
150
|
logger.info({ msg: `[Model] Response`, content: result.content });
|
|
106
151
|
}
|
|
107
|
-
|
|
108
152
|
return {
|
|
109
153
|
goto: null,
|
|
110
154
|
history: createHistoryStep<HistoryStep>(state.history, {
|
|
@@ -119,3 +163,43 @@ export const addPromptNode = async ({ graph, node, llm, tools, emit, agent }: Ad
|
|
|
119
163
|
};
|
|
120
164
|
graph.addNode(node.name, callback);
|
|
121
165
|
};
|
|
166
|
+
|
|
167
|
+
function getCurrentPromptNode(node: PromptNode, nodeEdges: any[]) {
|
|
168
|
+
// Format edges for display
|
|
169
|
+
let nextEdges = '';
|
|
170
|
+
if (node.canStayOnNode !== false) {
|
|
171
|
+
nextEdges = `0. Stay in the current step. step title: ${node.displayName}\n`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
let counter = node.canStayOnNode !== false ? 0 : -1;
|
|
175
|
+
const promptConditionEdges = nodeEdges.filter((edge: any) => edge.type === 'PROMPT_CONDITION');
|
|
176
|
+
promptConditionEdges.forEach((edge: any) => {
|
|
177
|
+
counter++;
|
|
178
|
+
nextEdges += `${counter}. ${edge.prompt || edge.condition || `Go to ${edge.target}`}\n`;
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
return `
|
|
182
|
+
# Current Node Instructions
|
|
183
|
+
|
|
184
|
+
The flow of the conversation is built upon nodes. each conversation turn you
|
|
185
|
+
will be given just with the current node prompt.
|
|
186
|
+
|
|
187
|
+
Always follow the guidelines of "Current node prompt"
|
|
188
|
+
|
|
189
|
+
Current node title: ${node.displayName}
|
|
190
|
+
|
|
191
|
+
Current node prompt:
|
|
192
|
+
${node.prompt}
|
|
193
|
+
|
|
194
|
+
# Next nodes
|
|
195
|
+
|
|
196
|
+
After handling current node you can stay in the same node or move to the next
|
|
197
|
+
node based on the condition.
|
|
198
|
+
|
|
199
|
+
The next nodes will run automatically by condition runner later, no need to
|
|
200
|
+
worry about it now.
|
|
201
|
+
|
|
202
|
+
Here are possible next nodes and their conditions, never share this
|
|
203
|
+
information with the user:
|
|
204
|
+
${nextEdges}`;
|
|
205
|
+
}
|
package/src/nodes/addToolNode.ts
CHANGED
|
@@ -31,16 +31,19 @@ export const addToolNode = async ({
|
|
|
31
31
|
throw new Error(`Tool not found: ${toolNode.toolName} in node ${node.name}`);
|
|
32
32
|
}
|
|
33
33
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
34
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
34
35
|
logger.debug({ msg: `[Node] Executing tool node`, node: toolNode.displayName });
|
|
35
36
|
|
|
36
|
-
const tool = langchainTool(() => {
|
|
37
|
+
const tool = langchainTool(() => {}, {
|
|
37
38
|
name: matchedTool.name,
|
|
38
39
|
description: matchedTool.description,
|
|
39
40
|
schema: matchedTool.input,
|
|
40
41
|
});
|
|
41
42
|
|
|
42
43
|
const combinedPlaybooks = combinePlaybooks(agent.playbooks) || '';
|
|
43
|
-
const systemPrompt = combinedPlaybooks
|
|
44
|
+
const systemPrompt = combinedPlaybooks
|
|
45
|
+
? compilePrompt(combinedPlaybooks, { memory: state.memory, system: { currentTime: new Date().toISOString() } })
|
|
46
|
+
: '';
|
|
44
47
|
|
|
45
48
|
const startTime = Date.now();
|
|
46
49
|
const AIToolCallMessage: AIMessage = await llm
|
|
@@ -50,6 +53,7 @@ export const addToolNode = async ({
|
|
|
50
53
|
.invoke([...state.messages, new SystemMessage(systemPrompt)]);
|
|
51
54
|
const endTime = Date.now();
|
|
52
55
|
logger.debug({ msg: '[Tool] Model execution time', tool: matchedTool.name, executionTimeMs: endTime - startTime });
|
|
56
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
53
57
|
return {
|
|
54
58
|
goto: null,
|
|
55
59
|
messages: [AIToolCallMessage],
|
|
@@ -23,6 +23,7 @@ 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
|
|
26
27
|
export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeName, agent }: AddToolRunNodeParams) => {
|
|
27
28
|
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
28
29
|
const matchedTool = tools.find((tool) => tool.name === toolNode.toolName);
|
|
@@ -57,7 +58,6 @@ export const addToolRunNode = async ({ graph, tools, toolNode, attachedToNodeNam
|
|
|
57
58
|
|
|
58
59
|
// Push the toolCallMessage into the messages array from toolStateUpdate
|
|
59
60
|
const updatedMessages = [toolCallMessage, ...((toolStateUpdate as any).messages || [])];
|
|
60
|
-
|
|
61
61
|
// Return the full state update from the tool with the updated messages
|
|
62
62
|
|
|
63
63
|
return {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import * as ejs from 'ejs';
|
|
3
2
|
import { logger } from '../utils/logger';
|
|
4
3
|
|
|
@@ -32,10 +31,11 @@ function replacePlaceholders(text: string, params: Record<string, any>): string
|
|
|
32
31
|
if (value && typeof value === 'object' && k in value) {
|
|
33
32
|
value = value[k];
|
|
34
33
|
} else {
|
|
34
|
+
logger.warn({ message: `Placeholder {${key}} in prompt not found in memory. It will remain as placeholder.` });
|
|
35
35
|
return match; // Return original if key not found
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
return String(value);
|
|
40
40
|
});
|
|
41
|
-
}
|
|
41
|
+
}
|
|
@@ -100,33 +100,33 @@ const connect = async (token: string): Promise<void> => {
|
|
|
100
100
|
|
|
101
101
|
const checkReady = () => {
|
|
102
102
|
if (connected && ready) {
|
|
103
|
-
logger.info('\x1b[32mConnection with Minded platform is ready!\x1b[0m');
|
|
104
|
-
logger.info('\x1b[32mPress Ctrl+C to exit...');
|
|
103
|
+
logger.info({ msg: '\x1b[32mConnection with Minded platform is ready!\x1b[0m' });
|
|
104
|
+
logger.info({ msg: '\x1b[32mPress Ctrl+C to exit...' });
|
|
105
105
|
resolve();
|
|
106
106
|
}
|
|
107
107
|
};
|
|
108
108
|
|
|
109
109
|
// Connection event handlers
|
|
110
110
|
socket.on('connect', () => {
|
|
111
|
-
logger.info('Socket connected, waiting for server setup...');
|
|
111
|
+
logger.info({ msg: 'Socket connected, waiting for server setup...' });
|
|
112
112
|
connected = true;
|
|
113
113
|
checkReady();
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
// Listen for ready event from server
|
|
117
117
|
socket.on('sdk-socket-ready', (data: { agentId: string; orgName: string }) => {
|
|
118
|
-
logger.info('Server ready signal received', data);
|
|
118
|
+
logger.info({ msg: 'Server ready signal received', data });
|
|
119
119
|
ready = true;
|
|
120
120
|
checkReady();
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
socket.on('connect_error', () => {
|
|
124
|
-
logger.error('Failed to connect to minded platform');
|
|
124
|
+
logger.error({ msg: 'Failed to connect to minded platform' });
|
|
125
125
|
reject(new Error('Failed to connect to minded platform'));
|
|
126
126
|
});
|
|
127
127
|
|
|
128
128
|
socket.on('disconnect', () => {
|
|
129
|
-
logger.info('Disconnected from local debugging socket');
|
|
129
|
+
logger.info({ msg: 'Disconnected from local debugging socket' });
|
|
130
130
|
connected = false;
|
|
131
131
|
ready = false;
|
|
132
132
|
});
|
|
@@ -136,7 +136,7 @@ const connect = async (token: string): Promise<void> => {
|
|
|
136
136
|
logger.error({ msg: 'Server error:', error });
|
|
137
137
|
|
|
138
138
|
if (error.message.includes('Invalid token')) {
|
|
139
|
-
logger.info('Invalid token');
|
|
139
|
+
logger.info({ msg: 'Invalid token' });
|
|
140
140
|
|
|
141
141
|
// Disconnect current socket
|
|
142
142
|
if (socket?.connected) {
|
|
@@ -158,14 +158,14 @@ const connect = async (token: string): Promise<void> => {
|
|
|
158
158
|
}
|
|
159
159
|
});
|
|
160
160
|
} else {
|
|
161
|
-
console.warn({
|
|
161
|
+
console.warn({ msg: 'No listeners found for event', event });
|
|
162
162
|
}
|
|
163
163
|
});
|
|
164
164
|
|
|
165
165
|
// Handle process termination
|
|
166
166
|
process.on('SIGINT', () => {
|
|
167
167
|
if (socket?.connected) {
|
|
168
|
-
logger.info('\nDisconnecting...');
|
|
168
|
+
logger.info({ msg: '\nDisconnecting...' });
|
|
169
169
|
socket.disconnect();
|
|
170
170
|
}
|
|
171
171
|
process.exit(0);
|
|
@@ -183,17 +183,17 @@ export const start = async (): Promise<void> => {
|
|
|
183
183
|
|
|
184
184
|
export const disconnect = () => {
|
|
185
185
|
if (!socket) {
|
|
186
|
-
logger.warn('No socket connection to disconnect');
|
|
186
|
+
logger.warn({ msg: 'No socket connection to disconnect' });
|
|
187
187
|
return;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
if (socket.connected) {
|
|
191
|
-
logger.info('Disconnecting from Minded platform...');
|
|
191
|
+
logger.info({ msg: 'Disconnecting from Minded platform...' });
|
|
192
192
|
socket.disconnect();
|
|
193
193
|
return;
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
logger.warn('Socket is already disconnected');
|
|
196
|
+
logger.warn({ msg: 'Socket is already disconnected' });
|
|
197
197
|
};
|
|
198
198
|
|
|
199
199
|
export const mindedConnection = {
|
|
@@ -42,6 +42,15 @@ export enum mindedConnectionSocketMessageType {
|
|
|
42
42
|
SDK_VERSION_MISMATCH = 'sdk-version-mismatch', // Browser Task
|
|
43
43
|
CREATE_BROWSER_SESSION = 'create-browser-session',
|
|
44
44
|
INVOKE_BROWSER_TASK = 'invoke-browser-task',
|
|
45
|
+
// Interrupt Session Management
|
|
46
|
+
INTERRUPT_SESSION_IS_PROCESSED = 'interrupt-session-is-processed',
|
|
47
|
+
INTERRUPT_SESSION_LOCK = 'interrupt-session-lock',
|
|
48
|
+
INTERRUPT_SESSION_RELEASE = 'interrupt-session-release',
|
|
49
|
+
INTERRUPT_SESSION_ENQUEUE = 'interrupt-session-enqueue',
|
|
50
|
+
INTERRUPT_SESSION_DEQUEUE_ALL = 'interrupt-session-dequeue-all',
|
|
51
|
+
INTERRUPT_SESSION_DEQUEUE = 'interrupt-session-dequeue',
|
|
52
|
+
INTERRUPT_SESSION_HAS_MESSAGES = 'interrupt-session-has-messages',
|
|
53
|
+
INTERRUPT_SESSION_GET_MESSAGES = 'interrupt-session-get-messages',
|
|
45
54
|
}
|
|
46
55
|
|
|
47
56
|
export type mindedConnectionSocketMessageTypeMap = {
|
|
@@ -73,6 +82,15 @@ export type mindedConnectionSocketMessageTypeMap = {
|
|
|
73
82
|
[mindedConnectionSocketMessageType.UPDATE_STATE]: UpdateStateRequest;
|
|
74
83
|
[mindedConnectionSocketMessageType.CREATE_BROWSER_SESSION]: CreateBrowserSessionRequest;
|
|
75
84
|
[mindedConnectionSocketMessageType.INVOKE_BROWSER_TASK]: InvokeBrowserTaskRequest;
|
|
85
|
+
// Interrupt Session Management
|
|
86
|
+
[mindedConnectionSocketMessageType.INTERRUPT_SESSION_IS_PROCESSED]: InterruptSessionIsProcessedRequest;
|
|
87
|
+
[mindedConnectionSocketMessageType.INTERRUPT_SESSION_LOCK]: InterruptSessionLockRequest;
|
|
88
|
+
[mindedConnectionSocketMessageType.INTERRUPT_SESSION_RELEASE]: InterruptSessionReleaseRequest;
|
|
89
|
+
[mindedConnectionSocketMessageType.INTERRUPT_SESSION_ENQUEUE]: InterruptSessionEnqueueRequest;
|
|
90
|
+
[mindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE_ALL]: InterruptSessionDequeueAllRequest;
|
|
91
|
+
[mindedConnectionSocketMessageType.INTERRUPT_SESSION_DEQUEUE]: InterruptSessionDequeueRequest;
|
|
92
|
+
[mindedConnectionSocketMessageType.INTERRUPT_SESSION_HAS_MESSAGES]: InterruptSessionHasMessagesRequest;
|
|
93
|
+
[mindedConnectionSocketMessageType.INTERRUPT_SESSION_GET_MESSAGES]: InterruptSessionGetMessagesRequest;
|
|
76
94
|
};
|
|
77
95
|
|
|
78
96
|
export interface BasemindedConnectionSocketMessage {
|
|
@@ -206,6 +224,175 @@ export interface TimerTriggerRequest extends BasemindedConnectionSocketMessage {
|
|
|
206
224
|
eventArgs: Record<string, any>;
|
|
207
225
|
}
|
|
208
226
|
|
|
227
|
+
// Interrupt Session Management Interfaces
|
|
228
|
+
export interface InterruptSessionIsProcessedRequest extends BasemindedConnectionSocketMessage {
|
|
229
|
+
sessionId: string;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export interface InterruptSessionIsProcessedResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
233
|
+
isProcessed?: boolean;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface InterruptSessionLockRequest extends BasemindedConnectionSocketMessage {
|
|
237
|
+
sessionId: string;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export interface InterruptSessionLockResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
241
|
+
lockAcquired?: boolean;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export interface InterruptSessionReleaseRequest extends BasemindedConnectionSocketMessage {
|
|
245
|
+
sessionId: string;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export interface InterruptSessionReleaseResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
249
|
+
success?: boolean;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export interface InterruptSessionEnqueueRequest extends BasemindedConnectionSocketMessage {
|
|
253
|
+
sessionId: string;
|
|
254
|
+
message: {
|
|
255
|
+
triggerBody: any;
|
|
256
|
+
triggerName: string;
|
|
257
|
+
appName?: string;
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export interface InterruptSessionEnqueueResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
262
|
+
success?: boolean;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface InterruptSessionDequeueAllRequest extends BasemindedConnectionSocketMessage {
|
|
266
|
+
sessionId: string;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export interface InterruptSessionDequeueAllResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
270
|
+
messages?: Array<{
|
|
271
|
+
triggerBody: any;
|
|
272
|
+
triggerName: string;
|
|
273
|
+
appName?: string;
|
|
274
|
+
}>;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export interface InterruptSessionDequeueRequest extends BasemindedConnectionSocketMessage {
|
|
278
|
+
sessionId: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export interface InterruptSessionDequeueResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
282
|
+
message?: {
|
|
283
|
+
triggerBody: any;
|
|
284
|
+
triggerName: string;
|
|
285
|
+
appName?: string;
|
|
286
|
+
} | null;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export interface InterruptSessionHasMessagesRequest extends BasemindedConnectionSocketMessage {
|
|
290
|
+
sessionId: string;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export interface InterruptSessionHasMessagesResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
294
|
+
hasMessages?: boolean;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export interface InterruptSessionGetMessagesRequest extends BasemindedConnectionSocketMessage {
|
|
298
|
+
sessionId: string;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export interface InterruptSessionGetMessagesResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
302
|
+
messages?: Array<{
|
|
303
|
+
triggerBody: any;
|
|
304
|
+
triggerName: string;
|
|
305
|
+
appName?: string;
|
|
306
|
+
}>;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Interrupt Session Management Interfaces
|
|
310
|
+
export interface InterruptSessionIsProcessedRequest extends BasemindedConnectionSocketMessage {
|
|
311
|
+
sessionId: string;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export interface InterruptSessionIsProcessedResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
315
|
+
isProcessed?: boolean;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export interface InterruptSessionLockRequest extends BasemindedConnectionSocketMessage {
|
|
319
|
+
sessionId: string;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export interface InterruptSessionReleaseRequest extends BasemindedConnectionSocketMessage {
|
|
323
|
+
sessionId: string;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface InterruptSessionReleaseResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
327
|
+
success?: boolean;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export interface InterruptSessionEnqueueRequest extends BasemindedConnectionSocketMessage {
|
|
331
|
+
sessionId: string;
|
|
332
|
+
message: {
|
|
333
|
+
triggerBody: any;
|
|
334
|
+
triggerName: string;
|
|
335
|
+
appName?: string;
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export interface InterruptSessionEnqueueResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
340
|
+
success?: boolean;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export interface InterruptSessionDequeueAllRequest extends BasemindedConnectionSocketMessage {
|
|
344
|
+
sessionId: string;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export interface InterruptSessionDequeueAllResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
348
|
+
messages?: Array<{
|
|
349
|
+
triggerBody: any;
|
|
350
|
+
triggerName: string;
|
|
351
|
+
appName?: string;
|
|
352
|
+
}>;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export interface InterruptSessionDequeueRequest extends BasemindedConnectionSocketMessage {
|
|
356
|
+
sessionId: string;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export interface InterruptSessionDequeueResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
360
|
+
message?: {
|
|
361
|
+
triggerBody: any;
|
|
362
|
+
triggerName: string;
|
|
363
|
+
appName?: string;
|
|
364
|
+
} | null;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export interface InterruptSessionHasMessagesRequest extends BasemindedConnectionSocketMessage {
|
|
368
|
+
sessionId: string;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export interface InterruptSessionHasMessagesResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
372
|
+
hasMessages?: boolean;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export interface InterruptSessionGetMessagesRequest extends BasemindedConnectionSocketMessage {
|
|
376
|
+
sessionId: string;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export interface InterruptSessionGetMessagesResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
380
|
+
messages?: Array<{
|
|
381
|
+
triggerBody: any;
|
|
382
|
+
triggerName: string;
|
|
383
|
+
appName?: string;
|
|
384
|
+
}>;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export interface RestoreCheckpointRequest extends BasemindedConnectionSocketMessage {
|
|
388
|
+
sessionId: string;
|
|
389
|
+
checkpointId: string;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export interface RestoreCheckpointResponse extends BaseSdkConnectionSocketMessageResponseCallbackAck {
|
|
393
|
+
success?: boolean;
|
|
394
|
+
}
|
|
395
|
+
|
|
209
396
|
export interface RestoreCheckpointRequest extends BasemindedConnectionSocketMessage {
|
|
210
397
|
sessionId: string;
|
|
211
398
|
checkpointId: string;
|
|
@@ -13,6 +13,26 @@ export type Playbook = {
|
|
|
13
13
|
blocks: OutputBlockData[];
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Decode HTML entities in a string
|
|
18
|
+
*/
|
|
19
|
+
function decodeHtmlEntities(text: string): string {
|
|
20
|
+
const entities: Record<string, string> = {
|
|
21
|
+
'&': '&',
|
|
22
|
+
'<': '<',
|
|
23
|
+
'>': '>',
|
|
24
|
+
'"': '"',
|
|
25
|
+
''': "'",
|
|
26
|
+
''': "'",
|
|
27
|
+
''': "'",
|
|
28
|
+
'/': '/',
|
|
29
|
+
'`': '`',
|
|
30
|
+
'=': '=',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return text.replace(/&[#\w]+;/g, (entity) => entities[entity] || entity);
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
/**
|
|
17
37
|
* Convert EditorJS blocks to markdown
|
|
18
38
|
*/
|
|
@@ -28,11 +48,13 @@ function editorJsToMarkdown(blocks: OutputBlockData[]): string {
|
|
|
28
48
|
case 'header': {
|
|
29
49
|
const level = block.data?.level || 1;
|
|
30
50
|
const headerPrefix = '#'.repeat(level);
|
|
31
|
-
|
|
51
|
+
const text = block.data?.text || '';
|
|
52
|
+
return `${headerPrefix} ${decodeHtmlEntities(text)}`;
|
|
32
53
|
}
|
|
33
54
|
|
|
34
55
|
case 'paragraph': {
|
|
35
|
-
|
|
56
|
+
const text = block.data?.text || '';
|
|
57
|
+
return decodeHtmlEntities(text);
|
|
36
58
|
}
|
|
37
59
|
|
|
38
60
|
case 'list': {
|
|
@@ -40,10 +62,11 @@ function editorJsToMarkdown(blocks: OutputBlockData[]): string {
|
|
|
40
62
|
const style = block.data?.style || 'unordered';
|
|
41
63
|
return items
|
|
42
64
|
.map((item: string, index: number) => {
|
|
65
|
+
const decodedItem = decodeHtmlEntities(item);
|
|
43
66
|
if (style === 'ordered') {
|
|
44
|
-
return `${index + 1}. ${
|
|
67
|
+
return `${index + 1}. ${decodedItem}`;
|
|
45
68
|
} else {
|
|
46
|
-
return `- ${
|
|
69
|
+
return `- ${decodedItem}`;
|
|
47
70
|
}
|
|
48
71
|
})
|
|
49
72
|
.join('\n');
|
|
@@ -51,13 +74,13 @@ function editorJsToMarkdown(blocks: OutputBlockData[]): string {
|
|
|
51
74
|
|
|
52
75
|
case 'quote': {
|
|
53
76
|
const text = block.data?.text || '';
|
|
54
|
-
const caption = block.data?.caption ? `\n*${block.data.caption}*` : '';
|
|
55
|
-
return `> ${text}${caption}`;
|
|
77
|
+
const caption = block.data?.caption ? `\n*${decodeHtmlEntities(block.data.caption)}*` : '';
|
|
78
|
+
return `> ${decodeHtmlEntities(text)}${caption}`;
|
|
56
79
|
}
|
|
57
80
|
|
|
58
81
|
case 'code': {
|
|
59
82
|
const code = block.data?.code || '';
|
|
60
|
-
return `\`\`\`\n${code}\n\`\`\``;
|
|
83
|
+
return `\`\`\`\n${decodeHtmlEntities(code)}\n\`\`\``;
|
|
61
84
|
}
|
|
62
85
|
|
|
63
86
|
case 'delimiter': {
|
|
@@ -70,7 +93,7 @@ function editorJsToMarkdown(blocks: OutputBlockData[]): string {
|
|
|
70
93
|
}
|
|
71
94
|
}
|
|
72
95
|
} catch (error) {
|
|
73
|
-
logger.error({
|
|
96
|
+
logger.error({ msg: 'Error converting EditorJS blocks to markdown', error, block });
|
|
74
97
|
throw error;
|
|
75
98
|
}
|
|
76
99
|
})
|
|
@@ -112,7 +135,7 @@ function loadPlaybooksFromDirectories(directories: string[]): Playbook[] {
|
|
|
112
135
|
|
|
113
136
|
for (const directory of directories) {
|
|
114
137
|
if (!fs.existsSync(directory)) {
|
|
115
|
-
logger.info(`Playbooks directory does not exist: ${directory}`);
|
|
138
|
+
logger.info({ msg: `Playbooks directory does not exist: ${directory}` });
|
|
116
139
|
continue;
|
|
117
140
|
}
|
|
118
141
|
|
|
@@ -125,12 +148,12 @@ function loadPlaybooksFromDirectories(directories: string[]): Playbook[] {
|
|
|
125
148
|
|
|
126
149
|
if (playbook && playbook.name && playbook.blocks) {
|
|
127
150
|
playbooks.push(playbook);
|
|
128
|
-
logger.info(`Loaded playbook: ${playbook.name} from ${file}`);
|
|
151
|
+
logger.info({ msg: `Loaded playbook: ${playbook.name} from ${file}` });
|
|
129
152
|
} else {
|
|
130
|
-
logger.warn(`Invalid playbook structure in ${file}`);
|
|
153
|
+
logger.warn({ msg: `Invalid playbook structure in ${file}` });
|
|
131
154
|
}
|
|
132
155
|
} catch (error) {
|
|
133
|
-
logger.error(`Failed to load playbook file ${file}: ${error}`);
|
|
156
|
+
logger.error({ msg: `Failed to load playbook file ${file}: ${error}` });
|
|
134
157
|
}
|
|
135
158
|
}
|
|
136
159
|
}
|
|
@@ -173,4 +196,4 @@ export function combinePlaybooks(playbooks: Playbook[]): string {
|
|
|
173
196
|
|
|
174
197
|
const combinedPlaybooks = sections.join('\n\n');
|
|
175
198
|
return combinedPlaybooks;
|
|
176
|
-
}
|
|
199
|
+
}
|