@minded-ai/mindedjs 2.0.2 → 2.0.4-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 +10 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +57 -20
- 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 +0 -0
- 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/platform/mindedConnection.d.ts.map +1 -1
- package/dist/platform/mindedConnection.js +31 -8
- package/dist/platform/mindedConnection.js.map +1 -1
- package/dist/utils/extractStateMemoryResponse.d.ts +5 -0
- package/dist/utils/extractStateMemoryResponse.d.ts.map +1 -0
- package/dist/utils/extractStateMemoryResponse.js +91 -0
- package/dist/utils/extractStateMemoryResponse.js.map +1 -0
- package/package.json +1 -1
- package/src/agent.ts +66 -21
- package/src/platform/mindedConnection.ts +34 -8
package/src/agent.ts
CHANGED
|
@@ -489,8 +489,8 @@ export class Agent {
|
|
|
489
489
|
if (handlerResult) {
|
|
490
490
|
if (!handlerResult.isQualified) {
|
|
491
491
|
logger.debug({ message: '[Trigger] Disqualified', triggerName, triggerBody, sessionId });
|
|
492
|
-
|
|
493
|
-
return;
|
|
492
|
+
// Process any queued messages even when disqualified
|
|
493
|
+
return await this.processQueuedMessages(sessionId);
|
|
494
494
|
}
|
|
495
495
|
}
|
|
496
496
|
|
|
@@ -541,26 +541,10 @@ export class Agent {
|
|
|
541
541
|
} else {
|
|
542
542
|
res = await this.compiledGraph.invoke(state, langgraphConfig);
|
|
543
543
|
}
|
|
544
|
-
const nextMessage = await this.interruptSessionManager.dequeue(sessionId);
|
|
545
|
-
if (nextMessage) {
|
|
546
|
-
// Dequeue the first message and process it recursively
|
|
547
|
-
// Recursively process the next message with bypass flag
|
|
548
|
-
const invokeParams: AgentInvokeParams = {
|
|
549
|
-
triggerBody: nextMessage.triggerBody,
|
|
550
|
-
triggerName: nextMessage.triggerName,
|
|
551
|
-
bypassSessionCheck: true,
|
|
552
|
-
};
|
|
553
|
-
if (nextMessage.appName) {
|
|
554
|
-
invokeParams.appName = nextMessage.appName;
|
|
555
|
-
}
|
|
556
|
-
logger.debug({ msg: 'Invoking next message in the queue', invokeParams });
|
|
557
|
-
return await this.invoke(invokeParams);
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
// Release the session lock
|
|
561
|
-
await this.interruptSessionManager.release(sessionId);
|
|
562
544
|
|
|
563
|
-
|
|
545
|
+
// Process any queued messages before returning
|
|
546
|
+
const queueResult = await this.processQueuedMessages(sessionId);
|
|
547
|
+
return queueResult !== undefined ? queueResult : res;
|
|
564
548
|
} catch (err) {
|
|
565
549
|
logger.error({ msg: '[Trigger] Error', err, sessionId });
|
|
566
550
|
|
|
@@ -946,4 +930,65 @@ export class Agent {
|
|
|
946
930
|
public onEnd(): void {
|
|
947
931
|
mindedConnection.disconnect();
|
|
948
932
|
}
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* Process any queued messages for a session.
|
|
936
|
+
* If a message is found, it will be processed recursively.
|
|
937
|
+
* If no messages are found, checks if the graph was interrupted and resumes if needed.
|
|
938
|
+
* Only releases the lock when there's nothing left to process.
|
|
939
|
+
*
|
|
940
|
+
* @param sessionId - The session ID to check for queued messages
|
|
941
|
+
* @returns The result of processing the next message or resuming the graph, or undefined if nothing to process
|
|
942
|
+
*/
|
|
943
|
+
private async processQueuedMessages(sessionId: string): Promise<any> {
|
|
944
|
+
const nextMessage = await this.interruptSessionManager.dequeue(sessionId);
|
|
945
|
+
if (nextMessage) {
|
|
946
|
+
// Dequeue the first message and process it recursively
|
|
947
|
+
const invokeParams: AgentInvokeParams = {
|
|
948
|
+
triggerBody: nextMessage.triggerBody,
|
|
949
|
+
triggerName: nextMessage.triggerName,
|
|
950
|
+
bypassSessionCheck: true,
|
|
951
|
+
};
|
|
952
|
+
if (nextMessage.appName) {
|
|
953
|
+
invokeParams.appName = nextMessage.appName;
|
|
954
|
+
}
|
|
955
|
+
logger.debug({
|
|
956
|
+
msg: 'Invoking next message in the queue',
|
|
957
|
+
invokeParams,
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
return await this.invoke(invokeParams);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
// No more messages in queue - check if we need to resume an interrupted graph
|
|
964
|
+
const langgraphConfig = this.getLangraphConfig(sessionId);
|
|
965
|
+
const langgraphState = await this.compiledGraph.getState(langgraphConfig);
|
|
966
|
+
const lastTask = langgraphState.tasks[langgraphState.tasks.length - 1];
|
|
967
|
+
const hasInterrupt = lastTask?.interrupts?.length > 0;
|
|
968
|
+
|
|
969
|
+
if (hasInterrupt) {
|
|
970
|
+
const interruptValue = lastTask!.interrupts[0].value as InterruptPayload;
|
|
971
|
+
if (interruptValue?.type === InterruptType.NEW_TRIGGERS) {
|
|
972
|
+
// Graph was interrupted by new triggers - resume it
|
|
973
|
+
logger.debug({ msg: 'Resuming interrupted graph after processing queued messages', sessionId });
|
|
974
|
+
|
|
975
|
+
const state = langgraphState.values as State<any>;
|
|
976
|
+
const resumeResult = await this.compiledGraph.invoke(
|
|
977
|
+
new Command({
|
|
978
|
+
update: state,
|
|
979
|
+
resume: '',
|
|
980
|
+
}),
|
|
981
|
+
langgraphConfig,
|
|
982
|
+
);
|
|
983
|
+
|
|
984
|
+
// After resuming, check again for queued messages (recursive)
|
|
985
|
+
const queueResult = await this.processQueuedMessages(sessionId);
|
|
986
|
+
return queueResult !== undefined ? queueResult : resumeResult;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// No more messages and no interrupt to resume - release the session lock
|
|
991
|
+
await this.interruptSessionManager.release(sessionId);
|
|
992
|
+
return undefined;
|
|
993
|
+
}
|
|
949
994
|
}
|
|
@@ -81,13 +81,16 @@ const getSdkVersion = (): string => {
|
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
const connect = async (token: string): Promise<void> => {
|
|
84
|
+
const connect = async (token: string, retryCount: number = 0): Promise<void> => {
|
|
85
85
|
const { isDeployed, baseUrl, env } = getConfig();
|
|
86
|
-
|
|
86
|
+
const maxRetries = isDeployed ? 3 : 0;
|
|
87
|
+
|
|
88
|
+
logger.info(`Connecting to Minded platform: ${baseUrl}${retryCount > 0 ? ` (retry ${retryCount}/${maxRetries})` : ''}`);
|
|
89
|
+
|
|
87
90
|
return new Promise<void>((resolve, reject) => {
|
|
88
91
|
socket = io(baseUrl, {
|
|
89
92
|
path: '/minded-connect',
|
|
90
|
-
transports: [
|
|
93
|
+
transports: ['websocket'],
|
|
91
94
|
query: {
|
|
92
95
|
isDeployedAgent: isDeployed,
|
|
93
96
|
token,
|
|
@@ -121,9 +124,32 @@ const connect = async (token: string): Promise<void> => {
|
|
|
121
124
|
checkReady();
|
|
122
125
|
});
|
|
123
126
|
|
|
124
|
-
socket.on('connect_error', (err) => {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
socket.on('connect_error', async (err) => {
|
|
128
|
+
// If we're in cloud mode and haven't exhausted retries, try again
|
|
129
|
+
if (isDeployed && retryCount < maxRetries) {
|
|
130
|
+
logger.info({ msg: `Retrying connection in ${(retryCount + 1) * 2} seconds...` });
|
|
131
|
+
|
|
132
|
+
// Disconnect current socket
|
|
133
|
+
if (socket?.connected) {
|
|
134
|
+
socket.disconnect();
|
|
135
|
+
}
|
|
136
|
+
socket = null;
|
|
137
|
+
|
|
138
|
+
// Wait with exponential backoff
|
|
139
|
+
await wait((retryCount + 1) * 2000);
|
|
140
|
+
|
|
141
|
+
// Retry connection
|
|
142
|
+
try {
|
|
143
|
+
await connect(token, retryCount + 1);
|
|
144
|
+
resolve();
|
|
145
|
+
} catch (retryErr) {
|
|
146
|
+
reject(retryErr);
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
// No more retries or not in cloud mode
|
|
150
|
+
logger.error({ msg: 'Failed to connect to minded platform', err });
|
|
151
|
+
reject(new Error('Failed to connect to minded platform'));
|
|
152
|
+
}
|
|
127
153
|
});
|
|
128
154
|
|
|
129
155
|
socket.on('disconnect', () => {
|
|
@@ -144,8 +170,8 @@ const connect = async (token: string): Promise<void> => {
|
|
|
144
170
|
socket.disconnect();
|
|
145
171
|
}
|
|
146
172
|
|
|
147
|
-
// Get new token and reconnect
|
|
148
|
-
await connect(token);
|
|
173
|
+
// Get new token and reconnect (start fresh with retry count 0)
|
|
174
|
+
await connect(token, 0);
|
|
149
175
|
}
|
|
150
176
|
});
|
|
151
177
|
|