@eka-care/medassist-core 1.0.69 → 1.0.71

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.
Files changed (138) hide show
  1. package/dist/Synapse.d.ts +0 -1
  2. package/dist/connection/ConnectionFactory.d.ts +0 -1
  3. package/dist/connection/SSE.d.ts +0 -1
  4. package/dist/connection/Websocket.d.ts +0 -1
  5. package/dist/constants/index.d.ts +0 -1
  6. package/dist/constants/types.d.ts +0 -1
  7. package/dist/conversation.d.ts +0 -1
  8. package/dist/events/Events.d.ts +0 -1
  9. package/dist/events/Incoming.d.ts +0 -1
  10. package/dist/events/Outgoing.d.ts +0 -1
  11. package/dist/events/index.d.ts +0 -1
  12. package/dist/events/types.d.ts +0 -1
  13. package/dist/index.d.mts +1442 -0
  14. package/dist/index.d.ts +0 -1
  15. package/dist/index.mjs +2 -0
  16. package/dist/internal/Api/BaseResource.d.ts +0 -1
  17. package/dist/internal/Api/HttpClient.d.ts +0 -1
  18. package/dist/internal/Api/types.d.ts +0 -1
  19. package/dist/internal/Error/Error.d.ts +0 -1
  20. package/dist/internal/Error/types.d.ts +0 -1
  21. package/dist/internal/connection/BaseConnection.d.ts +0 -1
  22. package/dist/internal/connection/types.d.ts +0 -1
  23. package/dist/internal/events/EventEmitter.d.ts +0 -1
  24. package/dist/internal/store/index.d.ts +0 -1
  25. package/dist/media/audio/Audio.copy.d.ts +0 -1
  26. package/dist/media/audio/Audio.d.ts +0 -1
  27. package/dist/media/audio/types.d.ts +0 -1
  28. package/dist/media/file/File.d.ts +0 -1
  29. package/dist/messages/MessageManager.d.ts +0 -1
  30. package/dist/messages/types.d.ts +1 -1
  31. package/dist/resources/config/Config.d.ts +0 -1
  32. package/dist/resources/feedback/Feedback.d.ts +0 -1
  33. package/dist/resources/feedback/types.d.ts +0 -1
  34. package/dist/resources/index.d.ts +0 -1
  35. package/dist/resources/session/Session.d.ts +0 -1
  36. package/dist/resources/session/types.d.ts +0 -1
  37. package/dist/resources/toolCall/ToolCall.d.ts +0 -1
  38. package/dist/resources/toolCall/types.d.ts +0 -1
  39. package/dist/resources/types.d.ts +0 -1
  40. package/dist/resources/voice/VoiceResource.d.ts +0 -1
  41. package/dist/resources/voice/types.d.ts +0 -1
  42. package/dist/types/index.d.ts +0 -1
  43. package/dist/utils/Error.d.ts +0 -1
  44. package/dist/voice/VoiceAgent.d.ts +0 -1
  45. package/dist/voice/VoiceAudioAnalyser.d.ts +0 -1
  46. package/dist/voice/index.d.ts +0 -1
  47. package/dist/voice/types.d.ts +0 -1
  48. package/package.json +1 -1
  49. package/dist/Synapse.d.ts.map +0 -1
  50. package/dist/connection/ConnectionFactory.d.ts.map +0 -1
  51. package/dist/connection/SSE.d.ts.map +0 -1
  52. package/dist/connection/Websocket.d.ts.map +0 -1
  53. package/dist/constants/index.d.ts.map +0 -1
  54. package/dist/constants/types.d.ts.map +0 -1
  55. package/dist/conversation.d.ts.map +0 -1
  56. package/dist/esm/Synapse.js +0 -612
  57. package/dist/esm/connection/ConnectionFactory.js +0 -27
  58. package/dist/esm/connection/SSE.js +0 -212
  59. package/dist/esm/connection/Websocket.js +0 -178
  60. package/dist/esm/constants/index.js +0 -25
  61. package/dist/esm/constants/types.js +0 -1
  62. package/dist/esm/conversation.js +0 -7
  63. package/dist/esm/events/Events.js +0 -41
  64. package/dist/esm/events/Incoming.js +0 -1
  65. package/dist/esm/events/Outgoing.js +0 -1
  66. package/dist/esm/events/index.js +0 -2
  67. package/dist/esm/events/types.js +0 -5
  68. package/dist/esm/index.js +0 -34
  69. package/dist/esm/internal/Api/BaseResource.js +0 -50
  70. package/dist/esm/internal/Api/HttpClient.js +0 -131
  71. package/dist/esm/internal/Api/types.js +0 -1
  72. package/dist/esm/internal/Error/Error.js +0 -229
  73. package/dist/esm/internal/Error/types.js +0 -9
  74. package/dist/esm/internal/connection/BaseConnection.js +0 -134
  75. package/dist/esm/internal/connection/types.js +0 -17
  76. package/dist/esm/internal/events/EventEmitter.js +0 -26
  77. package/dist/esm/internal/store/index.js +0 -5
  78. package/dist/esm/media/audio/Audio.copy.js +0 -363
  79. package/dist/esm/media/audio/Audio.js +0 -310
  80. package/dist/esm/media/audio/types.js +0 -13
  81. package/dist/esm/media/file/File.js +0 -159
  82. package/dist/esm/messages/MessageManager.js +0 -476
  83. package/dist/esm/messages/types.js +0 -35
  84. package/dist/esm/resources/config/Config.js +0 -11
  85. package/dist/esm/resources/feedback/Feedback.js +0 -9
  86. package/dist/esm/resources/feedback/types.js +0 -7
  87. package/dist/esm/resources/index.js +0 -152
  88. package/dist/esm/resources/session/Session.js +0 -44
  89. package/dist/esm/resources/session/types.js +0 -5
  90. package/dist/esm/resources/toolCall/ToolCall.js +0 -12
  91. package/dist/esm/resources/toolCall/types.js +0 -34
  92. package/dist/esm/resources/types.js +0 -4
  93. package/dist/esm/resources/voice/VoiceResource.js +0 -14
  94. package/dist/esm/resources/voice/types.js +0 -1
  95. package/dist/esm/types/index.js +0 -8
  96. package/dist/esm/utils/Error.js +0 -110
  97. package/dist/esm/voice/VoiceAgent.js +0 -305
  98. package/dist/esm/voice/VoiceAudioAnalyser.js +0 -32
  99. package/dist/esm/voice/index.js +0 -1
  100. package/dist/esm/voice/types.js +0 -15
  101. package/dist/events/Events.d.ts.map +0 -1
  102. package/dist/events/Incoming.d.ts.map +0 -1
  103. package/dist/events/Outgoing.d.ts.map +0 -1
  104. package/dist/events/index.d.ts.map +0 -1
  105. package/dist/events/types.d.ts.map +0 -1
  106. package/dist/index.d.ts.map +0 -1
  107. package/dist/internal/Api/BaseResource.d.ts.map +0 -1
  108. package/dist/internal/Api/HttpClient.d.ts.map +0 -1
  109. package/dist/internal/Api/types.d.ts.map +0 -1
  110. package/dist/internal/Error/Error.d.ts.map +0 -1
  111. package/dist/internal/Error/types.d.ts.map +0 -1
  112. package/dist/internal/connection/BaseConnection.d.ts.map +0 -1
  113. package/dist/internal/connection/types.d.ts.map +0 -1
  114. package/dist/internal/events/EventEmitter.d.ts.map +0 -1
  115. package/dist/internal/store/index.d.ts.map +0 -1
  116. package/dist/media/audio/Audio.copy.d.ts.map +0 -1
  117. package/dist/media/audio/Audio.d.ts.map +0 -1
  118. package/dist/media/audio/types.d.ts.map +0 -1
  119. package/dist/media/file/File.d.ts.map +0 -1
  120. package/dist/messages/MessageManager.d.ts.map +0 -1
  121. package/dist/messages/types.d.ts.map +0 -1
  122. package/dist/resources/config/Config.d.ts.map +0 -1
  123. package/dist/resources/feedback/Feedback.d.ts.map +0 -1
  124. package/dist/resources/feedback/types.d.ts.map +0 -1
  125. package/dist/resources/index.d.ts.map +0 -1
  126. package/dist/resources/session/Session.d.ts.map +0 -1
  127. package/dist/resources/session/types.d.ts.map +0 -1
  128. package/dist/resources/toolCall/ToolCall.d.ts.map +0 -1
  129. package/dist/resources/toolCall/types.d.ts.map +0 -1
  130. package/dist/resources/types.d.ts.map +0 -1
  131. package/dist/resources/voice/VoiceResource.d.ts.map +0 -1
  132. package/dist/resources/voice/types.d.ts.map +0 -1
  133. package/dist/types/index.d.ts.map +0 -1
  134. package/dist/utils/Error.d.ts.map +0 -1
  135. package/dist/voice/VoiceAgent.d.ts.map +0 -1
  136. package/dist/voice/VoiceAudioAnalyser.d.ts.map +0 -1
  137. package/dist/voice/index.d.ts.map +0 -1
  138. package/dist/voice/types.d.ts.map +0 -1
@@ -1,159 +0,0 @@
1
- /**
2
- * Class to store file states
3
- * Helpers: Zipping, uploading to presigned url, etc.
4
- */
5
- import { FileError, normalizeError } from "../../internal/Error/Error";
6
- export const MAX_FILE_SIZE = 3 * 1024 * 1024; // 3MB
7
- export class Filemanager {
8
- pendingFiles = [];
9
- pendingMessage = "";
10
- pendingFormats = [];
11
- /**
12
- * Set the files for upload
13
- */
14
- setFilesForUpload(files, message) {
15
- if (this.pendingFiles.length > 0) {
16
- this.clearPendingFilesState();
17
- }
18
- const validFiles = files.filter((file) => this.validateFile(file));
19
- if (validFiles.length === 0) {
20
- throw new FileError("File not supported", {
21
- context: { stage: "setFilesForUpload" },
22
- });
23
- }
24
- this.pendingFiles = validFiles;
25
- if (message && message.trim()) {
26
- this.pendingMessage = message;
27
- }
28
- this.pendingFormats = validFiles.map(file => file.type);
29
- }
30
- /**
31
- * Get the pending file state
32
- */
33
- getPendingFileState() {
34
- return {
35
- files: this.pendingFiles,
36
- message: this.pendingMessage || "",
37
- formats: this.pendingFormats || [],
38
- };
39
- }
40
- /**
41
- * Upload files to presigned URLs
42
- */
43
- async uploadFilesToPresignedUrl(presignedUrls) {
44
- let successIds = [];
45
- // Filter out invalid URLs
46
- const validUrls = presignedUrls.filter((url) => url.url && url.url.trim());
47
- try {
48
- if (validUrls.length === 0) {
49
- throw new FileError("No valid presigned URLs provided", {
50
- context: { stage: "uploadFilesToPresignedUrl" },
51
- });
52
- }
53
- if (!this.pendingFiles.length) {
54
- throw new FileError("No files to upload", {
55
- context: { stage: "uploadFilesToPresignedUrl" },
56
- });
57
- }
58
- for (let i = 0; i < validUrls.length; i++) {
59
- const url = validUrls[i].url;
60
- const response = await fetch(url, {
61
- method: "PUT",
62
- body: this.pendingFiles[i],
63
- headers: {
64
- "Content-Type": this.pendingFiles[i].type,
65
- "x-ms-blob-type": "BlockBlob",
66
- },
67
- });
68
- if (!response.ok) {
69
- throw new FileError(`Failed to upload ${this.pendingFiles[i].name} to URL ${i + 1}: ${response.status} ${response.statusText}`, {
70
- context: { stage: "uploadFilesToPresignedUrl" },
71
- });
72
- }
73
- successIds.push(validUrls[i].id);
74
- }
75
- // Call sendFileUploadComplete only once with the first presigned URL
76
- // this.sendFileUploadComplete(validUrls[0]);
77
- return successIds;
78
- }
79
- catch (error) {
80
- if (successIds.length > 0) {
81
- // this.sendFileUploadComplete(validUrls[0]);
82
- return successIds;
83
- }
84
- throw normalizeError(error, FileError, "Failed to upload files to presigned URL", { context: { stage: "uploadFilesToPresignedUrl" } });
85
- }
86
- }
87
- // /**
88
- // * Zips multiple files into a single zip file
89
- // * @param files Array of files to zip
90
- // * @param zipFileName Name for the zip file (without extension)
91
- // * @returns Promise<Blob> - The zipped file as a blob
92
- // */
93
- // public async zipFiles(): Promise<Blob> {
94
- // const zip = new JSZip();
95
- // // Add each file to the zip
96
- // this.pendingFiles.forEach((file) => {
97
- // zip.file(file.name, file);
98
- // });
99
- // // Generate the zip file as a blob
100
- // const zipBlob = await zip.generateAsync({ type: "blob" });
101
- // return zipBlob;
102
- // }
103
- /**
104
- * Creates a File object from a blob with a specific name
105
- * @param blob The blob to convert
106
- * @param fileName The name for the file
107
- * @returns File object
108
- */
109
- blobToFile(blob, fileName) {
110
- return new File([blob], fileName, { type: blob.type });
111
- }
112
- // /**
113
- // * Checks if multiple files should be zipped
114
- // * @param files Array of files
115
- // * @returns boolean - true if files should be zipped
116
- // */
117
- // public shouldZipFiles(): boolean {
118
- // return this.pendingFiles.length > 1;
119
- // }
120
- // /**
121
- // * Gets the appropriate file name for upload (either zip or single file)
122
- // * @param files Array of files
123
- // * @returns string - the file name to use for upload
124
- // */
125
- // public getUploadFileName(): string {
126
- // if (this.shouldZipFiles()) {
127
- // return `uploaded_files_${Date.now()}.zip`;
128
- // }
129
- // return this.pendingFiles[0]?.name || "file";
130
- // }
131
- /**
132
- * Validate file types
133
- * @param file The file to validate
134
- * @returns boolean - true if file type is supported
135
- */
136
- validateFile(file) {
137
- const validFormats = [
138
- "application/pdf",
139
- "image/jpeg",
140
- "image/png",
141
- "image/jpg",
142
- // "image/tiff",
143
- // "text/plain",
144
- // "text/markdown",
145
- // "image/heif",
146
- // "image/heic",
147
- // "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
148
- ];
149
- return validFormats.includes(file.type) && file.size < MAX_FILE_SIZE;
150
- }
151
- /**
152
- * Clears the pending files
153
- */
154
- clearPendingFilesState() {
155
- this.pendingFiles = [];
156
- this.pendingMessage = "";
157
- this.pendingFormats = [];
158
- }
159
- }
@@ -1,476 +0,0 @@
1
- import { SOCKET_CONTENT_TYPES, SOCKET_EVENTS, } from "../events/Events";
2
- import { Filemanager } from "../media/file/File";
3
- import { SYNAPSE_REALTIME_ERROR_CODES, SYNAPSE_REALTIME_EVENTS, SYNAPSE_REALTIME_RESERVED_EVENTS, } from "./types";
4
- import { AudioManager } from "../media/audio/Audio";
5
- import { ConnectionError, FileError, MessageError, RecordingError, normalizeError, } from "../internal/Error/Error";
6
- export class MessageManager {
7
- connection = null;
8
- callbacks = null;
9
- fileManager = null;
10
- audioManager = null;
11
- outgoingBuffer = null;
12
- constructor(callbacks) {
13
- this.callbacks = callbacks || null;
14
- }
15
- setConnection(connection) {
16
- this.connection = connection;
17
- }
18
- /**
19
- * Handle file upload process
20
- */
21
- handleFileUploadProcess({ files, message, urls, tool_declined, tool_result }) {
22
- if (!this.fileManager) {
23
- this.fileManager = new Filemanager();
24
- }
25
- let fileUploadMessage;
26
- if (files && files.length > 0) {
27
- //stage 1. of file upload process
28
- //--store files temproary in memory
29
- this.fileManager.setFilesForUpload(files, message);
30
- fileUploadMessage = {
31
- ev: SOCKET_EVENTS.CHAT,
32
- ct: SOCKET_CONTENT_TYPES.FILE,
33
- _id: Date.now().toString(),
34
- ts: Date.now(),
35
- data: {
36
- extensions: this.fileManager.getPendingFileState().formats,
37
- ...(tool_declined && { tool_declined }),
38
- ...(tool_result && { tool_result })
39
- },
40
- };
41
- }
42
- else if (urls && urls.length > 0) {
43
- //--stage 3. of file upload process
44
- //--only requirement is url
45
- //--send file upload acknowledgement to client
46
- const text = this.fileManager.getPendingFileState().message;
47
- fileUploadMessage = {
48
- ev: SOCKET_EVENTS.CHAT,
49
- ct: SOCKET_CONTENT_TYPES.FILE,
50
- _id: Date.now().toString(),
51
- ts: Date.now(),
52
- data: {
53
- urls: urls,
54
- ...(text && { text }),
55
- ...(tool_declined && { tool_declined }),
56
- ...(tool_result && { tool_result })
57
- },
58
- };
59
- this.fileManager?.clearPendingFilesState();
60
- }
61
- return fileUploadMessage;
62
- }
63
- /**
64
- * send chat message through socket
65
- */
66
- sendSocketMessage({ message, files, audio, urls, tool_declined, tool_id, tool_result, initial_prompts }) {
67
- if (!this.connection?.isConnected()) {
68
- this.outgoingBuffer = {
69
- ...(message !== undefined && { message }),
70
- ...(files && { files }),
71
- ...(audio && { audio }),
72
- ...(urls && { urls }),
73
- ...(tool_declined && { tool_declined }),
74
- ...(tool_id && { tool_id }),
75
- ...(tool_result && { tool_result }),
76
- ...(initial_prompts && { initial_prompts }),
77
- };
78
- return;
79
- }
80
- const connection = this.connection;
81
- let outMessage;
82
- if ((files && files.length > 0) || (urls && urls.length > 0)) {
83
- if (files && files.length > 3) {
84
- const error = new MessageError("Maximum 3 files are allowed to be sent at a time", {
85
- context: { stage: "sendSocketChatMessage" },
86
- });
87
- this.emitError(error);
88
- throw error;
89
- }
90
- outMessage = this.handleFileUploadProcess({
91
- files,
92
- message,
93
- urls,
94
- tool_declined,
95
- tool_result
96
- });
97
- }
98
- else if (message) {
99
- outMessage = {
100
- ev: SOCKET_EVENTS.CHAT,
101
- ct: SOCKET_CONTENT_TYPES.TEXT,
102
- _id: Date.now().toString(),
103
- ts: Date.now(),
104
- data: {
105
- text: message,
106
- ...(tool_declined && { tool_declined }),
107
- ...(tool_id && { tool_id }),
108
- ...(initial_prompts && { initial_prompts }),
109
- ...(tool_result && { tool_result })
110
- },
111
- };
112
- }
113
- else if (audio && audio?.audio && audio?.format) {
114
- outMessage = {
115
- ev: SOCKET_EVENTS.CHAT,
116
- ct: SOCKET_CONTENT_TYPES.AUDIO,
117
- _id: Date.now().toString(),
118
- ts: Date.now(),
119
- data: {
120
- audio: audio?.audio,
121
- format: audio?.format,
122
- ...(tool_declined && { tool_declined }),
123
- ...(tool_result && { tool_result })
124
- },
125
- };
126
- }
127
- else if (tool_result) {
128
- outMessage = {
129
- ev: SOCKET_EVENTS.CHAT,
130
- ct: SOCKET_CONTENT_TYPES.TEXT,
131
- _id: Date.now().toString(),
132
- ts: Date.now(),
133
- data: {
134
- text: "",
135
- tool_result,
136
- }
137
- };
138
- }
139
- if (!outMessage) {
140
- const error = new MessageError("No message to send", {
141
- context: { stage: "sendSocketChatMessage" },
142
- });
143
- this.emitError(error);
144
- throw error;
145
- }
146
- connection.sendMessage(outMessage);
147
- }
148
- /**
149
- * Handle incoming chat message
150
- */
151
- handleIncomingSocketChatMessage(message) {
152
- const connection = this.assertConnection("handleIncomingSocketChatMessage");
153
- switch (message.ct) {
154
- case SOCKET_CONTENT_TYPES.FILE: {
155
- if (message?.data?.urls && message.data.urls?.length > 0) {
156
- //stage 2. of file upload process
157
- this.fileManager
158
- ?.uploadFilesToPresignedUrl(message.data.urls)
159
- .then((validUrls) => {
160
- this.sendSocketMessage({
161
- urls: validUrls,
162
- });
163
- })
164
- .catch((error) => {
165
- const fileError = this.toFileError(error, "Failed to upload files to presigned URL", {
166
- stage: "handleIncomingSocketChatMessage",
167
- urls: message.data?.urls?.length,
168
- });
169
- this.emitError(fileError);
170
- });
171
- }
172
- break;
173
- }
174
- case SOCKET_CONTENT_TYPES.TEXT:
175
- if (message.data.text &&
176
- message.data.text.trim() === "" &&
177
- message._id) {
178
- const messageData = {
179
- data: { text: message.data.text },
180
- // type: message.ct,
181
- messageId: message._id,
182
- timestamp: message.ts,
183
- };
184
- connection.emit(SYNAPSE_REALTIME_EVENTS.MESSAGE_CHUNK, messageData);
185
- }
186
- break;
187
- case SOCKET_CONTENT_TYPES.TOOL_CALL:
188
- if (message?.data?.tool_id && message._id) {
189
- const chatMessageData = {
190
- data: { ...message.data },
191
- // type: message.ct,
192
- messageId: message._id,
193
- timestamp: message.ts,
194
- };
195
- connection.emit(SYNAPSE_REALTIME_EVENTS.TOOL_CALL, chatMessageData);
196
- // this.callbacks?.onElicitationTool?.(chatMessageData, message._id);
197
- }
198
- break;
199
- case SOCKET_CONTENT_TYPES.AUDIO_TRANSCRIPT:
200
- if (message?.data?.text) {
201
- const messageData = {
202
- data: { text: message.data.text },
203
- // type: message.ct,
204
- messageId: message._id,
205
- timestamp: message.ts,
206
- };
207
- connection.emit(SYNAPSE_REALTIME_EVENTS.AUDIO_TRANSCRIPT, messageData);
208
- // this.callbacks?.onChatmessage?.(message.data.text, message.ct);
209
- }
210
- break;
211
- default:
212
- // const error = new MessageError("Unsupported content type", {
213
- // context: {
214
- // stage: "handleIncomingSocketChatMessage",
215
- // contentType: message.ct,
216
- // },
217
- // });
218
- // this.emitError(error);
219
- // throw error;
220
- }
221
- }
222
- /**
223
- * Handle incoming stream message
224
- */
225
- handleIncomingSocketStreamMessage(message) {
226
- const connection = this.assertConnection("handleIncomingSocketStreamMessage");
227
- switch (message.ct) {
228
- case SOCKET_CONTENT_TYPES.TEXT:
229
- if (message?.data?.progress_msg) {
230
- const messageData = {
231
- data: { text: message.data.progress_msg },
232
- // type: message.ct,
233
- messageId: message._id,
234
- timestamp: message.ts,
235
- };
236
- connection.emit(SYNAPSE_REALTIME_EVENTS.PROGRESS_MESSAGE, messageData);
237
- return;
238
- }
239
- if (message?.data?.text) {
240
- const messageData = {
241
- data: { text: message.data.text },
242
- // type: message.ct,
243
- messageId: message._id,
244
- timestamp: message.ts,
245
- };
246
- //the ui layer will handle the aggregation logic for stream messages
247
- connection.emit(SYNAPSE_REALTIME_EVENTS.MESSAGE_CHUNK, messageData);
248
- }
249
- break;
250
- case SOCKET_CONTENT_TYPES.TIPS:
251
- if (message?.data?.tips) {
252
- const messageData = {
253
- data: { tips: message.data.tips },
254
- // type: message.ct,
255
- messageId: message._id,
256
- timestamp: message.ts,
257
- };
258
- connection.emit(SYNAPSE_REALTIME_EVENTS.TIPS_MESSAGE, messageData);
259
- return;
260
- }
261
- break;
262
- case SOCKET_CONTENT_TYPES.TOOL_CALL:
263
- if (message?.data?.tool_id && message._id) {
264
- const streamMessageData = {
265
- data: { ...message.data },
266
- // type: message.ct,
267
- messageId: message._id,
268
- timestamp: message.ts,
269
- };
270
- connection.emit(SYNAPSE_REALTIME_EVENTS.TOOL_CALL, streamMessageData);
271
- // this.callbacks?.onElicitationTool?.(chatMessageData, message._id);
272
- return;
273
- }
274
- break;
275
- case SOCKET_CONTENT_TYPES.TOOL_START:
276
- const toolStartMessage = {
277
- data: message?.data,
278
- messageId: message._id || Date.now().toString(),
279
- };
280
- connection.emit(SYNAPSE_REALTIME_EVENTS.TOOL_START, toolStartMessage);
281
- break;
282
- case SOCKET_CONTENT_TYPES.TOOL_END:
283
- const toolEndMessage = {
284
- data: message?.data,
285
- messageId: message._id || Date.now().toString(),
286
- };
287
- connection.emit(SYNAPSE_REALTIME_EVENTS.TOOL_END, toolEndMessage);
288
- break;
289
- default:
290
- const error = new MessageError(`Unsupported content type ${message?.ct}`, {
291
- context: {
292
- stage: "handleIncomingSocketStreamMessage",
293
- contentType: message.ct,
294
- },
295
- });
296
- this.emitError(error);
297
- throw error;
298
- }
299
- }
300
- handleDisconnect(details) {
301
- this.connection?.emit?.(SYNAPSE_REALTIME_EVENTS.DISCONNECTED, details);
302
- }
303
- /**
304
- * Handle incoming end of stream message
305
- */
306
- handleIncomingSocketEndOfStreamMessage(_message) {
307
- const connection = this.assertConnection("handleIncomingSocketEndOfStreamMessage");
308
- connection.emit(SYNAPSE_REALTIME_EVENTS.END_OF_STREAM);
309
- }
310
- /**
311
- * Handle incoming error message
312
- */
313
- handleIncomingSocketErrorMessage(message) {
314
- const connection = this.assertConnection("handleIncomingSocketErrorMessage");
315
- switch (message?.data?.code) {
316
- case SYNAPSE_REALTIME_ERROR_CODES.SESSION_EXPIRED:
317
- connection.emit(SYNAPSE_REALTIME_RESERVED_EVENTS.SESSION_EXPIRED);
318
- break;
319
- default:
320
- const error = new MessageError(message?.data?.msg || "Socket error received", {
321
- context: {
322
- stage: "handleIncomingSocketErrorMessage",
323
- errorCode: message?.data?.code,
324
- },
325
- hint: message?.data?.msg,
326
- cause: message,
327
- displayMessage: message?.data?.msg,
328
- });
329
- console.log("error from socket", error);
330
- connection.emit(SYNAPSE_REALTIME_EVENTS.ERROR, message);
331
- // this.emitError(error);
332
- }
333
- }
334
- /**
335
- * send authentication message
336
- */
337
- sendSocketAuthMessage(sessionToken) {
338
- const connection = this.assertConnection("sendSocketAuthMessage");
339
- const authMessage = {
340
- ev: SOCKET_EVENTS.AUTH,
341
- _id: Date.now().toString(),
342
- ts: Date.now(),
343
- data: { token: sessionToken },
344
- };
345
- connection.sendMessage(authMessage);
346
- }
347
- /**
348
- * send ping message
349
- */
350
- sendSocketPingMessage() {
351
- const connection = this.assertConnection("sendSocketPingMessage");
352
- const pingMessage = {
353
- ev: SOCKET_EVENTS.PING,
354
- _id: Date.now().toString(),
355
- ts: Date.now(),
356
- };
357
- connection.sendMessage(pingMessage);
358
- }
359
- /**
360
- * send audio message
361
- */
362
- async startRecording({ onChunks, onError, }) {
363
- if (!onChunks) {
364
- const error = new RecordingError("onChunks is required", {
365
- context: { stage: "startRecording" },
366
- hint: "onChunks is required",
367
- });
368
- this.emitError(error);
369
- throw error;
370
- }
371
- if (!this.audioManager) {
372
- this.audioManager = new AudioManager();
373
- }
374
- try {
375
- await this.audioManager.start(onChunks, (error) => {
376
- const recordingError = this.toRecordingError(error, "Failed to start audio recording", { stage: "startRecording" });
377
- onError?.(recordingError);
378
- this.emitError(recordingError);
379
- });
380
- }
381
- catch (error) {
382
- const recordingError = this.toRecordingError(error, "Failed to start audio recording", { stage: "startRecording" });
383
- onError?.(recordingError);
384
- this.emitError(recordingError);
385
- throw recordingError;
386
- }
387
- }
388
- /**
389
- * stop recording audio
390
- */
391
- endRecordingWithSocket() {
392
- if (!this.audioManager) {
393
- const error = new RecordingError("Audio manager not set. Call startRecording() first.", { context: { stage: "stopRecording" } });
394
- this.emitError(error);
395
- throw error;
396
- }
397
- try {
398
- this.audioManager.stop();
399
- }
400
- catch (error) {
401
- const recordingError = this.toRecordingError(error, "Failed to stop audio recording", { stage: "stopRecording" });
402
- this.emitError(recordingError);
403
- throw recordingError;
404
- }
405
- }
406
- /**
407
- * send pong message
408
- */
409
- sendSocketPongMessage() {
410
- const connection = this.assertConnection("sendSocketPongMessage");
411
- const pongMessage = {
412
- ev: SOCKET_EVENTS.PONG,
413
- _id: Date.now().toString(),
414
- ts: Date.now(),
415
- };
416
- connection.sendMessage(pongMessage);
417
- }
418
- handleConnectionEstablished() {
419
- this.connection?.handleConnected(); //this will call the onConnectionStatusChange callback with connected
420
- this.connection?.emit(SYNAPSE_REALTIME_EVENTS.CONNECTED);
421
- this.flushOutgoingBuffer();
422
- }
423
- flushOutgoingBuffer() {
424
- if (!this.connection?.isConnected() || !this.outgoingBuffer)
425
- return;
426
- const buf = this.outgoingBuffer;
427
- this.outgoingBuffer = null;
428
- this.sendSocketMessage(buf);
429
- }
430
- /**
431
- * Cleanup message service
432
- */
433
- cleanupMessageServerState() {
434
- this.outgoingBuffer = null;
435
- this.connection = null;
436
- if (this.fileManager) {
437
- this.fileManager.clearPendingFilesState();
438
- this.fileManager = null;
439
- }
440
- if (this.audioManager) {
441
- this.audioManager.destroy();
442
- this.audioManager = null;
443
- }
444
- }
445
- // /**
446
- // * Generate a unique message ID
447
- // */
448
- // private generateId(): string {
449
- // return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
450
- // }
451
- emitError(error) {
452
- this.callbacks?.onError?.(error);
453
- }
454
- toFileError(error, fallbackMessage, context, hint) {
455
- return normalizeError(error, FileError, fallbackMessage, {
456
- context,
457
- hint,
458
- });
459
- }
460
- toRecordingError(error, fallbackMessage, context, hint) {
461
- return normalizeError(error, RecordingError, fallbackMessage, {
462
- context,
463
- hint,
464
- });
465
- }
466
- assertConnection(stage) {
467
- if (!this.connection) {
468
- const error = new ConnectionError("Connection not set. Please ensure the connection is established before calling this method.", {
469
- context: { stage },
470
- });
471
- this.emitError(error);
472
- throw error;
473
- }
474
- return this.connection;
475
- }
476
- }
@@ -1,35 +0,0 @@
1
- /**
2
- * Types for message management
3
- */
4
- import { SOCKET_CONTENT_TYPES, } from "../events/Events";
5
- export const SYNAPSE_MESSAGE_TYPES = SOCKET_CONTENT_TYPES;
6
- //TOD0: reframe event names
7
- export const SYNAPSE_REALTIME_EVENTS = {
8
- CONNECTED: "connected",
9
- DISCONNECTED: "disconnected",
10
- PROGRESS_MESSAGE: "progress_message",
11
- MESSAGE_CHUNK: "message_chunk",
12
- TIPS_MESSAGE: "tips_message",
13
- END_OF_STREAM: "end_of_stream",
14
- ERROR: "error",
15
- TOOL_CALL: "tool_call",
16
- AUDIO_TRANSCRIPT: "audio_transcript",
17
- TOOL_START: "tool_start",
18
- TOOL_END: "tool_end"
19
- };
20
- export const SYNAPSE_REALTIME_ERROR_CODES = {
21
- SESSION_INACTIVE: "session_not_found",
22
- SESSION_EXPIRED: "session_expired",
23
- INVALID_EVENT: "invalid_event",
24
- INVALID_CONTENT_TYPE: "invalid_content",
25
- PARSING_ERROR: "parsing", // for all LLM related error
26
- FILE_UPLOAD_INPROGRESS: "file_upload_inprogress",
27
- TIMEOUT: "timeout",
28
- SERVER_ERROR: "server_error",
29
- SESSION_TOKEN_MISMATCH: "session_token_mismatch",
30
- PROMPT_FETCH_ERROR: "prompt_fetch_error",
31
- INVALID_FILE_REQUEST: "invalid_file_request",
32
- };
33
- export const SYNAPSE_REALTIME_RESERVED_EVENTS = {
34
- SESSION_EXPIRED: "session_expired", //to be used for session expiry
35
- };
@@ -1,11 +0,0 @@
1
- /**
2
- * resource for initial setup of the agent
3
- * will update soon
4
- */
5
- import { BaseResource } from "../../internal/Api/BaseResource";
6
- export class Config extends BaseResource {
7
- basePath = "/med-assist/agent-config";
8
- async retrieve(agentId) {
9
- return this.get(`${this.basePath}/${agentId}`);
10
- }
11
- }
@@ -1,9 +0,0 @@
1
- "use strict";
2
- // import { BaseResource } from "../../internal/Api/BaseResource";
3
- // import { FeedbackRequest } from "./types";
4
- // export class Feedback extends BaseResource {
5
- // private basePath = "/med-assist/session";
6
- // public async update(feedback: FeedbackRequest): Promise<{success: boolean, m}> {
7
- // return this.patch<Feedback>(`${this.basePath}/${feedback.sessionId}/message/${feedback.messageId}/feedback`, feedback);
8
- // }
9
- // }