sera-ai 1.0.28 → 1.0.29

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/index.js CHANGED
@@ -151,12 +151,12 @@ var useFFmpegConverter = () => {
151
151
  const [statusMessage, setStatusMessage] = React3.useState("");
152
152
  const loadFFmpeg = React3.useCallback(async () => {
153
153
  if (ffmpegInstance) {
154
- console.log("[FFmpeg] Already loaded, skipping");
154
+ console.log("[SERA] FFmpeg already loaded, skipping");
155
155
  setFfmpegLoaded(true);
156
156
  return true;
157
157
  }
158
158
  if (ffmpegLoadingPromise) {
159
- console.log("[FFmpeg] Already loading, waiting for existing promise");
159
+ console.log("[SERA] FFmpeg already loading, waiting for existing promise");
160
160
  const result = await ffmpegLoadingPromise;
161
161
  if (result) {
162
162
  setFfmpegLoaded(true);
@@ -166,7 +166,7 @@ var useFFmpegConverter = () => {
166
166
  ffmpegLoadingPromise = (async () => {
167
167
  try {
168
168
  const cdnCorePath = "https://unpkg.com/@ffmpeg/core@0.11.0/dist/ffmpeg-core.js";
169
- console.log("[FFmpeg] Loading from CDN:", cdnCorePath);
169
+ console.log(`[SERA] FFmpeg loading from CDN | corePath=${cdnCorePath}`);
170
170
  setStatusMessage("Loading FFmpeg...");
171
171
  const ffmpeg$1 = ffmpeg.createFFmpeg({
172
172
  log: false,
@@ -180,10 +180,10 @@ var useFFmpegConverter = () => {
180
180
  setFfmpegLoaded(true);
181
181
  setIsLoaded(true);
182
182
  setStatusMessage("");
183
- console.log("[FFmpeg] WASM loaded successfully from CDN");
183
+ console.log("[SERA] FFmpeg WASM loaded successfully from CDN");
184
184
  return true;
185
185
  } catch (err) {
186
- console.error("Failed to load FFmpeg:", err);
186
+ console.error("[SERA] FFmpeg loading failed:", err);
187
187
  setError("Failed to load FFmpeg");
188
188
  setStatusMessage("");
189
189
  ffmpegLoadingPromise = null;
@@ -253,13 +253,13 @@ var useFFmpegConverter = () => {
253
253
  if (!ffmpegInstance || !ffmpegLoaded) {
254
254
  const loaded = await loadFFmpeg();
255
255
  if (!loaded) {
256
- console.error("Failed to load FFmpeg for FLAC conversion");
256
+ console.error("[SERA] FFmpeg loading failed for FLAC conversion");
257
257
  return wavFile;
258
258
  }
259
259
  }
260
260
  const ffmpeg$1 = ffmpegInstance;
261
261
  if (!ffmpeg$1) {
262
- console.error("FFmpeg not available");
262
+ console.error("[SERA] FFmpeg not available for FLAC conversion");
263
263
  return wavFile;
264
264
  }
265
265
  try {
@@ -293,7 +293,7 @@ var useFFmpegConverter = () => {
293
293
  const flacFile = new File([flacBlob], flacFileName, { type: "audio/flac" });
294
294
  setProgress(100);
295
295
  setStatusMessage("FLAC conversion complete");
296
- console.log(`[FLAC] Converted ${wavFile.size} bytes WAV to ${flacFile.size} bytes FLAC (${Math.round((1 - flacFile.size / wavFile.size) * 100)}% reduction)`);
296
+ console.log(`[SERA] FLAC conversion complete | inputSize=${wavFile.size}, outputSize=${flacFile.size}, reduction=${Math.round((1 - flacFile.size / wavFile.size) * 100)}%`);
297
297
  setTimeout(() => {
298
298
  setIsConverting(false);
299
299
  setProgress(0);
@@ -301,7 +301,7 @@ var useFFmpegConverter = () => {
301
301
  }, 500);
302
302
  return flacFile;
303
303
  } catch (err) {
304
- console.error("FLAC conversion failed:", err);
304
+ console.error("[SERA] FLAC conversion failed:", err);
305
305
  setError("FLAC conversion failed");
306
306
  setIsConverting(false);
307
307
  setProgress(0);
@@ -318,7 +318,7 @@ var useFFmpegConverter = () => {
318
318
  }
319
319
  const maxFileSize = 50 * 1024 * 1024;
320
320
  if (file.size > maxFileSize) {
321
- console.warn(`[SILENCE] File too large (${file.size} bytes), skipping silence removal`);
321
+ console.warn(`[SERA] Silence removal skipped, file too large | size=${file.size}`);
322
322
  return file;
323
323
  }
324
324
  try {
@@ -326,12 +326,12 @@ var useFFmpegConverter = () => {
326
326
  setError(null);
327
327
  setProgress(0);
328
328
  setStatusMessage("Removing silence...");
329
- console.log(`[SILENCE] Processing file: ${file.size} bytes, name: ${file.name}`);
329
+ console.log(`[SERA] Silence removal started | size=${file.size}, name=${file.name}`);
330
330
  if (!ffmpegInstance) {
331
331
  setStatusMessage("Loading FFmpeg for silence removal...");
332
332
  const loaded = await loadFFmpeg();
333
333
  if (!loaded || !ffmpegInstance) {
334
- console.error("[SILENCE] Failed to load FFmpeg");
334
+ console.error("[SERA] FFmpeg loading failed for silence removal");
335
335
  setIsConverting(false);
336
336
  setProgress(0);
337
337
  setStatusMessage("");
@@ -345,7 +345,7 @@ var useFFmpegConverter = () => {
345
345
  const wavData = await ffmpeg.fetchFile(file);
346
346
  ffmpegInstance.FS("writeFile", inputFileName, wavData);
347
347
  const originalSize = file.size;
348
- console.log(`[SILENCE] Input file written: ${originalSize} bytes`);
348
+ console.log(`[SERA] Silence removal input written | size=${originalSize}`);
349
349
  setProgress(30);
350
350
  setStatusMessage("Analyzing and removing silence...");
351
351
  await ffmpegInstance.run(
@@ -364,11 +364,11 @@ var useFFmpegConverter = () => {
364
364
  ffmpegInstance.FS("unlink", inputFileName);
365
365
  ffmpegInstance.FS("unlink", outputFileName);
366
366
  } catch (cleanupErr) {
367
- console.warn("[SILENCE] Cleanup warning:", cleanupErr);
367
+ console.warn("[SERA] Silence removal cleanup warning:", cleanupErr);
368
368
  }
369
369
  const processedSize = outputData.length;
370
370
  const reductionPercent = Math.round((1 - processedSize / originalSize) * 100);
371
- console.log(`[SILENCE] Complete: ${originalSize} bytes -> ${processedSize} bytes (${reductionPercent}% reduction)`);
371
+ console.log(`[SERA] Silence removal complete | inputSize=${originalSize}, outputSize=${processedSize}, reduction=${reductionPercent}%`);
372
372
  const processedFile = new File(
373
373
  [new Uint8Array(outputData)],
374
374
  file.name,
@@ -383,7 +383,7 @@ var useFFmpegConverter = () => {
383
383
  }, 500);
384
384
  return processedFile;
385
385
  } catch (err) {
386
- console.error("[SILENCE] FFmpeg silence removal failed:", err);
386
+ console.error("[SERA] Silence removal failed:", err);
387
387
  setError("Silence removal failed");
388
388
  setIsConverting(false);
389
389
  setProgress(0);
@@ -1089,7 +1089,7 @@ var useHL7FHIRConverter = () => {
1089
1089
  let sessionId = "";
1090
1090
  let metadata = {};
1091
1091
  let speciality = "";
1092
- console.log("Parsing HL7 transcription segments:", segments);
1092
+ console.log(`[SERA] Parsing HL7 transcription | segments=${segments.length}`);
1093
1093
  for (const segment of segments) {
1094
1094
  switch (segment.type) {
1095
1095
  case "MSH":
@@ -1131,7 +1131,7 @@ var useHL7FHIRConverter = () => {
1131
1131
  const parsedClassification = JSON.parse(classificationJson);
1132
1132
  Object.assign(classifiedInfo, parsedClassification);
1133
1133
  } catch (e) {
1134
- console.error("Failed to parse classification JSON:", e);
1134
+ console.error("[SERA] Failed to parse HL7 classification JSON:", e);
1135
1135
  }
1136
1136
  }
1137
1137
  }
@@ -1182,7 +1182,7 @@ var useHL7FHIRConverter = () => {
1182
1182
  }
1183
1183
  };
1184
1184
  } catch (error) {
1185
- console.error("HL7 transcription conversion error:", error);
1185
+ console.error("[SERA] HL7 transcription conversion error:", error);
1186
1186
  throw new Error(
1187
1187
  `Failed to convert HL7 transcription data: ${error instanceof Error ? error.message : "Unknown error"}`
1188
1188
  );
@@ -1195,7 +1195,7 @@ var useHL7FHIRConverter = () => {
1195
1195
  try {
1196
1196
  const segments = parseHL7(hl7Data);
1197
1197
  const specialities = [];
1198
- console.log("Parsing HL7 specialities segments:", segments);
1198
+ console.log(`[SERA] Parsing HL7 specialities | segments=${segments.length}`);
1199
1199
  let currentSpeciality = null;
1200
1200
  for (const segment of segments) {
1201
1201
  switch (segment.type) {
@@ -1237,7 +1237,7 @@ var useHL7FHIRConverter = () => {
1237
1237
  specialities.push(specialityData);
1238
1238
  }
1239
1239
  } catch (e) {
1240
- console.error("Failed to parse legacy specialities JSON data:", e);
1240
+ console.error("[SERA] Failed to parse legacy specialities JSON data:", e);
1241
1241
  }
1242
1242
  }
1243
1243
  }
@@ -1250,10 +1250,10 @@ var useHL7FHIRConverter = () => {
1250
1250
  }
1251
1251
  specialities.push(currentSpeciality);
1252
1252
  }
1253
- console.log("Parsed specialities:", specialities);
1253
+ console.log(`[SERA] Parsed specialities | count=${specialities.length}`);
1254
1254
  return { specialities };
1255
1255
  } catch (error) {
1256
- console.error("HL7 specialities conversion error:", error);
1256
+ console.error("[SERA] HL7 specialities conversion error:", error);
1257
1257
  throw new Error(
1258
1258
  `Failed to convert HL7 specialities data: ${error instanceof Error ? error.message : "Unknown error"}`
1259
1259
  );
@@ -1300,8 +1300,7 @@ var useHL7FHIRConverter = () => {
1300
1300
  classification = conclusionData.classifiedInfo;
1301
1301
  }
1302
1302
  } catch (parseError) {
1303
- console.error("\u274C Failed to parse DiagnosticReport conclusion:", parseError);
1304
- console.log("Raw conclusion:", resource.conclusion);
1303
+ console.error("[SERA] Failed to parse DiagnosticReport conclusion:", parseError);
1305
1304
  if (!classification["Clinical Summary"]) {
1306
1305
  classification["Clinical Summary"] = [];
1307
1306
  }
@@ -1320,16 +1319,13 @@ var useHL7FHIRConverter = () => {
1320
1319
  break;
1321
1320
  case "Composition":
1322
1321
  if (resource.section && Array.isArray(resource.section) && resource.section.length > 0) {
1323
- console.log(`\u{1F4C4} Processing ${resource.section.length} sections...`);
1322
+ console.log(`[SERA] Processing FHIR Composition | sections=${resource.section.length}`);
1324
1323
  for (const section of resource.section) {
1325
1324
  if (section.title === "Transcription" && section.text?.div) {
1326
1325
  const textContent = section.text.div.replace(/<[^>]*>/g, "");
1327
1326
  transcription += (transcription ? "\n" : "") + textContent;
1328
- console.log(`\u2705 Extracted transcription text (${textContent.length} chars)`);
1327
+ console.log(`[SERA] Extracted transcription text | chars=${textContent.length}`);
1329
1328
  } else if (section.title === "Medical Classification") {
1330
- console.log(
1331
- "\u2139\uFE0F Skipping Medical Classification section (handled by DiagnosticReport)"
1332
- );
1333
1329
  }
1334
1330
  }
1335
1331
  } else if (resource.text?.div) {
@@ -1338,10 +1334,8 @@ var useHL7FHIRConverter = () => {
1338
1334
  }
1339
1335
  if (resource.identifier) {
1340
1336
  const identifiers = Array.isArray(resource.identifier) ? resource.identifier : [resource.identifier];
1341
- console.log(`\u{1F4CB} Found ${identifiers.length} identifier(s)`);
1342
1337
  for (let j = 0; j < identifiers.length; j++) {
1343
1338
  const identifier = identifiers[j];
1344
- console.log(` [${j}] system: ${identifier.system}, value: ${identifier.value}`);
1345
1339
  if (identifier.system === "http://nuxera.ai/session-identifier" && identifier.value) {
1346
1340
  sessionId = identifier.value;
1347
1341
  break;
@@ -1350,10 +1344,7 @@ var useHL7FHIRConverter = () => {
1350
1344
  }
1351
1345
  if (!sessionId && resource.id) {
1352
1346
  sessionId = resource.id;
1353
- console.log(
1354
- "\u26A0\uFE0F [Priority 2] Using Composition.id as fallback session ID:",
1355
- sessionId
1356
- );
1347
+ console.log(`[SERA] Using Composition.id as fallback sessionId | sessionId=${sessionId}`);
1357
1348
  }
1358
1349
  break;
1359
1350
  case "Task":
@@ -1361,10 +1352,7 @@ var useHL7FHIRConverter = () => {
1361
1352
  for (const identifier of resource.identifier) {
1362
1353
  if (identifier.system === "http://nuxera.ai/session-id" && identifier.value) {
1363
1354
  sessionId = identifier.value;
1364
- console.log(
1365
- "\u2705 [Priority 3] Extracted session ID from Task.identifier:",
1366
- sessionId
1367
- );
1355
+ console.log(`[SERA] Extracted sessionId from Task.identifier | sessionId=${sessionId}`);
1368
1356
  break;
1369
1357
  }
1370
1358
  }
@@ -1374,15 +1362,15 @@ var useHL7FHIRConverter = () => {
1374
1362
  }
1375
1363
  if (!sessionId && fhirData.resourceType === "Bundle" && fhirData.identifier?.value) {
1376
1364
  sessionId = fhirData.identifier.value;
1377
- console.log("\u26A0\uFE0F [Priority 4] Using Bundle.identifier as last resort:", sessionId);
1365
+ console.log(`[SERA] Using Bundle.identifier as fallback sessionId | sessionId=${sessionId}`);
1378
1366
  }
1379
1367
  if (!sessionId && fhirData.resourceType === "Bundle" && fhirData.id) {
1380
1368
  sessionId = fhirData.id;
1381
- console.log("\u26A0\uFE0F [Priority 5] Using Bundle.id as absolute last resort:", sessionId);
1369
+ console.log(`[SERA] Using Bundle.id as fallback sessionId | sessionId=${sessionId}`);
1382
1370
  }
1383
1371
  if (!sessionId) {
1384
1372
  sessionId = `session_${Date.now()}`;
1385
- console.warn("\u26A0\uFE0F\u26A0\uFE0F No session ID found in FHIR response, generated:", sessionId);
1373
+ console.warn(`[SERA] No sessionId found in FHIR response, generated | sessionId=${sessionId}`);
1386
1374
  }
1387
1375
  return {
1388
1376
  transcription: transcription || "No transcription found in FHIR data",
@@ -1395,7 +1383,7 @@ var useHL7FHIRConverter = () => {
1395
1383
  }
1396
1384
  };
1397
1385
  } catch (error) {
1398
- console.error("\u274C FHIR transcription conversion error:", error);
1386
+ console.error("[SERA] FHIR transcription conversion error:", error);
1399
1387
  throw new Error(
1400
1388
  `Failed to convert FHIR transcription data: ${error instanceof Error ? error.message : "Unknown error"}`
1401
1389
  );
@@ -1441,7 +1429,7 @@ var useHL7FHIRConverter = () => {
1441
1429
  } catch (error) {
1442
1430
  const errorMessage = error instanceof Error ? error.message : "Unknown conversion error";
1443
1431
  setConversionError(errorMessage);
1444
- console.error("Transcription conversion failed:", error);
1432
+ console.error("[SERA] Transcription conversion failed:", error);
1445
1433
  return {
1446
1434
  transcription: "Conversion failed - see raw response",
1447
1435
  classification: { "Conversion Error": [errorMessage] },
@@ -1537,7 +1525,7 @@ var useHL7FHIRConverter = () => {
1537
1525
  )}|||||F|||${timestamp}`
1538
1526
  );
1539
1527
  const hl7Message = hl7Lines.join("\r\n") + "\r\n";
1540
- console.log("Constructed HL7 Transcription Request:\n", hl7Message);
1528
+ console.log(`[SERA] HL7 transcription request constructed | size=${hl7Message.length}`);
1541
1529
  const formData = new FormData();
1542
1530
  const hl7Blob = new Blob([hl7Message], { type: "text/plain" });
1543
1531
  formData.append("hl7_request", hl7Blob, "transcription_request.hl7");
@@ -1792,10 +1780,7 @@ var useHL7FHIRConverter = () => {
1792
1780
  });
1793
1781
  }
1794
1782
  }
1795
- console.log(
1796
- "Constructed FHIR Transcription Request Bundle:",
1797
- JSON.stringify(fhirBundle, null, 2)
1798
- );
1783
+ console.log(`[SERA] FHIR transcription request constructed | entries=${fhirBundle.entry.length}`);
1799
1784
  const formData = new FormData();
1800
1785
  const fhirBlob = new Blob([JSON.stringify(fhirBundle, null, 2)], {
1801
1786
  type: "application/fhir+json"
@@ -1807,10 +1792,7 @@ var useHL7FHIRConverter = () => {
1807
1792
  }
1808
1793
  formData.append("sequence", requestData.sequence.toString());
1809
1794
  formData.append("isFinalChunk", requestData.isFinalChunk.toString());
1810
- console.log(
1811
- "Created FHIR FormData with session ID:",
1812
- requestData.sessionId || "none (first call)"
1813
- );
1795
+ console.log(`[SERA] FHIR FormData created | sessionId=${requestData.sessionId || "none"}`);
1814
1796
  return formData;
1815
1797
  },
1816
1798
  [formatFHIRDate, mapFHIRGender]
@@ -1882,16 +1864,7 @@ var useHL7FHIRConverter = () => {
1882
1864
  `OBX|${obxSequence++}|TX|REQUEST_TYPE^Request Type||DICTATION|||||F|||${timestamp}`
1883
1865
  );
1884
1866
  const hl7Message = hl7Lines.join("\r\n") + "\r\n";
1885
- console.log("=== HL7 Dictation Request Debug ===");
1886
- console.log("Request Data:", requestData);
1887
- console.log("Audio File:", {
1888
- name: audioFile.name,
1889
- size: audioFile.size,
1890
- type: audioFile.type
1891
- });
1892
- console.log("HL7 Message:");
1893
- console.log(hl7Message);
1894
- console.log("=== End Debug ===");
1867
+ console.log(`[SERA] HL7 dictation request constructed | size=${hl7Message.length}, audioFile=${audioFile.name}, audioSize=${audioFile.size}`);
1895
1868
  const formData = new FormData();
1896
1869
  formData.append("audio", audioFile);
1897
1870
  const hl7Blob = new Blob([hl7Message], { type: "text/plain; charset=utf-8" });
@@ -2046,15 +2019,7 @@ var useHL7FHIRConverter = () => {
2046
2019
  }
2047
2020
  ]
2048
2021
  };
2049
- console.log("=== FHIR Dictation Request Debug ===");
2050
- console.log("Request Data:", requestData);
2051
- console.log("Audio File:", {
2052
- name: audioFile.name,
2053
- size: audioFile.size,
2054
- type: audioFile.type
2055
- });
2056
- console.log("FHIR Bundle:", JSON.stringify(fhirBundle, null, 2));
2057
- console.log("=== End Debug ===");
2022
+ console.log(`[SERA] FHIR dictation request constructed | entries=${fhirBundle.entry.length}, audioFile=${audioFile.name}, audioSize=${audioFile.size}`);
2058
2023
  const formData = new FormData();
2059
2024
  formData.append("audio", audioFile);
2060
2025
  const fhirBlob = new Blob([JSON.stringify(fhirBundle, null, 2)], {
@@ -2070,7 +2035,7 @@ var useHL7FHIRConverter = () => {
2070
2035
  try {
2071
2036
  const segments = parseHL7(hl7Data);
2072
2037
  let dictationResponse = {};
2073
- console.log("Parsing HL7 dictation segments:", segments);
2038
+ console.log(`[SERA] Parsing HL7 dictation | segments=${segments.length}`);
2074
2039
  for (const segment of segments) {
2075
2040
  switch (segment.type) {
2076
2041
  case "MSH":
@@ -2165,7 +2130,7 @@ var useHL7FHIRConverter = () => {
2165
2130
  );
2166
2131
  }
2167
2132
  } catch (e) {
2168
- console.warn("Could not calculate processing time:", e);
2133
+ console.warn("[SERA] Could not calculate processing time:", e);
2169
2134
  }
2170
2135
  }
2171
2136
  const finalResponse = {
@@ -2175,10 +2140,10 @@ var useHL7FHIRConverter = () => {
2175
2140
  language: dictationResponse.language,
2176
2141
  processingTimes: dictationResponse.processingTimes
2177
2142
  };
2178
- console.log("Converted HL7 dictation response:", finalResponse);
2143
+ console.log(`[SERA] HL7 dictation converted | sessionId=${finalResponse.sessionId}, dictationLength=${finalResponse.dictation.length}`);
2179
2144
  return finalResponse;
2180
2145
  } catch (error) {
2181
- console.error("HL7 dictation conversion error:", error);
2146
+ console.error("[SERA] HL7 dictation conversion error:", error);
2182
2147
  throw new Error(
2183
2148
  `Failed to convert HL7 dictation data: ${error instanceof Error ? error.message : "Unknown error"}`
2184
2149
  );
@@ -2191,20 +2156,16 @@ var useHL7FHIRConverter = () => {
2191
2156
  let dictationResponse = {};
2192
2157
  let parsedData = fhirData;
2193
2158
  if (typeof fhirData === "string") {
2194
- console.log("\u{1F4DD} Response is a string, parsing JSON...");
2195
2159
  try {
2196
2160
  parsedData = JSON.parse(fhirData);
2197
- console.log("\u2705 JSON parsed successfully");
2198
2161
  } catch (e) {
2199
- console.error("\u274C Failed to parse JSON string:", e);
2162
+ console.error("[SERA] Failed to parse FHIR dictation JSON string:", e);
2200
2163
  throw new Error("Invalid JSON response from server");
2201
2164
  }
2202
2165
  }
2203
- console.log("Parsing FHIR dictation data:", parsedData);
2204
2166
  let resources = [];
2205
2167
  if (parsedData.resourceType === "Bundle" && parsedData.entry) {
2206
2168
  resources = parsedData.entry.map((entry) => entry.resource);
2207
- console.log(`\u{1F4E6} Found ${resources.length} resources in Bundle`);
2208
2169
  } else if (parsedData.resourceType) {
2209
2170
  resources = [parsedData];
2210
2171
  } else if (parsedData.resource) {
@@ -2212,26 +2173,17 @@ var useHL7FHIRConverter = () => {
2212
2173
  }
2213
2174
  for (let i = 0; i < resources.length; i++) {
2214
2175
  const resource = resources[i];
2215
- console.log(`
2216
- --- Processing resource [${i}]: ${resource?.resourceType || "unknown"} ---`);
2217
2176
  if (!resource || !resource.resourceType) continue;
2218
2177
  switch (resource.resourceType) {
2219
2178
  case "MessageHeader":
2220
2179
  dictationResponse.sessionId = resource.id;
2221
- console.log("\u2705 Session ID from MessageHeader:", resource.id);
2222
2180
  break;
2223
2181
  case "Media":
2224
- console.log("\u{1F3AF} Found Media resource for dictation");
2225
2182
  if (resource.extension && Array.isArray(resource.extension)) {
2226
- console.log(`\u{1F4CB} Processing ${resource.extension.length} extensions`);
2227
2183
  for (const ext of resource.extension) {
2228
- console.log(
2229
- ` Extension URL: ${ext.url}, valueString: ${ext.valueString || ext.valueInteger}`
2230
- );
2231
2184
  switch (ext.url) {
2232
2185
  case "http://nuxera.ai/extensions/transcription":
2233
2186
  dictationResponse.dictation = ext.valueString || "";
2234
- console.log("\u2705\u2705 Extracted dictation text:", dictationResponse.dictation);
2235
2187
  break;
2236
2188
  case "http://nuxera.ai/extensions/audio-size":
2237
2189
  if (!dictationResponse.processingTimes) {
@@ -2241,17 +2193,12 @@ var useHL7FHIRConverter = () => {
2241
2193
  if (sizeMatch) {
2242
2194
  dictationResponse.processingTimes.audioSizeMB = parseFloat(sizeMatch[1]);
2243
2195
  }
2244
- console.log(
2245
- "\u2705 Extracted audio size:",
2246
- dictationResponse.processingTimes.audioSizeMB
2247
- );
2248
2196
  break;
2249
2197
  case "http://nuxera.ai/extensions/processing-timestamp":
2250
2198
  if (!dictationResponse.processingTimes) {
2251
2199
  dictationResponse.processingTimes = {};
2252
2200
  }
2253
2201
  dictationResponse.processingTimes.requestTimestamp = ext.valueInteger;
2254
- console.log("\u2705 Extracted processing timestamp:", ext.valueInteger);
2255
2202
  break;
2256
2203
  case "http://nuxera.ai/extensions/confidence":
2257
2204
  dictationResponse.confidence = ext.valueDecimal || ext.valueInteger;
@@ -2276,11 +2223,9 @@ var useHL7FHIRConverter = () => {
2276
2223
  }
2277
2224
  if (!dictationResponse.sessionId && resource.identifier && resource.identifier[0]) {
2278
2225
  dictationResponse.sessionId = resource.identifier[0].value;
2279
- console.log("\u2705 Session ID from Media.identifier:", dictationResponse.sessionId);
2280
2226
  }
2281
2227
  if (!dictationResponse.sessionId && resource.id) {
2282
2228
  dictationResponse.sessionId = resource.id;
2283
- console.log("\u2705 Session ID from Media.id:", dictationResponse.sessionId);
2284
2229
  }
2285
2230
  if (resource.createdDateTime && dictationResponse.processingTimes) {
2286
2231
  dictationResponse.processingTimes.processedAt = resource.createdDateTime;
@@ -2369,14 +2314,9 @@ var useHL7FHIRConverter = () => {
2369
2314
  dictationResponse.processingTimes.totalProcessingMs = Math.round(
2370
2315
  processedAtMs - requestMs
2371
2316
  );
2372
- console.log(
2373
- "\u2705 Calculated total processing time:",
2374
- dictationResponse.processingTimes.totalProcessingMs,
2375
- "ms"
2376
- );
2377
2317
  }
2378
2318
  } catch (e) {
2379
- console.warn("Could not calculate processing time:", e);
2319
+ console.warn("[SERA] Could not calculate FHIR dictation processing time:", e);
2380
2320
  }
2381
2321
  }
2382
2322
  const finalResponse = {
@@ -2386,10 +2326,10 @@ var useHL7FHIRConverter = () => {
2386
2326
  language: dictationResponse.language,
2387
2327
  processingTimes: dictationResponse.processingTimes
2388
2328
  };
2389
- console.log("\u2705\u2705 Converted FHIR dictation response:", finalResponse);
2329
+ console.log(`[SERA] FHIR dictation converted | sessionId=${finalResponse.sessionId}, dictationLength=${finalResponse.dictation.length}`);
2390
2330
  return finalResponse;
2391
2331
  } catch (error) {
2392
- console.error("\u274C FHIR dictation conversion error:", error);
2332
+ console.error("[SERA] FHIR dictation conversion error:", error);
2393
2333
  throw new Error(
2394
2334
  `Failed to convert FHIR dictation data: ${error instanceof Error ? error.message : "Unknown error"}`
2395
2335
  );
@@ -2423,7 +2363,7 @@ var useHL7FHIRConverter = () => {
2423
2363
  } catch (error) {
2424
2364
  const errorMessage = error instanceof Error ? error.message : "Unknown conversion error";
2425
2365
  setConversionError(errorMessage);
2426
- console.error("Dictation conversion failed:", error);
2366
+ console.error("[SERA] Dictation conversion failed:", error);
2427
2367
  return {
2428
2368
  dictation: "",
2429
2369
  sessionId: null,
@@ -2498,12 +2438,7 @@ var useHL7FHIRConverter = () => {
2498
2438
  )}|||||F|||${timestamp}`
2499
2439
  );
2500
2440
  const hl7Message = hl7Lines.join("\r\n") + "\r\n";
2501
- console.log("=== HL7 API Key Request Debug ===");
2502
- console.log("Operation:", operation);
2503
- console.log("API Key Data:", apiKeyData);
2504
- console.log("HL7 Message:");
2505
- console.log(hl7Message);
2506
- console.log("=== End Debug ===");
2441
+ console.log(`[SERA] HL7 API key request constructed | operation=${operation}, size=${hl7Message.length}`);
2507
2442
  return hl7Message;
2508
2443
  },
2509
2444
  [escapeHL7]
@@ -2663,11 +2598,7 @@ var useHL7FHIRConverter = () => {
2663
2598
  });
2664
2599
  }
2665
2600
  }
2666
- console.log("=== FHIR API Key Request Debug ===");
2667
- console.log("Operation:", operation);
2668
- console.log("API Key Data:", apiKeyData);
2669
- console.log("FHIR Bundle:", JSON.stringify(fhirBundle, null, 2));
2670
- console.log("=== End Debug ===");
2601
+ console.log(`[SERA] FHIR API key request constructed | operation=${operation}, entries=${fhirBundle.entry.length}`);
2671
2602
  return JSON.stringify(fhirBundle);
2672
2603
  },
2673
2604
  []
@@ -2844,9 +2775,6 @@ var createAudioProcessorWorker = () => {
2844
2775
  });
2845
2776
  this._audioLevelCheckInterval = 0;
2846
2777
 
2847
- // Debug: Log audio capture status every few seconds
2848
- if (this._audioLevelCheckInterval % 1000 === 0) {
2849
- }
2850
2778
  }
2851
2779
 
2852
2780
  if (audioLevel > this._audioThreshold) {
@@ -2902,7 +2830,6 @@ var createAudioProcessorWorker = () => {
2902
2830
  },
2903
2831
  [flat.buffer]
2904
2832
  );
2905
- console.log('[UPLOAD] Sending chunk: ' + (this._bufferSize / this._sampleRate).toFixed(1) + 's');
2906
2833
  // Clear buffer after upload
2907
2834
  this._buffer = [];
2908
2835
  this._bufferSize = 0;
@@ -2987,31 +2914,17 @@ var useAudioRecorder = ({
2987
2914
  clearFailedSessions
2988
2915
  } = useAudioRecovery_default(async (audioChunks, metadata) => {
2989
2916
  try {
2990
- console.log("\u{1F504} Retry callback started with audio chunks:", {
2991
- chunksCount: audioChunks.length,
2992
- totalSamples: audioChunks.reduce((sum, chunk) => sum + chunk.length, 0),
2993
- chunkDetails: audioChunks.map((chunk, idx) => ({
2994
- index: idx,
2995
- length: chunk.length,
2996
- hasData: chunk.length > 0
2997
- }))
2998
- });
2999
2917
  if (audioChunks.length === 0) {
3000
2918
  throw new Error("No audio chunks provided for retry");
3001
2919
  }
3002
2920
  const combinedAudio = combineAudioChunks(audioChunks);
3003
- console.log("[AUDIO] Combined audio for retry:", {
3004
- combinedLength: combinedAudio.length,
3005
- hasAudio: combinedAudio.length > 0
3006
- });
2921
+ console.log(`[SERA] Recovery retry | chunks=${audioChunks.length}, samples=${combinedAudio.length}`);
3007
2922
  if (combinedAudio.length === 0) {
3008
2923
  throw new Error("Combined audio is empty");
3009
2924
  }
3010
2925
  if (!uploadChunkToServerRef.current) {
3011
2926
  throw new Error("Upload function not yet initialized");
3012
2927
  }
3013
- const newSessionId = `session_retry_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
3014
- console.log("\u{1F194} Generated new retry session ID:", newSessionId);
3015
2928
  await uploadChunkToServerRef.current(
3016
2929
  combinedAudio,
3017
2930
  true,
@@ -3020,9 +2933,9 @@ var useAudioRecorder = ({
3020
2933
  false,
3021
2934
  metadata.sampleRate
3022
2935
  );
3023
- console.log("[SUCCESS] Retry upload completed successfully");
2936
+ console.log("[SERA] Recovery retry completed successfully");
3024
2937
  } catch (error2) {
3025
- console.error("[ERROR] Retry session failed:", error2);
2938
+ console.error("[SERA] Recovery retry failed:", error2);
3026
2939
  throw error2;
3027
2940
  }
3028
2941
  });
@@ -3049,7 +2962,6 @@ var useAudioRecorder = ({
3049
2962
  const ffmpegLoadedRef = React3__namespace.default.useRef(ffmpegLoaded);
3050
2963
  React3__namespace.default.useEffect(() => {
3051
2964
  ffmpegLoadedRef.current = ffmpegLoaded;
3052
- console.log(`\u{1F504} ffmpegLoadedRef updated to: ${ffmpegLoaded}`);
3053
2965
  }, [ffmpegLoaded]);
3054
2966
  React3__namespace.default.useEffect(() => {
3055
2967
  selectedModelRef.current = selectedModel;
@@ -3064,11 +2976,6 @@ var useAudioRecorder = ({
3064
2976
  selectedFormatRef.current = selectedFormat;
3065
2977
  }, [selectedFormat]);
3066
2978
  React3__namespace.default.useEffect(() => {
3067
- console.log("Triggering onTranscriptionUpdate with:", {
3068
- alreadyDoneTranscription,
3069
- sessionId: sessionIdRef.current,
3070
- localSessionId: localSessionIdRef.current
3071
- });
3072
2979
  if (alreadyDoneTranscription.length > 0) {
3073
2980
  onTranscriptionUpdate(
3074
2981
  alreadyDoneTranscription,
@@ -3076,30 +2983,21 @@ var useAudioRecorder = ({
3076
2983
  );
3077
2984
  }
3078
2985
  }, [alreadyDoneTranscription]);
3079
- React3__namespace.default.useEffect(() => {
3080
- console.log("Speciality changed in useAudioRecorder:", speciality);
3081
- }, [speciality]);
3082
2986
  React3__namespace.default.useEffect(() => {
3083
2987
  let isMounted = true;
3084
2988
  if (!ffmpegLoadedRef.current) {
3085
2989
  (async () => {
3086
- console.log("Initializing FFmpeg WASM\u2026");
3087
2990
  try {
3088
2991
  const ok = await loadFFmpeg();
3089
- if (isMounted) {
3090
- console.log("FFmpeg init returned:", ok);
3091
- if (ok) {
3092
- console.log("FFmpeg WASM initialized successfully for audio recorder");
3093
- }
2992
+ if (isMounted && ok) {
2993
+ console.log("[SERA] FFmpeg WASM initialized");
3094
2994
  }
3095
2995
  } catch (error2) {
3096
2996
  if (isMounted) {
3097
- console.error("FFmpeg WASM initialization failed:", error2);
2997
+ console.error("[SERA] FFmpeg WASM initialization failed:", error2);
3098
2998
  }
3099
2999
  }
3100
3000
  })();
3101
- } else {
3102
- console.log("FFmpeg WASM already initialized, skipping");
3103
3001
  }
3104
3002
  return () => {
3105
3003
  isMounted = false;
@@ -3123,12 +3021,11 @@ var useAudioRecorder = ({
3123
3021
  const track = audioTracks[0];
3124
3022
  const settings = track.getSettings();
3125
3023
  setCurrentDeviceId(settings.deviceId || null);
3126
- console.log();
3127
3024
  }
3128
3025
  testStream.getTracks().forEach((track) => track.stop());
3129
3026
  return true;
3130
3027
  } catch (error2) {
3131
- console.error("Microphone validation failed:", error2);
3028
+ console.error("[SERA] Microphone validation failed:", error2);
3132
3029
  if (error2 instanceof Error) {
3133
3030
  let errorMessage = "";
3134
3031
  if (error2.name === "NotFoundError" || error2.name === "DevicesNotFoundError") {
@@ -3151,9 +3048,6 @@ var useAudioRecorder = ({
3151
3048
  }
3152
3049
  }, [currentDeviceId]);
3153
3050
  React3__namespace.default.useEffect(() => {
3154
- if (speciality) {
3155
- console.log("Speciality set, microphone validation will happen on recording start");
3156
- }
3157
3051
  }, [speciality]);
3158
3052
  const clearAllSessions = React3__namespace.default.useCallback(async () => {
3159
3053
  await clearFailedSessions();
@@ -3162,30 +3056,16 @@ var useAudioRecorder = ({
3162
3056
  const uploadChunkToServer = React3__namespace.default.useCallback(
3163
3057
  async (audioData, isFinalChunk, sequence, retry = false, isPausedChunk = false, sampleRateOverride) => {
3164
3058
  const currentFfmpegLoaded = ffmpegLoadedRef.current;
3165
- console.log("\u{1F527} uploadChunkToServer called with:", {
3166
- ffmpegLoaded: currentFfmpegLoaded,
3167
- silenceRemovalEnabled: removeSilenceRef.current,
3168
- hasRemoveSilenceFunction: typeof removeSilence === "function",
3169
- isFinalChunk,
3170
- sequence,
3171
- audioDataLength: audioData?.length,
3172
- requestFormat: selectedFormatRef.current,
3173
- sessionHasFailed: sessionHasFailedChunkRef.current
3174
- });
3059
+ console.log(`[SERA] Step 6: Upload chunk | sequence=${sequence}, isFinal=${isFinalChunk}, samples=${audioData?.length || 0}, format=${selectedFormatRef.current}`);
3175
3060
  processorRef.current?.port.postMessage({ command: "resetUploadChunk" });
3176
3061
  if (audioData && localSessionIdRef.current && !retry) {
3177
3062
  try {
3178
- console.log(`[DB] Saving chunk ${sequence} to IndexedDB session ${localSessionIdRef.current}`);
3179
3063
  await appendAudioToSession(localSessionIdRef.current, audioData, sequence);
3180
- console.log(`[DB] \u2713 Successfully saved audio chunk ${sequence} to IndexedDB (${audioData.length} samples)`);
3181
3064
  } catch (error2) {
3182
- console.error(`[DB] \u2717 Failed to save audio chunk ${sequence} to IndexedDB:`, error2);
3065
+ console.error(`[SERA] IndexedDB save failed for chunk ${sequence}:`, error2);
3183
3066
  }
3184
- } else {
3185
- console.log(`[DB] Skipping IndexedDB save: audioData=${!!audioData}, sessionId=${localSessionIdRef.current}, retry=${retry}`);
3186
3067
  }
3187
3068
  if (sessionHasFailedChunkRef.current && !retry) {
3188
- console.log(`[SKIP] Session has failed chunk - skipping server upload for sequence ${sequence}, continuing to record audio`);
3189
3069
  if (isFinalChunk) {
3190
3070
  setShowRetrySessionPrompt(true);
3191
3071
  setIsProcessing(false);
@@ -3193,151 +3073,96 @@ var useAudioRecorder = ({
3193
3073
  return;
3194
3074
  }
3195
3075
  try {
3196
- const data = await pRetry__default.default(
3197
- async (attemptNumber) => {
3198
- console.log(`\u{1F504} Transcribe attempt ${attemptNumber} for sequence ${sequence}`);
3199
- if (!audioData || audioData.length === 0) {
3200
- console.log();
3201
- if (retry) {
3202
- throw new pRetry.AbortError("No audio data provided for retry");
3203
- }
3204
- throw new Error("No audio data provided");
3205
- }
3206
- console.log();
3207
- const currentSampleRate = sampleRateOverride ?? recordingSampleRateRef.current ?? audioContextRef.current?.sampleRate;
3208
- if (!isValidSampleRate(currentSampleRate)) {
3209
- throw new InvalidSampleRateError(currentSampleRate);
3210
- }
3211
- console.log(
3212
- `[PROCESSING] Processing audio chunk: ${audioData.length} samples (${(audioData.length / currentSampleRate).toFixed(2)}s) at ${currentSampleRate}Hz`
3213
- );
3214
- let maxAmplitude = 0;
3215
- let nonZeroSamples = 0;
3216
- for (let i = 0; i < audioData.length; i++) {
3217
- const amplitude = Math.abs(audioData[i]);
3218
- if (amplitude > maxAmplitude) maxAmplitude = amplitude;
3219
- if (amplitude > 1e-3) {
3220
- nonZeroSamples++;
3221
- }
3222
- }
3223
- const audioPercentage = nonZeroSamples / audioData.length;
3224
- console.log(
3225
- `[AUDIO] Audio stats: maxAmplitude=${maxAmplitude.toFixed(4)}, audioContent=${(audioPercentage * 100).toFixed(2)}%, sequence=${sequence}, isFinal=${isFinalChunk}`
3226
- );
3227
- console.log(`[WAV] Converting to WAV with sample rate: ${currentSampleRate}Hz`);
3228
- const timestamp = Date.now();
3229
- const fileName = `audio-chunk-${timestamp}.wav`;
3230
- let wavFile = await convertToWav(audioData, currentSampleRate, fileName);
3231
- if (!wavFile) {
3232
- throw new Error("WAV conversion failed through FFmpeg");
3233
- }
3234
- console.log(`[INFO] Original WAV file: ${wavFile.size} bytes, ${wavFile.name}`);
3235
- if (currentFfmpegLoaded && removeSilenceRef.current) {
3236
- try {
3237
- console.log("[SILENCE] Attempting to remove silence from audio chunk...");
3238
- const processedFile = await removeSilence(wavFile);
3239
- if (processedFile) {
3240
- console.log(
3241
- `[SUCCESS] Silence removed successfully: ${processedFile.size} bytes (was ${wavFile.size} bytes)`
3242
- );
3243
- if (processedFile.size < 1e3) {
3244
- console.warn(
3245
- `[WARN] Processed file very small (${processedFile.size} bytes), using original file`
3246
- );
3247
- } else {
3248
- wavFile = processedFile;
3249
- }
3250
- } else {
3251
- console.warn("Silence removal returned null, using original file");
3252
- }
3253
- } catch (silenceError) {
3254
- console.warn("Silence removal failed, using original file:", silenceError);
3255
- }
3256
- } else {
3257
- console.log("[SILENCE] Silence removal disabled or not loaded");
3258
- }
3259
- let audioFile = wavFile;
3260
- try {
3261
- console.log("[FLAC] Converting WAV to FLAC...");
3262
- const flacFile = await convertToFlac(wavFile);
3263
- if (flacFile && flacFile.type === "audio/flac") {
3264
- audioFile = flacFile;
3265
- console.log(
3266
- `[FLAC] Conversion successful: ${wavFile.size} bytes WAV \u2192 ${flacFile.size} bytes FLAC`
3267
- );
3268
- } else {
3269
- console.warn("[FLAC] Conversion failed, using WAV file");
3270
- }
3271
- } catch (flacError) {
3272
- console.warn("[FLAC] Conversion error, using WAV file:", flacError);
3076
+ if (!audioData || audioData.length === 0) {
3077
+ if (retry) {
3078
+ throw new pRetry.AbortError("No audio data provided for retry");
3079
+ }
3080
+ throw new Error("No audio data provided");
3081
+ }
3082
+ const currentSampleRate = sampleRateOverride ?? recordingSampleRateRef.current ?? audioContextRef.current?.sampleRate;
3083
+ if (!isValidSampleRate(currentSampleRate)) {
3084
+ throw new InvalidSampleRateError(currentSampleRate);
3085
+ }
3086
+ console.log(`[SERA] Step 7: Audio preparation | ${audioData.length} samples, ${(audioData.length / currentSampleRate).toFixed(1)}s, ${currentSampleRate}Hz`);
3087
+ const timestamp = Date.now();
3088
+ const fileName = `audio-chunk-${timestamp}.wav`;
3089
+ let wavFile = await convertToWav(audioData, currentSampleRate, fileName);
3090
+ if (!wavFile) {
3091
+ throw new Error("WAV conversion failed through FFmpeg");
3092
+ }
3093
+ if (currentFfmpegLoaded && removeSilenceRef.current) {
3094
+ try {
3095
+ const processedFile = await removeSilence(wavFile);
3096
+ if (processedFile && processedFile.size >= 1e3) {
3097
+ wavFile = processedFile;
3273
3098
  }
3274
- console.log(
3275
- `[OUT] Final file for transcription: ${audioFile.size} bytes, ${audioFile.name}`
3276
- );
3277
- if (audioFile.size < 500) {
3278
- console.warn(
3279
- `[WARN] Small audio file (${audioFile.size} bytes) - may contain minimal audio data, sending to server anyway`
3280
- );
3099
+ } catch (silenceError) {
3100
+ console.warn("[SERA] Silence removal failed, using original file:", silenceError);
3101
+ }
3102
+ }
3103
+ let audioFile = wavFile;
3104
+ try {
3105
+ const flacFile = await convertToFlac(wavFile);
3106
+ if (flacFile && flacFile.type === "audio/flac") {
3107
+ audioFile = flacFile;
3108
+ }
3109
+ } catch (flacError) {
3110
+ console.warn("[SERA] FLAC conversion failed, using WAV file:", flacError);
3111
+ }
3112
+ console.log(`[SERA] Step 8: Audio file ready | ${audioFile.name}, ${audioFile.size} bytes`);
3113
+ const patientDetailsPayload = patientDetails;
3114
+ const requestData = {
3115
+ sessionId: retry ? void 0 : sessionIdRef.current || void 0,
3116
+ model: selectedModelRef.current,
3117
+ doctorName,
3118
+ patientDetails: patientDetailsPayload,
3119
+ removeSilence: removeSilenceRef.current,
3120
+ skipDiarization: skipDiarizationRef.current,
3121
+ isFinalChunk,
3122
+ isPaused: isPausedChunk,
3123
+ sequence,
3124
+ speciality,
3125
+ retry
3126
+ };
3127
+ let formData;
3128
+ switch (selectedFormatRef.current) {
3129
+ case "hl7":
3130
+ formData = createHL7TranscriptionRequest(audioFile, requestData);
3131
+ break;
3132
+ case "fhir":
3133
+ formData = createFHIRTranscriptionRequest(audioFile, requestData);
3134
+ break;
3135
+ case "json":
3136
+ default:
3137
+ formData = new FormData();
3138
+ if (retry) {
3139
+ formData.append("retry", "true");
3140
+ } else if (sessionIdRef.current) {
3141
+ formData.append("sessionId", sessionIdRef.current);
3281
3142
  }
3282
- const patientDetailsPayload = patientDetails;
3283
- const requestData = {
3284
- sessionId: retry ? void 0 : sessionIdRef.current || void 0,
3285
- model: selectedModelRef.current,
3286
- doctorName,
3287
- patientDetails: patientDetailsPayload,
3288
- removeSilence: removeSilenceRef.current,
3289
- skipDiarization: skipDiarizationRef.current,
3290
- isFinalChunk,
3291
- isPaused: isPausedChunk,
3292
- sequence,
3293
- speciality,
3294
- retry
3295
- };
3296
- let formData;
3297
- let contentType;
3298
- switch (selectedFormatRef.current) {
3299
- case "hl7":
3300
- formData = createHL7TranscriptionRequest(audioFile, requestData);
3301
- contentType = "multipart/form-data; hl7-request=true";
3302
- console.log("Created HL7-formatted request");
3303
- console.log("HL7 FormData entries:", Array.from(formData.entries()));
3304
- break;
3305
- case "fhir":
3306
- formData = createFHIRTranscriptionRequest(audioFile, requestData);
3307
- contentType = "multipart/form-data; fhir-request=true";
3308
- console.log("Created FHIR-formatted request");
3309
- console.log("FHIR FormData entries:", Array.from(formData.entries()));
3310
- break;
3311
- case "json":
3312
- default:
3313
- formData = new FormData();
3314
- if (retry) {
3315
- formData.append("retry", "true");
3316
- } else if (sessionIdRef.current) {
3317
- formData.append("sessionId", sessionIdRef.current);
3318
- }
3319
- formData.append("audio", audioFile);
3320
- formData.append("model", selectedModelRef.current);
3321
- formData.append("doctorName", doctorName);
3322
- if (patientHistory) formData.append("patientHistory", patientHistory);
3323
- if (patientDetailsPayload) {
3324
- formData.append("patientDetails", JSON.stringify(patientDetailsPayload));
3325
- }
3326
- formData.append("removeSilence", removeSilenceRef.current.toString());
3327
- formData.append("skipDiarization", skipDiarizationRef.current.toString());
3328
- formData.append("isFinalChunk", isFinalChunk.toString());
3329
- formData.append("isPaused", isPausedChunk.toString());
3330
- formData.append("sequence", sequence.toString());
3331
- formData.append("speciality", speciality);
3332
- console.log("Created JSON-formatted request");
3333
- break;
3143
+ formData.append("audio", audioFile);
3144
+ formData.append("model", selectedModelRef.current);
3145
+ formData.append("doctorName", doctorName);
3146
+ if (patientHistory) formData.append("patientHistory", patientHistory);
3147
+ if (patientDetailsPayload) {
3148
+ formData.append("patientDetails", JSON.stringify(patientDetailsPayload));
3334
3149
  }
3335
- const headers = {
3336
- "x-api-key": effectiveApiKey || "",
3337
- "x-response-format": selectedFormatRef.current,
3338
- "x-request-format": selectedFormatRef.current
3339
- // Add request format header
3340
- };
3150
+ formData.append("removeSilence", removeSilenceRef.current.toString());
3151
+ formData.append("skipDiarization", skipDiarizationRef.current.toString());
3152
+ formData.append("isFinalChunk", isFinalChunk.toString());
3153
+ formData.append("isPaused", isPausedChunk.toString());
3154
+ formData.append("sequence", sequence.toString());
3155
+ formData.append("speciality", speciality);
3156
+ break;
3157
+ }
3158
+ const headers = {
3159
+ "x-api-key": effectiveApiKey || "",
3160
+ "x-response-format": selectedFormatRef.current,
3161
+ "x-request-format": selectedFormatRef.current
3162
+ };
3163
+ const data = await pRetry__default.default(
3164
+ async (attemptNumber) => {
3165
+ console.log(`[SERA] Step 9: Sending to server | sequence=${sequence}, attempt=${attemptNumber}`);
3341
3166
  const response = await fetch(`${apiBaseUrl}/api/transcribe`, {
3342
3167
  method: "POST",
3343
3168
  headers,
@@ -3345,11 +3170,7 @@ var useAudioRecorder = ({
3345
3170
  });
3346
3171
  if (!response.ok) {
3347
3172
  const errorText = await response.text();
3348
- console.error("Transcription server error response:", {
3349
- status: response.status,
3350
- statusText: response.statusText,
3351
- body: errorText
3352
- });
3173
+ console.error(`[SERA] Server error | status=${response.status}, body=${errorText}`);
3353
3174
  let errorMessage = `HTTP ${response.status}`;
3354
3175
  try {
3355
3176
  const errorData = JSON.parse(errorText);
@@ -3370,30 +3191,20 @@ var useAudioRecorder = ({
3370
3191
  let responseData;
3371
3192
  if (selectedFormatRef.current === "json") {
3372
3193
  responseData = await response.json();
3373
- console.log("Parsed JSON response:", responseData);
3374
3194
  } else if (selectedFormatRef.current === "hl7") {
3375
3195
  responseData = await response.text();
3376
- console.log("Received HL7 response:", responseData);
3377
3196
  } else if (selectedFormatRef.current === "fhir") {
3378
3197
  responseData = await response.json();
3379
- console.log("Received FHIR response:", responseData);
3380
3198
  } else {
3381
3199
  const responseText = await response.text();
3382
3200
  try {
3383
3201
  responseData = JSON.parse(responseText);
3384
- console.log("Fallback: Parsed as JSON:", responseData);
3385
3202
  } catch {
3386
3203
  responseData = responseText;
3387
- console.log("Fallback: Using as text:", responseData);
3388
3204
  }
3389
3205
  }
3390
- const convertedData = convertTranscriptionResponse(
3391
- responseData,
3392
- selectedFormatRef.current
3393
- );
3394
- console.log("Original response:", responseData);
3395
- console.log("Converted response:", convertedData);
3396
- return convertedData;
3206
+ console.log(`[SERA] Step 10: Server response received | sequence=${sequence}`);
3207
+ return responseData;
3397
3208
  },
3398
3209
  {
3399
3210
  retries: 3,
@@ -3402,13 +3213,7 @@ var useAudioRecorder = ({
3402
3213
  maxTimeout: 1e4,
3403
3214
  randomize: true,
3404
3215
  onFailedAttempt: (error2) => {
3405
- console.warn(
3406
- `[WARN] Transcribe attempt ${error2.attemptNumber} failed for sequence ${sequence}:`,
3407
- {
3408
- error: error2,
3409
- retriesLeft: error2.retriesLeft
3410
- }
3411
- );
3216
+ console.warn(`[SERA] Attempt ${error2.attemptNumber} failed for sequence ${sequence} | retriesLeft=${error2.retriesLeft}`);
3412
3217
  if (error2.retriesLeft > 0) {
3413
3218
  setError(
3414
3219
  `Network issue detected. Retrying... (${error2.retriesLeft} attempts remaining)`
@@ -3417,27 +3222,23 @@ var useAudioRecorder = ({
3417
3222
  }
3418
3223
  }
3419
3224
  );
3225
+ const convertedData = convertTranscriptionResponse(data, selectedFormatRef.current);
3420
3226
  if (conversionError) {
3421
3227
  clearError();
3422
3228
  }
3423
3229
  if (error && error.includes("Retrying")) {
3424
3230
  setError(null);
3425
3231
  }
3426
- if (!data) {
3232
+ if (!convertedData) {
3427
3233
  throw new Error("No data received from transcription server");
3428
3234
  }
3429
- console.log(`[SUCCESS] Received transcription for sequence ${sequence}:`, data);
3430
- if (retry && data.sessionId) {
3431
- console.log(
3432
- "[SUCCESS] Retry successful - received new server session ID:",
3433
- data.sessionId
3434
- );
3435
- sessionIdRef.current = data.sessionId;
3436
- } else if (!retry && data.sessionId && !sessionIdRef.current) {
3437
- console.log("[SUCCESS] Received initial server session ID:", data.sessionId);
3438
- sessionIdRef.current = data.sessionId;
3235
+ if (retry && convertedData.sessionId) {
3236
+ sessionIdRef.current = convertedData.sessionId;
3237
+ } else if (!retry && convertedData.sessionId && !sessionIdRef.current) {
3238
+ sessionIdRef.current = convertedData.sessionId;
3439
3239
  }
3440
- receivedTranscriptionsRef.current.set(sequence, data.transcription);
3240
+ console.log(`[SERA] Step 11: Transcription received | sequence=${sequence}, sessionId=${sessionIdRef.current}`);
3241
+ receivedTranscriptionsRef.current.set(sequence, convertedData.transcription);
3441
3242
  while (receivedTranscriptionsRef.current.has(nextExpectedSequenceRef.current)) {
3442
3243
  const t = receivedTranscriptionsRef.current.get(nextExpectedSequenceRef.current);
3443
3244
  setAlreadyDoneTranscription(t);
@@ -3445,17 +3246,21 @@ var useAudioRecorder = ({
3445
3246
  nextExpectedSequenceRef.current++;
3446
3247
  }
3447
3248
  if (isFinalChunk) {
3249
+ console.log(`[SERA] Step 12: Final chunk complete - transcription done | sessionId=${sessionIdRef.current}`);
3448
3250
  setTranscriptionDone(true);
3449
- onTranscriptionComplete(data.transcription, data.classifiedInfo, sessionIdRef.current);
3251
+ onTranscriptionComplete(
3252
+ convertedData.transcription,
3253
+ convertedData.classifiedInfo,
3254
+ sessionIdRef.current
3255
+ );
3450
3256
  if (localSessionIdRef.current) {
3451
3257
  await markSessionComplete(localSessionIdRef.current);
3452
3258
  setShowRetrySessionPrompt(false);
3453
3259
  }
3454
3260
  }
3455
3261
  } catch (err) {
3456
- console.error(`[ERROR] Upload error occurred after all retries:`, err);
3262
+ console.error(`[SERA] Upload failed for sequence ${sequence}:`, err);
3457
3263
  if (conversionError) {
3458
- console.error("Conversion error during upload:", conversionError);
3459
3264
  setError(`Data conversion failed: ${conversionError}`);
3460
3265
  }
3461
3266
  const isAbortError = err instanceof Error && err.name === "AbortError";
@@ -3466,7 +3271,7 @@ var useAudioRecorder = ({
3466
3271
  localSessionIdRef.current,
3467
3272
  err instanceof Error ? err.message : "Unknown error"
3468
3273
  );
3469
- console.log(`[FAIL] Chunk ${sequence} failed - session marked as failed, will continue recording audio locally`);
3274
+ console.warn(`[SERA] Chunk ${sequence} failed - continuing to record audio locally`);
3470
3275
  if (isFinalChunk) {
3471
3276
  setShowRetrySessionPrompt(true);
3472
3277
  }
@@ -3537,18 +3342,17 @@ var useAudioRecorder = ({
3537
3342
  if (failedSession) {
3538
3343
  const success = await retrySession(failedSession.id);
3539
3344
  if (success) {
3540
- console.log(`Successfully retried session ${failedSession.id}`);
3541
3345
  await deleteSession(failedSession.id);
3542
- console.log(`Deleted session ${failedSession.id} from IndexedDB after successful retry`);
3346
+ console.log(`[SERA] Session retry succeeded | sessionId=${failedSession.id}`);
3543
3347
  setError(null);
3544
3348
  retrySucceeded = true;
3545
3349
  } else {
3546
- console.log(`Retry failed for session ${failedSession.id} - will show retry UI`);
3350
+ console.warn(`[SERA] Session retry failed | sessionId=${failedSession.id}`);
3547
3351
  setError("Retry failed. Please check your connection and try again.");
3548
3352
  }
3549
3353
  }
3550
3354
  } catch (error2) {
3551
- console.error("Error retrying failed sessions:", error2);
3355
+ console.error("[SERA] Error retrying failed session:", error2);
3552
3356
  setError("Failed to retry sessions. Please try again.");
3553
3357
  } finally {
3554
3358
  setIsRetryingSession(false);
@@ -3581,7 +3385,7 @@ var useAudioRecorder = ({
3581
3385
  const localSessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
3582
3386
  localSessionIdRef.current = localSessionId;
3583
3387
  sessionIdRef.current = null;
3584
- console.log("Created local session ID for IndexedDB:", localSessionId);
3388
+ console.log(`[SERA] Step 1: New recording session created | localSessionId=${localSessionId}`);
3585
3389
  }
3586
3390
  const stream = await navigator.mediaDevices.getUserMedia({
3587
3391
  audio: {
@@ -3597,9 +3401,8 @@ var useAudioRecorder = ({
3597
3401
  const track = audioTracks[0];
3598
3402
  const settings = track.getSettings();
3599
3403
  setCurrentDeviceId(settings.deviceId || null);
3600
- console.log("Recording started with local session:", localSessionIdRef.current);
3601
3404
  track.addEventListener("ended", () => {
3602
- console.log("Audio track ended - device disconnected");
3405
+ console.warn("[SERA] Microphone disconnected during recording");
3603
3406
  setError("Microphone disconnected. Session saved - please reconnect and retry.");
3604
3407
  stopRecording();
3605
3408
  });
@@ -3626,38 +3429,26 @@ var useAudioRecorder = ({
3626
3429
  level,
3627
3430
  silentDuration,
3628
3431
  hasDetectedAudio,
3629
- isInitialPhase,
3630
- totalRecordingTime,
3631
- lastAudioTime
3432
+ isInitialPhase
3632
3433
  } = event.data;
3633
3434
  if (command === "finalChunk" && audioBuffer) {
3634
3435
  const sequence = sequenceCounterRef.current++;
3635
3436
  const audioArray = new Float32Array(audioBuffer);
3636
- console.log(`[RECEIVE] Final chunk: ${audioArray.length} samples, sequence: ${sequence}`);
3437
+ console.log(`[SERA] Step 4: Final chunk received | sequence=${sequence}, samples=${audioArray.length}`);
3637
3438
  enqueueChunk(audioArray, true, sequence);
3638
3439
  } else if (command === "chunk" && audioBuffer) {
3639
3440
  const sequence = sequenceCounterRef.current++;
3640
3441
  const audioArray = new Float32Array(audioBuffer);
3641
- console.log(`[RECEIVE] Chunk: ${audioArray.length} samples, sequence: ${sequence}`);
3442
+ console.log(`[SERA] Step 4: Chunk received | sequence=${sequence}, samples=${audioArray.length}`);
3642
3443
  enqueueChunk(audioArray, false, sequence);
3643
3444
  } else if (command === "pauseChunk" && audioBuffer) {
3644
3445
  const sequence = sequenceCounterRef.current++;
3645
- console.log(`[RECEIVE] Pause chunk with audioBuffer, sequence: ${sequence}`);
3646
3446
  enqueueChunk(new Float32Array(audioBuffer), false, sequence, true);
3647
3447
  } else if (command === "audioLevel") {
3648
3448
  setAudioLevel(level);
3649
3449
  } else if (command === "prolongedSilence") {
3650
- console.log(
3651
- `Prolonged silence detected: ${Math.round(silentDuration)}s silent, ${Math.round(
3652
- totalRecordingTime
3653
- )}s total, last audio ${Math.round(lastAudioTime)}s ago`
3654
- );
3450
+ console.warn(`[SERA] Prolonged silence: ${Math.round(silentDuration)}s`);
3655
3451
  } else if (command === "noAudioDetected") {
3656
- console.log(
3657
- `No audio detected: ${Math.round(
3658
- silentDuration
3659
- )}s silent, hasDetectedAudio: ${hasDetectedAudio}, isInitialPhase: ${isInitialPhase}`
3660
- );
3661
3452
  setNoAudioDetected(true);
3662
3453
  let errorMessage;
3663
3454
  if (isInitialPhase && !hasDetectedAudio) {
@@ -3677,7 +3468,7 @@ var useAudioRecorder = ({
3677
3468
  source.connect(processor);
3678
3469
  audioContextRef.current = audioContext;
3679
3470
  recordingSampleRateRef.current = audioContext.sampleRate;
3680
- console.log(`[AUDIO] Recording sample rate set to: ${audioContext.sampleRate}Hz`);
3471
+ console.log(`[SERA] Step 2: Recording started | sampleRate=${audioContext.sampleRate}Hz`);
3681
3472
  processorRef.current = processor;
3682
3473
  setIsRecording(true);
3683
3474
  const intervalId = window.setInterval(() => {
@@ -3685,7 +3476,7 @@ var useAudioRecorder = ({
3685
3476
  }, 47e3);
3686
3477
  setUploadChunkInterval(intervalId);
3687
3478
  } catch (err) {
3688
- console.error("Recording start failed:", err);
3479
+ console.error("[SERA] Recording start failed:", err);
3689
3480
  }
3690
3481
  }, [
3691
3482
  validateMicrophoneAccess,
@@ -3697,13 +3488,12 @@ var useAudioRecorder = ({
3697
3488
  currentDeviceId
3698
3489
  ]);
3699
3490
  const stopRecording = React3__namespace.default.useCallback(async () => {
3700
- console.log("Stopping recording...");
3491
+ console.log("[SERA] Step 3: Stop recording requested");
3701
3492
  if (uploadChunkInterval) {
3702
3493
  clearInterval(uploadChunkInterval);
3703
3494
  setUploadChunkInterval(null);
3704
3495
  }
3705
3496
  if (processorRef.current) {
3706
- console.log("Stopping recording and sending final chunk --> ", isPaused ? "paused" : "final");
3707
3497
  processorRef.current.port.postMessage({ command: "stop" });
3708
3498
  setTimeout(async () => {
3709
3499
  if (processorRef.current) {
@@ -3721,18 +3511,13 @@ var useAudioRecorder = ({
3721
3511
  }, 500);
3722
3512
  }
3723
3513
  setIsRecording(false);
3724
- console.log("\u{1F50D} Stop recording - checking for failed session:", {
3725
- hasSessionFailed: sessionHasFailedChunkRef.current,
3726
- localSessionId: localSessionIdRef.current
3727
- });
3728
3514
  if (sessionHasFailedChunkRef.current && localSessionIdRef.current) {
3729
- console.log("\u26A0\uFE0F Recording stopped with failed session - showing retry UI");
3515
+ console.warn("[SERA] Recording stopped with failed session - showing retry UI");
3730
3516
  setShowRetrySessionPrompt(true);
3731
3517
  }
3732
3518
  }, [uploadChunkInterval]);
3733
3519
  React3__namespace.default.useEffect(() => {
3734
3520
  const handleDeviceChange = async () => {
3735
- console.log("Audio device change detected");
3736
3521
  try {
3737
3522
  const devices = await navigator.mediaDevices.enumerateDevices();
3738
3523
  const audioInputDevices = devices.filter((device) => device.kind === "audioinput");
@@ -3751,7 +3536,7 @@ var useAudioRecorder = ({
3751
3536
  }
3752
3537
  }
3753
3538
  } catch (error2) {
3754
- console.error("Device change detection failed:", error2);
3539
+ console.error("[SERA] Device change detection failed:", error2);
3755
3540
  setError("Unable to detect audio devices. Please check your microphone permissions.");
3756
3541
  }
3757
3542
  };
@@ -3771,7 +3556,7 @@ var useAudioRecorder = ({
3771
3556
  }, 1e3);
3772
3557
  }
3773
3558
  } catch (error2) {
3774
- console.error("Device selection failed:", error2);
3559
+ console.error("[SERA] Device selection failed:", error2);
3775
3560
  setError("Failed to switch to selected microphone.");
3776
3561
  }
3777
3562
  },
@@ -3807,7 +3592,7 @@ var useAudioRecorder = ({
3807
3592
  return;
3808
3593
  }
3809
3594
  const { chunk, isFinal, sequence, isPaused: isPaused2 = false } = chunkQueueRef.current.shift();
3810
- console.log(`[QUEUE] Processing chunk ${sequence} from queue, remaining: ${chunkQueueRef.current.length}`);
3595
+ console.log(`[SERA] Step 5: Queue processing | sequence=${sequence}, isFinal=${isFinal}, queued=${chunkQueueRef.current.length}`);
3811
3596
  isProcessingQueueRef.current = true;
3812
3597
  uploadChunkToServer(chunk, isFinal, sequence, false, isPaused2).finally(() => {
3813
3598
  isProcessingQueueRef.current = false;
@@ -3816,12 +3601,9 @@ var useAudioRecorder = ({
3816
3601
  }, [uploadChunkToServer, isLoaded]);
3817
3602
  const enqueueChunk = React3__namespace.default.useCallback(
3818
3603
  (audioData, isFinalChunk, sequence, isPausedChunk = false) => {
3819
- console.log(`[QUEUE] Enqueuing ${isFinalChunk ? "FINAL" : isPausedChunk ? "PAUSED" : "regular"} chunk ${sequence}, samples: ${audioData?.length || 0}, queue size: ${chunkQueueRef.current.length}`);
3820
3604
  if (isFinalChunk) {
3821
3605
  if (!sessionHasFailedChunkRef.current) {
3822
3606
  setIsProcessing(true);
3823
- } else {
3824
- console.log("\u26A0\uFE0F Session has failed - skipping processing state (IndexedDB save only)");
3825
3607
  }
3826
3608
  }
3827
3609
  chunkQueueRef.current.push({
@@ -4531,21 +4313,13 @@ var AudioRecorder = ({
4531
4313
  patientDetails,
4532
4314
  selectedFormat,
4533
4315
  onTranscriptionUpdate: (text, sessionId) => {
4534
- console.log("onTranscriptionUpdate called with text:", text, "sessionId:", sessionId);
4316
+ console.log(`[SERA] Transcription update received | sessionId=${sessionId}, textLength=${text.length}`);
4535
4317
  if (text.length > 0) {
4536
- console.log("Transcription update:", text, sessionId);
4537
4318
  onTranscriptionUpdate && onTranscriptionUpdate(text, sessionId);
4538
4319
  }
4539
4320
  },
4540
4321
  onTranscriptionComplete: (text, classification, sessionId) => {
4541
- console.log(
4542
- "onTranscriptionComplete called with text:",
4543
- text,
4544
- "classification:",
4545
- classification,
4546
- "sessionId:",
4547
- sessionId
4548
- );
4322
+ console.log(`[SERA] Transcription complete | sessionId=${sessionId}, textLength=${text.length}, hasClassification=${!!classification}`);
4549
4323
  onTranscriptionComplete && onTranscriptionComplete(text, classification, sessionId);
4550
4324
  }
4551
4325
  });
@@ -4604,7 +4378,7 @@ var AudioRecorder = ({
4604
4378
  ] }) });
4605
4379
  }
4606
4380
  if (isMicrophoneError) {
4607
- console.log("\u{1F534} Showing microphone error UI");
4381
+ console.log("[SERA] Showing microphone error UI");
4608
4382
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start", children: [
4609
4383
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-5 w-5 text-red-400" }) }),
4610
4384
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-3 flex-1", children: [
@@ -4614,7 +4388,7 @@ var AudioRecorder = ({
4614
4388
  "button",
4615
4389
  {
4616
4390
  onClick: () => {
4617
- console.log("\u{1F504} Check Again button clicked");
4391
+ console.log("[SERA] Microphone check again requested");
4618
4392
  validateMicrophoneAccess();
4619
4393
  },
4620
4394
  className: "bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded text-sm transition-colors",