@minded-ai/mindedjs 1.0.93 → 1.0.95-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 +7 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +108 -18
- 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 +4 -3
- 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/interrupts/InterruptSessionManager.types.d.ts +36 -0
- package/dist/interrupts/InterruptSessionManager.types.d.ts.map +1 -0
- package/dist/interrupts/InterruptSessionManager.types.js +40 -0
- package/dist/interrupts/InterruptSessionManager.types.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 +51 -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 +154 -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 +56 -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/addHumanInTheLoopNode.d.ts.map +1 -1
- package/dist/nodes/addHumanInTheLoopNode.js +3 -2
- 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 +46 -1
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolNode.js +1 -1
- package/dist/nodes/addToolNode.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 +163 -1
- package/dist/platform/mindedConnectionTypes.d.ts.map +1 -1
- package/dist/platform/mindedConnectionTypes.js +10 -0
- 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 +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/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +1 -0
- package/dist/utils/logger.js.map +1 -1
- package/package.json +2 -2
- package/src/agent.ts +135 -26
- package/src/cli/index.ts +12 -12
- package/src/edges/createDirectEdge.ts +1 -1
- package/src/edges/createLogicalRouter.ts +7 -8
- package/src/edges/createPromptRouter.ts +4 -3
- package/src/edges/edgeFactory.ts +2 -2
- package/src/interrupts/InterruptSessionManager.types.ts +80 -0
- package/src/interrupts/MemoryInterruptSessionManager.ts +56 -0
- package/src/interrupts/MindedInterruptSessionManager.ts +154 -0
- package/src/interrupts/interruptSessionManagerFactory.ts +20 -0
- package/src/nodes/addAppToolNode.ts +1 -1
- package/src/nodes/addHumanInTheLoopNode.ts +3 -2
- package/src/nodes/addJumpToNode.ts +1 -1
- package/src/nodes/addPromptNode.ts +51 -5
- package/src/nodes/addToolNode.ts +1 -1
- package/src/nodes/addTriggerNode.ts +1 -1
- package/src/platform/mindedConnection.ts +15 -25
- package/src/platform/mindedConnectionTypes.ts +202 -0
- package/src/playbooks/playbooks.ts +4 -4
- package/src/types/Agent.types.ts +2 -0
- package/src/types/LangGraph.types.ts +3 -1
- package/src/utils/logger.ts +1 -0
|
@@ -31,7 +31,9 @@ const createStateAnnotation = () => langgraph_1.Annotation.Root({
|
|
|
31
31
|
default: () => [],
|
|
32
32
|
reducer: (a, b) => a.concat(b),
|
|
33
33
|
}),
|
|
34
|
-
sessionId: (0, langgraph_1.Annotation)(
|
|
34
|
+
sessionId: (0, langgraph_1.Annotation)({
|
|
35
|
+
reducer: (a, b) => b || a,
|
|
36
|
+
}),
|
|
35
37
|
sessionType: (0, langgraph_1.Annotation)({
|
|
36
38
|
default: () => Agent_types_1.SessionType.TEXT,
|
|
37
39
|
reducer: (a, b) => b || a,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LangGraph.types.js","sourceRoot":"","sources":["../../src/types/LangGraph.types.ts"],"names":[],"mappings":";;;AACA,oDAAkF;AAClF,+CAAyD;AAElD,MAAM,qBAAqB,GAAG,GAAiB,EAAE,CACtD,sBAAU,CAAC,IAAI,CAAC;IACd,QAAQ,EAAE,IAAA,sBAAU,EAAqB;QACvC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;QACjB,OAAO,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,EAAE;;YACrC,MAAM,GAAG,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;YAC9B,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;gBAClC,IAAI,MAAA,OAAO,CAAC,iBAAiB,0CAAE,MAAM,EAAE,CAAC;oBACtC,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC;oBAChE,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;wBACjB,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;oBACvC,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;IACF,MAAM,EAAE,IAAA,sBAAU,EAAS;QACzB,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAa,CAAA;QAC7B,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;KACpC,CAAC;IACF,OAAO,EAAE,IAAA,sBAAU,EAAqB;QACtC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;QACjB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;KAC/B,CAAC;IACF,SAAS,EAAE,IAAA,sBAAU,
|
|
1
|
+
{"version":3,"file":"LangGraph.types.js","sourceRoot":"","sources":["../../src/types/LangGraph.types.ts"],"names":[],"mappings":";;;AACA,oDAAkF;AAClF,+CAAyD;AAElD,MAAM,qBAAqB,GAAG,GAAiB,EAAE,CACtD,sBAAU,CAAC,IAAI,CAAC;IACd,QAAQ,EAAE,IAAA,sBAAU,EAAqB;QACvC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;QACjB,OAAO,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,EAAE;;YACrC,MAAM,GAAG,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;YAC9B,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;gBAClC,IAAI,MAAA,OAAO,CAAC,iBAAiB,0CAAE,MAAM,EAAE,CAAC;oBACtC,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC;oBAChE,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;wBACjB,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;oBACvC,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;IACF,MAAM,EAAE,IAAA,sBAAU,EAAS;QACzB,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAa,CAAA;QAC7B,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;KACpC,CAAC;IACF,OAAO,EAAE,IAAA,sBAAU,EAAqB;QACtC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;QACjB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;KAC/B,CAAC;IACF,SAAS,EAAE,IAAA,sBAAU,EAAS;QAC5B,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC;KAC1B,CAAC;IACF,WAAW,EAAE,IAAA,sBAAU,EAAc;QACnC,OAAO,EAAE,GAAG,EAAE,CAAC,yBAAW,CAAC,IAAI;QAC/B,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC;KAC1B,CAAC;CACH,CAAC,CAAC;AAlCQ,QAAA,qBAAqB,yBAkC7B;AAEL,gDAAgD;AACnC,QAAA,eAAe,GAAG,IAAA,6BAAqB,GAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,MAAM,uCAiBjB,CAAC"}
|
package/dist/utils/logger.js
CHANGED
package/dist/utils/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,oDAA4B;AAC5B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,gDAAgD;AACnC,QAAA,MAAM,GAAG,IAAA,cAAI,EAAC;IACzB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;IACtC,IAAI,EAAE,IAAI;IACV,SAAS,EAAE;QACT,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE;YACP,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,IAAI;YACV,aAAa,EAAE,cAAc;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,oDAA4B;AAC5B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,gDAAgD;AACnC,QAAA,MAAM,GAAG,IAAA,cAAI,EAAC;IACzB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;IACtC,IAAI,EAAE,IAAI;IACV,SAAS,EAAE;QACT,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE;YACP,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,IAAI;YACV,aAAa,EAAE,cAAc;YAC7B,UAAU,EAAE,SAAS,EAAE,yCAAyC;SACjE;KACF;IACD,UAAU,EAAE;QACV,KAAK,CAAC,KAAK;YACT,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC1B,CAAC;KACF;CACF,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@minded-ai/mindedjs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.95-beta-1",
|
|
4
4
|
"description": "MindedJS is a TypeScript library for building agents.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -65,4 +65,4 @@
|
|
|
65
65
|
"uuid": "^11.1.0",
|
|
66
66
|
"ws": "^8.15.1"
|
|
67
67
|
}
|
|
68
|
-
}
|
|
68
|
+
}
|
package/src/agent.ts
CHANGED
|
@@ -11,10 +11,7 @@ import { edgeFactory } from './edges/edgeFactory';
|
|
|
11
11
|
import { AgentEventRequestPayloads, AgentEventResponsePayloads, AgentEvents } from './events/AgentEvents';
|
|
12
12
|
import { z } from 'zod';
|
|
13
13
|
import * as mindedConnection from './platform/mindedConnection';
|
|
14
|
-
import {
|
|
15
|
-
InvokeMessage,
|
|
16
|
-
mindedConnectionSocketMessageType,
|
|
17
|
-
} from './platform/mindedConnectionTypes';
|
|
14
|
+
import { InvokeMessage, mindedConnectionSocketMessageType } from './platform/mindedConnectionTypes';
|
|
18
15
|
import * as fs from 'fs';
|
|
19
16
|
import * as path from 'path';
|
|
20
17
|
import * as yaml from 'js-yaml';
|
|
@@ -29,6 +26,8 @@ import {
|
|
|
29
26
|
import { createLlmInstance } from './llm/createLlmInstance';
|
|
30
27
|
import { createCheckpointSaver } from './checkpointer/checkpointSaverFactory';
|
|
31
28
|
import { getConfig } from './platform/config';
|
|
29
|
+
import { InterruptSessionManager, InterruptType } from './interrupts/InterruptSessionManager.types';
|
|
30
|
+
import { createInterruptSessionManager } from './interrupts/interruptSessionManagerFactory';
|
|
32
31
|
import { BaseMessage, HumanMessage } from '@langchain/core/messages';
|
|
33
32
|
import triggerTypeToDefaultMessage from './triggers/triggerTypeToDefaultMessage';
|
|
34
33
|
import appActionRunnerToolCreator from './internalTools/appActionRunnerTool';
|
|
@@ -46,6 +45,7 @@ type CreateAgentParams<Memory> = {
|
|
|
46
45
|
tools: Tool<any, Memory>[];
|
|
47
46
|
platformToken?: string;
|
|
48
47
|
memorySaver?: BaseCheckpointSaver;
|
|
48
|
+
interruptSessionManager?: InterruptSessionManager;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
/**
|
|
@@ -78,6 +78,8 @@ export class Agent {
|
|
|
78
78
|
|
|
79
79
|
// Langgraph memory saver. In memory for local development, Custom for Platform
|
|
80
80
|
private checkpointer!: BaseCheckpointSaver;
|
|
81
|
+
// Interrupt session manager. In memory for local development, Custom for Platform
|
|
82
|
+
public interruptSessionManager!: InterruptSessionManager;
|
|
81
83
|
// Langgraph compiled graph
|
|
82
84
|
public compiledGraph!: CompiledGraph;
|
|
83
85
|
// Cache for secrets to avoid repeated API calls
|
|
@@ -148,13 +150,14 @@ export class Agent {
|
|
|
148
150
|
|
|
149
151
|
private async init(params: CreateAgentParams<z.infer<typeof this.memorySchema>>): Promise<void> {
|
|
150
152
|
try {
|
|
151
|
-
const { config, tools, memorySaver } = params;
|
|
153
|
+
const { config, tools, memorySaver, interruptSessionManager } = params;
|
|
152
154
|
const { runLocally } = getConfig();
|
|
153
155
|
if (!runLocally) {
|
|
154
156
|
await mindedConnection.start();
|
|
155
157
|
|
|
156
158
|
// Initialize PII gateway
|
|
157
159
|
this._piiGateway = new PIIGateway();
|
|
160
|
+
|
|
158
161
|
mindedConnection.on(mindedConnectionSocketMessageType.INVOKE, async (message, callback) => {
|
|
159
162
|
const invokeMessage = message as InvokeMessage;
|
|
160
163
|
const result = await this.invoke({
|
|
@@ -165,13 +168,14 @@ export class Agent {
|
|
|
165
168
|
});
|
|
166
169
|
callback(result);
|
|
167
170
|
});
|
|
171
|
+
|
|
172
|
+
mindedConnection.on(mindedConnectionSocketMessageType.RESTORE_CHECKPOINT, async (restoreCheckpointMessage, callback) => {
|
|
173
|
+
await this.restoreCheckpoint(restoreCheckpointMessage.sessionId, restoreCheckpointMessage.checkpointId);
|
|
174
|
+
callback({ success: true });
|
|
175
|
+
});
|
|
168
176
|
}
|
|
169
177
|
|
|
170
|
-
const [, flows, playbooks] = await Promise.all([
|
|
171
|
-
this.loadSecrets(),
|
|
172
|
-
this.loadFlows(config.flows),
|
|
173
|
-
loadPlaybooks(config.playbooks),
|
|
174
|
-
]);
|
|
178
|
+
const [, flows, playbooks] = await Promise.all([this.loadSecrets(), this.loadFlows(config.flows), loadPlaybooks(config.playbooks)]);
|
|
175
179
|
|
|
176
180
|
this.playbooks = playbooks;
|
|
177
181
|
this.flows = flows;
|
|
@@ -179,6 +183,7 @@ export class Agent {
|
|
|
179
183
|
const appActionsRunnerTools = this.initAppActionsRunnerTools();
|
|
180
184
|
this.tools = [...tools, ...appActionsRunnerTools];
|
|
181
185
|
this.checkpointer = memorySaver || createCheckpointSaver();
|
|
186
|
+
this.interruptSessionManager = interruptSessionManager || createInterruptSessionManager();
|
|
182
187
|
|
|
183
188
|
// call here methods that needs environment variables to be loaded
|
|
184
189
|
this.llm = createLlmInstance(config.llm);
|
|
@@ -407,10 +412,26 @@ export class Agent {
|
|
|
407
412
|
* });
|
|
408
413
|
* ```
|
|
409
414
|
*/
|
|
410
|
-
public async invoke({ triggerBody, triggerName, sessionId, appName }: AgentInvokeParams) {
|
|
415
|
+
public async invoke({ triggerBody, triggerName, sessionId, appName, bypassSessionCheck }: AgentInvokeParams): Promise<any> {
|
|
411
416
|
sessionId = sessionId ?? uuidv4();
|
|
412
417
|
try {
|
|
413
418
|
await this.waitForInitialization();
|
|
419
|
+
|
|
420
|
+
// Check if session is already being processed (unless bypassing)
|
|
421
|
+
if (!bypassSessionCheck && (await this.interruptSessionManager.isProcessed(sessionId))) {
|
|
422
|
+
// Enqueue the raw message and return
|
|
423
|
+
logger.info({ message: 'Enqueuing message', sessionId, triggerBody, triggerName, appName });
|
|
424
|
+
await this.interruptSessionManager.enqueueMessage(sessionId, {
|
|
425
|
+
triggerBody,
|
|
426
|
+
triggerName,
|
|
427
|
+
appName,
|
|
428
|
+
});
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Lock the session for processing
|
|
433
|
+
await this.interruptSessionManager.lock(sessionId);
|
|
434
|
+
|
|
414
435
|
let messages: Array<BaseMessage> = [];
|
|
415
436
|
let memoryUpdate = {};
|
|
416
437
|
let sessionType: SessionType = SessionType.TEXT;
|
|
@@ -438,7 +459,8 @@ export class Agent {
|
|
|
438
459
|
const handlerResult = results.find((r) => r !== undefined);
|
|
439
460
|
if (handlerResult) {
|
|
440
461
|
if (!handlerResult.isQualified) {
|
|
441
|
-
logger.info(`Trigger ${triggerName} was disqualified`);
|
|
462
|
+
logger.info({ message: `Trigger ${triggerName} was disqualified` });
|
|
463
|
+
await this.interruptSessionManager.release(sessionId);
|
|
442
464
|
return;
|
|
443
465
|
}
|
|
444
466
|
memoryUpdate = handlerResult.memory || {};
|
|
@@ -465,22 +487,95 @@ export class Agent {
|
|
|
465
487
|
|
|
466
488
|
let res;
|
|
467
489
|
// Resume interruption
|
|
468
|
-
if (state.tasks
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
490
|
+
if (state.tasks && state.tasks.length > 0) {
|
|
491
|
+
const lastTask = state.tasks[state.tasks.length - 1];
|
|
492
|
+
if (lastTask?.interrupts?.length > 0) {
|
|
493
|
+
const interrupt = lastTask.interrupts[0];
|
|
494
|
+
const interruptValue = (interrupt as any).value;
|
|
495
|
+
|
|
496
|
+
if (interruptValue?.type === InterruptType.HUMAN_IN_THE_LOOP) {
|
|
497
|
+
// For HUMAN_IN_THE_LOOP, use resume with the full object
|
|
498
|
+
res = await this.compiledGraph.invoke(
|
|
499
|
+
new Command({
|
|
500
|
+
resume: { memory: memoryUpdate, messages, history: historyStep, sessionId, sessionType },
|
|
501
|
+
}),
|
|
502
|
+
langraphConfig,
|
|
503
|
+
);
|
|
504
|
+
} else if (interruptValue?.type === InterruptType.NEW_TRIGGERS) {
|
|
505
|
+
// For NEW_TRIGGERS, check if there's an updateStateObject to apply first
|
|
506
|
+
const finalState = { memory: memoryUpdate, messages, history: [historyStep], sessionId, sessionType };
|
|
507
|
+
if (interruptValue.updateStateObject) {
|
|
508
|
+
finalState.messages = [...interruptValue.updateStateObject.messages, ...messages];
|
|
509
|
+
finalState.history = [...(interruptValue.updateStateObject.history || []), historyStep];
|
|
510
|
+
//add handlers for other state fields as needed
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// Then use update with the full object and empty resume
|
|
514
|
+
res = await this.compiledGraph.invoke(
|
|
515
|
+
new Command({
|
|
516
|
+
update: finalState,
|
|
517
|
+
resume: '',
|
|
518
|
+
}),
|
|
519
|
+
langraphConfig,
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
} else {
|
|
523
|
+
res = await this.compiledGraph.invoke(
|
|
524
|
+
{ messages, memory: memoryUpdate, history: historyStep, sessionId, sessionType },
|
|
525
|
+
langraphConfig,
|
|
526
|
+
);
|
|
527
|
+
}
|
|
475
528
|
} else {
|
|
476
529
|
res = await this.compiledGraph.invoke(
|
|
477
530
|
{ messages, memory: memoryUpdate, history: historyStep, sessionId, sessionType },
|
|
478
531
|
langraphConfig,
|
|
479
532
|
);
|
|
480
533
|
}
|
|
534
|
+
|
|
535
|
+
// Check if graph was interrupted with NEW_TRIGGERS flag
|
|
536
|
+
const finalState = await this.compiledGraph.getState(langraphConfig);
|
|
537
|
+
if (finalState.tasks && finalState.tasks.length > 0) {
|
|
538
|
+
const lastTask = finalState.tasks[finalState.tasks.length - 1];
|
|
539
|
+
if (lastTask?.interrupts?.length > 0) {
|
|
540
|
+
const interrupt = lastTask.interrupts[0];
|
|
541
|
+
const interruptValue = (interrupt as any).value;
|
|
542
|
+
|
|
543
|
+
if (interruptValue?.type === InterruptType.NEW_TRIGGERS) {
|
|
544
|
+
// Dequeue the first message and process it recursively
|
|
545
|
+
const nextMessage = await this.interruptSessionManager.dequeue(sessionId);
|
|
546
|
+
if (nextMessage) {
|
|
547
|
+
// Recursively process the next message with bypass flag
|
|
548
|
+
const invokeParams: AgentInvokeParams = {
|
|
549
|
+
triggerBody: nextMessage.triggerBody,
|
|
550
|
+
triggerName: nextMessage.triggerName,
|
|
551
|
+
sessionId: sessionId,
|
|
552
|
+
bypassSessionCheck: true,
|
|
553
|
+
};
|
|
554
|
+
if (nextMessage.appName) {
|
|
555
|
+
invokeParams.appName = nextMessage.appName;
|
|
556
|
+
}
|
|
557
|
+
logger.info({ message: 'Invoking next message in the queue', invokeParams });
|
|
558
|
+
return await this.invoke(invokeParams);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Release the session lock
|
|
565
|
+
await this.interruptSessionManager.release(sessionId);
|
|
566
|
+
|
|
481
567
|
return res;
|
|
482
568
|
} catch (error: any) {
|
|
483
|
-
logger.error({
|
|
569
|
+
logger.error({
|
|
570
|
+
message: 'Invoke error',
|
|
571
|
+
errorMessage: error.message,
|
|
572
|
+
stack: error.stack,
|
|
573
|
+
sessionId,
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
// Release the session lock on error
|
|
577
|
+
await this.interruptSessionManager.release(sessionId);
|
|
578
|
+
|
|
484
579
|
const state = await this.compiledGraph.getState(this.getLangraphConfig(sessionId));
|
|
485
580
|
this.emit(AgentEvents.ERROR, { error: error instanceof Error ? error : new Error(JSON.stringify(error)), state: state.values });
|
|
486
581
|
throw error;
|
|
@@ -683,8 +778,6 @@ export class Agent {
|
|
|
683
778
|
(this.eventHandlers[event] as Array<typeof handler>).push(handler);
|
|
684
779
|
}
|
|
685
780
|
|
|
686
|
-
|
|
687
|
-
|
|
688
781
|
// Internal method to emit events to the registered listeners
|
|
689
782
|
private async emit<E extends keyof AgentEventRequestPayloads<z.infer<typeof this.memorySchema>>>(
|
|
690
783
|
event: E,
|
|
@@ -712,7 +805,7 @@ export class Agent {
|
|
|
712
805
|
// Skip secret loading in local development
|
|
713
806
|
const { runLocally } = getConfig();
|
|
714
807
|
if (runLocally) {
|
|
715
|
-
logger.info('Running locally - skipping secret loading');
|
|
808
|
+
logger.info({ message: 'Running locally - skipping secret loading' });
|
|
716
809
|
return {};
|
|
717
810
|
}
|
|
718
811
|
if (!mindedConnection.isConnected()) {
|
|
@@ -753,12 +846,12 @@ export class Agent {
|
|
|
753
846
|
}
|
|
754
847
|
}
|
|
755
848
|
|
|
756
|
-
public getLangraphConfig(sessionId: string
|
|
757
|
-
return { configurable: { thread_id: sessionId, recursionLimit: 3 } };
|
|
849
|
+
public getLangraphConfig(sessionId: string, checkpointId?: string) {
|
|
850
|
+
return { configurable: { thread_id: sessionId, recursionLimit: 3, checkpoint_id: checkpointId } };
|
|
758
851
|
}
|
|
759
852
|
|
|
760
853
|
private setupVoice(): void {
|
|
761
|
-
logger.info('Setting up voice');
|
|
854
|
+
logger.info({ message: 'Setting up voice' });
|
|
762
855
|
if (!mindedConnection.isConnected()) {
|
|
763
856
|
throw new Error('Minded connection is required');
|
|
764
857
|
}
|
|
@@ -847,4 +940,20 @@ export class Agent {
|
|
|
847
940
|
});
|
|
848
941
|
}
|
|
849
942
|
}
|
|
943
|
+
|
|
944
|
+
/*
|
|
945
|
+
To be used by the Lambda wrapper to restore checkpoints
|
|
946
|
+
*/
|
|
947
|
+
public async restoreCheckpoint(sessionId: string, checkpointId: string): Promise<void> {
|
|
948
|
+
logger.info({ message: 'Restoring checkpoint', sessionId, checkpointId });
|
|
949
|
+
const langraphConfig = this.getLangraphConfig(sessionId, checkpointId);
|
|
950
|
+
await this.compiledGraph.invoke(
|
|
951
|
+
new Command({
|
|
952
|
+
resume: {
|
|
953
|
+
sessionId,
|
|
954
|
+
},
|
|
955
|
+
}),
|
|
956
|
+
langraphConfig,
|
|
957
|
+
);
|
|
958
|
+
}
|
|
850
959
|
}
|
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({ message: `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({ message: `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({ message: `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({ message: '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({ message: '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({ message: '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({ message: '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({ message: `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({ message: '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(`Successfully compiled Lambda handler to ${outDir}/index.js`);
|
|
141
|
+
logger.info({ message: `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('Please provide a token');
|
|
158
|
+
logger.error({ message: '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({ message: '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(`Executing edge ${JSON.stringify(edge)}`);
|
|
8
|
+
logger.info({ message: `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(edge => edge.condition.trim() !== 'else');
|
|
15
|
-
const elseEdges = edges.filter(edge => edge.condition.trim() === 'else');
|
|
14
|
+
const regularEdges = edges.filter((edge) => edge.condition.trim() !== 'else');
|
|
15
|
+
const elseEdges = edges.filter((edge) => edge.condition.trim() === 'else');
|
|
16
16
|
|
|
17
17
|
// First, evaluate all regular conditions
|
|
18
18
|
for (const edge of regularEdges) {
|
|
@@ -59,17 +59,16 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
|
|
|
59
59
|
]);
|
|
60
60
|
|
|
61
61
|
if (result === true) {
|
|
62
|
-
logger.info(`Condition matched for edge ${edge.source} → ${edge.target}`);
|
|
62
|
+
logger.info({ message: `Condition matched for edge ${edge.source} → ${edge.target}` });
|
|
63
63
|
return edge.target;
|
|
64
64
|
}
|
|
65
|
-
|
|
66
65
|
} catch (error) {
|
|
67
66
|
// Provide detailed error information back to the customer
|
|
68
67
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
69
68
|
const conditionPreview = edge.condition.length > 100 ? `${edge.condition.substring(0, 100)}...` : edge.condition;
|
|
70
69
|
|
|
71
70
|
logger.error({
|
|
72
|
-
|
|
71
|
+
message: `Error evaluating condition for edge ${edge.source} → ${edge.target}`,
|
|
73
72
|
condition: conditionPreview,
|
|
74
73
|
error: errorMessage,
|
|
75
74
|
edgeIndex: edges.indexOf(edge),
|
|
@@ -84,15 +83,15 @@ export const createLogicalRouter = ({ edges }: { edges: LogicalConditionEdge[] }
|
|
|
84
83
|
|
|
85
84
|
// If no regular conditions matched, check for "else" conditions
|
|
86
85
|
if (elseEdges.length > 0) {
|
|
87
|
-
logger.info(`No regular conditions matched, evaluating ${elseEdges.length} else condition(s)`);
|
|
86
|
+
logger.info({ message: `No regular conditions matched, evaluating ${elseEdges.length} else condition(s)` });
|
|
88
87
|
// Return the first "else" condition's target
|
|
89
88
|
const elseEdge = elseEdges[0];
|
|
90
|
-
logger.info(`Else condition matched for edge ${elseEdge.source} → ${elseEdge.target}
|
|
89
|
+
logger.info({ message: `Else condition matched for edge ${elseEdge.source} → ${elseEdge.target}`, edge: elseEdge });
|
|
91
90
|
return elseEdge.target;
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
// If no conditions matched or all failed, return to the source node
|
|
95
|
-
logger.info('No conditions matched');
|
|
94
|
+
logger.info({ message: 'No conditions matched' });
|
|
96
95
|
return null;
|
|
97
96
|
};
|
|
98
97
|
};
|
|
@@ -70,11 +70,11 @@ export const createPromptRouter = ({
|
|
|
70
70
|
currentNodeName?: string;
|
|
71
71
|
}) => {
|
|
72
72
|
return async (state: typeof stateAnnotation.State) => {
|
|
73
|
-
logger.info(`Executing prompt router. Edges: ${JSON.stringify(edges)}`);
|
|
73
|
+
logger.info({ message: `Executing prompt router. Edges: ${JSON.stringify(edges)}` });
|
|
74
74
|
|
|
75
75
|
// If canStayInCurrentNode is true and there are no edges, return current node immediately
|
|
76
76
|
if (canStayInCurrentNode && edges.length === 0 && currentNodeName) {
|
|
77
|
-
logger.info(`No edges available and canStayInCurrentNode is true, staying in current node: ${currentNodeName}`);
|
|
77
|
+
logger.info({ message: `No edges available and canStayInCurrentNode is true, staying in current node: ${currentNodeName}` });
|
|
78
78
|
return currentNodeName;
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -174,13 +174,14 @@ export const createPromptRouter = ({
|
|
|
174
174
|
|
|
175
175
|
const decision = validatedResponse.nextNodeId === currentNodeName ? 'stay in current node' : validatedResponse.nextNodeId;
|
|
176
176
|
const reasoning = includeReasoning && 'reasoning' in validatedResponse ? ` - Reasoning: ${validatedResponse.reasoning}` : '';
|
|
177
|
-
logger.info({
|
|
177
|
+
logger.info({ message: `Router decision: ${decision}`, reasoning });
|
|
178
178
|
|
|
179
179
|
return validatedResponse.nextNodeId;
|
|
180
180
|
} catch (error) {
|
|
181
181
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
182
182
|
logger.warn({
|
|
183
183
|
message: `Prompt router attempt ${attempts} failed`,
|
|
184
|
+
edge: edges,
|
|
184
185
|
error: lastError.message,
|
|
185
186
|
attempt: attempts,
|
|
186
187
|
maxRetries,
|
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('No logical conditions matched, continuing to prompt conditions');
|
|
52
|
+
logger.debug({ message: 'No logical conditions matched, continuing to prompt conditions' });
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -69,7 +69,7 @@ export const edgeFactory = ({
|
|
|
69
69
|
|
|
70
70
|
// Fallback: stay at current source node
|
|
71
71
|
const source = originalNode?.name || sourceNode;
|
|
72
|
-
logger.info(`No conditions matched, returning to source: ${source}`);
|
|
72
|
+
logger.info({ message: `No conditions matched, returning to source: ${source}` });
|
|
73
73
|
return source;
|
|
74
74
|
};
|
|
75
75
|
};
|
|
@@ -0,0 +1,80 @@
|
|
|
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 interface QueuedMessage {
|
|
11
|
+
triggerBody: any;
|
|
12
|
+
triggerName: string;
|
|
13
|
+
appName?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// export interface UpdateStateObject {
|
|
17
|
+
// memory: any;
|
|
18
|
+
// messages: any[];
|
|
19
|
+
// history: any[];
|
|
20
|
+
// sessionId: string;
|
|
21
|
+
// sessionType: SessionType;
|
|
22
|
+
// }
|
|
23
|
+
export interface InterruptPayload {
|
|
24
|
+
type: InterruptType.NEW_TRIGGERS;
|
|
25
|
+
updateStateObject?: Partial<State>;
|
|
26
|
+
id?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface InterruptSessionManager {
|
|
30
|
+
isProcessed(sessionId: string): boolean | Promise<boolean>;
|
|
31
|
+
lock(sessionId: string): void | Promise<void>;
|
|
32
|
+
release(sessionId: string): void | Promise<void>;
|
|
33
|
+
enqueueMessage(sessionId: string, message: QueuedMessage): void | Promise<void>;
|
|
34
|
+
dequeueAll(sessionId: string): QueuedMessage[] | Promise<QueuedMessage[]>;
|
|
35
|
+
dequeue(sessionId: string): QueuedMessage | null | Promise<QueuedMessage | null>;
|
|
36
|
+
checkQueueAndInterrupt(sessionId: string, updateStateObject?: Partial<State>): Promise<boolean>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export abstract class BaseInterruptSessionManager implements InterruptSessionManager {
|
|
40
|
+
// Abstract methods that subclasses must implement for queue management
|
|
41
|
+
abstract isProcessed(sessionId: string): boolean | Promise<boolean>;
|
|
42
|
+
abstract lock(sessionId: string): void | Promise<void>;
|
|
43
|
+
abstract release(sessionId: string): void | Promise<void>;
|
|
44
|
+
abstract enqueueMessage(sessionId: string, message: QueuedMessage): void | Promise<void>;
|
|
45
|
+
abstract dequeueAll(sessionId: string): QueuedMessage[] | Promise<QueuedMessage[]>;
|
|
46
|
+
abstract dequeue(sessionId: string): QueuedMessage | null | Promise<QueuedMessage | null>;
|
|
47
|
+
|
|
48
|
+
// Abstract method to check if queue has messages - this is the only queue-specific part
|
|
49
|
+
protected abstract hasQueuedMessages(sessionId: string): boolean | Promise<boolean>;
|
|
50
|
+
protected abstract getQueuedMessages(sessionId: string): QueuedMessage[] | Promise<QueuedMessage[]>;
|
|
51
|
+
|
|
52
|
+
// Common implementation of checkQueueAndInterrupt
|
|
53
|
+
async checkQueueAndInterrupt(sessionId: string, updateStateObject?: Partial<State>): Promise<boolean> {
|
|
54
|
+
if (await this.hasQueuedMessages(sessionId)) {
|
|
55
|
+
const queue = await this.getQueuedMessages(sessionId);
|
|
56
|
+
logger.trace({ message: 'graph has queued messagess, interrupting graph', sessionId, queue });
|
|
57
|
+
|
|
58
|
+
// Interrupt the graph with NEW_TRIGGERS flag and optional updateStateObject
|
|
59
|
+
const interruptPayload: InterruptPayload = { type: InterruptType.NEW_TRIGGERS };
|
|
60
|
+
if (updateStateObject) {
|
|
61
|
+
interruptPayload.updateStateObject = {
|
|
62
|
+
messages: updateStateObject.messages,
|
|
63
|
+
memory: updateStateObject.memory,
|
|
64
|
+
history: updateStateObject.history,
|
|
65
|
+
sessionId: updateStateObject.sessionId,
|
|
66
|
+
sessionType: updateStateObject.sessionType,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
throw new GraphInterrupt([
|
|
71
|
+
{
|
|
72
|
+
value: interruptPayload,
|
|
73
|
+
when: 'during',
|
|
74
|
+
resumable: true,
|
|
75
|
+
},
|
|
76
|
+
]);
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|