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
@@ -1 +1 @@
1
- {"version":3,"file":"llm.service.js","sourceRoot":"","sources":["../../src/services/llm.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { LLMProvider, SpeechToTextProvider, ServiceProviderConfig, TranscriptionProvider, CompletionProvider } from '../types/service-providers.types';\r\nimport { FormSchema } from '../types/form-schema.types';\r\nimport { fuzzyMatchOption } from '../utils/fuzzy-match';\r\n\r\nexport class OpenAILLMService implements LLMProvider {\r\n private apiKey: string;\r\n private model: string;\r\n private baseUrl: string;\r\n private useProxy: boolean;\r\n private proxyUrl: string;\r\n\r\n constructor(config: ServiceProviderConfig['llm']) {\r\n this.useProxy = config?.useProxy || false;\r\n this.proxyUrl = config?.proxyUrl || 'http://localhost:8492';\r\n \r\n if (this.useProxy) {\r\n // Mode proxy: pas besoin d'API key\r\n this.apiKey = '';\r\n this.baseUrl = this.proxyUrl;\r\n } else {\r\n // Mode direct: API key requise\r\n this.apiKey = config?.apiKey || this.getEnvironmentVariable('OPENAI_API_KEY') || '';\r\n this.baseUrl = config?.baseUrl || 'https://api.openai.com/v1';\r\n \r\n if (!this.apiKey) {\r\n throw new Error('OpenAI API key is required for LLM service');\r\n }\r\n }\r\n \r\n this.model = config?.model || 'gpt-5-mini';\r\n }\r\n\r\n private getEnvironmentVariable(name: string): string | undefined {\r\n // In browser environment, we might get env vars through other means\r\n if (typeof process !== 'undefined' && process.env) {\r\n return process.env[name];\r\n }\r\n // Check if it's available as a global variable or through other means\r\n return (window as any)[name] || undefined;\r\n }\r\n\r\n private getOptimizeFieldsDescription(schema: any){\r\n if (Array.isArray(schema)) {\r\n return schema.map((field: any) => {\r\n let description = `- ID:${field.id || field.name} | ${field.name || field.title} ` +\r\n `(${field.type}` +\r\n `${field.required ? ', required' : ''}` +\r\n `${field.readonly ? ', readonly' : ''}` +\r\n `${field.default !== undefined && field.default !== null && field.default !== '' ? ', default='+field.default : ''}` +\r\n `${field.min && field.min !== \"\" ? ', min='+field.min : ''}` +\r\n `${field.max && field.max !== \"\" ? ', max='+field.max : ''}` +\r\n `${field.pattern && field.pattern !== \"\" ? ', pattern='+field.pattern : ''}`;\r\n \r\n if (field.options && field.options.length > 0) {\r\n if (field.options.length < 50) {\r\n description += `) - options: ${field.options.join(', ')}`;\r\n } else {\r\n description += `, many options: ${field.options.length} total) - extract raw value, will be matched locally`;\r\n }\r\n } else {\r\n description += ')';\r\n }\r\n \r\n return description;\r\n }).join('\\n');\r\n }\r\n \r\n return Object.entries(schema).map(([fieldName, field]: [string, any]) => {\r\n let description = `- ID:${field.id || fieldName} | ${field.title || fieldName} ` +\r\n `(${field.type}` +\r\n `${field.required ? ', required' : ''}` +\r\n `${field.readonly ? ', readonly' : ''}` +\r\n `${field.default !== undefined && field.default !== null && field.default !== '' ? ', default='+field.default : ''}` +\r\n `${field.min && field.min !== \"\" ? ', min='+field.min : ''}` +\r\n `${field.max && field.max !== \"\" ? ', max='+field.max : ''}` +\r\n `${field.pattern && field.pattern !== \"\" ? ', pattern='+field.pattern : ''}`;\r\n \r\n if (field.options && field.options.length > 0) {\r\n if (field.options.length < 50) {\r\n description += `) - options: ${field.options.join(', ')}`;\r\n } else {\r\n description += `, many options: ${field.options.length} total) - extract raw value, will be matched locally`;\r\n }\r\n } else {\r\n description += ')';\r\n }\r\n \r\n return description;\r\n }).join('\\n');\r\n }\r\n\r\n async fillFormFromTranscription(transcription: string, schema: any): Promise<any> {\r\n return this.fillForm(transcription, schema, true);\r\n }\r\n\r\n private applyFuzzyMatching(llmResponse: any, schema: any): any {\r\n // Handle complex schema format with fields array\r\n if (schema?.fields || schema?.schema) {\r\n const finalSchema = schema?.fields || schema?.schema;\r\n const fieldsWithErrors: string[] = [];\r\n \r\n if (llmResponse.fields && Array.isArray(llmResponse.fields)) {\r\n llmResponse.fields = llmResponse.fields.map((field: any) => {\r\n // Find corresponding schema field\r\n const schemaField = Object.values(finalSchema).find((sf: any) => \r\n (sf.name === field.name || sf.title === field.name)\r\n ) as any;\r\n \r\n if (schemaField && schemaField.options && schemaField.options.length >= 50 && field.value) {\r\n const isMultiselect = schemaField.type === 'multiselect';\r\n \r\n // Handle multiselect (array of values)\r\n if (isMultiselect && Array.isArray(field.value)) {\r\n const matchedValues: string[] = [];\r\n const failedValues: string[] = [];\r\n \r\n field.value.forEach((val: string) => {\r\n const matchResult = fuzzyMatchOption(val, schemaField.options);\r\n if (matchResult) {\r\n matchedValues.push(matchResult.match);\r\n } else {\r\n failedValues.push(val);\r\n }\r\n });\r\n \r\n if (failedValues.length > 0) {\r\n fieldsWithErrors.push(field.name);\r\n field.error = `Could not match values: ${failedValues.join(', ')}`;\r\n }\r\n \r\n field.value = matchedValues.length > 0 ? matchedValues : null;\r\n field.fuzzyMatchConfidence = matchedValues.length / (matchedValues.length + failedValues.length);\r\n } else if (!isMultiselect) {\r\n // Handle single value (select, classification, thesaurus, position)\r\n const singleValue = Array.isArray(field.value) ? field.value[0] : field.value;\r\n const matchResult = fuzzyMatchOption(singleValue, schemaField.options);\r\n \r\n if (matchResult) {\r\n field.value = matchResult.match;\r\n field.fuzzyMatchConfidence = matchResult.confidence;\r\n } else {\r\n fieldsWithErrors.push(field.name);\r\n field.value = null;\r\n field.error = `Could not match \"${singleValue}\" to available options`;\r\n }\r\n }\r\n }\r\n \r\n return field;\r\n });\r\n }\r\n \r\n if (fieldsWithErrors.length > 0) {\r\n llmResponse.matchingErrors = fieldsWithErrors;\r\n }\r\n \r\n return llmResponse;\r\n }\r\n \r\n // Handle simple schema format\r\n if (schema?.schema) {\r\n const fieldsWithErrors: string[] = [];\r\n \r\n Object.entries(schema.schema).forEach(([fieldName, fieldDef]: [string, any]) => {\r\n if (fieldDef.options && fieldDef.options.length >= 50) {\r\n const fieldValue = llmResponse.schema?.[fieldName]?.default;\r\n \r\n if (fieldValue) {\r\n const isMultiselect = fieldDef.type === 'multiselect';\r\n \r\n // Handle multiselect (array of values)\r\n if (isMultiselect && Array.isArray(fieldValue)) {\r\n const matchedValues: string[] = [];\r\n const failedValues: string[] = [];\r\n \r\n fieldValue.forEach((val: string) => {\r\n const matchResult = fuzzyMatchOption(val, fieldDef.options);\r\n if (matchResult) {\r\n matchedValues.push(matchResult.match);\r\n } else {\r\n failedValues.push(val);\r\n }\r\n });\r\n \r\n if (failedValues.length > 0) {\r\n fieldsWithErrors.push(fieldName);\r\n llmResponse.schema[fieldName].error = `Could not match values: ${failedValues.join(', ')}`;\r\n }\r\n \r\n llmResponse.schema[fieldName].default = matchedValues.length > 0 ? matchedValues : null;\r\n llmResponse.schema[fieldName].fuzzyMatchConfidence = matchedValues.length / (matchedValues.length + failedValues.length);\r\n } else if (!isMultiselect) {\r\n // Handle single value (select, classification, thesaurus, position)\r\n const singleValue = Array.isArray(fieldValue) ? fieldValue[0] : fieldValue;\r\n const matchResult = fuzzyMatchOption(singleValue, fieldDef.options);\r\n \r\n if (matchResult) {\r\n llmResponse.schema[fieldName].default = matchResult.match;\r\n llmResponse.schema[fieldName].fuzzyMatchConfidence = matchResult.confidence;\r\n } else {\r\n fieldsWithErrors.push(fieldName);\r\n llmResponse.schema[fieldName].default = null;\r\n llmResponse.schema[fieldName].error = `Could not match \"${singleValue}\" to available options`;\r\n }\r\n }\r\n }\r\n }\r\n });\r\n \r\n if (fieldsWithErrors.length > 0) {\r\n llmResponse.matchingErrors = fieldsWithErrors;\r\n }\r\n }\r\n \r\n return llmResponse;\r\n }\r\n\r\n async fillFormFromJson(json: string, schema: any): Promise<any> {\r\n return this.fillForm(json, schema, false);\r\n }\r\n\r\n private async fillForm(data: string, schema: any, dataIsTranscription: boolean = true): Promise<any> {\r\n try {\r\n // Handle complex schema format with fields array\r\n if (schema?.fields || schema?.schema) {\r\n const finalSchema = schema?.fields || schema?.schema;\r\n const systemPrompt = `You are an expert form-filling assistant. You will receive a voice transcription and form field definitions. Your task is to extract values from the spoken content.\r\n Rules:\r\n 1. Only extract values that can be confidently determined from the transcription\r\n 2. Respect field types (string, number, datetime, boolean, select)\r\n 3. For datetime fields, use ISO format (YYYY-MM-DDTHH:MM)\r\n 4. For date fields, use the following format: DD/MM/YYYY\r\n 5. For boolean fields, interpret yes/no, true/false, positive/negative responses\r\n 6. For select fields, use exact option values from the provided choices\r\n 7. Only include fields where relevant information is found\r\n 8. The current GMT datetime is ${(new Date() as any).toGMTString()}\r\n 9. Respect the constraints written between parenthesis for readonly status (readonly fields MUST NOT be filled with values), min and max values, whatever the transcription says\r\n 9b. CRITICAL - DATE/DATETIME OUT OF RANGE: For date and datetime fields with min and/or max constraints, if the value from the transcription falls outside the allowed range, leave the field EMPTY. NEVER clamp, adjust, or substitute a boundary date - either the date is valid and within range, or the field is left empty\r\n 10. IMPORTANT: Fields marked as \"readonly\" are presentation elements (headers, labels) that provide context but MUST NOT receive values\r\n 11. CRITICAL - DUPLICATE FIELDS: When you see multiple fields with the same name but different IDs (e.g., \"ID:field1 | Event date\" and \"ID:field2 | Event date\"), these are DIFFERENT fields in DIFFERENT sections. The user may explicitly say which section they are filling (e.g., \"for the first/second sub-form\"). Listen VERY CAREFULLY to these contextual clues. Use the readonly headers to understand which section each field belongs to. If the user says \"for the clinical sign, the event date is X\", you must fill the Event date field that comes AFTER the \"MC Clinical sign\" header, NOT the first Event date you see\r\n 12. Use readonly fields as contextual hints to understand form structure and field grouping, but never fill them\r\n 13. CRITICAL - UNKNOWN/NO/N-A VALUES: The interpretation of words like \"Unknown\", \"Inconnu\", \"No\", \"Non\", \"N/A\", \"Non applicable\" depends ENTIRELY on whether the field has those words as explicit options. Rule: if the user says \"field X is Unknown\" (or any similar phrasing) AND \"Unknown\" (or a close variant) exists in the options list for that field, then SELECT that option - it is a valid value. If the user says such words for a field that does NOT have them as options (string, number, date, etc.), then it means the user has no value to provide - leave the field empty, do NOT fill it with the literal text\r\n 14. CRITICAL: Each field has a unique ID shown as \"ID:xxx\" at the start of its description. You MUST include this exact ID in your response for each field you fill. The ID is the ONLY way to distinguish between fields with the same name\r\n 15. CRITICAL - DEFAULT VALUES: Some fields have default values shown as \"default=xxx\". If the user does NOT mention a specific value for that field in the transcription, you MUST return the default value. Default values should be preserved unless explicitly overridden by the user\r\n 16. CRITICAL - PATTERN VALIDATION: Some fields have a regex pattern shown as \"pattern=xxx\". The value you extract MUST match this pattern exactly. If the transcription is too ambiguous to produce a value that matches the pattern, leave the field EMPTY\r\n\r\n Respond with JSON in this exact format: {\"fields\": [{\"id\": \"field_id\", \"name\": \"field_name\", \"value\": \"extracted_value\"}]}`;\r\n\r\n let userPrompt = `\r\n Voice transcription: \"${data}\"\r\n\r\n Form fields:\r\n ${this.getOptimizeFieldsDescription(finalSchema)}\r\n\r\n Please extract values from the Transcription for these fields.\r\n `;\r\n\r\n //TODO\r\n\r\n // const userPrompt = (\r\n // dataIsTranscription \r\n // ?\r\n // `Voice transcription: \"${data}\"`\r\n // : \r\n // `Json datas: \"${JSON.stringify(data)}\"`\r\n // )+`\r\n\r\n // Form fields:\r\n // ${this.getOptimizeFieldsDescription(finalSchema)}\r\n\r\n // Please extract values from the ` + \r\n // (\r\n // dataIsTranscription \r\n // ?\r\n // `Transcription`\r\n // : \r\n // `Json generated file`\r\n // )+` for these fields.`;\r\n\r\n const endpoint = this.useProxy ? `${this.baseUrl}/complete` : `${this.baseUrl}/chat/completions`;\r\n const headers: any = { 'Content-Type': 'application/json' };\r\n \r\n if (!this.useProxy) {\r\n headers['Authorization'] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers: headers,\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n { role: 'system', content: systemPrompt },\r\n { role: 'user', content: userPrompt }\r\n ],\r\n response_format: { type: 'json_object' },\r\n temperature: 1,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));\r\n throw new Error(`LLM API failed: ${errorData.error?.message || response.statusText}`);\r\n }\r\n\r\n const result = await response.json();\r\n const llmResponse = JSON.parse(result.choices[0].message.content);\r\n \r\n // Apply fuzzy matching for fields with many options\r\n return this.applyFuzzyMatching(llmResponse, schema);\r\n }\r\n\r\n // Handle simple schema format (backward compatibility)\r\n const systemPrompt = `You are an expert form-filling assistant. You will receive a voice transcription and a JSON form schema. Your task is to intelligently fill the form fields based on the spoken content.\r\n Rules:\r\n 1. Only fill fields that can be confidently determined from the transcription\r\n 2. Respect field types (string, number, date, boolean, select)\r\n 3. For datetime fields, use ISO format (YYYY-MM-DDTHH:MM)\r\n 4. For date fields, use the following format: DD/MM/YYYY\r\n 5. For boolean fields, interpret yes/no, true/false, positive/negative responses\r\n 6. For select fields, match the closest option from the provided choices\r\n 7. Leave fields empty if no relevant information is found\r\n 8. Return the same schema structure with 'default' values filled\r\n 9. The current GMT datetime is ${(new Date() as any).toGMTString()}\r\n 10. Respect the constraints written between parenthesis for readonly status (readonly fields MUST NOT be filled with values), min and max values, whatever the transcription says\r\n 10b. CRITICAL - DATE/DATETIME OUT OF RANGE: For date and datetime fields with min and/or max constraints, if the value from the transcription falls outside the allowed range, leave the field EMPTY. NEVER clamp, adjust, or substitute a boundary date - either the date is valid and within range, or the field is left empty\r\n 11. IMPORTANT: Fields marked as \"readonly\" are presentation elements (headers, labels) that provide context but MUST NOT receive values\r\n 12. CRITICAL - DUPLICATE FIELDS: When you see multiple fields with the same name but different IDs (e.g., \"ID:field1 | Event date\" and \"ID:field2 | Event date\"), these are DIFFERENT fields in DIFFERENT sections. The user will explicitly say which section they are filling (e.g., \"for the first/second sub-form\", \"in the anamnesis section\", \"for the clinical sign\"). Listen VERY CAREFULLY to these contextual clues. Use the readonly headers to understand which section each field belongs to. If the user says \"for the clinical sign, the event date is X\", you must fill the Event date field that comes AFTER the \"MC Clinical sign\" header, NOT the first Event date you see\r\n 13. Use readonly fields as contextual hints to understand form structure and field grouping, but never fill them\r\n 14. CRITICAL - UNKNOWN/NO/N-A VALUES: The interpretation of words like \"Unknown\", \"Inconnu\", \"No\", \"Non\", \"N/A\", \"Non applicable\" depends ENTIRELY on whether the field has those words as explicit options. Rule: if the user says \"field X is Unknown\" (or any similar phrasing) AND \"Unknown\" (or a close variant) exists in the options list for that field, then SELECT that option - it is a valid value. If the user says such words for a field that does NOT have them as options (string, number, date, etc.), then it means the user has no value to provide - leave the field empty, do NOT fill it with the literal text\r\n 15. CRITICAL - PATTERN VALIDATION: Some fields have a regex pattern shown as \"pattern=xxx\". The value you extract MUST match this pattern exactly. If the transcription is too ambiguous to produce a value that matches the pattern, leave the field EMPTY\r\n\r\n Respond with JSON in this exact format: {\"schema\": {...}}`;\r\n\r\n let userPrompt = `\r\n Voice transcription: \"${data}\"\r\n\r\n Form schema to fill:\r\n ${JSON.stringify(schema, null, 2)}\r\n\r\n Please fill the form fields based on the Transcription and return the schema with default values populated.\r\n `;\r\n\r\n // const userPrompt = (\r\n // dataIsTranscription \r\n // ?\r\n // `Voice transcription: \"${data}\"`\r\n // : \r\n // `Json datas: \"${JSON.stringify(data)}\"`\r\n // )+`\r\n\r\n // Form schema to fill:\r\n // ${JSON.stringify(schema, null, 2)}\r\n\r\n // Please fill the form fields based on the ` + \r\n // (\r\n // dataIsTranscription \r\n // ?\r\n // `Transcription`\r\n // : \r\n // `Json generated file`\r\n // )+` nd return the schema with default values populated.`;\r\n\r\n const endpoint = this.useProxy ? `${this.baseUrl}/complete` : `${this.baseUrl}/chat/completions`;\r\n const headers: any = { 'Content-Type': 'application/json' };\r\n \r\n if (!this.useProxy) {\r\n headers['Authorization'] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers: headers,\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n { role: 'system', content: systemPrompt },\r\n { role: 'user', content: userPrompt }\r\n ],\r\n response_format: { type: 'json_object' },\r\n temperature: 1, // Low temperature for consistency\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));\r\n throw new Error(`LLM API failed: ${errorData.error?.message || response.statusText}`);\r\n }\r\n\r\n const result = await response.json();\r\n const filledSchema = JSON.parse(result.choices[0].message.content);\r\n \r\n // Validate that the response has the correct structure\r\n if (!filledSchema.schema) {\r\n throw new Error('Invalid response format from LLM service');\r\n }\r\n\r\n // Apply fuzzy matching for fields with many options\r\n return this.applyFuzzyMatching(filledSchema, schema);\r\n } catch (error) {\r\n throw new Error(`Form filling failed: ${error.message}`);\r\n }\r\n }\r\n}\r\n\r\nexport class AnthropicLLMService implements LLMProvider {\r\n private apiKey: string;\r\n private model: string;\r\n private useProxy: boolean;\r\n private proxyUrl: string;\r\n\r\n constructor(config: ServiceProviderConfig['llm']) {\r\n this.useProxy = config?.useProxy || false;\r\n this.proxyUrl = config?.proxyUrl || 'http://localhost:8492';\r\n this.model = config?.model || 'claude-sonnet-4.5';\r\n this.apiKey = this.useProxy ? '' : (config?.apiKey || '');\r\n if (!this.useProxy && !this.apiKey) {\r\n throw new Error('Anthropic API key is required');\r\n }\r\n }\r\n\r\n async fillFormFromTranscription(transcription: string, schema: any): Promise<any> {\r\n return this.fillForm(transcription, schema);\r\n }\r\n\r\n async fillFormFromJson(json: string, schema: any): Promise<any> {\r\n return this.fillForm(json, schema);\r\n }\r\n\r\n private async fillForm(data: string, schema: any): Promise<any> {\r\n const endpoint = this.useProxy ? `${this.proxyUrl}/complete-anthropic` : 'https://api.anthropic.com/v1/messages';\r\n const headers: any = { 'Content-Type': 'application/json' };\r\n if (!this.useProxy) {\r\n headers['x-api-key'] = this.apiKey;\r\n headers['anthropic-version'] = '2023-06-01';\r\n }\r\n\r\n const finalSchema = schema?.fields || schema?.schema || schema;\r\n const systemPrompt = this.buildSystemPrompt();\r\n const userPrompt = `Data: \"${data}\"\r\n\r\nForm fields:\r\n${JSON.stringify(finalSchema, null, 2)}\r\n\r\nRespond with JSON: {\"fields\": [{\"id\": \"field_id\", \"name\": \"field_name\", \"value\": \"extracted_value\"}]}`;\r\n\r\n const body = this.useProxy\r\n ? { model: this.model, messages: [{ role: 'user', content: userPrompt }], system: systemPrompt }\r\n : { model: this.model, max_tokens: 4096, system: systemPrompt, messages: [{ role: 'user', content: userPrompt }] };\r\n\r\n const response = await fetch(endpoint, { method: 'POST', headers, body: JSON.stringify(body) });\r\n if (!response.ok) {\r\n const err = await response.json().catch(() => ({ error: 'Unknown error' }));\r\n throw new Error(`Anthropic API failed: ${err.error?.message || response.statusText}`);\r\n }\r\n const result = await response.json();\r\n const content = this.useProxy ? result.choices[0].message.content : result.content[0].text;\r\n return JSON.parse(content);\r\n }\r\n\r\n private buildSystemPrompt(): string {\r\n return `You are an expert form-filling assistant. Extract values from the input data and fill form fields.\r\nRules:\r\n1. Only extract values that can be confidently determined\r\n2. Respect field types (string, number, datetime, boolean, select)\r\n3. For datetime fields, use ISO format (YYYY-MM-DDTHH:MM)\r\n4. For date fields, use DD/MM/YYYY format\r\n5. For select fields, use exact option values from the provided choices\r\n6. Leave fields empty if no relevant information is found\r\n7. Fields marked readonly MUST NOT receive values\r\n8. DATE/DATETIME OUT OF RANGE: if a date falls outside min/max constraints, leave the field EMPTY\r\n9. PATTERN VALIDATION: if a field has a pattern, the value MUST match it exactly, otherwise leave empty\r\n10. UNKNOWN VALUES: if the user says \"Unknown\" and it exists as an option, select it; otherwise leave empty\r\nRespond ONLY with valid JSON.`;\r\n }\r\n}\r\n\r\nexport class MistralLLMService implements LLMProvider {\r\n private apiKey: string;\r\n private model: string;\r\n private useProxy: boolean;\r\n private proxyUrl: string;\r\n\r\n constructor(config: ServiceProviderConfig['llm']) {\r\n this.useProxy = config?.useProxy || false;\r\n this.proxyUrl = config?.proxyUrl || 'http://localhost:8492';\r\n this.model = config?.model || 'mistral-medium-latest';\r\n this.apiKey = this.useProxy ? '' : (config?.apiKey || '');\r\n if (!this.useProxy && !this.apiKey) {\r\n throw new Error('Mistral API key is required');\r\n }\r\n }\r\n\r\n async fillFormFromTranscription(transcription: string, schema: any): Promise<any> {\r\n return this.fillForm(transcription, schema);\r\n }\r\n\r\n async fillFormFromJson(json: string, schema: any): Promise<any> {\r\n return this.fillForm(json, schema);\r\n }\r\n\r\n private async fillForm(data: string, schema: any): Promise<any> {\r\n const endpoint = this.useProxy ? `${this.proxyUrl}/complete-mistral` : 'https://api.mistral.ai/v1/chat/completions';\r\n const headers: any = { 'Content-Type': 'application/json' };\r\n if (!this.useProxy) {\r\n headers['Authorization'] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n const finalSchema = schema?.fields || schema?.schema || schema;\r\n const systemPrompt = this.buildSystemPrompt();\r\n const userPrompt = `Data: \"${data}\"\r\n\r\nForm fields:\r\n${JSON.stringify(finalSchema, null, 2)}\r\n\r\nRespond with JSON: {\"fields\": [{\"id\": \"field_id\", \"name\": \"field_name\", \"value\": \"extracted_value\"}]}`;\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [{ role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt }],\r\n response_format: { type: 'json_object' },\r\n }),\r\n });\r\n if (!response.ok) {\r\n const err = await response.json().catch(() => ({ error: 'Unknown error' }));\r\n throw new Error(`Mistral API failed: ${err.error?.message || response.statusText}`);\r\n }\r\n const result = await response.json();\r\n return JSON.parse(result.choices[0].message.content);\r\n }\r\n\r\n private buildSystemPrompt(): string {\r\n return `You are an expert form-filling assistant. Extract values from the input data and fill form fields.\r\nRules:\r\n1. Only extract values that can be confidently determined\r\n2. Respect field types (string, number, datetime, boolean, select)\r\n3. For datetime fields, use ISO format (YYYY-MM-DDTHH:MM)\r\n4. For date fields, use DD/MM/YYYY format\r\n5. For select fields, use exact option values from the provided choices\r\n6. Leave fields empty if no relevant information is found\r\n7. Fields marked readonly MUST NOT receive values\r\n8. DATE/DATETIME OUT OF RANGE: if a date falls outside min/max constraints, leave the field EMPTY\r\n9. PATTERN VALIDATION: if a field has a pattern, the value MUST match it exactly, otherwise leave empty\r\n10. UNKNOWN VALUES: if the user says \"Unknown\" and it exists as an option, select it; otherwise leave empty\r\nRespond ONLY with valid JSON.`;\r\n }\r\n}\r\n\r\nexport class LLMServiceFactory {\r\n static create(config: ServiceProviderConfig): LLMProvider {\r\n const provider = config.llm?.provider || 'openai';\r\n switch (provider) {\r\n case 'openai': return new OpenAILLMService(config.llm);\r\n case 'anthropic': return new AnthropicLLMService(config.llm);\r\n case 'mistral': return new MistralLLMService(config.llm);\r\n default: throw new Error(`Unsupported LLM provider: ${provider}`);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"llm.service.js","sourceRoot":"","sources":["../../src/services/llm.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { LLMProvider, SpeechToTextProvider, ServiceProviderConfig, TranscriptionProvider, CompletionProvider } from '../types/service-providers.types';\r\nimport { FormSchema } from '../types/form-schema.types';\r\nimport { fuzzyMatchOption } from '../utils/fuzzy-match';\r\n\r\nexport class OpenAILLMService implements LLMProvider {\r\n private apiKey: string;\r\n private model: string;\r\n private baseUrl: string;\r\n private useProxy: boolean;\r\n private proxyUrl: string;\r\n\r\n constructor(config: ServiceProviderConfig['llm']) {\r\n this.useProxy = config?.useProxy || false;\r\n this.proxyUrl = config?.proxyUrl || 'http://localhost:8492';\r\n \r\n if (this.useProxy) {\r\n // Mode proxy: pas besoin d'API key\r\n this.apiKey = '';\r\n this.baseUrl = this.proxyUrl;\r\n } else {\r\n // Mode direct: API key requise\r\n this.apiKey = config?.apiKey || this.getEnvironmentVariable('OPENAI_API_KEY') || '';\r\n this.baseUrl = config?.baseUrl || 'https://api.openai.com/v1';\r\n \r\n if (!this.apiKey) {\r\n throw new Error('OpenAI API key is required for LLM service');\r\n }\r\n }\r\n \r\n this.model = config?.model || 'gpt-5-mini';\r\n }\r\n\r\n private getEnvironmentVariable(name: string): string | undefined {\r\n // In browser environment, we might get env vars through other means\r\n if (typeof process !== 'undefined' && process.env) {\r\n return process.env[name];\r\n }\r\n // Check if it's available as a global variable or through other means\r\n return (window as any)[name] || undefined;\r\n }\r\n\r\n private getOptimizeFieldsDescription(schema: any){\r\n if (Array.isArray(schema)) {\r\n return schema.map((field: any) => {\r\n let description = `- ID:${field.id || field.name} | ${field.name || field.title} ` +\r\n `(${field.type}` +\r\n `${field.required ? ', required' : ''}` +\r\n `${field.readonly ? ', readonly' : ''}` +\r\n `${field.default !== undefined && field.default !== null && field.default !== '' ? ', default='+field.default : ''}` +\r\n `${field.min && field.min !== \"\" ? ', min='+field.min : ''}` +\r\n `${field.max && field.max !== \"\" ? ', max='+field.max : ''}` +\r\n `${field.pattern && field.pattern !== \"\" ? ', pattern='+field.pattern : ''}`;\r\n \r\n if (field.options && field.options.length > 0) {\r\n if (field.options.length < 50) {\r\n description += `) - options: ${field.options.join(', ')}`;\r\n } else {\r\n description += `, many options: ${field.options.length} total) - extract raw value, will be matched locally`;\r\n }\r\n } else {\r\n description += ')';\r\n }\r\n \r\n return description;\r\n }).join('\\n');\r\n }\r\n \r\n return Object.entries(schema).map(([fieldName, field]: [string, any]) => {\r\n let description = `- ID:${field.id || fieldName} | ${field.title || fieldName} ` +\r\n `(${field.type}` +\r\n `${field.required ? ', required' : ''}` +\r\n `${field.readonly ? ', readonly' : ''}` +\r\n `${field.default !== undefined && field.default !== null && field.default !== '' ? ', default='+field.default : ''}` +\r\n `${field.min && field.min !== \"\" ? ', min='+field.min : ''}` +\r\n `${field.max && field.max !== \"\" ? ', max='+field.max : ''}` +\r\n `${field.pattern && field.pattern !== \"\" ? ', pattern='+field.pattern : ''}`;\r\n \r\n if (field.options && field.options.length > 0) {\r\n if (field.options.length < 50) {\r\n description += `) - options: ${field.options.join(', ')}`;\r\n } else {\r\n description += `, many options: ${field.options.length} total) - extract raw value, will be matched locally`;\r\n }\r\n } else {\r\n description += ')';\r\n }\r\n \r\n return description;\r\n }).join('\\n');\r\n }\r\n\r\n async fillFormFromTranscription(transcription: string, schema: any): Promise<any> {\r\n return this.fillForm(transcription, schema, true);\r\n }\r\n\r\n private applyFuzzyMatching(llmResponse: any, schema: any): any {\r\n // Handle complex schema format with fields array\r\n if (schema?.fields || schema?.schema) {\r\n const finalSchema = schema?.fields || schema?.schema;\r\n const fieldsWithErrors: string[] = [];\r\n \r\n if (llmResponse.fields && Array.isArray(llmResponse.fields)) {\r\n llmResponse.fields = llmResponse.fields.map((field: any) => {\r\n // Find corresponding schema field\r\n const schemaField = Object.values(finalSchema).find((sf: any) => \r\n (sf.name === field.name || sf.title === field.name)\r\n ) as any;\r\n \r\n if (schemaField && schemaField.options && schemaField.options.length >= 50 && field.value) {\r\n const isMultiselect = schemaField.type === 'multiselect';\r\n \r\n // Handle multiselect (array of values)\r\n if (isMultiselect && Array.isArray(field.value)) {\r\n const matchedValues: string[] = [];\r\n const failedValues: string[] = [];\r\n \r\n field.value.forEach((val: string) => {\r\n const matchResult = fuzzyMatchOption(val, schemaField.options);\r\n if (matchResult) {\r\n matchedValues.push(matchResult.match);\r\n } else {\r\n failedValues.push(val);\r\n }\r\n });\r\n \r\n if (failedValues.length > 0) {\r\n fieldsWithErrors.push(field.name);\r\n field.error = `Could not match values: ${failedValues.join(', ')}`;\r\n }\r\n \r\n field.value = matchedValues.length > 0 ? matchedValues : null;\r\n field.fuzzyMatchConfidence = matchedValues.length / (matchedValues.length + failedValues.length);\r\n } else if (!isMultiselect) {\r\n // Handle single value (select, classification, thesaurus, position)\r\n const singleValue = Array.isArray(field.value) ? field.value[0] : field.value;\r\n const matchResult = fuzzyMatchOption(singleValue, schemaField.options);\r\n \r\n if (matchResult) {\r\n field.value = matchResult.match;\r\n field.fuzzyMatchConfidence = matchResult.confidence;\r\n } else {\r\n fieldsWithErrors.push(field.name);\r\n field.value = null;\r\n field.error = `Could not match \"${singleValue}\" to available options`;\r\n }\r\n }\r\n }\r\n \r\n return field;\r\n });\r\n }\r\n \r\n if (fieldsWithErrors.length > 0) {\r\n llmResponse.matchingErrors = fieldsWithErrors;\r\n }\r\n \r\n return llmResponse;\r\n }\r\n \r\n // Handle simple schema format\r\n if (schema?.schema) {\r\n const fieldsWithErrors: string[] = [];\r\n \r\n Object.entries(schema.schema).forEach(([fieldName, fieldDef]: [string, any]) => {\r\n if (fieldDef.options && fieldDef.options.length >= 50) {\r\n const fieldValue = llmResponse.schema?.[fieldName]?.default;\r\n \r\n if (fieldValue) {\r\n const isMultiselect = fieldDef.type === 'multiselect';\r\n \r\n // Handle multiselect (array of values)\r\n if (isMultiselect && Array.isArray(fieldValue)) {\r\n const matchedValues: string[] = [];\r\n const failedValues: string[] = [];\r\n \r\n fieldValue.forEach((val: string) => {\r\n const matchResult = fuzzyMatchOption(val, fieldDef.options);\r\n if (matchResult) {\r\n matchedValues.push(matchResult.match);\r\n } else {\r\n failedValues.push(val);\r\n }\r\n });\r\n \r\n if (failedValues.length > 0) {\r\n fieldsWithErrors.push(fieldName);\r\n llmResponse.schema[fieldName].error = `Could not match values: ${failedValues.join(', ')}`;\r\n }\r\n \r\n llmResponse.schema[fieldName].default = matchedValues.length > 0 ? matchedValues : null;\r\n llmResponse.schema[fieldName].fuzzyMatchConfidence = matchedValues.length / (matchedValues.length + failedValues.length);\r\n } else if (!isMultiselect) {\r\n // Handle single value (select, classification, thesaurus, position)\r\n const singleValue = Array.isArray(fieldValue) ? fieldValue[0] : fieldValue;\r\n const matchResult = fuzzyMatchOption(singleValue, fieldDef.options);\r\n \r\n if (matchResult) {\r\n llmResponse.schema[fieldName].default = matchResult.match;\r\n llmResponse.schema[fieldName].fuzzyMatchConfidence = matchResult.confidence;\r\n } else {\r\n fieldsWithErrors.push(fieldName);\r\n llmResponse.schema[fieldName].default = null;\r\n llmResponse.schema[fieldName].error = `Could not match \"${singleValue}\" to available options`;\r\n }\r\n }\r\n }\r\n }\r\n });\r\n \r\n if (fieldsWithErrors.length > 0) {\r\n llmResponse.matchingErrors = fieldsWithErrors;\r\n }\r\n }\r\n \r\n return llmResponse;\r\n }\r\n\r\n async fillFormFromJson(json: string, schema: any): Promise<any> {\r\n return this.fillForm(json, schema, false);\r\n }\r\n\r\n private async fillForm(data: string, schema: any, dataIsTranscription: boolean = true): Promise<any> {\r\n try {\r\n // Handle complex schema format with fields array\r\n if (schema?.fields || schema?.schema) {\r\n const finalSchema = schema?.fields || schema?.schema;\r\n const systemPrompt = `You are an expert form-filling assistant. You will receive a voice transcription and form field definitions. Your task is to extract values from the spoken content.\r\n Rules:\r\n 1. Only extract values that can be confidently determined from the transcription\r\n 2. Respect field types (string, number, datetime, boolean, select)\r\n 3. For datetime fields, use ISO format (YYYY-MM-DDTHH:MM)\r\n 4. For date fields, use the following format: DD/MM/YYYY\r\n 5. For boolean fields, interpret yes/no, true/false, positive/negative responses\r\n 6. For select fields, use exact option values from the provided choices\r\n 7. Only include fields where relevant information is found\r\n 8. The current GMT datetime is ${(new Date() as any).toGMTString()}\r\n 9. Respect the constraints written between parenthesis for readonly status (readonly fields MUST NOT be filled with values), min and max values, whatever the transcription says\r\n 9b. CRITICAL - DATE/DATETIME OUT OF RANGE: For date and datetime fields with min and/or max constraints, if the value from the transcription falls outside the allowed range, leave the field EMPTY. NEVER clamp, adjust, or substitute a boundary date - either the date is valid and within range, or the field is left empty\r\n 10. IMPORTANT: Fields marked as \"readonly\" are presentation elements (headers, labels) that provide context but MUST NOT receive values\r\n 11. CRITICAL - DUPLICATE FIELDS: When you see multiple fields with the same name but different IDs (e.g., \"ID:field1 | Event date\" and \"ID:field2 | Event date\"), these are DIFFERENT fields in DIFFERENT sections. The user may explicitly say which section they are filling (e.g., \"for the first/second sub-form\"). Listen VERY CAREFULLY to these contextual clues. Use the readonly headers to understand which section each field belongs to. If the user says \"for the clinical sign, the event date is X\", you must fill the Event date field that comes AFTER the \"MC Clinical sign\" header, NOT the first Event date you see\r\n 12. Use readonly fields as contextual hints to understand form structure and field grouping, but never fill them\r\n 13. CRITICAL - UNKNOWN/NO/N-A VALUES: The interpretation of words like \"Unknown\", \"Inconnu\", \"No\", \"Non\", \"N/A\", \"Non applicable\" depends ENTIRELY on whether the field has those words as explicit options. Rule: if the user says \"field X is Unknown\" (or any similar phrasing) AND \"Unknown\" (or a close variant) exists in the options list for that field, then SELECT that option - it is a valid value. If the user says such words for a field that does NOT have them as options (string, number, date, etc.), then it means the user has no value to provide - leave the field empty, do NOT fill it with the literal text\r\n 14. CRITICAL: Each field has a unique ID shown as \"ID:xxx\" at the start of its description. You MUST include this exact ID in your response for each field you fill. The ID is the ONLY way to distinguish between fields with the same name\r\n 15. CRITICAL - DEFAULT VALUES: Some fields have default values shown as \"default=xxx\". If the user does NOT mention a specific value for that field in the transcription, you MUST return the default value. Default values should be preserved unless explicitly overridden by the user\r\n 16. CRITICAL - PATTERN VALIDATION: Some fields have a regex pattern shown as \"pattern=xxx\". The value you extract MUST match this pattern exactly. If the transcription is too ambiguous to produce a value that matches the pattern, leave the field EMPTY\r\n 17. CONFIDENCE SCORE: For each field you fill, add a \"confidence\" property (number between 0.01 and 0.99, maximum 2 decimal places) reflecting how certain you are about the extracted value. Use values close to 0.99 for values that are explicitly and unambiguously stated, lower values when you had to infer, interpret, paraphrase, or when the match was approximate.\r\n\r\n Respond with JSON in this exact format: {\"fields\": [{\"id\": \"field_id\", \"name\": \"field_name\", \"value\": \"extracted_value\", \"confidence\": 0.87}]}`;\r\n\r\n let userPrompt = `\r\n Voice transcription: \"${data}\"\r\n\r\n Form fields:\r\n ${this.getOptimizeFieldsDescription(finalSchema)}\r\n\r\n Please extract values from the Transcription for these fields.\r\n `;\r\n\r\n //TODO\r\n\r\n // const userPrompt = (\r\n // dataIsTranscription \r\n // ?\r\n // `Voice transcription: \"${data}\"`\r\n // : \r\n // `Json datas: \"${JSON.stringify(data)}\"`\r\n // )+`\r\n\r\n // Form fields:\r\n // ${this.getOptimizeFieldsDescription(finalSchema)}\r\n\r\n // Please extract values from the ` + \r\n // (\r\n // dataIsTranscription \r\n // ?\r\n // `Transcription`\r\n // : \r\n // `Json generated file`\r\n // )+` for these fields.`;\r\n\r\n const endpoint = this.useProxy ? `${this.baseUrl}/complete` : `${this.baseUrl}/chat/completions`;\r\n const headers: any = { 'Content-Type': 'application/json' };\r\n \r\n if (!this.useProxy) {\r\n headers['Authorization'] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers: headers,\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n { role: 'system', content: systemPrompt },\r\n { role: 'user', content: userPrompt }\r\n ],\r\n response_format: { type: 'json_object' },\r\n temperature: 1,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));\r\n throw new Error(`LLM API failed: ${errorData.error?.message || response.statusText}`);\r\n }\r\n\r\n const result = await response.json();\r\n const llmResponse = JSON.parse(result.choices[0].message.content);\r\n \r\n // Apply fuzzy matching for fields with many options\r\n return this.applyFuzzyMatching(llmResponse, schema);\r\n }\r\n\r\n // Handle simple schema format (backward compatibility)\r\n const systemPrompt = `You are an expert form-filling assistant. You will receive a voice transcription and a JSON form schema. Your task is to intelligently fill the form fields based on the spoken content.\r\n Rules:\r\n 1. Only fill fields that can be confidently determined from the transcription\r\n 2. Respect field types (string, number, date, boolean, select)\r\n 3. For datetime fields, use ISO format (YYYY-MM-DDTHH:MM)\r\n 4. For date fields, use the following format: DD/MM/YYYY\r\n 5. For boolean fields, interpret yes/no, true/false, positive/negative responses\r\n 6. For select fields, match the closest option from the provided choices\r\n 7. Leave fields empty if no relevant information is found\r\n 8. Return the same schema structure with 'default' values filled\r\n 9. The current GMT datetime is ${(new Date() as any).toGMTString()}\r\n 10. Respect the constraints written between parenthesis for readonly status (readonly fields MUST NOT be filled with values), min and max values, whatever the transcription says\r\n 10b. CRITICAL - DATE/DATETIME OUT OF RANGE: For date and datetime fields with min and/or max constraints, if the value from the transcription falls outside the allowed range, leave the field EMPTY. NEVER clamp, adjust, or substitute a boundary date - either the date is valid and within range, or the field is left empty\r\n 11. IMPORTANT: Fields marked as \"readonly\" are presentation elements (headers, labels) that provide context but MUST NOT receive values\r\n 12. CRITICAL - DUPLICATE FIELDS: When you see multiple fields with the same name but different IDs (e.g., \"ID:field1 | Event date\" and \"ID:field2 | Event date\"), these are DIFFERENT fields in DIFFERENT sections. The user will explicitly say which section they are filling (e.g., \"for the first/second sub-form\", \"in the anamnesis section\", \"for the clinical sign\"). Listen VERY CAREFULLY to these contextual clues. Use the readonly headers to understand which section each field belongs to. If the user says \"for the clinical sign, the event date is X\", you must fill the Event date field that comes AFTER the \"MC Clinical sign\" header, NOT the first Event date you see\r\n 13. Use readonly fields as contextual hints to understand form structure and field grouping, but never fill them\r\n 14. CRITICAL - UNKNOWN/NO/N-A VALUES: The interpretation of words like \"Unknown\", \"Inconnu\", \"No\", \"Non\", \"N/A\", \"Non applicable\" depends ENTIRELY on whether the field has those words as explicit options. Rule: if the user says \"field X is Unknown\" (or any similar phrasing) AND \"Unknown\" (or a close variant) exists in the options list for that field, then SELECT that option - it is a valid value. If the user says such words for a field that does NOT have them as options (string, number, date, etc.), then it means the user has no value to provide - leave the field empty, do NOT fill it with the literal text\r\n 15. CRITICAL - PATTERN VALIDATION: Some fields have a regex pattern shown as \"pattern=xxx\". The value you extract MUST match this pattern exactly. If the transcription is too ambiguous to produce a value that matches the pattern, leave the field EMPTY\r\n 16. CONFIDENCE SCORE: For each field you fill, add its name as a key in a top-level \"confidence\" object with a score from 0.01 to 0.99 (max 2 decimal places). Use values close to 0.99 for clearly stated values, lower when you had to infer, interpret, or approximate.\r\n\r\n Respond with JSON in this exact format: {\"schema\": {...}, \"confidence\": {\"field_name\": 0.87}}`;\r\n\r\n let userPrompt = `\r\n Voice transcription: \"${data}\"\r\n\r\n Form schema to fill:\r\n ${JSON.stringify(schema, null, 2)}\r\n\r\n Please fill the form fields based on the Transcription and return the schema with default values populated.\r\n `;\r\n\r\n // const userPrompt = (\r\n // dataIsTranscription \r\n // ?\r\n // `Voice transcription: \"${data}\"`\r\n // : \r\n // `Json datas: \"${JSON.stringify(data)}\"`\r\n // )+`\r\n\r\n // Form schema to fill:\r\n // ${JSON.stringify(schema, null, 2)}\r\n\r\n // Please fill the form fields based on the ` + \r\n // (\r\n // dataIsTranscription \r\n // ?\r\n // `Transcription`\r\n // : \r\n // `Json generated file`\r\n // )+` nd return the schema with default values populated.`;\r\n\r\n const endpoint = this.useProxy ? `${this.baseUrl}/complete` : `${this.baseUrl}/chat/completions`;\r\n const headers: any = { 'Content-Type': 'application/json' };\r\n \r\n if (!this.useProxy) {\r\n headers['Authorization'] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers: headers,\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [\r\n { role: 'system', content: systemPrompt },\r\n { role: 'user', content: userPrompt }\r\n ],\r\n response_format: { type: 'json_object' },\r\n temperature: 1, // Low temperature for consistency\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));\r\n throw new Error(`LLM API failed: ${errorData.error?.message || response.statusText}`);\r\n }\r\n\r\n const result = await response.json();\r\n const filledSchema = JSON.parse(result.choices[0].message.content);\r\n \r\n // Validate that the response has the correct structure\r\n if (!filledSchema.schema) {\r\n throw new Error('Invalid response format from LLM service');\r\n }\r\n\r\n // Apply fuzzy matching for fields with many options\r\n return this.applyFuzzyMatching(filledSchema, schema);\r\n } catch (error) {\r\n throw new Error(`Form filling failed: ${error.message}`);\r\n }\r\n }\r\n}\r\n\r\nexport class AnthropicLLMService implements LLMProvider {\r\n private apiKey: string;\r\n private model: string;\r\n private useProxy: boolean;\r\n private proxyUrl: string;\r\n\r\n constructor(config: ServiceProviderConfig['llm']) {\r\n this.useProxy = config?.useProxy || false;\r\n this.proxyUrl = config?.proxyUrl || 'http://localhost:8492';\r\n this.model = config?.model || 'claude-sonnet-4.5';\r\n this.apiKey = this.useProxy ? '' : (config?.apiKey || '');\r\n if (!this.useProxy && !this.apiKey) {\r\n throw new Error('Anthropic API key is required');\r\n }\r\n }\r\n\r\n async fillFormFromTranscription(transcription: string, schema: any): Promise<any> {\r\n return this.fillForm(transcription, schema);\r\n }\r\n\r\n async fillFormFromJson(json: string, schema: any): Promise<any> {\r\n return this.fillForm(json, schema);\r\n }\r\n\r\n private async fillForm(data: string, schema: any): Promise<any> {\r\n const endpoint = this.useProxy ? `${this.proxyUrl}/complete-anthropic` : 'https://api.anthropic.com/v1/messages';\r\n const headers: any = { 'Content-Type': 'application/json' };\r\n if (!this.useProxy) {\r\n headers['x-api-key'] = this.apiKey;\r\n headers['anthropic-version'] = '2023-06-01';\r\n }\r\n\r\n const finalSchema = schema?.fields || schema?.schema || schema;\r\n const systemPrompt = this.buildSystemPrompt();\r\n const userPrompt = `Data: \"${data}\"\r\n\r\nForm fields:\r\n${JSON.stringify(finalSchema, null, 2)}\r\n\r\nRespond with JSON: {\"fields\": [{\"id\": \"field_id\", \"name\": \"field_name\", \"value\": \"extracted_value\", \"confidence\": 0.87}]}`;\r\n\r\n const body = this.useProxy\r\n ? { model: this.model, messages: [{ role: 'user', content: userPrompt }], system: systemPrompt }\r\n : { model: this.model, max_tokens: 4096, system: systemPrompt, messages: [{ role: 'user', content: userPrompt }] };\r\n\r\n const response = await fetch(endpoint, { method: 'POST', headers, body: JSON.stringify(body) });\r\n if (!response.ok) {\r\n const err = await response.json().catch(() => ({ error: 'Unknown error' }));\r\n throw new Error(`Anthropic API failed: ${err.error?.message || response.statusText}`);\r\n }\r\n const result = await response.json();\r\n const content = this.useProxy ? result.choices[0].message.content : result.content[0].text;\r\n return JSON.parse(content);\r\n }\r\n\r\n private buildSystemPrompt(): string {\r\n return `You are an expert form-filling assistant. Extract values from the input data and fill form fields.\r\nRules:\r\n1. Only extract values that can be confidently determined\r\n2. Respect field types (string, number, datetime, boolean, select)\r\n3. For datetime fields, use ISO format (YYYY-MM-DDTHH:MM)\r\n4. For date fields, use DD/MM/YYYY format\r\n5. For select fields, use exact option values from the provided choices\r\n6. Leave fields empty if no relevant information is found\r\n7. Fields marked readonly MUST NOT receive values\r\n8. DATE/DATETIME OUT OF RANGE: if a date falls outside min/max constraints, leave the field EMPTY\r\n9. PATTERN VALIDATION: if a field has a pattern, the value MUST match it exactly, otherwise leave empty\r\n10. UNKNOWN VALUES: if the user says \"Unknown\" and it exists as an option, select it; otherwise leave empty\r\n11. CONFIDENCE SCORE: For each field you fill, add a \"confidence\" property (number between 0.01 and 0.99, max 2 decimal places) reflecting how certain you are about the extracted value. Use values close to 0.99 for clearly stated values, lower when you had to infer or approximate.\r\nRespond ONLY with valid JSON.`;\r\n }\r\n}\r\n\r\nexport class MistralLLMService implements LLMProvider {\r\n private apiKey: string;\r\n private model: string;\r\n private useProxy: boolean;\r\n private proxyUrl: string;\r\n\r\n constructor(config: ServiceProviderConfig['llm']) {\r\n this.useProxy = config?.useProxy || false;\r\n this.proxyUrl = config?.proxyUrl || 'http://localhost:8492';\r\n this.model = config?.model || 'mistral-medium-latest';\r\n this.apiKey = this.useProxy ? '' : (config?.apiKey || '');\r\n if (!this.useProxy && !this.apiKey) {\r\n throw new Error('Mistral API key is required');\r\n }\r\n }\r\n\r\n async fillFormFromTranscription(transcription: string, schema: any): Promise<any> {\r\n return this.fillForm(transcription, schema);\r\n }\r\n\r\n async fillFormFromJson(json: string, schema: any): Promise<any> {\r\n return this.fillForm(json, schema);\r\n }\r\n\r\n private async fillForm(data: string, schema: any): Promise<any> {\r\n const endpoint = this.useProxy ? `${this.proxyUrl}/complete-mistral` : 'https://api.mistral.ai/v1/chat/completions';\r\n const headers: any = { 'Content-Type': 'application/json' };\r\n if (!this.useProxy) {\r\n headers['Authorization'] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n const finalSchema = schema?.fields || schema?.schema || schema;\r\n const systemPrompt = this.buildSystemPrompt();\r\n const userPrompt = `Data: \"${data}\"\r\n\r\nForm fields:\r\n${JSON.stringify(finalSchema, null, 2)}\r\n\r\nRespond with JSON: {\"fields\": [{\"id\": \"field_id\", \"name\": \"field_name\", \"value\": \"extracted_value\", \"confidence\": 0.87}]}`;\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify({\r\n model: this.model,\r\n messages: [{ role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt }],\r\n response_format: { type: 'json_object' },\r\n }),\r\n });\r\n if (!response.ok) {\r\n const err = await response.json().catch(() => ({ error: 'Unknown error' }));\r\n throw new Error(`Mistral API failed: ${err.error?.message || response.statusText}`);\r\n }\r\n const result = await response.json();\r\n return JSON.parse(result.choices[0].message.content);\r\n }\r\n\r\n private buildSystemPrompt(): string {\r\n return `You are an expert form-filling assistant. Extract values from the input data and fill form fields.\r\nRules:\r\n1. Only extract values that can be confidently determined\r\n2. Respect field types (string, number, datetime, boolean, select)\r\n3. For datetime fields, use ISO format (YYYY-MM-DDTHH:MM)\r\n4. For date fields, use DD/MM/YYYY format\r\n5. For select fields, use exact option values from the provided choices\r\n6. Leave fields empty if no relevant information is found\r\n7. Fields marked readonly MUST NOT receive values\r\n8. DATE/DATETIME OUT OF RANGE: if a date falls outside min/max constraints, leave the field EMPTY\r\n9. PATTERN VALIDATION: if a field has a pattern, the value MUST match it exactly, otherwise leave empty\r\n10. UNKNOWN VALUES: if the user says \"Unknown\" and it exists as an option, select it; otherwise leave empty\r\n11. CONFIDENCE SCORE: For each field you fill, add a \"confidence\" property (number between 0.01 and 0.99, max 2 decimal places) reflecting how certain you are about the extracted value. Use values close to 0.99 for clearly stated values, lower when you had to infer or approximate.\r\nRespond ONLY with valid JSON.`;\r\n }\r\n}\r\n\r\nexport class LLMServiceFactory {\r\n static create(config: ServiceProviderConfig): LLMProvider {\r\n const provider = config.llm?.provider || 'openai';\r\n switch (provider) {\r\n case 'openai': return new OpenAILLMService(config.llm);\r\n case 'anthropic': return new AnthropicLLMService(config.llm);\r\n case 'mistral': return new MistralLLMService(config.llm);\r\n default: throw new Error(`Unsupported LLM provider: ${provider}`);\r\n }\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"form-schema.types.js","sourceRoot":"","sources":["../../src/types/form-schema.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface FormField {\r\n id?: string;\r\n type: 'string' | 'number' | 'date' | 'boolean' | 'select' | 'header' | 'dbpicker';\r\n title: string;\r\n description?: string;\r\n required?: boolean;\r\n default?: any;\r\n options?: string[]; // For select fields\r\n pattern?: string; // For validation\r\n readonly?: boolean;\r\n min?: number;\r\n max?: number;\r\n}\r\nexport interface FormFieldExtended extends FormField {\r\n realType?: string;\r\n pickerOptions?: any[];\r\n\r\n ID?: string;\r\n TFie_PK_ID?: string;\r\n TVal_PK_ID?: string;\r\n TFIn_PK_ID?: string;\r\n Enabled?: boolean;\r\n isForm?: string;\r\n LabelText?: string;\r\n LabelTextFr?: string;\r\n SystemName?: string;\r\n HelpText?: string;\r\n CssStyle?: string;\r\n ControlType?: string;\r\n ValidationRequired?: string;\r\n ValidationMin?: string;\r\n ValidationMax?: string;\r\n Mask?: string;\r\n TypeId?: string;\r\n Unit?: string;\r\n TFie_Fullpath?: string;\r\n TVal_FK_Parent_ID?: string;\r\n value?: any;\r\n}\r\n\r\nexport interface FormSchema {\r\n schema: {\r\n [fieldName: string]: FormField;\r\n };\r\n title?: string;\r\n description?: string;\r\n}\r\n\r\nexport interface FormSchemaFieldsOnly {\r\n fields: {\r\n [fieldName: string]: FormField;\r\n };\r\n}\r\n\r\nexport interface FormSchemaExtended {\r\n schema: {\r\n [fieldName: string]: FormFieldExtended;\r\n };\r\n title?: string;\r\n description?: string;\r\n}\r\n\r\n\r\nexport interface FormSchemaFieldsOnlyExtended {\r\n fields: {\r\n [fieldName: string]: FormFieldExtended;\r\n };\r\n}\r\n\r\nexport interface FilledFormData {\r\n [fieldName: string]: any;\r\n}\r\n\r\nexport interface VoiceFormRecorderResult {\r\n success: boolean;\r\n data?: FilledFormData;\r\n error?: string;\r\n transcription?: string;\r\n jsonForm?: string;\r\n}\r\n"]}
1
+ {"version":3,"file":"form-schema.types.js","sourceRoot":"","sources":["../../src/types/form-schema.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface FormField {\r\n id?: string;\r\n type: 'string' | 'number' | 'date' | 'boolean' | 'select' | 'header' | 'dbpicker';\r\n title: string;\r\n description?: string;\r\n required?: boolean;\r\n default?: any;\r\n options?: string[]; // For select fields\r\n pattern?: string; // For validation\r\n readonly?: boolean;\r\n min?: number;\r\n max?: number;\r\n}\r\nexport interface FormFieldExtended extends FormField {\r\n realType?: string;\r\n pickerOptions?: any[];\r\n\r\n ID?: string;\r\n TFie_PK_ID?: string;\r\n TVal_PK_ID?: string;\r\n TFIn_PK_ID?: string;\r\n Enabled?: boolean;\r\n isForm?: string;\r\n LabelText?: string;\r\n LabelTextFr?: string;\r\n SystemName?: string;\r\n HelpText?: string;\r\n CssStyle?: string;\r\n ControlType?: string;\r\n ValidationRequired?: string;\r\n ValidationMin?: string;\r\n ValidationMax?: string;\r\n Mask?: string;\r\n TypeId?: string;\r\n Unit?: string;\r\n TFie_Fullpath?: string;\r\n TVal_FK_Parent_ID?: string;\r\n value?: any;\r\n}\r\n\r\nexport interface FormSchema {\r\n schema: {\r\n [fieldName: string]: FormField;\r\n };\r\n title?: string;\r\n description?: string;\r\n}\r\n\r\nexport interface FormSchemaFieldsOnly {\r\n fields: {\r\n [fieldName: string]: FormField;\r\n };\r\n}\r\n\r\nexport interface FormSchemaExtended {\r\n schema: {\r\n [fieldName: string]: FormFieldExtended;\r\n };\r\n title?: string;\r\n description?: string;\r\n}\r\n\r\n\r\nexport interface FormSchemaFieldsOnlyExtended {\r\n fields: {\r\n [fieldName: string]: FormFieldExtended;\r\n };\r\n}\r\n\r\nexport interface FilledFormData {\r\n [fieldName: string]: any;\r\n}\r\n\r\nexport interface VoiceFormRecorderResult {\r\n success: boolean;\r\n data?: FilledFormData;\r\n confidence?: Record<string, number>;\r\n error?: string;\r\n transcription?: string;\r\n jsonForm?: string;\r\n}\r\n"]}
@@ -562,8 +562,9 @@ class OpenAILLMService {
562
562
  14. CRITICAL: Each field has a unique ID shown as "ID:xxx" at the start of its description. You MUST include this exact ID in your response for each field you fill. The ID is the ONLY way to distinguish between fields with the same name
563
563
  15. CRITICAL - DEFAULT VALUES: Some fields have default values shown as "default=xxx". If the user does NOT mention a specific value for that field in the transcription, you MUST return the default value. Default values should be preserved unless explicitly overridden by the user
564
564
  16. CRITICAL - PATTERN VALIDATION: Some fields have a regex pattern shown as "pattern=xxx". The value you extract MUST match this pattern exactly. If the transcription is too ambiguous to produce a value that matches the pattern, leave the field EMPTY
565
+ 17. CONFIDENCE SCORE: For each field you fill, add a "confidence" property (number between 0.01 and 0.99, maximum 2 decimal places) reflecting how certain you are about the extracted value. Use values close to 0.99 for values that are explicitly and unambiguously stated, lower values when you had to infer, interpret, paraphrase, or when the match was approximate.
565
566
 
566
- Respond with JSON in this exact format: {"fields": [{"id": "field_id", "name": "field_name", "value": "extracted_value"}]}`;
567
+ Respond with JSON in this exact format: {"fields": [{"id": "field_id", "name": "field_name", "value": "extracted_value", "confidence": 0.87}]}`;
567
568
  let userPrompt = `
568
569
  Voice transcription: "${data}"
569
570
 
@@ -636,8 +637,9 @@ class OpenAILLMService {
636
637
  13. Use readonly fields as contextual hints to understand form structure and field grouping, but never fill them
637
638
  14. CRITICAL - UNKNOWN/NO/N-A VALUES: The interpretation of words like "Unknown", "Inconnu", "No", "Non", "N/A", "Non applicable" depends ENTIRELY on whether the field has those words as explicit options. Rule: if the user says "field X is Unknown" (or any similar phrasing) AND "Unknown" (or a close variant) exists in the options list for that field, then SELECT that option - it is a valid value. If the user says such words for a field that does NOT have them as options (string, number, date, etc.), then it means the user has no value to provide - leave the field empty, do NOT fill it with the literal text
638
639
  15. CRITICAL - PATTERN VALIDATION: Some fields have a regex pattern shown as "pattern=xxx". The value you extract MUST match this pattern exactly. If the transcription is too ambiguous to produce a value that matches the pattern, leave the field EMPTY
640
+ 16. CONFIDENCE SCORE: For each field you fill, add its name as a key in a top-level "confidence" object with a score from 0.01 to 0.99 (max 2 decimal places). Use values close to 0.99 for clearly stated values, lower when you had to infer, interpret, or approximate.
639
641
 
640
- Respond with JSON in this exact format: {"schema": {...}}`;
642
+ Respond with JSON in this exact format: {"schema": {...}, "confidence": {"field_name": 0.87}}`;
641
643
  let userPrompt = `
642
644
  Voice transcription: "${data}"
643
645
 
@@ -730,7 +732,7 @@ class AnthropicLLMService {
730
732
  Form fields:
731
733
  ${JSON.stringify(finalSchema, null, 2)}
732
734
 
733
- Respond with JSON: {"fields": [{"id": "field_id", "name": "field_name", "value": "extracted_value"}]}`;
735
+ Respond with JSON: {"fields": [{"id": "field_id", "name": "field_name", "value": "extracted_value", "confidence": 0.87}]}`;
734
736
  const body = this.useProxy
735
737
  ? { model: this.model, messages: [{ role: 'user', content: userPrompt }], system: systemPrompt }
736
738
  : { model: this.model, max_tokens: 4096, system: systemPrompt, messages: [{ role: 'user', content: userPrompt }] };
@@ -756,6 +758,7 @@ Rules:
756
758
  8. DATE/DATETIME OUT OF RANGE: if a date falls outside min/max constraints, leave the field EMPTY
757
759
  9. PATTERN VALIDATION: if a field has a pattern, the value MUST match it exactly, otherwise leave empty
758
760
  10. UNKNOWN VALUES: if the user says "Unknown" and it exists as an option, select it; otherwise leave empty
761
+ 11. CONFIDENCE SCORE: For each field you fill, add a "confidence" property (number between 0.01 and 0.99, max 2 decimal places) reflecting how certain you are about the extracted value. Use values close to 0.99 for clearly stated values, lower when you had to infer or approximate.
759
762
  Respond ONLY with valid JSON.`;
760
763
  }
761
764
  }
@@ -789,7 +792,7 @@ class MistralLLMService {
789
792
  Form fields:
790
793
  ${JSON.stringify(finalSchema, null, 2)}
791
794
 
792
- Respond with JSON: {"fields": [{"id": "field_id", "name": "field_name", "value": "extracted_value"}]}`;
795
+ Respond with JSON: {"fields": [{"id": "field_id", "name": "field_name", "value": "extracted_value", "confidence": 0.87}]}`;
793
796
  const response = await fetch(endpoint, {
794
797
  method: 'POST',
795
798
  headers,
@@ -819,6 +822,7 @@ Rules:
819
822
  8. DATE/DATETIME OUT OF RANGE: if a date falls outside min/max constraints, leave the field EMPTY
820
823
  9. PATTERN VALIDATION: if a field has a pattern, the value MUST match it exactly, otherwise leave empty
821
824
  10. UNKNOWN VALUES: if the user says "Unknown" and it exists as an option, select it; otherwise leave empty
825
+ 11. CONFIDENCE SCORE: For each field you fill, add a "confidence" property (number between 0.01 and 0.99, max 2 decimal places) reflecting how certain you are about the extracted value. Use values close to 0.99 for clearly stated values, lower when you had to infer or approximate.
822
826
  Respond ONLY with valid JSON.`;
823
827
  }
824
828
  }
@@ -4326,7 +4330,7 @@ const defineCustomElements = async (win, options) => {
4326
4330
 
4327
4331
  (function(){if("undefined"!==typeof window&&void 0!==window.Reflect&&void 0!==window.customElements){var a=HTMLElement;window.HTMLElement=function(){return Reflect.construct(a,[],this.constructor)};HTMLElement.prototype=a.prototype;HTMLElement.prototype.constructor=HTMLElement;Object.setPrototypeOf(HTMLElement,a);}})();
4328
4332
 
4329
- const voiceInputModuleCss = ":host{display:block;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif}.row-audio-area{display:flex;flex-direction:row;align-items:center;gap:8px;flex-wrap:wrap;justify-content:center}.voice-recorder-container{display:flex;flex-direction:column;align-items:center;gap:1rem;padding:1rem;border:1px solid #e5e7eb;border-radius:0.5rem;background:#ffffff;margin:0 auto}.voice-recorder-container-debug{display:flex;flex-direction:column;align-items:center;gap:1rem;padding:1rem;border:1px solid #e5e7eb;border-radius:0.5rem;background:#ffffff;margin:0 auto}.upload-record-container{display:inline-flex;cursor:pointer}.upload-record-button{display:flex;align-items:center;justify-content:center;transition:transform 0.2s ease, box-shadow 0.2s ease;user-select:none}.upload-record-button svg{width:100%;height:100%;transition:transform 0.2s ease}.upload-record-container:hover .upload-record-button svg{transform:scale(1.05)}.upload-record-button svg path{}.record-button{display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:#ee4444;color:white;cursor:pointer;transition:all 0.2s ease;position:relative;overflow:hidden;flex-shrink:0}.record-button:hover:not(:disabled){background:#dd3333;transform:scale(1.05)}.record-button:disabled{opacity:0.6;cursor:not-allowed}.record-button.recording{background:#dd3333;animation:pulse 1.5s infinite}.record-button.processing{background:#3b82f6}@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(239, 68, 68, 0.7)}70%{box-shadow:0 0 0 10px rgba(239, 68, 68, 0)}100%{box-shadow:0 0 0 0 rgba(239, 68, 68, 0)}}.record-icon{width:24px;height:24px;fill:currentColor}.status-text{font-size:0.875rem;color:#6b7280;text-align:center;min-height:1.25rem}.status-text.error{color:#ee4444}.status-text.success{color:#10b981}.debug-panel{width:100%;margin-top:1rem;padding:1rem;background:#f9fafb;border:1px solid #e5e7eb;border-radius:0.375rem;font-family:'Monaco', 'Menlo', 'Ubuntu Mono', monospace;font-size:0.75rem}.debug-title{font-weight:600;margin-bottom:0.5rem;color:#374151}.debug-content{white-space:pre-wrap;word-break:break-word;color:#6b7280;max-height:200px;overflow-y:auto}.permissions-warning{padding:0.75rem;background:#fef3c7;border:1px solid #f59e0b;border-radius:0.375rem;color:#92400e;font-size:0.875rem;text-align:center}.form-preview{width:100%;margin-top:1rem;padding:1rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:0.375rem}.form-preview-title{font-weight:600;margin-bottom:0.5rem;color:#1e293b}.form-field{margin-bottom:0.5rem;font-size:0.875rem}.field-name{font-weight:500;color:#475569}.field-value{color:#64748b;margin-left:0.5rem}.field-value.filled{color:#059669;font-weight:500}.voice-filled-form{display:grid;grid-template-columns:repeat(auto-fit, minmax(250px, 1fr));gap:0.5rem;margin-top:1rem}.form-group{display:flex;flex-direction:column;gap:0.15rem}.form-group.full-width{grid-column:1 / -1}.form-header{grid-column:1 / -1;font-weight:600;font-size:1rem;color:#1e293b;margin-top:0.75rem;margin-bottom:0.25rem;padding-bottom:0.25rem;border-bottom:2px solid #e2e8f0}.form-label{font-weight:500;color:#374151;font-size:0.8rem}.required{color:#ee4444;margin-left:0.125rem}.form-input{padding:0.4rem;border:1px solid #d1d5db;border-radius:0.375rem;font-size:0.8rem;transition:border-color 0.2s ease}.form-input:focus{outline:none;border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59, 130, 246, 0.1)}.form-checkbox{width:auto;padding:0;margin:0}select.form-input{background-color:white;cursor:pointer}input[type=\"date\"].form-input{cursor:pointer}.readonly-select{background:#f9fafb;border:1px solid #d1d5db;border-radius:0.375rem;padding:0.5rem}.select-placeholder{font-size:0.875rem;color:#6b7280;margin-bottom:0.5rem}.select-options-list{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:0.25rem;max-height:150px;overflow-y:auto}.select-option{background:#e5e7eb;padding:0.25rem 0.5rem;border-radius:0.25rem;font-size:0.875rem;color:#374151}.multiselect-container{display:grid;grid-template-columns:repeat(2, 1fr);gap:0.25rem;padding:0.5rem;border:1px solid #d1d5db;border-radius:0.375rem;background:white}.multiselect-option{display:flex;align-items:center;gap:0.5rem;padding:0.5rem;border-radius:0.25rem;cursor:pointer;transition:background 0.2s ease}.multiselect-option:hover{background:#f3f4f6}.multiselect-option input[type=\"checkbox\"]{width:18px;height:18px;cursor:pointer}.multiselect-option input[type=\"checkbox\"]:checked+.multiselect-label{font-weight:600;color:#059669}.multiselect-label{font-size:0.875rem;color:#374151;user-select:none}@keyframes skeleton-shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}.skeleton-circle{border-radius:50%;flex-shrink:0;background:linear-gradient(\r\n 90deg,\r\n #e2e8f0 25%,\r\n #f8fafc 50%,\r\n #e2e8f0 75%\r\n );background-size:200% 100%;animation:skeleton-shimmer 1.5s ease-in-out infinite}.skeleton-status{height:14px;border-radius:7px;width:140px;background:linear-gradient(\r\n 90deg,\r\n #e2e8f0 25%,\r\n #f8fafc 50%,\r\n #e2e8f0 75%\r\n );background-size:200% 100%;animation:skeleton-shimmer 1.5s ease-in-out infinite;animation-delay:0.15s}ocr-file-uploader{display:block;width:100% !important;height:100% !important;max-width:100% !important;max-height:100% !important}ocr-file-uploader *{max-width:100% !important;max-height:100% !important}";
4333
+ const voiceInputModuleCss = ":host{display:block;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif}.row-audio-area{display:flex;flex-direction:row;align-items:center;gap:8px;flex-wrap:wrap;justify-content:center}.voice-recorder-container{display:flex;flex-direction:column;align-items:center;gap:1rem;padding:1rem;border:1px solid #e5e7eb;border-radius:0.5rem;background:#ffffff;margin:0 auto}.voice-recorder-container-debug{display:flex;flex-direction:column;align-items:center;gap:1rem;padding:1rem;border:1px solid #e5e7eb;border-radius:0.5rem;background:#ffffff;margin:0 auto}.upload-record-container{display:inline-flex;cursor:pointer}.upload-record-button{display:flex;align-items:center;justify-content:center;transition:transform 0.2s ease, box-shadow 0.2s ease;user-select:none}.upload-record-button svg{width:100%;height:100%;transition:transform 0.2s ease}.upload-record-container:hover .upload-record-button svg{transform:scale(1.05)}.record-button{display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:#ee4444;color:white;cursor:pointer;transition:all 0.2s ease;position:relative;overflow:hidden;flex-shrink:0}.record-button:hover:not(:disabled){background:#dd3333;transform:scale(1.05)}.record-button:disabled{opacity:0.6;cursor:not-allowed}.record-button.recording{background:#dd3333;animation:pulse 1.5s infinite}.record-button.processing{background:#3b82f6}@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(239, 68, 68, 0.7)}70%{box-shadow:0 0 0 10px rgba(239, 68, 68, 0)}100%{box-shadow:0 0 0 0 rgba(239, 68, 68, 0)}}.record-icon{width:24px;height:24px;fill:currentColor}.status-text{font-size:0.875rem;color:#6b7280;text-align:center;min-height:1.25rem}.status-text.error{color:#ee4444}.status-text.success{color:#10b981}.debug-panel{width:100%;margin-top:1rem;padding:1rem;background:#f9fafb;border:1px solid #e5e7eb;border-radius:0.375rem;font-family:'Monaco', 'Menlo', 'Ubuntu Mono', monospace;font-size:0.75rem}.debug-title{font-weight:600;margin-bottom:0.5rem;color:#374151}.debug-content{white-space:pre-wrap;word-break:break-word;color:#6b7280;max-height:200px;overflow-y:auto}.permissions-warning{padding:0.75rem;background:#fef3c7;border:1px solid #f59e0b;border-radius:0.375rem;color:#92400e;font-size:0.875rem;text-align:center}.form-preview{width:100%;margin-top:1rem;padding:1rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:0.375rem}.form-preview-title{font-weight:600;margin-bottom:0.5rem;color:#1e293b}.form-field{margin-bottom:0.5rem;font-size:0.875rem}.field-name{font-weight:500;color:#475569}.field-value{color:#64748b;margin-left:0.5rem}.field-value.filled{color:#059669;font-weight:500}.voice-filled-form{display:grid;grid-template-columns:repeat(auto-fit, minmax(250px, 1fr));gap:0.5rem;margin-top:1rem}.form-group{display:flex;flex-direction:column;gap:0.15rem}.form-group.full-width{grid-column:1 / -1}.form-header{grid-column:1 / -1;font-weight:600;font-size:1rem;color:#1e293b;margin-top:0.75rem;margin-bottom:0.25rem;padding-bottom:0.25rem;border-bottom:2px solid #e2e8f0}.form-label{font-weight:500;color:#374151;font-size:0.8rem}.required{color:#ee4444;margin-left:0.125rem}.form-input{padding:0.4rem;border:1px solid #d1d5db;border-radius:0.375rem;font-size:0.8rem;transition:border-color 0.2s ease}.form-input:focus{outline:none;border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59, 130, 246, 0.1)}.form-checkbox{width:auto;padding:0;margin:0}select.form-input{background-color:white;cursor:pointer}input[type=\"date\"].form-input{cursor:pointer}.readonly-select{background:#f9fafb;border:1px solid #d1d5db;border-radius:0.375rem;padding:0.5rem}.select-placeholder{font-size:0.875rem;color:#6b7280;margin-bottom:0.5rem}.select-options-list{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:0.25rem;max-height:150px;overflow-y:auto}.select-option{background:#e5e7eb;padding:0.25rem 0.5rem;border-radius:0.25rem;font-size:0.875rem;color:#374151}.multiselect-container{display:grid;grid-template-columns:repeat(2, 1fr);gap:0.25rem;padding:0.5rem;border:1px solid #d1d5db;border-radius:0.375rem;background:white}.multiselect-option{display:flex;align-items:center;gap:0.5rem;padding:0.5rem;border-radius:0.25rem;cursor:pointer;transition:background 0.2s ease}.multiselect-option:hover{background:#f3f4f6}.multiselect-option input[type=\"checkbox\"]{width:18px;height:18px;cursor:pointer}.multiselect-option input[type=\"checkbox\"]:checked+.multiselect-label{font-weight:600;color:#059669}.multiselect-label{font-size:0.875rem;color:#374151;user-select:none}.confidence-badge{display:inline-flex;align-items:center;margin-left:4px;padding:1px 5px;border-radius:3px;font-size:0.65rem;font-weight:700;vertical-align:middle;line-height:1.4;cursor:help}.confidence-medium{background:#fef3c7;color:#92400e;border:1px solid #fde68a}.confidence-low{background:#fee2e2;color:#991b1b;border:1px solid #fca5a5}@keyframes skeleton-shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}.skeleton-circle{border-radius:50%;flex-shrink:0;background:linear-gradient(\r\n 90deg,\r\n #e2e8f0 25%,\r\n #f8fafc 50%,\r\n #e2e8f0 75%\r\n );background-size:200% 100%;animation:skeleton-shimmer 1.5s ease-in-out infinite}.skeleton-status{height:14px;border-radius:7px;width:140px;background:linear-gradient(\r\n 90deg,\r\n #e2e8f0 25%,\r\n #f8fafc 50%,\r\n #e2e8f0 75%\r\n );background-size:200% 100%;animation:skeleton-shimmer 1.5s ease-in-out infinite;animation-delay:0.15s}ocr-file-uploader{display:block;width:100% !important;height:100% !important;max-width:100% !important;max-height:100% !important}ocr-file-uploader *{max-width:100% !important;max-height:100% !important}";
4330
4334
 
4331
4335
  // Initialize OCR
4332
4336
  defineCustomElements();
@@ -4368,6 +4372,7 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4368
4372
  this.hasTransientError = false;
4369
4373
  this.transcription = '';
4370
4374
  this.filledData = null;
4375
+ this.confidenceScores = null;
4371
4376
  this.debugInfo = {};
4372
4377
  this.isReadonlyMode = true; // Start in readonly preview mode
4373
4378
  this.isInitializing = true;
@@ -4402,9 +4407,17 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4402
4407
  this.audioRecorder = new AudioRecorderService();
4403
4408
  }
4404
4409
  componentWillLoad() {
4405
- this.initializeServices();
4410
+ // Parse theme only so the skeleton can be styled correctly on first render.
4411
+ // Full initialization runs in componentDidLoad() to give the skeleton time to paint.
4412
+ try {
4413
+ this.parsedTheme = this.theme ? JSON.parse(this.theme) : this.getDefaultTheme();
4414
+ }
4415
+ catch (_a) {
4416
+ this.parsedTheme = this.getDefaultTheme();
4417
+ }
4406
4418
  }
4407
4419
  componentDidLoad() {
4420
+ this.initializeServices();
4408
4421
  this.isInitializing = false;
4409
4422
  }
4410
4423
  initializeServices() {
@@ -4607,6 +4620,7 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4607
4620
  return;
4608
4621
  this.isProcessing = true;
4609
4622
  this.hasTransientError = false;
4623
+ this.confidenceScores = null;
4610
4624
  this.statusMessage = ((_a = this.parsedTheme.texts) === null || _a === void 0 ? void 0 : _a.processing) || (this.language == 'en' ? 'Processing document...' : 'Traitement du document ...');
4611
4625
  try {
4612
4626
  const extractedData = (ocrData === null || ocrData === void 0 ? void 0 : ocrData.content) || ocrData;
@@ -4624,10 +4638,11 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4624
4638
  throw Object.assign(new Error(llmError.message), { phase: 'llm' });
4625
4639
  }
4626
4640
  this.filledData = this.extractFilledData(filledSchema);
4627
- this.updateDebugInfo('Form Filled', { filledSchema, extractedData: this.filledData });
4641
+ this.confidenceScores = this.extractConfidenceScores(filledSchema);
4642
+ this.updateDebugInfo('Form Filled', { filledSchema, extractedData: this.filledData, confidence: this.confidenceScores });
4628
4643
  this.parsedSchema = this.filledData;
4629
4644
  this.statusMessage = ((_c = this.parsedTheme.texts) === null || _c === void 0 ? void 0 : _c.completed) || (this.language == 'en' ? 'Form completed!' : 'Formulaire rempli !');
4630
- this.formFilled.emit({ success: true, data: this.filledData, jsonForm });
4645
+ this.formFilled.emit({ success: true, data: this.filledData, jsonForm, confidence: this.confidenceScores });
4631
4646
  }
4632
4647
  catch (error) {
4633
4648
  console.error('OCR processing error:', error);
@@ -4646,6 +4661,7 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4646
4661
  return;
4647
4662
  this.isProcessing = true;
4648
4663
  this.hasTransientError = false;
4664
+ this.confidenceScores = null;
4649
4665
  this.updateDebugInfo('Audio Captured', { size: audioFile.size, type: audioFile.type });
4650
4666
  try {
4651
4667
  // Validate audio file before sending to API
@@ -4666,7 +4682,6 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4666
4682
  this.formFilled.emit({ success: false, error: 'Audio file too large' });
4667
4683
  return;
4668
4684
  }
4669
- // Step 1: Transcription
4670
4685
  let transcription;
4671
4686
  try {
4672
4687
  this.statusMessage = ((_a = this.parsedTheme.texts) === null || _a === void 0 ? void 0 : _a.transcribing) || (this.language == 'en' ? 'Transcribing speech...' : 'Transcription du texte ...');
@@ -4685,7 +4700,6 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4685
4700
  this.formFilled.emit({ success: false, error: 'No speech detected', transcription: '' });
4686
4701
  return;
4687
4702
  }
4688
- // Step 2: LLM form filling
4689
4703
  let filledSchema;
4690
4704
  try {
4691
4705
  this.statusMessage = ((_b = this.parsedTheme.texts) === null || _b === void 0 ? void 0 : _b.filling) || (this.language == 'en' ? 'Filling form fields...' : 'Remplissage du formulaire ...');
@@ -4696,10 +4710,11 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4696
4710
  throw Object.assign(new Error(llmError.message), { phase: 'llm' });
4697
4711
  }
4698
4712
  this.filledData = this.extractFilledData(filledSchema);
4699
- this.updateDebugInfo('Form Filled', { filledSchema, extractedData: this.filledData });
4713
+ this.confidenceScores = this.extractConfidenceScores(filledSchema);
4714
+ this.updateDebugInfo('Form Filled', { filledSchema, extractedData: this.filledData, confidence: this.confidenceScores });
4700
4715
  this.parsedSchema = this.filledData;
4701
4716
  this.statusMessage = ((_c = this.parsedTheme.texts) === null || _c === void 0 ? void 0 : _c.completed) || (this.language == 'en' ? 'Form completed!' : 'Formulaire rempli !');
4702
- this.formFilled.emit({ success: true, data: this.filledData, transcription });
4717
+ this.formFilled.emit({ success: true, data: this.filledData, transcription, confidence: this.confidenceScores });
4703
4718
  }
4704
4719
  catch (error) {
4705
4720
  console.error('Audio processing error:', error);
@@ -4723,7 +4738,8 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4723
4738
  try {
4724
4739
  const audioBlob = await this.audioRecorder.stopRecording();
4725
4740
  const audioContent = new File([audioBlob], 'audio.wav', { type: 'audio/wav' });
4726
- // processAudioContent manages isProcessing itself; await ensures we don't return early
4741
+ // Reset isProcessing so the guard inside processAudioContent doesn't block this internal call
4742
+ this.isProcessing = false;
4727
4743
  await this.processAudioContent(audioContent);
4728
4744
  }
4729
4745
  catch (error) {
@@ -4740,12 +4756,52 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4740
4756
  this.recordingStateChanged.emit({ isRecording: false, state: 'idle' });
4741
4757
  }
4742
4758
  }
4759
+ extractConfidenceScores(filledData) {
4760
+ const scores = {};
4761
+ if (!filledData)
4762
+ return scores;
4763
+ // Fields array format: [{"id": "...", "name": "...", "value": "...", "confidence": 0.87}]
4764
+ if (filledData.fields && Array.isArray(filledData.fields)) {
4765
+ filledData.fields.forEach((field) => {
4766
+ const raw = typeof field.confidence === 'number' ? field.confidence : parseFloat(field.confidence);
4767
+ if (!isNaN(raw)) {
4768
+ const clamped = Math.min(0.99, Math.max(0.01, Math.round(raw * 100) / 100));
4769
+ // Store under both id and name so label-based lookups always work
4770
+ if (field.id)
4771
+ scores[field.id] = clamped;
4772
+ if (field.name)
4773
+ scores[field.name] = clamped;
4774
+ }
4775
+ });
4776
+ }
4777
+ // Simple schema format: {"schema": {...}, "confidence": {"field_name": 0.87}}
4778
+ if (filledData.confidence && typeof filledData.confidence === 'object') {
4779
+ Object.entries(filledData.confidence).forEach(([k, v]) => {
4780
+ const raw = typeof v === 'number' ? v : parseFloat(v);
4781
+ if (!isNaN(raw)) {
4782
+ scores[k] = Math.min(0.99, Math.max(0.01, Math.round(raw * 100) / 100));
4783
+ }
4784
+ });
4785
+ }
4786
+ return scores;
4787
+ }
4788
+ getFieldConfidence(primary, fallback) {
4789
+ var _a, _b;
4790
+ if (!this.confidenceScores)
4791
+ return null;
4792
+ return (_a = this.confidenceScores[primary]) !== null && _a !== void 0 ? _a : (fallback ? ((_b = this.confidenceScores[fallback]) !== null && _b !== void 0 ? _b : null) : null);
4793
+ }
4794
+ renderConfidenceIndicator(confidence) {
4795
+ if (confidence === null || confidence >= 0.95)
4796
+ return null;
4797
+ const pct = Math.round(confidence * 100);
4798
+ const isApproximate = confidence >= 0.85;
4799
+ return (h$1("span", { class: `confidence-badge ${isApproximate ? 'confidence-medium' : 'confidence-low'}`, title: this.language === 'en' ? `Confidence: ${pct}%` : `Confiance : ${pct}%` }, pct, "%"));
4800
+ }
4743
4801
  extractFilledData(filledData) {
4744
- // console.log("extractFilledData", filledData);
4745
4802
  const updatedSchema = JSON.parse(JSON.stringify(this.parsedSchema));
4746
4803
  switch (this.context) {
4747
4804
  case "ecoteka":
4748
- // console.log("TODO extractFilledData", filledData);
4749
4805
  case "ng":
4750
4806
  if (filledData === null || filledData === void 0 ? void 0 : filledData.fields) {
4751
4807
  // Map AI response back to original schema structure
@@ -4760,7 +4816,6 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4760
4816
  }
4761
4817
  break;
4762
4818
  case "ecoll-veto":
4763
- // console.log("TODO extractFilledData", filledData, updatedSchema);
4764
4819
  if (filledData === null || filledData === void 0 ? void 0 : filledData.fields) {
4765
4820
  // Map AI response back to original schema structure
4766
4821
  filledData.fields.forEach((field) => {
@@ -4801,15 +4856,12 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4801
4856
  }
4802
4857
  break;
4803
4858
  }
4804
- // console.log("extractFilledData result", updatedSchema);
4805
4859
  return updatedSchema;
4806
4860
  }
4807
4861
  async trimSchemaForAI(schema) {
4808
4862
  var _a, _b;
4809
- // console.log("trimSchemaForAI", schema);
4810
4863
  switch (this.context) {
4811
4864
  case "ecoteka":
4812
- // console.log("TODO trimSchemaForAI", schema)
4813
4865
  case "ng":
4814
4866
  const trimmed = { fields: [] };
4815
4867
  schema.Children.forEach((child) => {
@@ -4828,10 +4880,8 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4828
4880
  }
4829
4881
  trimmed.fields.push(fieldData);
4830
4882
  });
4831
- // console.log("Schema apres transformation, contexte NG:", trimmed);
4832
4883
  return trimmed;
4833
4884
  case "ecoll-veto":
4834
- // console.log("TODO trimSchemaForAI", schema)
4835
4885
  const mergedItemsSchema = (this.parsedSchema[0].items).concat(this.parsedSchema[1].items);
4836
4886
  if (mergedItemsSchema) {
4837
4887
  const trimmedSchema = {
@@ -4876,7 +4926,6 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4876
4926
  default: '',
4877
4927
  };
4878
4928
  });
4879
- // console.log("Schema apres transformation, contexte Track:", trimmedSchema);
4880
4929
  return trimmedSchema;
4881
4930
  }
4882
4931
  case "track":
@@ -5073,13 +5122,11 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
5073
5122
  return (h$1("div", { class: "form-preview" }, h$1("div", { class: "form-preview-title" }, title), h$1("form", { class: "voice-filled-form" }, this.renderFormFields())));
5074
5123
  }
5075
5124
  renderFormFields() {
5076
- // console.log("renderFormFields", this.parsedSchema);
5077
5125
  if (!this.parsedSchema)
5078
5126
  return null;
5079
5127
  const largeFieldTypes = ['select', 'multiselect', 'classification', 'thesaurus', 'position'];
5080
5128
  switch (this.context) {
5081
5129
  case "ecoteka":
5082
- // console.log("TODO renderFormFields", this.parsedSchema);
5083
5130
  case "ng":
5084
5131
  return this.parsedSchema.Children.map((child) => {
5085
5132
  var _a, _b, _c;
@@ -5091,7 +5138,7 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
5091
5138
  const isRequired = child.Required || false;
5092
5139
  const fieldValue = (_b = child.Settings) === null || _b === void 0 ? void 0 : _b.Default_Value;
5093
5140
  const isLargeField = largeFieldTypes.includes(fieldType) || (child.Children && child.Children.length > 5);
5094
- return (h$1("div", { class: isLargeField ? "form-group full-width" : "form-group", key: fieldName }, h$1("label", { htmlFor: fieldName, class: "form-label" }, fieldLabel, isRequired && h$1("span", { class: "required" }, "*")), this.renderFormField(fieldName, {
5141
+ return (h$1("div", { class: isLargeField ? "form-group full-width" : "form-group", key: fieldName }, h$1("label", { htmlFor: fieldName, class: "form-label" }, fieldLabel, isRequired && h$1("span", { class: "required" }, "*"), this.renderConfidenceIndicator(this.getFieldConfidence(fieldLabel, fieldName))), this.renderFormField(fieldName, {
5095
5142
  type: fieldType,
5096
5143
  title: fieldLabel,
5097
5144
  required: isRequired,
@@ -5099,8 +5146,6 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
5099
5146
  }, fieldValue)));
5100
5147
  }).filter(Boolean);
5101
5148
  case "ecoll-veto":
5102
- // NOTE STEP 2
5103
- // console.log("TODO renderFormFields", this.parsedSchema);
5104
5149
  const mergedItemsSchema = (this.parsedSchema[0].items).concat(this.parsedSchema[1].items);
5105
5150
  return Object.entries(mergedItemsSchema).map(([key, field]) => {
5106
5151
  var _a, _b;
@@ -5131,7 +5176,7 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
5131
5176
  // console.error("Error fetching classification data:", error);
5132
5177
  // }
5133
5178
  // }
5134
- return (h$1("div", { class: "form-group", key: fieldName }, h$1("label", { htmlFor: fieldName, class: "form-label" }, fieldLabel, isRequired && h$1("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))));
5179
+ return (h$1("div", { class: "form-group", key: fieldName }, h$1("label", { htmlFor: fieldName, class: "form-label" }, fieldLabel, isRequired && h$1("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))));
5135
5180
  });
5136
5181
  case "track":
5137
5182
  default:
@@ -5140,7 +5185,7 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
5140
5185
  if (field.type === 'header') {
5141
5186
  return (h$1("div", { class: "form-header", key: fieldName }, field.title || fieldName));
5142
5187
  }
5143
- return (h$1("div", { class: "form-group", key: fieldName }, h$1("label", { htmlFor: fieldName, class: "form-label" }, field.title || fieldName, field.required && h$1("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))));
5188
+ return (h$1("div", { class: "form-group", key: fieldName }, h$1("label", { htmlFor: fieldName, class: "form-label" }, field.title || fieldName, field.required && h$1("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))));
5144
5189
  });
5145
5190
  }
5146
5191
  }
@@ -5216,7 +5261,8 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
5216
5261
  };
5217
5262
  }
5218
5263
  getContainerStyle() {
5219
- const c = this.parsedTheme.container || {};
5264
+ var _a;
5265
+ const c = ((_a = this.parsedTheme) === null || _a === void 0 ? void 0 : _a.container) || {};
5220
5266
  return {
5221
5267
  width: c.width || 'auto',
5222
5268
  height: c.height || 'auto',
@@ -5228,7 +5274,8 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
5228
5274
  };
5229
5275
  }
5230
5276
  getStatusStyle() {
5231
- const s = this.parsedTheme.statusText || {};
5277
+ var _a;
5278
+ const s = ((_a = this.parsedTheme) === null || _a === void 0 ? void 0 : _a.statusText) || {};
5232
5279
  return {
5233
5280
  color: s.color || '#1e293b',
5234
5281
  fontSize: s.fontSize || '14px'
@@ -5275,6 +5322,7 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
5275
5322
  "hasTransientError": [32],
5276
5323
  "transcription": [32],
5277
5324
  "filledData": [32],
5325
+ "confidenceScores": [32],
5278
5326
  "debugInfo": [32],
5279
5327
  "isReadonlyMode": [32],
5280
5328
  "isInitializing": [32],