@minded-ai/mindedjs 1.0.122 → 1.0.123-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 +65 -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/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.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/addBrowserTaskNode.js +2 -0
- 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 +43 -1
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolNode.d.ts.map +1 -1
- package/dist/nodes/addToolNode.js +2 -0
- 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/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.js +5 -5
- 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/package.json +1 -1
- package/src/agent.ts +89 -19
- package/src/cli/index.ts +14 -14
- package/src/edges/edgeFactory.ts +2 -2
- package/src/index.ts +14 -1
- package/src/interrupts/BaseInterruptSessionManager.ts +88 -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/addBrowserTaskNode.ts +2 -2
- package/src/nodes/addHumanInTheLoopNode.ts +2 -1
- package/src/nodes/addJumpToNode.ts +1 -1
- package/src/nodes/addPromptNode.ts +47 -4
- package/src/nodes/addToolNode.ts +2 -0
- package/src/nodes/addToolRunNode.ts +1 -1
- package/src/platform/mindedConnection.ts +12 -12
- package/src/platform/mindedConnectionTypes.ts +187 -0
- package/src/playbooks/playbooks.ts +5 -5
- package/src/types/Agent.types.ts +2 -0
- package/src/types/LangGraph.types.ts +3 -1
- package/src/voice/voiceSession.ts +9 -1
|
@@ -32,6 +32,7 @@ const messages_1 = require("@langchain/core/messages");
|
|
|
32
32
|
const uuid_1 = require("uuid");
|
|
33
33
|
const logger_1 = require("../utils/logger");
|
|
34
34
|
const Agent_types_1 = require("../types/Agent.types");
|
|
35
|
+
const BaseInterruptSessionManager_1 = require("../interrupts/BaseInterruptSessionManager");
|
|
35
36
|
/**
|
|
36
37
|
* Voice Conversation class for managing individual ElevenLabs voice conversations
|
|
37
38
|
*/
|
|
@@ -149,6 +150,12 @@ class VoiceSession {
|
|
|
149
150
|
break;
|
|
150
151
|
case 'interruption':
|
|
151
152
|
logger_1.logger.debug({ msg: '[Voice] Received interruption' });
|
|
153
|
+
if (await this.agent.interruptSessionManager.isProcessed(this.sessionId)) {
|
|
154
|
+
await this.agent.interruptSessionManager.enqueueMessage(this.sessionId, {
|
|
155
|
+
triggerBody: {},
|
|
156
|
+
triggerName: BaseInterruptSessionManager_1.QUEUE_INTERRUPT_DETECTED_BEFORE_SPEECH,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
152
159
|
(_a = this.onInterruptionCallback) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
153
160
|
// Send interruption event to dashboard if connected
|
|
154
161
|
if ((0, config_1.getConfig)().dashboardConnected) {
|
|
@@ -216,8 +223,9 @@ class VoiceSession {
|
|
|
216
223
|
}
|
|
217
224
|
}
|
|
218
225
|
async updateAgentResponse(originalAgentResponse, correctedAgentResponse) {
|
|
226
|
+
const cleanedOriginalAgentResponse = originalAgentResponse.replace('... ', '');
|
|
219
227
|
const graphState = await this.agent.compiledGraph.getState(this.agent.getLangraphConfig(this.sessionId));
|
|
220
|
-
const agentMessage = graphState.values.messages.find((message) => message.content ===
|
|
228
|
+
const agentMessage = graphState.values.messages.find((message) => message.content === cleanedOriginalAgentResponse && message instanceof messages_1.AIMessage);
|
|
221
229
|
if (agentMessage) {
|
|
222
230
|
agentMessage.content = correctedAgentResponse;
|
|
223
231
|
agentMessage.additional_kwargs = agentMessage.additional_kwargs || {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voiceSession.js","sourceRoot":"","sources":["../../src/voice/voiceSession.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2BAA+B;AAE/B,+EAAiE;AACjE,6EAAsF;AACtF,+CAA+C;AAE/C,uDAAgF;AAChF,+BAAoC;AACpC,4CAAyC;AACzC,sDAAmD;
|
|
1
|
+
{"version":3,"file":"voiceSession.js","sourceRoot":"","sources":["../../src/voice/voiceSession.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/agent.ts
CHANGED
|
@@ -36,6 +36,8 @@ import {
|
|
|
36
36
|
import { createLlmInstance } from './llm/createLlmInstance';
|
|
37
37
|
import { createCheckpointSaver } from './checkpointer/checkpointSaverFactory';
|
|
38
38
|
import { getConfig } from './platform/config';
|
|
39
|
+
import { InterruptSessionManager, InterruptType } from './interrupts/BaseInterruptSessionManager';
|
|
40
|
+
import { createInterruptSessionManager } from './interrupts/interruptSessionManagerFactory';
|
|
39
41
|
import { BaseMessage, HumanMessage } from '@langchain/core/messages';
|
|
40
42
|
import triggerTypeToDefaultMessage from './triggers/triggerTypeToDefaultMessage';
|
|
41
43
|
import appActionRunnerToolCreator from './internalTools/appActionRunnerTool';
|
|
@@ -55,6 +57,7 @@ type CreateAgentParams<Memory> = {
|
|
|
55
57
|
tools: Tool<any, Memory>[];
|
|
56
58
|
platformToken?: string;
|
|
57
59
|
memorySaver?: BaseCheckpointSaver;
|
|
60
|
+
interruptSessionManager?: InterruptSessionManager;
|
|
58
61
|
};
|
|
59
62
|
|
|
60
63
|
/**
|
|
@@ -87,6 +90,8 @@ export class Agent {
|
|
|
87
90
|
|
|
88
91
|
// Langgraph memory saver. In memory for local development, Custom for Platform
|
|
89
92
|
private checkpointer!: BaseCheckpointSaver;
|
|
93
|
+
// Interrupt session manager. In memory for local development, Custom for Platform
|
|
94
|
+
public interruptSessionManager!: InterruptSessionManager;
|
|
90
95
|
// Langgraph compiled graph
|
|
91
96
|
public compiledGraph!: CompiledGraph;
|
|
92
97
|
// Cache for secrets to avoid repeated API calls
|
|
@@ -157,7 +162,7 @@ export class Agent {
|
|
|
157
162
|
|
|
158
163
|
private async init(params: CreateAgentParams<z.infer<typeof this.memorySchema>>): Promise<void> {
|
|
159
164
|
try {
|
|
160
|
-
const { config, tools, memorySaver } = params;
|
|
165
|
+
const { config, tools, memorySaver, interruptSessionManager } = params;
|
|
161
166
|
const { runLocally } = getConfig();
|
|
162
167
|
if (!runLocally) {
|
|
163
168
|
await mindedConnection.start();
|
|
@@ -196,6 +201,7 @@ export class Agent {
|
|
|
196
201
|
const libraryActionsRunnerTools = this.initLibraryActionsRunnerTools();
|
|
197
202
|
this.tools = [...tools, ...appActionsRunnerTools, ...libraryActionsRunnerTools];
|
|
198
203
|
this.checkpointer = memorySaver || createCheckpointSaver();
|
|
204
|
+
this.interruptSessionManager = interruptSessionManager || createInterruptSessionManager();
|
|
199
205
|
|
|
200
206
|
// call here methods that needs environment variables to be loaded
|
|
201
207
|
this.llm = createLlmInstance(config.llm);
|
|
@@ -430,14 +436,14 @@ export class Agent {
|
|
|
430
436
|
|
|
431
437
|
return appName
|
|
432
438
|
? createHistoryStep<AppTriggerHistoryStep>(currentHistory, {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
439
|
+
...baseStep,
|
|
440
|
+
type: NodeType.TRIGGER,
|
|
441
|
+
appName,
|
|
442
|
+
})
|
|
437
443
|
: createHistoryStep<TriggerHistoryStep>(currentHistory, {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
444
|
+
...baseStep,
|
|
445
|
+
type: NodeType.TRIGGER,
|
|
446
|
+
});
|
|
441
447
|
}
|
|
442
448
|
|
|
443
449
|
/**
|
|
@@ -468,10 +474,24 @@ export class Agent {
|
|
|
468
474
|
* });
|
|
469
475
|
* ```
|
|
470
476
|
*/
|
|
471
|
-
public async invoke({ triggerBody, triggerName, sessionId, appName }: AgentInvokeParams) {
|
|
477
|
+
public async invoke({ triggerBody, triggerName, sessionId, appName, bypassSessionCheck }: AgentInvokeParams): Promise<any> {
|
|
472
478
|
sessionId = sessionId ?? uuidv4();
|
|
473
479
|
try {
|
|
474
480
|
await this.waitForInitialization();
|
|
481
|
+
|
|
482
|
+
// Try to acquire lock atomically (unless bypassing session check)
|
|
483
|
+
if (!bypassSessionCheck && !(await this.interruptSessionManager.lock(sessionId))) {
|
|
484
|
+
// Could not acquire lock, session is being processed - enqueue the message
|
|
485
|
+
logger.info({ msg: 'Enqueuing message', sessionId, triggerBody, triggerName, appName });
|
|
486
|
+
await this.interruptSessionManager.enqueueMessage(sessionId, {
|
|
487
|
+
triggerBody,
|
|
488
|
+
triggerName,
|
|
489
|
+
appName,
|
|
490
|
+
});
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
// Session lock acquired, proceed with processing
|
|
494
|
+
|
|
475
495
|
let messages: Array<BaseMessage> = [];
|
|
476
496
|
let memoryUpdate = {};
|
|
477
497
|
let sessionType: SessionType = SessionType.TEXT;
|
|
@@ -507,7 +527,8 @@ export class Agent {
|
|
|
507
527
|
const handlerResult = results.find((r) => r !== undefined);
|
|
508
528
|
if (handlerResult) {
|
|
509
529
|
if (!handlerResult.isQualified) {
|
|
510
|
-
logger.
|
|
530
|
+
logger.info({ message: '[Trigger] Disqualified', triggerName, triggerBody, sessionId });
|
|
531
|
+
await this.interruptSessionManager.release(sessionId);
|
|
511
532
|
return;
|
|
512
533
|
}
|
|
513
534
|
memoryUpdate = handlerResult.memory || {};
|
|
@@ -540,13 +561,37 @@ export class Agent {
|
|
|
540
561
|
|
|
541
562
|
let res;
|
|
542
563
|
// Resume interruption
|
|
543
|
-
if (state.tasks?.[
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
564
|
+
if (state.tasks?.[state.tasks.length - 1]?.interrupts?.length > 0) {
|
|
565
|
+
const lastTask = state.tasks[state.tasks.length - 1];
|
|
566
|
+
const interrupt = lastTask.interrupts[0];
|
|
567
|
+
const interruptValue = (interrupt as any).value;
|
|
568
|
+
|
|
569
|
+
if (interruptValue?.type === InterruptType.HUMAN_IN_THE_LOOP) {
|
|
570
|
+
// For HUMAN_IN_THE_LOOP, use resume with the full object
|
|
571
|
+
res = await this.compiledGraph.invoke(
|
|
572
|
+
new Command({
|
|
573
|
+
resume: { memory: memoryUpdate, messages, history: historyStep, sessionId, sessionType, overrideStartFromNodeId: null },
|
|
574
|
+
}),
|
|
575
|
+
langraphConfig,
|
|
576
|
+
);
|
|
577
|
+
} else if (interruptValue?.type === InterruptType.NEW_TRIGGERS) {
|
|
578
|
+
// For NEW_TRIGGERS, check if there's an updateStateObject to apply first
|
|
579
|
+
const finalState = { memory: memoryUpdate, messages, history: [historyStep], sessionId, sessionType };
|
|
580
|
+
if (interruptValue.updateStateObject) {
|
|
581
|
+
finalState.messages = [...interruptValue.updateStateObject.messages, ...messages];
|
|
582
|
+
finalState.history = [...(interruptValue.updateStateObject.history || []), historyStep];
|
|
583
|
+
//add handlers for other state fields as needed
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// Then use update with the full object and empty resume
|
|
587
|
+
res = await this.compiledGraph.invoke(
|
|
588
|
+
new Command({
|
|
589
|
+
update: finalState,
|
|
590
|
+
resume: '',
|
|
591
|
+
}),
|
|
592
|
+
langraphConfig,
|
|
593
|
+
);
|
|
594
|
+
}
|
|
550
595
|
} else if (state.values.overrideStartFromNodeId) {
|
|
551
596
|
res = await this.compiledGraph.invoke(
|
|
552
597
|
new Command({
|
|
@@ -568,6 +613,26 @@ export class Agent {
|
|
|
568
613
|
langraphConfig,
|
|
569
614
|
);
|
|
570
615
|
}
|
|
616
|
+
const nextMessage = await this.interruptSessionManager.dequeue(sessionId);
|
|
617
|
+
if (nextMessage) {
|
|
618
|
+
// Dequeue the first message and process it recursively
|
|
619
|
+
// Recursively process the next message with bypass flag
|
|
620
|
+
const invokeParams: AgentInvokeParams = {
|
|
621
|
+
triggerBody: nextMessage.triggerBody,
|
|
622
|
+
triggerName: nextMessage.triggerName,
|
|
623
|
+
sessionId: sessionId,
|
|
624
|
+
bypassSessionCheck: true,
|
|
625
|
+
};
|
|
626
|
+
if (nextMessage.appName) {
|
|
627
|
+
invokeParams.appName = nextMessage.appName;
|
|
628
|
+
}
|
|
629
|
+
logger.info({ msg: 'Invoking next message in the queue', invokeParams });
|
|
630
|
+
return await this.invoke(invokeParams);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Release the session lock
|
|
634
|
+
await this.interruptSessionManager.release(sessionId);
|
|
635
|
+
|
|
571
636
|
return res;
|
|
572
637
|
} catch (error: any) {
|
|
573
638
|
logger.error({
|
|
@@ -576,6 +641,10 @@ export class Agent {
|
|
|
576
641
|
stack: error.stack,
|
|
577
642
|
sessionId,
|
|
578
643
|
});
|
|
644
|
+
|
|
645
|
+
// Release the session lock on error
|
|
646
|
+
await this.interruptSessionManager.release(sessionId);
|
|
647
|
+
|
|
579
648
|
const state = await this.compiledGraph.getState(this.getLangraphConfig(sessionId));
|
|
580
649
|
this.emit(AgentEvents.ERROR, { error: error instanceof Error ? error : new Error(JSON.stringify(error)), state: state.values });
|
|
581
650
|
throw error;
|
|
@@ -767,7 +836,7 @@ export class Agent {
|
|
|
767
836
|
// Hangup / end session handler
|
|
768
837
|
connection.on(mindedConnectionSocketMessageType.VOICE_SESSION_END, (message) => {
|
|
769
838
|
const hangup = message as BaseVoiceMessage;
|
|
770
|
-
logger.debug({
|
|
839
|
+
logger.debug({ msg: '[Voice] Dashboard eneded voice session', sessionId: hangup.sessionId });
|
|
771
840
|
const voiceSession = this.voiceSessions.get(hangup.sessionId);
|
|
772
841
|
if (voiceSession) {
|
|
773
842
|
voiceSession.hangup();
|
|
@@ -816,7 +885,8 @@ export class Agent {
|
|
|
816
885
|
voiceId: voiceTrigger.voiceId,
|
|
817
886
|
});
|
|
818
887
|
await voiceSession.init();
|
|
819
|
-
logger.debug({
|
|
888
|
+
logger.debug({ msg: '[Voice] Voice session initialized', sessionId: params.sessionId });
|
|
889
|
+
|
|
820
890
|
this.voiceSessions.set(params.sessionId, voiceSession);
|
|
821
891
|
|
|
822
892
|
// Emit voice session start event
|
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(`Created ${envPath} and added token`);
|
|
22
|
+
logger.info({ msg: `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(`Updated MINDED_CONNECTION_TOKEN in ${envPath}`);
|
|
32
|
+
logger.info({ msg: `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(`Added MINDED_CONNECTION_TOKEN to ${envPath}`);
|
|
37
|
+
logger.info({ msg: `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('minded.json not found in the current directory');
|
|
47
|
+
logger.error({ msg: '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('Failed to read or parse minded.json:', error);
|
|
57
|
+
logger.error({ msg: '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('No agent path found in minded.json');
|
|
64
|
+
logger.error({ msg: '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('Could not find Lambda handler template file');
|
|
94
|
+
logger.error({ msg: '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(`Generated Lambda handler at ${outputPath}`);
|
|
105
|
+
logger.info({ msg: `Generated Lambda handler at ${outputPath}` });
|
|
106
106
|
|
|
107
107
|
// Compile the index.ts file using TypeScript
|
|
108
|
-
logger.info('Compiling the Lambda handler...');
|
|
108
|
+
logger.info({ msg: 'Compiling the Lambda handler...' });
|
|
109
109
|
|
|
110
110
|
try {
|
|
111
111
|
// Read tsconfig.json to get the outDir
|
|
@@ -138,12 +138,12 @@ function generateLambdaHandler(): void {
|
|
|
138
138
|
cwd: process.cwd(),
|
|
139
139
|
});
|
|
140
140
|
|
|
141
|
-
logger.info(`Successfully compiled Lambda handler to ${outDir}/index.js`);
|
|
141
|
+
logger.info({ msg: `Successfully compiled Lambda handler to ${outDir}/index.js` });
|
|
142
142
|
} catch (compileError) {
|
|
143
|
-
logger.error({
|
|
143
|
+
logger.error({ msg: 'Failed to compile Lambda handler', error: compileError });
|
|
144
144
|
}
|
|
145
145
|
} catch (error) {
|
|
146
|
-
logger.error({
|
|
146
|
+
logger.error({ msg: 'Failed to generate Lambda handler', error: error });
|
|
147
147
|
process.exit(1);
|
|
148
148
|
}
|
|
149
149
|
}
|
|
@@ -155,14 +155,14 @@ function main() {
|
|
|
155
155
|
if (command === 'token') {
|
|
156
156
|
const token = args[1];
|
|
157
157
|
if (!token) {
|
|
158
|
-
logger.error('Please provide a token');
|
|
158
|
+
logger.error({ msg: '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('Unknown command. Available commands: token, generate-lambda-ts-handler');
|
|
165
|
+
logger.error({ msg: 'Unknown command. Available commands: token, generate-lambda-ts-handler' });
|
|
166
166
|
process.exit(1);
|
|
167
167
|
}
|
|
168
168
|
}
|
package/src/edges/edgeFactory.ts
CHANGED
|
@@ -60,7 +60,7 @@ export const edgeFactory = ({
|
|
|
60
60
|
if (result) {
|
|
61
61
|
return result;
|
|
62
62
|
} else {
|
|
63
|
-
logger.debug('No logical conditions matched, continuing to prompt conditions');
|
|
63
|
+
logger.debug({ msg: 'No logical conditions matched, continuing to prompt conditions' });
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -85,7 +85,7 @@ export const edgeFactory = ({
|
|
|
85
85
|
|
|
86
86
|
// Fallback: stay at current source node
|
|
87
87
|
const source = originalNode?.name || sourceNode;
|
|
88
|
-
logger.info(`No conditions matched, returning to source: ${source}`);
|
|
88
|
+
logger.info({ msg: `No conditions matched, returning to source: ${source}` });
|
|
89
89
|
return source;
|
|
90
90
|
};
|
|
91
91
|
};
|
package/src/index.ts
CHANGED
|
@@ -5,9 +5,22 @@ import { sendPlaceholderMessage } from './internalTools/voice/sendPlaceholderMes
|
|
|
5
5
|
import { resetTimer, cancelTimer, onTimer } from './internalTools/timer';
|
|
6
6
|
import { retellCall, retellGetCall } from './internalTools/voice/retell';
|
|
7
7
|
import { escalateVoiceCall } from './internalTools/voice/escalateVoiceCall';
|
|
8
|
+
import { mindedConnectionSocketMessageType } from './platform/mindedConnectionTypes';
|
|
8
9
|
|
|
9
10
|
export type { ElevenLabsContext } from './types/Voice.types';
|
|
10
|
-
export {
|
|
11
|
+
export {
|
|
12
|
+
Agent,
|
|
13
|
+
events,
|
|
14
|
+
logger,
|
|
15
|
+
sendPlaceholderMessage,
|
|
16
|
+
resetTimer,
|
|
17
|
+
cancelTimer,
|
|
18
|
+
onTimer,
|
|
19
|
+
retellCall,
|
|
20
|
+
retellGetCall,
|
|
21
|
+
escalateVoiceCall,
|
|
22
|
+
mindedConnectionSocketMessageType,
|
|
23
|
+
};
|
|
11
24
|
|
|
12
25
|
// Export LLM implementations
|
|
13
26
|
export { MindedChatOpenAI } from './platform/models/mindedChatOpenAI';
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { State } from '../types/LangGraph.types';
|
|
2
|
+
import { GraphInterrupt } from '@langchain/langgraph';
|
|
3
|
+
import { logger } from '../utils/logger';
|
|
4
|
+
|
|
5
|
+
export enum InterruptType {
|
|
6
|
+
NEW_TRIGGERS = 'NEW_TRIGGERS',
|
|
7
|
+
HUMAN_IN_THE_LOOP = 'HUMAN_IN_THE_LOOP',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const QUEUE_INTERRUPT_DETECTED_BEFORE_SPEECH = 'QUEUE_INTERRUPT_DETECTED_BEFORE_SPEECH';
|
|
11
|
+
|
|
12
|
+
export interface QueuedMessage {
|
|
13
|
+
triggerBody: any;
|
|
14
|
+
triggerName: string;
|
|
15
|
+
appName?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface InterruptPayload {
|
|
18
|
+
type: InterruptType.NEW_TRIGGERS;
|
|
19
|
+
updateStateObject?: Partial<State>;
|
|
20
|
+
id?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface InterruptSessionManager {
|
|
24
|
+
isProcessed(sessionId: string): boolean | Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Atomically attempts to acquire a lock for the given session.
|
|
27
|
+
* This method should only succeed if the session is not already being processed.
|
|
28
|
+
*
|
|
29
|
+
* @param sessionId - The session ID to lock
|
|
30
|
+
* @returns true if the lock was successfully acquired, false if the session is already locked
|
|
31
|
+
*/
|
|
32
|
+
lock(sessionId: string): boolean | Promise<boolean>;
|
|
33
|
+
release(sessionId: string): void | Promise<void>;
|
|
34
|
+
enqueueMessage(sessionId: string, message: QueuedMessage): void | Promise<void>;
|
|
35
|
+
dequeueAll(sessionId: string): QueuedMessage[] | Promise<QueuedMessage[]>;
|
|
36
|
+
dequeue(sessionId: string): QueuedMessage | null | Promise<QueuedMessage | null>;
|
|
37
|
+
checkQueueAndInterrupt(sessionId: string, updateStateObject?: Partial<State>): Promise<boolean>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export abstract class BaseInterruptSessionManager implements InterruptSessionManager {
|
|
41
|
+
// Abstract methods that subclasses must implement for queue management
|
|
42
|
+
abstract isProcessed(sessionId: string): boolean | Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Atomically attempts to acquire a lock for the given session.
|
|
45
|
+
* This method should only succeed if the session is not already being processed.
|
|
46
|
+
* Implementations must ensure this operation is atomic to prevent race conditions.
|
|
47
|
+
*
|
|
48
|
+
* @param sessionId - The session ID to lock
|
|
49
|
+
* @returns true if the lock was successfully acquired, false if the session is already locked
|
|
50
|
+
*/
|
|
51
|
+
abstract lock(sessionId: string): boolean | Promise<boolean>;
|
|
52
|
+
abstract release(sessionId: string): void | Promise<void>;
|
|
53
|
+
abstract enqueueMessage(sessionId: string, message: QueuedMessage): void | Promise<void>;
|
|
54
|
+
abstract dequeueAll(sessionId: string): QueuedMessage[] | Promise<QueuedMessage[]>;
|
|
55
|
+
abstract dequeue(sessionId: string): QueuedMessage | null | Promise<QueuedMessage | null>;
|
|
56
|
+
|
|
57
|
+
// Abstract method to check if queue has messages - this is the only queue-specific part
|
|
58
|
+
protected abstract hasQueuedMessages(sessionId: string): boolean | Promise<boolean>;
|
|
59
|
+
protected abstract getQueuedMessages(sessionId: string): QueuedMessage[] | Promise<QueuedMessage[]>;
|
|
60
|
+
|
|
61
|
+
// Common implementation of checkQueueAndInterrupt
|
|
62
|
+
async checkQueueAndInterrupt(sessionId: string, updateStateObject?: Partial<State>): Promise<boolean> {
|
|
63
|
+
if (await this.hasQueuedMessages(sessionId)) {
|
|
64
|
+
logger.trace({ msg: 'graph has queued messagess, interrupting graph', sessionId });
|
|
65
|
+
|
|
66
|
+
// Interrupt the graph with NEW_TRIGGERS flag and optional updateStateObject
|
|
67
|
+
const interruptPayload: InterruptPayload = { type: InterruptType.NEW_TRIGGERS };
|
|
68
|
+
if (updateStateObject) {
|
|
69
|
+
interruptPayload.updateStateObject = {
|
|
70
|
+
messages: updateStateObject.messages,
|
|
71
|
+
memory: updateStateObject.memory,
|
|
72
|
+
history: updateStateObject.history,
|
|
73
|
+
sessionId: updateStateObject.sessionId,
|
|
74
|
+
sessionType: updateStateObject.sessionType,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
throw new GraphInterrupt([
|
|
79
|
+
{
|
|
80
|
+
value: interruptPayload,
|
|
81
|
+
when: 'during',
|
|
82
|
+
resumable: true,
|
|
83
|
+
},
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { BaseInterruptSessionManager, QueuedMessage, QUEUE_INTERRUPT_DETECTED_BEFORE_SPEECH } from './BaseInterruptSessionManager';
|
|
2
|
+
|
|
3
|
+
export class MemoryInterruptSessionManager extends BaseInterruptSessionManager {
|
|
4
|
+
private sessionProcessing: Map<string, boolean> = new Map();
|
|
5
|
+
private sessionMessageQueues: Map<string, QueuedMessage[]> = new Map();
|
|
6
|
+
|
|
7
|
+
isProcessed(sessionId: string): boolean {
|
|
8
|
+
return this.sessionProcessing.get(sessionId) || false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
lock(sessionId: string): boolean {
|
|
12
|
+
const isCurrentlyProcessed = this.sessionProcessing.get(sessionId) || false;
|
|
13
|
+
if (isCurrentlyProcessed) {
|
|
14
|
+
return false; // Could not acquire lock
|
|
15
|
+
}
|
|
16
|
+
this.sessionProcessing.set(sessionId, true);
|
|
17
|
+
return true; // Successfully acquired lock
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
release(sessionId: string): void {
|
|
21
|
+
this.sessionProcessing.delete(sessionId);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
enqueueMessage(sessionId: string, message: QueuedMessage): void {
|
|
25
|
+
if (!this.sessionMessageQueues.has(sessionId)) {
|
|
26
|
+
this.sessionMessageQueues.set(sessionId, []);
|
|
27
|
+
}
|
|
28
|
+
this.sessionMessageQueues.get(sessionId)!.push(message);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
dequeueAll(sessionId: string): QueuedMessage[] {
|
|
32
|
+
const messages = this.sessionMessageQueues.get(sessionId) || [];
|
|
33
|
+
const result = [...messages];
|
|
34
|
+
this.sessionMessageQueues.set(sessionId, []);
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
dequeue(sessionId: string): QueuedMessage | null {
|
|
39
|
+
const messages = this.sessionMessageQueues.get(sessionId) || [];
|
|
40
|
+
if (messages.length === 0) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const firstMessage = messages.shift()!;
|
|
44
|
+
this.sessionMessageQueues.set(sessionId, messages);
|
|
45
|
+
|
|
46
|
+
// If the dequeued message has the special trigger name, recursively dequeue the next one
|
|
47
|
+
if (firstMessage.triggerName === QUEUE_INTERRUPT_DETECTED_BEFORE_SPEECH) {
|
|
48
|
+
return this.dequeue(sessionId);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return firstMessage;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Implementation of abstract methods from BaseInterruptSessionManager
|
|
55
|
+
protected hasQueuedMessages(sessionId: string): boolean {
|
|
56
|
+
const queue = this.sessionMessageQueues.get(sessionId) || [];
|
|
57
|
+
return queue.length > 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
protected getQueuedMessages(sessionId: string): QueuedMessage[] {
|
|
61
|
+
return this.sessionMessageQueues.get(sessionId) || [];
|
|
62
|
+
}
|
|
63
|
+
}
|