@minded-ai/mindedjs 1.0.92 → 1.0.93-beta.2
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/README.md +1 -1
- package/dist/agent.d.ts +5 -10
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +39 -70
- package/dist/agent.js.map +1 -1
- package/dist/checkpointer/checkpointSaverFactory.d.ts +1 -3
- package/dist/checkpointer/checkpointSaverFactory.d.ts.map +1 -1
- package/dist/checkpointer/checkpointSaverFactory.js +38 -5
- package/dist/checkpointer/checkpointSaverFactory.js.map +1 -1
- package/dist/cli/index.js +0 -0
- package/dist/events/AgentEvents.d.ts +1 -8
- package/dist/events/AgentEvents.d.ts.map +1 -1
- package/dist/events/AgentEvents.js +0 -1
- package/dist/events/AgentEvents.js.map +1 -1
- package/dist/guidelines/guidelinesManager.d.ts +37 -0
- package/dist/guidelines/guidelinesManager.d.ts.map +1 -0
- package/dist/guidelines/guidelinesManager.js +172 -0
- package/dist/guidelines/guidelinesManager.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/zendesk.d.ts.map +1 -1
- package/dist/interfaces/zendesk.js +70 -48
- package/dist/interfaces/zendesk.js.map +1 -1
- package/dist/internalTools/appActionRunnerTool.d.ts +1 -2
- package/dist/internalTools/appActionRunnerTool.d.ts.map +1 -1
- package/dist/internalTools/appActionRunnerTool.js +36 -2
- package/dist/internalTools/appActionRunnerTool.js.map +1 -1
- 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/internalTools/timer.d.ts +93 -0
- package/dist/internalTools/timer.d.ts.map +1 -0
- package/dist/internalTools/timer.js +152 -0
- package/dist/internalTools/timer.js.map +1 -0
- package/dist/platform/mindedCheckpointSaver.d.ts +1 -3
- package/dist/platform/mindedCheckpointSaver.d.ts.map +1 -1
- package/dist/platform/mindedCheckpointSaver.js +43 -10
- package/dist/platform/mindedCheckpointSaver.js.map +1 -1
- package/dist/platform/mindedConnection.d.ts +14 -14
- package/dist/platform/mindedConnection.d.ts.map +1 -1
- package/dist/platform/mindedConnection.js +152 -131
- package/dist/platform/mindedConnection.js.map +1 -1
- package/dist/platform/mindedConnectionTypes.d.ts +47 -38
- package/dist/platform/mindedConnectionTypes.d.ts.map +1 -1
- package/dist/platform/mindedConnectionTypes.js +25 -24
- package/dist/platform/mindedConnectionTypes.js.map +1 -1
- package/dist/platform/piiGateway/gateway.d.ts +1 -3
- package/dist/platform/piiGateway/gateway.d.ts.map +1 -1
- package/dist/platform/piiGateway/gateway.js +39 -6
- package/dist/platform/piiGateway/gateway.js.map +1 -1
- package/dist/playbooks/playbooks.d.ts +1 -2
- package/dist/playbooks/playbooks.d.ts.map +1 -1
- package/dist/playbooks/playbooks.js +4 -3
- package/dist/playbooks/playbooks.js.map +1 -1
- package/dist/utils/extractToolMemoryResponse.d.ts +4 -0
- package/dist/utils/extractToolMemoryResponse.d.ts.map +1 -0
- package/dist/utils/extractToolMemoryResponse.js +16 -0
- package/dist/utils/extractToolMemoryResponse.js.map +1 -0
- package/dist/voice/voiceSession.d.ts.map +1 -1
- package/dist/voice/voiceSession.js +39 -5
- package/dist/voice/voiceSession.js.map +1 -1
- package/docs/SUMMARY.md +4 -0
- package/docs/tooling/timers.md +61 -0
- package/package.json +3 -4
- package/src/agent.ts +56 -87
- package/src/checkpointer/checkpointSaverFactory.ts +5 -6
- package/src/events/AgentEvents.ts +1 -8
- package/src/index.ts +3 -1
- package/src/interfaces/zendesk.ts +38 -37
- package/src/internalTools/appActionRunnerTool.ts +4 -4
- package/src/internalTools/sendPlaceholderMessage.ts +27 -0
- package/src/internalTools/timer.ts +137 -0
- package/src/platform/mindedCheckpointSaver.ts +27 -27
- package/src/platform/mindedConnection.ts +176 -147
- package/src/platform/mindedConnectionTypes.ts +49 -38
- package/src/platform/piiGateway/gateway.ts +8 -10
- package/src/playbooks/playbooks.ts +5 -5
- package/src/voice/voiceSession.ts +6 -5
- package/docs-structure.md +0 -141
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import * as mindedConnection from '../platform/mindedConnection';
|
|
2
|
+
import { mindedConnectionSocketMessageType, TimerResetResponse, TimerCancelResponse } from '../platform/mindedConnectionTypes';
|
|
3
|
+
|
|
4
|
+
// Store timer handlers by timer name
|
|
5
|
+
export const timerHandlers = new Map<string, Array<{
|
|
6
|
+
handler: (params: { sessionId: string; payload: Record<string, any> }) => void | Promise<void>;
|
|
7
|
+
}>>();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reset or set a timer for a specific session.
|
|
11
|
+
* When the timer expires, all registered timer handlers will be called.
|
|
12
|
+
*
|
|
13
|
+
* @param params - The timer configuration
|
|
14
|
+
* @param params.sessionId - The session ID to associate the timer with
|
|
15
|
+
* @param params.seconds - Number of seconds until the timer expires
|
|
16
|
+
* @param params.timerName - Unique name for this timer (used for cancellation and identification)
|
|
17
|
+
* @param params.eventArgs - Additional data to pass to the timer handler when it triggers
|
|
18
|
+
* @returns Promise resolving to timer reset response
|
|
19
|
+
* @throws {Error} When the Minded connection is not established
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { resetTimer } from '@minded-ai/mindedjs';
|
|
24
|
+
*
|
|
25
|
+
* // Set a timer to follow up in 10 seconds
|
|
26
|
+
* await resetTimer({
|
|
27
|
+
* sessionId: 'session-123',
|
|
28
|
+
* seconds: 10,
|
|
29
|
+
* timerName: 'followup',
|
|
30
|
+
* payload: {
|
|
31
|
+
* message: 'Are you still there?'
|
|
32
|
+
* }
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export async function resetTimer({
|
|
37
|
+
sessionId,
|
|
38
|
+
seconds,
|
|
39
|
+
timerName,
|
|
40
|
+
payload = {}
|
|
41
|
+
}: {
|
|
42
|
+
sessionId: string;
|
|
43
|
+
seconds: number;
|
|
44
|
+
timerName: string;
|
|
45
|
+
payload?: Record<string, any>;
|
|
46
|
+
}): Promise<TimerResetResponse> {
|
|
47
|
+
return await mindedConnection.awaitEmit(mindedConnectionSocketMessageType.TIMER_RESET, {
|
|
48
|
+
sessionId,
|
|
49
|
+
seconds,
|
|
50
|
+
timerName,
|
|
51
|
+
eventArgs: payload,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Cancel an existing timer for a specific session.
|
|
57
|
+
*
|
|
58
|
+
* @param sessionId - The session ID the timer is associated with
|
|
59
|
+
* @param timerName - The name of the timer to cancel
|
|
60
|
+
* @returns Promise resolving to timer cancel response
|
|
61
|
+
* @throws {Error} When the Minded connection is not established
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* import { cancelTimer } from '@minded-ai/mindedjs';
|
|
66
|
+
*
|
|
67
|
+
* // Cancel a previously set timer
|
|
68
|
+
* await cancelTimer('session-123', 'followup');
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export async function cancelTimer(sessionId: string, timerName: string): Promise<TimerCancelResponse> {
|
|
72
|
+
if (!mindedConnection.isConnected()) {
|
|
73
|
+
throw new Error('Minded connection is not established when trying to cancel timer');
|
|
74
|
+
}
|
|
75
|
+
return await mindedConnection.awaitEmit(mindedConnectionSocketMessageType.TIMER_CANCEL, {
|
|
76
|
+
sessionId,
|
|
77
|
+
timerName,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Register a handler for timer trigger events for a specific timer name.
|
|
83
|
+
* The handler will be called when the specified timer expires for any session.
|
|
84
|
+
*
|
|
85
|
+
* @param params - The configuration for the timer handler
|
|
86
|
+
* @param params.timerName - The name of the timer to handle
|
|
87
|
+
* @param params.handler - Function to call when the timer triggers
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* import { onTimer } from '@minded-ai/mindedjs';
|
|
92
|
+
*
|
|
93
|
+
* // Register a handler for the 'followup' timer
|
|
94
|
+
* onTimer({
|
|
95
|
+
* timerName: 'followup',
|
|
96
|
+
* handler: async ({ sessionId, payload }) => {
|
|
97
|
+
* console.log(`Followup timer triggered for session ${sessionId}`);
|
|
98
|
+
*
|
|
99
|
+
* // Handle the followup timer
|
|
100
|
+
* await agent.invoke({
|
|
101
|
+
* triggerName: 'timerFollowup',
|
|
102
|
+
* triggerBody: { message: payload.message },
|
|
103
|
+
* sessionId
|
|
104
|
+
* });
|
|
105
|
+
* }
|
|
106
|
+
* });
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export function onTimer({
|
|
110
|
+
timerName,
|
|
111
|
+
handler
|
|
112
|
+
}: {
|
|
113
|
+
timerName: string;
|
|
114
|
+
handler: (params: { sessionId: string; payload: Record<string, any> }) => void | Promise<void>;
|
|
115
|
+
}): void {
|
|
116
|
+
// Initialize handlers array for this timer name if it doesn't exist
|
|
117
|
+
if (!timerHandlers.has(timerName)) {
|
|
118
|
+
timerHandlers.set(timerName, []);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Add the handler to the array for this timer name
|
|
122
|
+
const handlers = timerHandlers.get(timerName)!;
|
|
123
|
+
handlers.push({ handler });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
mindedConnection.on(mindedConnectionSocketMessageType.TIMER_TRIGGER, async (timerTriggerMessage) => {
|
|
127
|
+
// Get handlers for the specific timer name
|
|
128
|
+
const handlers = timerHandlers.get(timerTriggerMessage.timerName) || [];
|
|
129
|
+
|
|
130
|
+
// Call all handlers registered for this timer name
|
|
131
|
+
for (const { handler } of handlers) {
|
|
132
|
+
await handler({
|
|
133
|
+
sessionId: timerTriggerMessage.sessionId,
|
|
134
|
+
payload: timerTriggerMessage.eventArgs,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
});
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
CheckpointPendingWrite,
|
|
10
10
|
} from '@langchain/langgraph-checkpoint';
|
|
11
11
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
12
|
-
import
|
|
12
|
+
import * as mindedConnection from './mindedConnection';
|
|
13
13
|
import {
|
|
14
|
-
|
|
14
|
+
mindedConnectionSocketMessageType,
|
|
15
15
|
OnCheckpointGetTuple,
|
|
16
16
|
OnCheckpointGetTupleResponse,
|
|
17
17
|
OnCheckpointList,
|
|
@@ -23,15 +23,15 @@ import {
|
|
|
23
23
|
import { logger } from '../utils/logger';
|
|
24
24
|
|
|
25
25
|
export class MindedCheckpointSaver extends BaseCheckpointSaver<number> {
|
|
26
|
-
constructor(
|
|
26
|
+
constructor() {
|
|
27
27
|
super();
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
async getTuple(config: RunnableConfig<Record<string, any>>): Promise<CheckpointTuple | undefined> {
|
|
31
|
-
const response = await
|
|
32
|
-
|
|
31
|
+
const response = await mindedConnection.awaitEmit<OnCheckpointGetTuple, OnCheckpointGetTupleResponse>(
|
|
32
|
+
mindedConnectionSocketMessageType.CHECKPOINT_GET_TUPLE,
|
|
33
33
|
{
|
|
34
|
-
type:
|
|
34
|
+
type: mindedConnectionSocketMessageType.CHECKPOINT_GET_TUPLE,
|
|
35
35
|
config,
|
|
36
36
|
},
|
|
37
37
|
);
|
|
@@ -49,21 +49,21 @@ export class MindedCheckpointSaver extends BaseCheckpointSaver<number> {
|
|
|
49
49
|
// Re-serialize and deserialize metadata to restore class information
|
|
50
50
|
const metadata = tuple.metadata
|
|
51
51
|
? (() => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
const [metadataType, serializedMetadata] = this.serde.dumpsTyped(tuple.metadata);
|
|
53
|
+
return this.serde.loadsTyped(metadataType, serializedMetadata) as CheckpointMetadata;
|
|
54
|
+
})()
|
|
55
55
|
: undefined;
|
|
56
56
|
|
|
57
57
|
// Re-serialize and deserialize pending writes to restore class information
|
|
58
58
|
const pendingWrites: CheckpointPendingWrite[] = tuple.pendingWrites
|
|
59
59
|
? await Promise.all(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
tuple.pendingWrites.map(async (write) => {
|
|
61
|
+
const [taskId, channel, value] = write;
|
|
62
|
+
const [valueType, serializedValue] = this.serde.dumpsTyped(value);
|
|
63
|
+
const deserializedValue = await this.serde.loadsTyped(valueType, serializedValue);
|
|
64
|
+
return [taskId, channel, deserializedValue] as CheckpointPendingWrite;
|
|
65
|
+
}),
|
|
66
|
+
)
|
|
67
67
|
: [];
|
|
68
68
|
|
|
69
69
|
return {
|
|
@@ -76,10 +76,10 @@ export class MindedCheckpointSaver extends BaseCheckpointSaver<number> {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
async *list(config: RunnableConfig<Record<string, any>>, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple, any, any> {
|
|
79
|
-
const response = await
|
|
80
|
-
|
|
79
|
+
const response = await mindedConnection.awaitEmit<OnCheckpointList, OnCheckpointListResponse>(
|
|
80
|
+
mindedConnectionSocketMessageType.CHECKPOINT_LIST,
|
|
81
81
|
{
|
|
82
|
-
type:
|
|
82
|
+
type: mindedConnectionSocketMessageType.CHECKPOINT_LIST,
|
|
83
83
|
config,
|
|
84
84
|
options,
|
|
85
85
|
},
|
|
@@ -93,9 +93,9 @@ export class MindedCheckpointSaver extends BaseCheckpointSaver<number> {
|
|
|
93
93
|
// Re-serialize and deserialize metadata to restore class information
|
|
94
94
|
const metadata = tuple.metadata
|
|
95
95
|
? (() => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
const [metadataType, serializedMetadata] = this.serde.dumpsTyped(tuple.metadata);
|
|
97
|
+
return this.serde.loadsTyped(metadataType, serializedMetadata) as CheckpointMetadata;
|
|
98
|
+
})()
|
|
99
99
|
: undefined;
|
|
100
100
|
|
|
101
101
|
yield {
|
|
@@ -114,10 +114,10 @@ export class MindedCheckpointSaver extends BaseCheckpointSaver<number> {
|
|
|
114
114
|
newVersions: ChannelVersions,
|
|
115
115
|
): Promise<RunnableConfig<Record<string, any>>> {
|
|
116
116
|
try {
|
|
117
|
-
const response = await
|
|
118
|
-
|
|
117
|
+
const response = await mindedConnection.awaitEmit<OnCheckpointPut, OnCheckpointPutResponse>(
|
|
118
|
+
mindedConnectionSocketMessageType.CHECKPOINT_PUT,
|
|
119
119
|
{
|
|
120
|
-
type:
|
|
120
|
+
type: mindedConnectionSocketMessageType.CHECKPOINT_PUT,
|
|
121
121
|
config,
|
|
122
122
|
checkpoint,
|
|
123
123
|
metadata,
|
|
@@ -133,8 +133,8 @@ export class MindedCheckpointSaver extends BaseCheckpointSaver<number> {
|
|
|
133
133
|
|
|
134
134
|
async putWrites(config: RunnableConfig<Record<string, any>>, writes: PendingWrite[], taskId: string): Promise<void> {
|
|
135
135
|
try {
|
|
136
|
-
await
|
|
137
|
-
type:
|
|
136
|
+
await mindedConnection.awaitEmit<OnCheckpointPutWrites, any>(mindedConnectionSocketMessageType.CHECKPOINT_PUT_WRITES, {
|
|
137
|
+
type: mindedConnectionSocketMessageType.CHECKPOINT_PUT_WRITES,
|
|
138
138
|
config,
|
|
139
139
|
writes,
|
|
140
140
|
taskId,
|
|
@@ -1,170 +1,199 @@
|
|
|
1
1
|
import { io, Socket } from 'socket.io-client';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
MindedConnectionSocketMessageTypeMap,
|
|
3
|
+
mindedConnectionSocketMessageType,
|
|
4
|
+
mindedConnectionSocketMessageTypeMap,
|
|
6
5
|
} from './mindedConnectionTypes';
|
|
7
6
|
import { stringify } from 'flatted';
|
|
8
7
|
import { getConfig } from './config';
|
|
9
8
|
import { logger } from '../utils/logger';
|
|
9
|
+
import { wait } from '../utils/wait';
|
|
10
|
+
|
|
11
|
+
// Module-level singleton state
|
|
12
|
+
let socket: Socket | null = null;
|
|
13
|
+
const listeners: {
|
|
14
|
+
[key: string]: ((message: any, callback: (response: any) => void) => void)[];
|
|
15
|
+
} = {};
|
|
16
|
+
|
|
17
|
+
export const isConnected = (): boolean => {
|
|
18
|
+
return socket?.connected ?? false;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const on = <E extends keyof mindedConnectionSocketMessageTypeMap>(
|
|
22
|
+
event: E,
|
|
23
|
+
callback: (message: mindedConnectionSocketMessageTypeMap[E], callback: (response: any) => void) => void,
|
|
24
|
+
) => {
|
|
25
|
+
if (!listeners[event]) {
|
|
26
|
+
listeners[event] = [];
|
|
27
|
+
}
|
|
28
|
+
listeners[event].push(callback);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const emit = <E extends keyof mindedConnectionSocketMessageTypeMap>(
|
|
32
|
+
event: E,
|
|
33
|
+
message: mindedConnectionSocketMessageTypeMap[E]
|
|
34
|
+
) => {
|
|
35
|
+
if (socket) {
|
|
36
|
+
socket.emit(event, message);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const awaitEmit = async <T, R>(
|
|
41
|
+
event: mindedConnectionSocketMessageType,
|
|
42
|
+
message: T,
|
|
43
|
+
timeoutMs: number = 5000
|
|
44
|
+
): Promise<R> => {
|
|
45
|
+
if (!socket) {
|
|
46
|
+
throw new Error('Socket is not connected');
|
|
47
|
+
}
|
|
10
48
|
|
|
11
|
-
|
|
12
|
-
private socket: Socket | null = null;
|
|
13
|
-
listeners: {
|
|
14
|
-
[key: string]: ((message: BaseMindedConnectionSocketMessage, callback: (response: any) => void) => void)[];
|
|
15
|
-
} = {};
|
|
49
|
+
await waitForConnection();
|
|
16
50
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
// Set up timeout
|
|
53
|
+
const timeout = setTimeout(() => {
|
|
54
|
+
reject(new Error(`Acknowledgement timeout after ${timeoutMs}ms; event type: ${event}}`));
|
|
55
|
+
}, timeoutMs);
|
|
20
56
|
|
|
21
|
-
|
|
22
|
-
event:
|
|
23
|
-
|
|
24
|
-
) => {
|
|
25
|
-
if (!this.listeners[event]) {
|
|
26
|
-
this.listeners[event] = [];
|
|
27
|
-
}
|
|
28
|
-
this.listeners[event].push(callback);
|
|
29
|
-
};
|
|
57
|
+
// Emit with acknowledgement callback
|
|
58
|
+
socket!.emit(event, stringify(message), (response: any) => {
|
|
59
|
+
clearTimeout(timeout);
|
|
30
60
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
61
|
+
// Check if the response indicates an error
|
|
62
|
+
if (response && response.error) {
|
|
63
|
+
reject(new Error(response.error));
|
|
64
|
+
} else {
|
|
65
|
+
resolve(response);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const waitForConnection = async (): Promise<void> => {
|
|
72
|
+
const timeout = 10000;
|
|
73
|
+
const interval = 100;
|
|
74
|
+
let cnt = 0;
|
|
75
|
+
while (!isConnected()) {
|
|
76
|
+
await wait(interval);
|
|
77
|
+
cnt += interval;
|
|
78
|
+
if (cnt > timeout) {
|
|
79
|
+
throw new Error('Minded connection timeout');
|
|
34
80
|
}
|
|
35
|
-
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const connect = async (token: string): Promise<void> => {
|
|
85
|
+
const { isDeployed, baseUrl } = getConfig();
|
|
86
|
+
return new Promise<void>((resolve, reject) => {
|
|
87
|
+
socket = io(baseUrl, {
|
|
88
|
+
path: '/minded-connect',
|
|
89
|
+
query: {
|
|
90
|
+
isDeployedAgent: isDeployed,
|
|
91
|
+
token,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
36
94
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
95
|
+
let connected = false;
|
|
96
|
+
let ready = false;
|
|
97
|
+
|
|
98
|
+
const checkReady = () => {
|
|
99
|
+
if (connected && ready) {
|
|
100
|
+
logger.info('\x1b[32mConnection with Minded platform is ready!\x1b[0m');
|
|
101
|
+
logger.info('\x1b[32mPress Ctrl+C to exit...');
|
|
102
|
+
resolve();
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Connection event handlers
|
|
107
|
+
socket.on('connect', () => {
|
|
108
|
+
logger.info('Socket connected, waiting for server setup...');
|
|
109
|
+
connected = true;
|
|
110
|
+
checkReady();
|
|
111
|
+
});
|
|
41
112
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
// Check if the response indicates an error
|
|
53
|
-
if (response && response.error) {
|
|
54
|
-
reject(new Error(response.error));
|
|
55
|
-
} else {
|
|
56
|
-
resolve(response);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
113
|
+
// Listen for ready event from server
|
|
114
|
+
socket.on('sdk-socket-ready', (data: { agentId: string; orgName: string }) => {
|
|
115
|
+
logger.info('Server ready signal received', data);
|
|
116
|
+
ready = true;
|
|
117
|
+
checkReady();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
socket.on('connect_error', () => {
|
|
121
|
+
logger.error('Failed to connect to minded platform');
|
|
122
|
+
reject(new Error('Failed to connect to minded platform'));
|
|
59
123
|
});
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
private async connect(token: string) {
|
|
63
|
-
const { isDeployed, baseUrl } = getConfig();
|
|
64
|
-
return new Promise<void>((resolve, reject) => {
|
|
65
|
-
this.socket = io(baseUrl, {
|
|
66
|
-
path: '/minded-connect',
|
|
67
|
-
query: {
|
|
68
|
-
isDeployedAgent: isDeployed,
|
|
69
|
-
token,
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
let connected = false;
|
|
74
|
-
let ready = false;
|
|
75
|
-
|
|
76
|
-
const checkReady = () => {
|
|
77
|
-
if (connected && ready) {
|
|
78
|
-
logger.info('\x1b[32mConnection with Minded platform is ready!\x1b[0m');
|
|
79
|
-
logger.info('\x1b[32mPress Ctrl+C to exit...');
|
|
80
|
-
resolve();
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// Connection event handlers
|
|
85
|
-
this.socket.on('connect', () => {
|
|
86
|
-
logger.info('Socket connected, waiting for server setup...');
|
|
87
|
-
connected = true;
|
|
88
|
-
checkReady();
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// Listen for ready event from server
|
|
92
|
-
this.socket.on('sdk-socket-ready', (data: { agentId: string; orgName: string }) => {
|
|
93
|
-
logger.info('Server ready signal received', data);
|
|
94
|
-
ready = true;
|
|
95
|
-
checkReady();
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
this.socket.on('connect_error', () => {
|
|
99
|
-
logger.error('Failed to connect to minded platform');
|
|
100
|
-
reject(new Error('Failed to connect to minded platform'));
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
this.socket.on('disconnect', () => {
|
|
104
|
-
logger.info('Disconnected from local debugging socket');
|
|
105
|
-
connected = false;
|
|
106
|
-
ready = false;
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Listen for error messages from the server
|
|
110
|
-
this.socket.on('error', async (error: { message: string }) => {
|
|
111
|
-
logger.error({ msg: 'Server error:', error });
|
|
112
|
-
|
|
113
|
-
if (error.message.includes('Invalid token')) {
|
|
114
|
-
logger.info('Invalid token');
|
|
115
|
-
|
|
116
|
-
// Disconnect current socket
|
|
117
|
-
if (this.socket?.connected) {
|
|
118
|
-
this.socket.disconnect();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Get new token and reconnect
|
|
122
|
-
await this.connect(token);
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// Listen for specific message types
|
|
127
|
-
this.socket.onAny((event, message, callback) => {
|
|
128
|
-
if (this.listeners[event]) {
|
|
129
|
-
this.listeners[event].forEach((listener) => {
|
|
130
|
-
listener(message, callback);
|
|
131
|
-
});
|
|
132
|
-
} else {
|
|
133
|
-
console.warn({ message: 'No listeners found for event', event });
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
124
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
125
|
+
socket.on('disconnect', () => {
|
|
126
|
+
logger.info('Disconnected from local debugging socket');
|
|
127
|
+
connected = false;
|
|
128
|
+
ready = false;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Listen for error messages from the server
|
|
132
|
+
socket.on('error', async (error: { message: string }) => {
|
|
133
|
+
logger.error({ msg: 'Server error:', error });
|
|
134
|
+
|
|
135
|
+
if (error.message.includes('Invalid token')) {
|
|
136
|
+
logger.info('Invalid token');
|
|
137
|
+
|
|
138
|
+
// Disconnect current socket
|
|
139
|
+
if (socket?.connected) {
|
|
140
|
+
socket.disconnect();
|
|
142
141
|
}
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
|
|
143
|
+
// Get new token and reconnect
|
|
144
|
+
await connect(token);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Listen for specific message types
|
|
149
|
+
socket.onAny((event, message, callback) => {
|
|
150
|
+
if (listeners[event]) {
|
|
151
|
+
listeners[event].forEach((listener) => {
|
|
152
|
+
listener(message, callback);
|
|
153
|
+
});
|
|
154
|
+
} else {
|
|
155
|
+
console.warn({ message: 'No listeners found for event', event });
|
|
156
|
+
}
|
|
145
157
|
});
|
|
158
|
+
|
|
159
|
+
// Handle process termination
|
|
160
|
+
process.on('SIGINT', () => {
|
|
161
|
+
if (socket?.connected) {
|
|
162
|
+
logger.info('\nDisconnecting...');
|
|
163
|
+
socket.disconnect();
|
|
164
|
+
}
|
|
165
|
+
process.exit(0);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export const start = async (): Promise<void> => {
|
|
171
|
+
const { token } = getConfig();
|
|
172
|
+
if (!token) {
|
|
173
|
+
throw new Error('Minded token not found');
|
|
146
174
|
}
|
|
175
|
+
await connect(token);
|
|
176
|
+
};
|
|
147
177
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
await this.connect(token);
|
|
178
|
+
export const disconnect = () => {
|
|
179
|
+
if (!socket) {
|
|
180
|
+
logger.warn('No socket connection to disconnect');
|
|
181
|
+
return;
|
|
154
182
|
}
|
|
155
183
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
184
|
+
if (socket.connected) {
|
|
185
|
+
logger.info('Disconnecting from Minded platform...');
|
|
186
|
+
socket.disconnect();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
161
189
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
this.socket.disconnect();
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
190
|
+
logger.warn('Socket is already disconnected');
|
|
191
|
+
};
|
|
167
192
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
193
|
+
export const mindedConnection = {
|
|
194
|
+
isConnected,
|
|
195
|
+
on,
|
|
196
|
+
emit,
|
|
197
|
+
awaitEmit,
|
|
198
|
+
start,
|
|
199
|
+
};
|