reneco-advanced-input-module 0.0.24 → 0.0.26

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 (74) hide show
  1. package/dist/cjs/{index-BTSzTkSZ.js → index-BtdDZbi5.js} +11 -4
  2. package/dist/cjs/index-BtdDZbi5.js.map +1 -0
  3. package/dist/cjs/loader.cjs.js +3 -4
  4. package/dist/cjs/loader.cjs.js.map +1 -1
  5. package/dist/cjs/ocr-file-uploader.cjs.entry.js +1 -1
  6. package/dist/cjs/voice-input-module.cjs.entry.js +79 -32
  7. package/dist/cjs/voice-input-module.cjs.entry.js.map +1 -1
  8. package/dist/cjs/voice-input-module.cjs.js +3 -4
  9. package/dist/cjs/voice-input-module.cjs.js.map +1 -1
  10. package/dist/cjs/voice-input-module.entry.cjs.js.map +1 -1
  11. package/dist/collection/components/voice-input-module/voice-input-module.css +26 -3
  12. package/dist/collection/components/voice-input-module/voice-input-module.js +70 -26
  13. package/dist/collection/components/voice-input-module/voice-input-module.js.map +1 -1
  14. package/dist/collection/services/llm.service.js +8 -4
  15. package/dist/collection/services/llm.service.js.map +1 -1
  16. package/dist/collection/types/form-schema.types.js.map +1 -1
  17. package/dist/components/voice-input-module.js +79 -31
  18. package/dist/components/voice-input-module.js.map +1 -1
  19. package/dist/esm/{index-jmc2yzBp.js → index-a7QWC-5I.js} +11 -5
  20. package/dist/esm/index-a7QWC-5I.js.map +1 -0
  21. package/dist/esm/loader.js +3 -4
  22. package/dist/esm/loader.js.map +1 -1
  23. package/dist/esm/ocr-file-uploader.entry.js +1 -1
  24. package/dist/esm/voice-input-module.entry.js +79 -32
  25. package/dist/esm/voice-input-module.entry.js.map +1 -1
  26. package/dist/esm/voice-input-module.js +3 -4
  27. package/dist/esm/voice-input-module.js.map +1 -1
  28. package/dist/types/components/voice-input-module/voice-input-module.d.ts +4 -0
  29. package/dist/types/types/form-schema.types.d.ts +1 -0
  30. package/dist/voice-input-module/loader.esm.js.map +1 -1
  31. package/dist/voice-input-module/p-a7QWC-5I.js +3 -0
  32. package/dist/voice-input-module/p-a7QWC-5I.js.map +1 -0
  33. package/dist/voice-input-module/{p-a5eeaf1c.entry.js → p-ba3d83d1.entry.js} +2 -2
  34. package/dist/voice-input-module/p-f14c05d0.entry.js +3 -0
  35. package/dist/voice-input-module/p-f14c05d0.entry.js.map +1 -0
  36. package/dist/voice-input-module/voice-input-module.css +6 -0
  37. package/dist/voice-input-module/voice-input-module.entry.esm.js.map +1 -1
  38. package/dist/voice-input-module/voice-input-module.esm.js +1 -1
  39. package/dist/voice-input-module/voice-input-module.esm.js.map +1 -1
  40. package/package.json +1 -1
  41. package/www/build/loader.esm.js.map +1 -1
  42. package/www/build/p-4e26fbbb.js +2 -0
  43. package/www/build/p-6cd2a3a1.css +6 -0
  44. package/www/build/p-a7QWC-5I.js +3 -0
  45. package/www/build/p-a7QWC-5I.js.map +1 -0
  46. package/www/build/{p-a5eeaf1c.entry.js → p-ba3d83d1.entry.js} +2 -2
  47. package/www/build/p-f14c05d0.entry.js +3 -0
  48. package/www/build/p-f14c05d0.entry.js.map +1 -0
  49. package/www/build/voice-input-module.css +6 -0
  50. package/www/build/voice-input-module.entry.esm.js.map +1 -1
  51. package/www/build/voice-input-module.esm.js +1 -1
  52. package/www/build/voice-input-module.esm.js.map +1 -1
  53. package/www/index.html +9 -9
  54. package/dist/cjs/app-globals-V2Kpy_OQ.js +0 -8
  55. package/dist/cjs/app-globals-V2Kpy_OQ.js.map +0 -1
  56. package/dist/cjs/index-BTSzTkSZ.js.map +0 -1
  57. package/dist/esm/app-globals-DQuL1Twl.js +0 -6
  58. package/dist/esm/app-globals-DQuL1Twl.js.map +0 -1
  59. package/dist/esm/index-jmc2yzBp.js.map +0 -1
  60. package/dist/voice-input-module/p-DQuL1Twl.js +0 -2
  61. package/dist/voice-input-module/p-DQuL1Twl.js.map +0 -1
  62. package/dist/voice-input-module/p-b3bf4feb.entry.js +0 -3
  63. package/dist/voice-input-module/p-b3bf4feb.entry.js.map +0 -1
  64. package/dist/voice-input-module/p-jmc2yzBp.js +0 -3
  65. package/dist/voice-input-module/p-jmc2yzBp.js.map +0 -1
  66. package/www/build/p-3aeb495d.js +0 -2
  67. package/www/build/p-DQuL1Twl.js +0 -2
  68. package/www/build/p-DQuL1Twl.js.map +0 -1
  69. package/www/build/p-b3bf4feb.entry.js +0 -3
  70. package/www/build/p-b3bf4feb.entry.js.map +0 -1
  71. package/www/build/p-jmc2yzBp.js +0 -3
  72. package/www/build/p-jmc2yzBp.js.map +0 -1
  73. /package/dist/voice-input-module/{p-a5eeaf1c.entry.js.map → p-ba3d83d1.entry.js.map} +0 -0
  74. /package/www/build/{p-a5eeaf1c.entry.js.map → p-ba3d83d1.entry.js.map} +0 -0
@@ -59,9 +59,6 @@
59
59
  transform: scale(1.05);
60
60
  }
61
61
 
62
- .upload-record-button svg path {
63
- /* Color applied via inline style from theme */
64
- }
65
62
 
66
63
  .record-button {
67
64
  display: flex;
@@ -341,6 +338,32 @@ input[type="date"].form-input {
341
338
  user-select: none;
342
339
  }
343
340
 
341
+ /* Confidence score badges */
342
+ .confidence-badge {
343
+ display: inline-flex;
344
+ align-items: center;
345
+ margin-left: 4px;
346
+ padding: 1px 5px;
347
+ border-radius: 3px;
348
+ font-size: 0.65rem;
349
+ font-weight: 700;
350
+ vertical-align: middle;
351
+ line-height: 1.4;
352
+ cursor: help;
353
+ }
354
+
355
+ .confidence-medium {
356
+ background: #fef3c7;
357
+ color: #92400e;
358
+ border: 1px solid #fde68a;
359
+ }
360
+
361
+ .confidence-low {
362
+ background: #fee2e2;
363
+ color: #991b1b;
364
+ border: 1px solid #fca5a5;
365
+ }
366
+
344
367
  /* Skeleton loading state */
345
368
  @keyframes skeleton-shimmer {
346
369
  0% { background-position: -200% 0; }
@@ -40,6 +40,7 @@ export class VoiceFormRecorder {
40
40
  this.hasTransientError = false;
41
41
  this.transcription = '';
42
42
  this.filledData = null;
43
+ this.confidenceScores = null;
43
44
  this.debugInfo = {};
44
45
  this.isReadonlyMode = true; // Start in readonly preview mode
45
46
  this.isInitializing = true;
@@ -74,9 +75,17 @@ export class VoiceFormRecorder {
74
75
  this.audioRecorder = new AudioRecorderService();
75
76
  }
76
77
  componentWillLoad() {
77
- this.initializeServices();
78
+ // Parse theme only so the skeleton can be styled correctly on first render.
79
+ // Full initialization runs in componentDidLoad() to give the skeleton time to paint.
80
+ try {
81
+ this.parsedTheme = this.theme ? JSON.parse(this.theme) : this.getDefaultTheme();
82
+ }
83
+ catch (_a) {
84
+ this.parsedTheme = this.getDefaultTheme();
85
+ }
78
86
  }
79
87
  componentDidLoad() {
88
+ this.initializeServices();
80
89
  this.isInitializing = false;
81
90
  }
82
91
  initializeServices() {
@@ -279,6 +288,7 @@ export class VoiceFormRecorder {
279
288
  return;
280
289
  this.isProcessing = true;
281
290
  this.hasTransientError = false;
291
+ this.confidenceScores = null;
282
292
  this.statusMessage = ((_a = this.parsedTheme.texts) === null || _a === void 0 ? void 0 : _a.processing) || (this.language == 'en' ? 'Processing document...' : 'Traitement du document ...');
283
293
  try {
284
294
  const extractedData = (ocrData === null || ocrData === void 0 ? void 0 : ocrData.content) || ocrData;
@@ -296,10 +306,11 @@ export class VoiceFormRecorder {
296
306
  throw Object.assign(new Error(llmError.message), { phase: 'llm' });
297
307
  }
298
308
  this.filledData = this.extractFilledData(filledSchema);
299
- this.updateDebugInfo('Form Filled', { filledSchema, extractedData: this.filledData });
309
+ this.confidenceScores = this.extractConfidenceScores(filledSchema);
310
+ this.updateDebugInfo('Form Filled', { filledSchema, extractedData: this.filledData, confidence: this.confidenceScores });
300
311
  this.parsedSchema = this.filledData;
301
312
  this.statusMessage = ((_c = this.parsedTheme.texts) === null || _c === void 0 ? void 0 : _c.completed) || (this.language == 'en' ? 'Form completed!' : 'Formulaire rempli !');
302
- this.formFilled.emit({ success: true, data: this.filledData, jsonForm });
313
+ this.formFilled.emit({ success: true, data: this.filledData, jsonForm, confidence: this.confidenceScores });
303
314
  }
304
315
  catch (error) {
305
316
  console.error('OCR processing error:', error);
@@ -318,6 +329,7 @@ export class VoiceFormRecorder {
318
329
  return;
319
330
  this.isProcessing = true;
320
331
  this.hasTransientError = false;
332
+ this.confidenceScores = null;
321
333
  this.updateDebugInfo('Audio Captured', { size: audioFile.size, type: audioFile.type });
322
334
  try {
323
335
  // Validate audio file before sending to API
@@ -338,7 +350,6 @@ export class VoiceFormRecorder {
338
350
  this.formFilled.emit({ success: false, error: 'Audio file too large' });
339
351
  return;
340
352
  }
341
- // Step 1: Transcription
342
353
  let transcription;
343
354
  try {
344
355
  this.statusMessage = ((_a = this.parsedTheme.texts) === null || _a === void 0 ? void 0 : _a.transcribing) || (this.language == 'en' ? 'Transcribing speech...' : 'Transcription du texte ...');
@@ -357,7 +368,6 @@ export class VoiceFormRecorder {
357
368
  this.formFilled.emit({ success: false, error: 'No speech detected', transcription: '' });
358
369
  return;
359
370
  }
360
- // Step 2: LLM form filling
361
371
  let filledSchema;
362
372
  try {
363
373
  this.statusMessage = ((_b = this.parsedTheme.texts) === null || _b === void 0 ? void 0 : _b.filling) || (this.language == 'en' ? 'Filling form fields...' : 'Remplissage du formulaire ...');
@@ -368,10 +378,11 @@ export class VoiceFormRecorder {
368
378
  throw Object.assign(new Error(llmError.message), { phase: 'llm' });
369
379
  }
370
380
  this.filledData = this.extractFilledData(filledSchema);
371
- this.updateDebugInfo('Form Filled', { filledSchema, extractedData: this.filledData });
381
+ this.confidenceScores = this.extractConfidenceScores(filledSchema);
382
+ this.updateDebugInfo('Form Filled', { filledSchema, extractedData: this.filledData, confidence: this.confidenceScores });
372
383
  this.parsedSchema = this.filledData;
373
384
  this.statusMessage = ((_c = this.parsedTheme.texts) === null || _c === void 0 ? void 0 : _c.completed) || (this.language == 'en' ? 'Form completed!' : 'Formulaire rempli !');
374
- this.formFilled.emit({ success: true, data: this.filledData, transcription });
385
+ this.formFilled.emit({ success: true, data: this.filledData, transcription, confidence: this.confidenceScores });
375
386
  }
376
387
  catch (error) {
377
388
  console.error('Audio processing error:', error);
@@ -395,7 +406,8 @@ export class VoiceFormRecorder {
395
406
  try {
396
407
  const audioBlob = await this.audioRecorder.stopRecording();
397
408
  const audioContent = new File([audioBlob], 'audio.wav', { type: 'audio/wav' });
398
- // processAudioContent manages isProcessing itself; await ensures we don't return early
409
+ // Reset isProcessing so the guard inside processAudioContent doesn't block this internal call
410
+ this.isProcessing = false;
399
411
  await this.processAudioContent(audioContent);
400
412
  }
401
413
  catch (error) {
@@ -412,12 +424,52 @@ export class VoiceFormRecorder {
412
424
  this.recordingStateChanged.emit({ isRecording: false, state: 'idle' });
413
425
  }
414
426
  }
427
+ extractConfidenceScores(filledData) {
428
+ const scores = {};
429
+ if (!filledData)
430
+ return scores;
431
+ // Fields array format: [{"id": "...", "name": "...", "value": "...", "confidence": 0.87}]
432
+ if (filledData.fields && Array.isArray(filledData.fields)) {
433
+ filledData.fields.forEach((field) => {
434
+ const raw = typeof field.confidence === 'number' ? field.confidence : parseFloat(field.confidence);
435
+ if (!isNaN(raw)) {
436
+ const clamped = Math.min(0.99, Math.max(0.01, Math.round(raw * 100) / 100));
437
+ // Store under both id and name so label-based lookups always work
438
+ if (field.id)
439
+ scores[field.id] = clamped;
440
+ if (field.name)
441
+ scores[field.name] = clamped;
442
+ }
443
+ });
444
+ }
445
+ // Simple schema format: {"schema": {...}, "confidence": {"field_name": 0.87}}
446
+ if (filledData.confidence && typeof filledData.confidence === 'object') {
447
+ Object.entries(filledData.confidence).forEach(([k, v]) => {
448
+ const raw = typeof v === 'number' ? v : parseFloat(v);
449
+ if (!isNaN(raw)) {
450
+ scores[k] = Math.min(0.99, Math.max(0.01, Math.round(raw * 100) / 100));
451
+ }
452
+ });
453
+ }
454
+ return scores;
455
+ }
456
+ getFieldConfidence(primary, fallback) {
457
+ var _a, _b;
458
+ if (!this.confidenceScores)
459
+ return null;
460
+ return (_a = this.confidenceScores[primary]) !== null && _a !== void 0 ? _a : (fallback ? ((_b = this.confidenceScores[fallback]) !== null && _b !== void 0 ? _b : null) : null);
461
+ }
462
+ renderConfidenceIndicator(confidence) {
463
+ if (confidence === null || confidence >= 0.95)
464
+ return null;
465
+ const pct = Math.round(confidence * 100);
466
+ const isApproximate = confidence >= 0.85;
467
+ return (h("span", { class: `confidence-badge ${isApproximate ? 'confidence-medium' : 'confidence-low'}`, title: this.language === 'en' ? `Confidence: ${pct}%` : `Confiance : ${pct}%` }, pct, "%"));
468
+ }
415
469
  extractFilledData(filledData) {
416
- // console.log("extractFilledData", filledData);
417
470
  const updatedSchema = JSON.parse(JSON.stringify(this.parsedSchema));
418
471
  switch (this.context) {
419
472
  case "ecoteka":
420
- // console.log("TODO extractFilledData", filledData);
421
473
  case "ng":
422
474
  if (filledData === null || filledData === void 0 ? void 0 : filledData.fields) {
423
475
  // Map AI response back to original schema structure
@@ -432,7 +484,6 @@ export class VoiceFormRecorder {
432
484
  }
433
485
  break;
434
486
  case "ecoll-veto":
435
- // console.log("TODO extractFilledData", filledData, updatedSchema);
436
487
  if (filledData === null || filledData === void 0 ? void 0 : filledData.fields) {
437
488
  // Map AI response back to original schema structure
438
489
  filledData.fields.forEach((field) => {
@@ -473,15 +524,12 @@ export class VoiceFormRecorder {
473
524
  }
474
525
  break;
475
526
  }
476
- // console.log("extractFilledData result", updatedSchema);
477
527
  return updatedSchema;
478
528
  }
479
529
  async trimSchemaForAI(schema) {
480
530
  var _a, _b;
481
- // console.log("trimSchemaForAI", schema);
482
531
  switch (this.context) {
483
532
  case "ecoteka":
484
- // console.log("TODO trimSchemaForAI", schema)
485
533
  case "ng":
486
534
  const trimmed = { fields: [] };
487
535
  schema.Children.forEach((child) => {
@@ -500,10 +548,8 @@ export class VoiceFormRecorder {
500
548
  }
501
549
  trimmed.fields.push(fieldData);
502
550
  });
503
- // console.log("Schema apres transformation, contexte NG:", trimmed);
504
551
  return trimmed;
505
552
  case "ecoll-veto":
506
- // console.log("TODO trimSchemaForAI", schema)
507
553
  const mergedItemsSchema = (this.parsedSchema[0].items).concat(this.parsedSchema[1].items);
508
554
  if (mergedItemsSchema) {
509
555
  const trimmedSchema = {
@@ -550,7 +596,6 @@ export class VoiceFormRecorder {
550
596
  default: '',
551
597
  };
552
598
  });
553
- // console.log("Schema apres transformation, contexte Track:", trimmedSchema);
554
599
  return trimmedSchema;
555
600
  }
556
601
  case "track":
@@ -747,13 +792,11 @@ export class VoiceFormRecorder {
747
792
  return (h("div", { class: "form-preview" }, h("div", { class: "form-preview-title" }, title), h("form", { class: "voice-filled-form" }, this.renderFormFields())));
748
793
  }
749
794
  renderFormFields() {
750
- // console.log("renderFormFields", this.parsedSchema);
751
795
  if (!this.parsedSchema)
752
796
  return null;
753
797
  const largeFieldTypes = ['select', 'multiselect', 'classification', 'thesaurus', 'position'];
754
798
  switch (this.context) {
755
799
  case "ecoteka":
756
- // console.log("TODO renderFormFields", this.parsedSchema);
757
800
  case "ng":
758
801
  return this.parsedSchema.Children.map((child) => {
759
802
  var _a, _b, _c;
@@ -765,7 +808,7 @@ export class VoiceFormRecorder {
765
808
  const isRequired = child.Required || false;
766
809
  const fieldValue = (_b = child.Settings) === null || _b === void 0 ? void 0 : _b.Default_Value;
767
810
  const isLargeField = largeFieldTypes.includes(fieldType) || (child.Children && child.Children.length > 5);
768
- return (h("div", { class: isLargeField ? "form-group full-width" : "form-group", key: fieldName }, h("label", { htmlFor: fieldName, class: "form-label" }, fieldLabel, isRequired && h("span", { class: "required" }, "*")), this.renderFormField(fieldName, {
811
+ return (h("div", { class: isLargeField ? "form-group full-width" : "form-group", key: fieldName }, h("label", { htmlFor: fieldName, class: "form-label" }, fieldLabel, isRequired && h("span", { class: "required" }, "*"), this.renderConfidenceIndicator(this.getFieldConfidence(fieldLabel, fieldName))), this.renderFormField(fieldName, {
769
812
  type: fieldType,
770
813
  title: fieldLabel,
771
814
  required: isRequired,
@@ -773,8 +816,6 @@ export class VoiceFormRecorder {
773
816
  }, fieldValue)));
774
817
  }).filter(Boolean);
775
818
  case "ecoll-veto":
776
- // NOTE STEP 2
777
- // console.log("TODO renderFormFields", this.parsedSchema);
778
819
  const mergedItemsSchema = (this.parsedSchema[0].items).concat(this.parsedSchema[1].items);
779
820
  return Object.entries(mergedItemsSchema).map(([key, field]) => {
780
821
  var _a, _b;
@@ -805,7 +846,7 @@ export class VoiceFormRecorder {
805
846
  // console.error("Error fetching classification data:", error);
806
847
  // }
807
848
  // }
808
- return (h("div", { class: "form-group", key: fieldName }, h("label", { htmlFor: fieldName, class: "form-label" }, fieldLabel, isRequired && h("span", { class: "required" }, "*")), this.renderFormField(fieldName, field, ((_b = (_a = this.filledData) === null || _a === void 0 ? void 0 : _a[fieldName]) !== null && _b !== void 0 ? _b : fieldValue))));
849
+ return (h("div", { class: "form-group", key: fieldName }, h("label", { htmlFor: fieldName, class: "form-label" }, fieldLabel, isRequired && h("span", { class: "required" }, "*"), this.renderConfidenceIndicator(this.getFieldConfidence(fieldLabel, fieldName))), this.renderFormField(fieldName, field, ((_b = (_a = this.filledData) === null || _a === void 0 ? void 0 : _a[fieldName]) !== null && _b !== void 0 ? _b : fieldValue))));
809
850
  });
810
851
  case "track":
811
852
  default:
@@ -814,7 +855,7 @@ export class VoiceFormRecorder {
814
855
  if (field.type === 'header') {
815
856
  return (h("div", { class: "form-header", key: fieldName }, field.title || fieldName));
816
857
  }
817
- return (h("div", { class: "form-group", key: fieldName }, h("label", { htmlFor: fieldName, class: "form-label" }, field.title || fieldName, field.required && h("span", { class: "required" }, "*")), this.renderFormField(fieldName, field, ((_b = (_a = this.filledData) === null || _a === void 0 ? void 0 : _a[fieldName]) !== null && _b !== void 0 ? _b : field.value))));
858
+ return (h("div", { class: "form-group", key: fieldName }, h("label", { htmlFor: fieldName, class: "form-label" }, field.title || fieldName, field.required && h("span", { class: "required" }, "*"), this.renderConfidenceIndicator(this.getFieldConfidence(fieldName))), this.renderFormField(fieldName, field, ((_b = (_a = this.filledData) === null || _a === void 0 ? void 0 : _a[fieldName]) !== null && _b !== void 0 ? _b : field.value))));
818
859
  });
819
860
  }
820
861
  }
@@ -890,7 +931,8 @@ export class VoiceFormRecorder {
890
931
  };
891
932
  }
892
933
  getContainerStyle() {
893
- const c = this.parsedTheme.container || {};
934
+ var _a;
935
+ const c = ((_a = this.parsedTheme) === null || _a === void 0 ? void 0 : _a.container) || {};
894
936
  return {
895
937
  width: c.width || 'auto',
896
938
  height: c.height || 'auto',
@@ -902,7 +944,8 @@ export class VoiceFormRecorder {
902
944
  };
903
945
  }
904
946
  getStatusStyle() {
905
- const s = this.parsedTheme.statusText || {};
947
+ var _a;
948
+ const s = ((_a = this.parsedTheme) === null || _a === void 0 ? void 0 : _a.statusText) || {};
906
949
  return {
907
950
  color: s.color || '#1e293b',
908
951
  fontSize: s.fontSize || '14px'
@@ -1271,6 +1314,7 @@ export class VoiceFormRecorder {
1271
1314
  "hasTransientError": {},
1272
1315
  "transcription": {},
1273
1316
  "filledData": {},
1317
+ "confidenceScores": {},
1274
1318
  "debugInfo": {},
1275
1319
  "isReadonlyMode": {},
1276
1320
  "isInitializing": {}