reneco-advanced-input-module 0.0.26 → 0.0.28

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.
@@ -1 +1 @@
1
- {"version":3,"file":"llm.service.js","sourceRoot":"","sources":["../../src/services/llm.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,OAAO,gBAAgB;IAO3B,YAAY,MAAoC;QAC9C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,KAAK,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,uBAAuB,CAAC;QAE5D,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,mCAAmC;YACnC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,IAAI,CAAC,MAAM,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,KAAI,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;YACpF,IAAI,CAAC,OAAO,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,KAAI,2BAA2B,CAAC;YAE9D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,KAAI,YAAY,CAAC;IAC7C,CAAC;IAEO,sBAAsB,CAAC,IAAY;QACzC,oEAAoE;QACpE,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAClD,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,sEAAsE;QACtE,OAAQ,MAAc,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;IAC5C,CAAC;IAEO,4BAA4B,CAAC,MAAW;QAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE;gBAC/B,IAAI,WAAW,GAAG,QAAQ,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,GAAG;oBAChF,IAAI,KAAK,CAAC,IAAI,EAAE;oBAChB,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;oBACvC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;oBACvC,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,GAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;oBACpH,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBAC5D,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBAC5D,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,GAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAE/E,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;wBAC9B,WAAW,IAAI,gBAAgB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5D,CAAC;yBAAM,CAAC;wBACN,WAAW,IAAI,mBAAmB,KAAK,CAAC,OAAO,CAAC,MAAM,sDAAsD,CAAC;oBAC/G,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,WAAW,IAAI,GAAG,CAAC;gBACrB,CAAC;gBAED,OAAO,WAAW,CAAC;YACrB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAED,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAgB,EAAE,EAAE;YACtE,IAAI,WAAW,GAAG,QAAQ,KAAK,CAAC,EAAE,IAAI,SAAS,MAAM,KAAK,CAAC,KAAK,IAAI,SAAS,GAAG;gBAC9E,IAAI,KAAK,CAAC,IAAI,EAAE;gBAChB,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;gBACvC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;gBACvC,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,GAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACpH,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC5D,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC5D,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,GAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAE/E,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;oBAC9B,WAAW,IAAI,gBAAgB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5D,CAAC;qBAAM,CAAC;oBACN,WAAW,IAAI,mBAAmB,KAAK,CAAC,OAAO,CAAC,MAAM,sDAAsD,CAAC;gBAC/G,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,WAAW,IAAI,GAAG,CAAC;YACrB,CAAC;YAED,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,aAAqB,EAAE,MAAW;QAChE,OAAO,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IAEO,kBAAkB,CAAC,WAAgB,EAAE,MAAW;QACtD,iDAAiD;QACjD,IAAI,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,EAAE,CAAC;YACrC,MAAM,WAAW,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,CAAC;YACrD,MAAM,gBAAgB,GAAa,EAAE,CAAC;YAEtC,IAAI,WAAW,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5D,WAAW,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE;oBACzD,kCAAkC;oBAClC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,EAAO,EAAE,EAAE,CAC9D,CAAC,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,CAC7C,CAAC;oBAET,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;wBAC1F,MAAM,aAAa,GAAG,WAAW,CAAC,IAAI,KAAK,aAAa,CAAC;wBAEzD,uCAAuC;wBACvC,IAAI,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;4BAChD,MAAM,aAAa,GAAa,EAAE,CAAC;4BACnC,MAAM,YAAY,GAAa,EAAE,CAAC;4BAElC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAW,EAAE,EAAE;gCAClC,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;gCAC/D,IAAI,WAAW,EAAE,CAAC;oCAChB,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gCACxC,CAAC;qCAAM,CAAC;oCACN,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gCACzB,CAAC;4BACH,CAAC,CAAC,CAAC;4BAEH,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCAC5B,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gCAClC,KAAK,CAAC,KAAK,GAAG,2BAA2B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;4BACrE,CAAC;4BAED,KAAK,CAAC,KAAK,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;4BAC9D,KAAK,CAAC,oBAAoB,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,aAAa,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;wBACnG,CAAC;6BAAM,IAAI,CAAC,aAAa,EAAE,CAAC;4BAC1B,oEAAoE;4BACpE,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;4BAC9E,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;4BAEvE,IAAI,WAAW,EAAE,CAAC;gCAChB,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;gCAChC,KAAK,CAAC,oBAAoB,GAAG,WAAW,CAAC,UAAU,CAAC;4BACtD,CAAC;iCAAM,CAAC;gCACN,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gCAClC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;gCACnB,KAAK,CAAC,KAAK,GAAG,oBAAoB,WAAW,wBAAwB,CAAC;4BACxE,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,OAAO,KAAK,CAAC;gBACf,CAAC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,WAAW,CAAC,cAAc,GAAG,gBAAgB,CAAC;YAChD,CAAC;YAED,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,8BAA8B;QAC9B,IAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,EAAE,CAAC;YACnB,MAAM,gBAAgB,GAAa,EAAE,CAAC;YAEtC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAgB,EAAE,EAAE;;gBAC7E,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;oBACtD,MAAM,UAAU,GAAG,MAAA,MAAA,WAAW,CAAC,MAAM,0CAAG,SAAS,CAAC,0CAAE,OAAO,CAAC;oBAE5D,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,KAAK,aAAa,CAAC;wBAEtD,uCAAuC;wBACvC,IAAI,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;4BAC/C,MAAM,aAAa,GAAa,EAAE,CAAC;4BACnC,MAAM,YAAY,GAAa,EAAE,CAAC;4BAElC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAW,EAAE,EAAE;gCACjC,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;gCAC5D,IAAI,WAAW,EAAE,CAAC;oCAChB,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gCACxC,CAAC;qCAAM,CAAC;oCACN,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gCACzB,CAAC;4BACH,CAAC,CAAC,CAAC;4BAEH,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCAC5B,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gCACjC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,GAAG,2BAA2B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;4BAC7F,CAAC;4BAED,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;4BACxF,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,aAAa,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;wBAC3H,CAAC;6BAAM,IAAI,CAAC,aAAa,EAAE,CAAC;4BAC1B,oEAAoE;4BACpE,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;4BAC3E,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;4BAEpE,IAAI,WAAW,EAAE,CAAC;gCAChB,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC;gCAC1D,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,GAAG,WAAW,CAAC,UAAU,CAAC;4BAC9E,CAAC;iCAAM,CAAC;gCACN,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gCACjC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;gCAC7C,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,GAAG,oBAAoB,WAAW,wBAAwB,CAAC;4BAChG,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,WAAW,CAAC,cAAc,GAAG,gBAAgB,CAAC;YAChD,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,MAAW;QAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,MAAW,EAAE,sBAA+B,IAAI;;QACnF,IAAI,CAAC;YACH,iDAAiD;YACjD,IAAI,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,EAAE,CAAC;gBACrC,MAAM,WAAW,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,CAAC;gBACrD,MAAM,YAAY,GAAG;;;;;;;;;2CASe,IAAI,IAAI,EAAU,CAAC,WAAW,EAAE;;;;;;;;;;;;yJAY6E,CAAC;gBAElJ,IAAI,UAAU,GAAG;kCACS,IAAI;;;YAG1B,IAAI,CAAC,4BAA4B,CAAC,WAAW,CAAC;;;SAGjD,CAAC;gBAEF,MAAM;gBAEN,uBAAuB;gBACvB,yBAAyB;gBACzB,MAAM;gBACN,qCAAqC;gBACrC,OAAO;gBACP,4CAA4C;gBAC5C,QAAQ;gBAER,iBAAiB;gBACjB,sDAAsD;gBAEtD,wCAAwC;gBACxC,MAAM;gBACN,yBAAyB;gBACzB,MAAM;gBACN,oBAAoB;gBACpB,OAAO;gBACP,0BAA0B;gBAC1B,4BAA4B;gBAE5B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,mBAAmB,CAAC;gBACjG,MAAM,OAAO,GAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;gBAE5D,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACnB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;gBACrD,CAAC;gBAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;oBACrC,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,OAAO;oBAChB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,QAAQ,EAAE;4BACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;4BACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE;yBACtC;wBACD,eAAe,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE;wBACxC,WAAW,EAAE,CAAC;qBACf,CAAC;iBACH,CAAC,CAAC;gBAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;oBAClF,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAA,MAAA,SAAS,CAAC,KAAK,0CAAE,OAAO,KAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;gBACxF,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACrC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAElE,oDAAoD;gBACpD,OAAO,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YACtD,CAAC;YAED,uDAAuD;YACvD,MAAM,YAAY,GAAG;;;;;;;;;;yCAUe,IAAI,IAAI,EAAU,CAAC,WAAW,EAAE;;;;;;;;;;sGAU4B,CAAC;YAE/F,IAAI,UAAU,GAAG;kCACS,IAAI;;;YAG1B,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;;;SAGlC,CAAC;YAEF,uBAAuB;YACvB,yBAAyB;YACzB,MAAM;YACN,qCAAqC;YACrC,OAAO;YACP,4CAA4C;YAC5C,QAAQ;YAER,yBAAyB;YACzB,uCAAuC;YAEvC,kDAAkD;YAClD,MAAM;YACN,yBAAyB;YACzB,MAAM;YACN,oBAAoB;YACpB,OAAO;YACP,0BAA0B;YAC1B,8DAA8D;YAEhE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,mBAAmB,CAAC;YACjG,MAAM,OAAO,GAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;YAE5D,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;YACrD,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;gBACrC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,OAAO;gBAChB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE;wBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;wBACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE;qBACtC;oBACD,eAAe,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE;oBACxC,WAAW,EAAE,CAAC,EAAE,kCAAkC;iBACnD,CAAC;aACH,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;gBAClF,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAA,MAAA,SAAS,CAAC,KAAK,0CAAE,OAAO,KAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACxF,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACrC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAEnE,uDAAuD;YACvD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC9D,CAAC;YAED,oDAAoD;YACpD,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;CACF;AAED,MAAM,OAAO,mBAAmB;IAM9B,YAAY,MAAoC;QAC9C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,KAAK,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,uBAAuB,CAAC;QAC5D,IAAI,CAAC,KAAK,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,KAAI,mBAAmB,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,KAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,aAAqB,EAAE,MAAW;QAChE,OAAO,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,MAAW;QAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,MAAW;;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,qBAAqB,CAAC,CAAC,CAAC,uCAAuC,CAAC;QACjH,MAAM,OAAO,GAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QAC5D,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;YACnC,OAAO,CAAC,mBAAmB,CAAC,GAAG,YAAY,CAAC;QAC9C,CAAC;QAED,MAAM,WAAW,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,IAAI,MAAM,CAAC;QAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC9C,MAAM,UAAU,GAAG,UAAU,IAAI;;;EAGnC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;;0HAEoF,CAAC;QAEvH,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ;YACxB,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE;YAChG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QAErH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChG,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,OAAO,KAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3F,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAEO,iBAAiB;QACvB,OAAO;;;;;;;;;;;;;8BAamB,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,iBAAiB;IAM5B,YAAY,MAAoC;QAC9C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,KAAK,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,uBAAuB,CAAC;QAC5D,IAAI,CAAC,KAAK,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,KAAI,uBAAuB,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,KAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,aAAqB,EAAE,MAAW;QAChE,OAAO,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,MAAW;QAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,MAAW;;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,mBAAmB,CAAC,CAAC,CAAC,4CAA4C,CAAC;QACpH,MAAM,OAAO,GAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QAC5D,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;QACrD,CAAC;QAED,MAAM,WAAW,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,IAAI,MAAM,CAAC;QAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC9C,MAAM,UAAU,GAAG,UAAU,IAAI;;;EAGnC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;;0HAEoF,CAAC;QAEvH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;gBAC5F,eAAe,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE;aACzC,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,OAAO,KAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IAEO,iBAAiB;QACvB,OAAO;;;;;;;;;;;;;8BAamB,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,iBAAiB;IAC5B,MAAM,CAAC,MAAM,CAAC,MAA6B;;QACzC,MAAM,QAAQ,GAAG,CAAA,MAAA,MAAM,CAAC,GAAG,0CAAE,QAAQ,KAAI,QAAQ,CAAC;QAClD,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,QAAQ,CAAC,CAAC,OAAO,IAAI,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvD,KAAK,WAAW,CAAC,CAAC,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,KAAK,SAAS,CAAC,CAAC,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzD,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;CACF","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
+ {"version":3,"file":"llm.service.js","sourceRoot":"","sources":["../../src/services/llm.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,OAAO,gBAAgB;IAO3B,YAAY,MAAoC;QAC9C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,KAAK,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,uBAAuB,CAAC;QAE5D,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,mCAAmC;YACnC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,IAAI,CAAC,MAAM,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,KAAI,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;YACpF,IAAI,CAAC,OAAO,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,KAAI,2BAA2B,CAAC;YAE9D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,KAAI,YAAY,CAAC;IAC7C,CAAC;IAEO,sBAAsB,CAAC,IAAY;QACzC,oEAAoE;QACpE,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAClD,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,sEAAsE;QACtE,OAAQ,MAAc,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;IAC5C,CAAC;IAEO,4BAA4B,CAAC,MAAW;QAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE;gBAC/B,IAAI,WAAW,GAAG,QAAQ,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,GAAG;oBAChF,IAAI,KAAK,CAAC,IAAI,EAAE;oBAChB,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;oBACvC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;oBACvC,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,GAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;oBACpH,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBAC5D,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBAC5D,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,GAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAE/E,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;wBAC9B,WAAW,IAAI,gBAAgB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5D,CAAC;yBAAM,CAAC;wBACN,WAAW,IAAI,mBAAmB,KAAK,CAAC,OAAO,CAAC,MAAM,sDAAsD,CAAC;oBAC/G,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,WAAW,IAAI,GAAG,CAAC;gBACrB,CAAC;gBAED,OAAO,WAAW,CAAC;YACrB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAED,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAgB,EAAE,EAAE;YACtE,IAAI,WAAW,GAAG,QAAQ,KAAK,CAAC,EAAE,IAAI,SAAS,MAAM,KAAK,CAAC,KAAK,IAAI,SAAS,GAAG;gBAC9E,IAAI,KAAK,CAAC,IAAI,EAAE;gBAChB,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;gBACvC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;gBACvC,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,GAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACpH,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC5D,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC5D,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,GAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAE/E,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;oBAC9B,WAAW,IAAI,gBAAgB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5D,CAAC;qBAAM,CAAC;oBACN,WAAW,IAAI,mBAAmB,KAAK,CAAC,OAAO,CAAC,MAAM,sDAAsD,CAAC;gBAC/G,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,WAAW,IAAI,GAAG,CAAC;YACrB,CAAC;YAED,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,aAAqB,EAAE,MAAW;QAChE,OAAO,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IAEO,kBAAkB,CAAC,WAAgB,EAAE,MAAW;QACtD,iDAAiD;QACjD,IAAI,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,EAAE,CAAC;YACrC,MAAM,WAAW,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,CAAC;YACrD,MAAM,gBAAgB,GAAa,EAAE,CAAC;YAEtC,IAAI,WAAW,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5D,WAAW,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE;oBACzD,kCAAkC;oBAClC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,EAAO,EAAE,EAAE,CAC9D,CAAC,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,CAC7C,CAAC;oBAET,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;wBAC1F,MAAM,aAAa,GAAG,WAAW,CAAC,IAAI,KAAK,aAAa,CAAC;wBAEzD,uCAAuC;wBACvC,IAAI,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;4BAChD,MAAM,aAAa,GAAa,EAAE,CAAC;4BACnC,MAAM,YAAY,GAAa,EAAE,CAAC;4BAElC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAW,EAAE,EAAE;gCAClC,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;gCAC/D,IAAI,WAAW,EAAE,CAAC;oCAChB,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gCACxC,CAAC;qCAAM,CAAC;oCACN,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gCACzB,CAAC;4BACH,CAAC,CAAC,CAAC;4BAEH,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCAC5B,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gCAClC,KAAK,CAAC,KAAK,GAAG,2BAA2B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;4BACrE,CAAC;4BAED,KAAK,CAAC,KAAK,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;4BAC9D,KAAK,CAAC,oBAAoB,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,aAAa,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;wBACnG,CAAC;6BAAM,IAAI,CAAC,aAAa,EAAE,CAAC;4BAC1B,oEAAoE;4BACpE,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;4BAC9E,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;4BAEvE,IAAI,WAAW,EAAE,CAAC;gCAChB,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;gCAChC,KAAK,CAAC,oBAAoB,GAAG,WAAW,CAAC,UAAU,CAAC;4BACtD,CAAC;iCAAM,CAAC;gCACN,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gCAClC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;gCACnB,KAAK,CAAC,KAAK,GAAG,oBAAoB,WAAW,wBAAwB,CAAC;4BACxE,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,OAAO,KAAK,CAAC;gBACf,CAAC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,WAAW,CAAC,cAAc,GAAG,gBAAgB,CAAC;YAChD,CAAC;YAED,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,8BAA8B;QAC9B,IAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,EAAE,CAAC;YACnB,MAAM,gBAAgB,GAAa,EAAE,CAAC;YAEtC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAgB,EAAE,EAAE;;gBAC7E,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;oBACtD,MAAM,UAAU,GAAG,MAAA,MAAA,WAAW,CAAC,MAAM,0CAAG,SAAS,CAAC,0CAAE,OAAO,CAAC;oBAE5D,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,KAAK,aAAa,CAAC;wBAEtD,uCAAuC;wBACvC,IAAI,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;4BAC/C,MAAM,aAAa,GAAa,EAAE,CAAC;4BACnC,MAAM,YAAY,GAAa,EAAE,CAAC;4BAElC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAW,EAAE,EAAE;gCACjC,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;gCAC5D,IAAI,WAAW,EAAE,CAAC;oCAChB,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gCACxC,CAAC;qCAAM,CAAC;oCACN,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gCACzB,CAAC;4BACH,CAAC,CAAC,CAAC;4BAEH,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCAC5B,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gCACjC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,GAAG,2BAA2B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;4BAC7F,CAAC;4BAED,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;4BACxF,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,aAAa,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;wBAC3H,CAAC;6BAAM,IAAI,CAAC,aAAa,EAAE,CAAC;4BAC1B,oEAAoE;4BACpE,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;4BAC3E,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;4BAEpE,IAAI,WAAW,EAAE,CAAC;gCAChB,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC;gCAC1D,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,GAAG,WAAW,CAAC,UAAU,CAAC;4BAC9E,CAAC;iCAAM,CAAC;gCACN,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gCACjC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;gCAC7C,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,GAAG,oBAAoB,WAAW,wBAAwB,CAAC;4BAChG,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,WAAW,CAAC,cAAc,GAAG,gBAAgB,CAAC;YAChD,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,MAAW;QAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,MAAW,EAAE,sBAA+B,IAAI;;QACnF,IAAI,CAAC;YACH,iDAAiD;YACjD,IAAI,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,EAAE,CAAC;gBACrC,MAAM,WAAW,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,CAAC;gBACrD,MAAM,YAAY,GAAG;;;;;;;;;2CASe,IAAI,IAAI,EAAU,CAAC,WAAW,EAAE;;;;;;;;;;;;yJAY6E,CAAC;gBAElJ,IAAI,UAAU,GAAG;kCACS,IAAI;;;YAG1B,IAAI,CAAC,4BAA4B,CAAC,WAAW,CAAC;;;SAGjD,CAAC;gBAEF,MAAM;gBAEN,uBAAuB;gBACvB,yBAAyB;gBACzB,MAAM;gBACN,qCAAqC;gBACrC,OAAO;gBACP,4CAA4C;gBAC5C,QAAQ;gBAER,iBAAiB;gBACjB,sDAAsD;gBAEtD,wCAAwC;gBACxC,MAAM;gBACN,yBAAyB;gBACzB,MAAM;gBACN,oBAAoB;gBACpB,OAAO;gBACP,0BAA0B;gBAC1B,4BAA4B;gBAE5B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,mBAAmB,CAAC;gBACjG,MAAM,OAAO,GAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;gBAE5D,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACnB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;gBACrD,CAAC;gBAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;oBACrC,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,OAAO;oBAChB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,QAAQ,EAAE;4BACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;4BACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE;yBACtC;wBACD,eAAe,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE;wBACxC,WAAW,EAAE,CAAC;qBACf,CAAC;iBACH,CAAC,CAAC;gBAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;oBAClF,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAA,MAAA,SAAS,CAAC,KAAK,0CAAE,OAAO,KAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;gBACxF,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACrC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAElE,oDAAoD;gBACpD,OAAO,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YACtD,CAAC;YAED,uDAAuD;YACvD,MAAM,YAAY,GAAG;;;;;;;;;;yCAUe,IAAI,IAAI,EAAU,CAAC,WAAW,EAAE;;;;;;;;;;sGAU4B,CAAC;YAE/F,IAAI,UAAU,GAAG;kCACS,IAAI;;;YAG1B,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;;;SAGlC,CAAC;YAEF,uBAAuB;YACvB,yBAAyB;YACzB,MAAM;YACN,qCAAqC;YACrC,OAAO;YACP,4CAA4C;YAC5C,QAAQ;YAER,yBAAyB;YACzB,uCAAuC;YAEvC,kDAAkD;YAClD,MAAM;YACN,yBAAyB;YACzB,MAAM;YACN,oBAAoB;YACpB,OAAO;YACP,0BAA0B;YAC1B,8DAA8D;YAEhE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,mBAAmB,CAAC;YACjG,MAAM,OAAO,GAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;YAE5D,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;YACrD,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;gBACrC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,OAAO;gBAChB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE;wBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;wBACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE;qBACtC;oBACD,eAAe,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE;oBACxC,WAAW,EAAE,CAAC,EAAE,kCAAkC;iBACnD,CAAC;aACH,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;gBAClF,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAA,MAAA,SAAS,CAAC,KAAK,0CAAE,OAAO,KAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACxF,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACrC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAEnE,uDAAuD;YACvD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC9D,CAAC;YAED,oDAAoD;YACpD,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;CACF;AAED,MAAM,OAAO,mBAAmB;IAM9B,YAAY,MAAoC;QAC9C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,KAAK,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,uBAAuB,CAAC;QAC5D,IAAI,CAAC,KAAK,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,KAAI,mBAAmB,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,KAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,aAAqB,EAAE,MAAW;QAChE,OAAO,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,MAAW;QAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,MAAW;;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,qBAAqB,CAAC,CAAC,CAAC,uCAAuC,CAAC;QACjH,MAAM,OAAO,GAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QAC5D,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;YACnC,OAAO,CAAC,mBAAmB,CAAC,GAAG,YAAY,CAAC;QAC9C,CAAC;QAED,MAAM,WAAW,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,IAAI,MAAM,CAAC;QAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC9C,MAAM,UAAU,GAAG,UAAU,IAAI;;;EAGnC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;;0HAEoF,CAAC;QAEvH,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ;YACxB,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE;YAChG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QAErH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChG,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,OAAO,KAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3F,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAEO,iBAAiB;QACvB,OAAO;;;;;;;;;;;;;;8BAcmB,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,iBAAiB;IAM5B,YAAY,MAAoC;QAC9C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,KAAK,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,KAAI,uBAAuB,CAAC;QAC5D,IAAI,CAAC,KAAK,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,KAAI,uBAAuB,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,KAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,aAAqB,EAAE,MAAW;QAChE,OAAO,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,MAAW;QAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,MAAW;;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,mBAAmB,CAAC,CAAC,CAAC,4CAA4C,CAAC;QACpH,MAAM,OAAO,GAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QAC5D,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;QACrD,CAAC;QAED,MAAM,WAAW,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,IAAI,MAAM,CAAC;QAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC9C,MAAM,UAAU,GAAG,UAAU,IAAI;;;EAGnC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;;0HAEoF,CAAC;QAEvH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;gBAC5F,eAAe,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE;aACzC,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,OAAO,KAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IAEO,iBAAiB;QACvB,OAAO;;;;;;;;;;;;;;8BAcmB,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,iBAAiB;IAC5B,MAAM,CAAC,MAAM,CAAC,MAA6B;;QACzC,MAAM,QAAQ,GAAG,CAAA,MAAA,MAAM,CAAC,GAAG,0CAAE,QAAQ,KAAI,QAAQ,CAAC;QAClD,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,QAAQ,CAAC,CAAC,OAAO,IAAI,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvD,KAAK,WAAW,CAAC,CAAC,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,KAAK,SAAS,CAAC,CAAC,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzD,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;CACF","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. TWO CASES APPLY: (a) The user SPECIFIES a section or instance (e.g., \"for the first sub-form\", \"for the clinical sign\", \"the second one\"): fill ONLY the field that belongs to that section - use readonly headers as structural markers and listen VERY CAREFULLY to contextual clues; (b) The user mentions a field name WITHOUT any section or instance qualifier (e.g., simply \"the event date is X\"): apply the SAME value to ALL fields sharing that name, each as a separate entry in the response\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. TWO CASES APPLY: (a) The user SPECIFIES a section or instance (e.g., \"for the first sub-form\", \"in the anamnesis section\", \"for the clinical sign\"): fill ONLY the field that belongs to that section - use readonly headers as structural markers and listen VERY CAREFULLY to contextual clues; (b) The user mentions a field name WITHOUT any section or instance qualifier: apply the SAME value to ALL fields sharing that name, each as a separate entry in the response\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. DUPLICATE FIELD NAMES: if multiple fields share the same name (different IDs/sections) and the user specifies which section, fill only the matching one. If the user gives a value with NO section qualifier, apply the same value to ALL fields sharing that name, each as a separate entry.\r\n12. 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. DUPLICATE FIELD NAMES: if multiple fields share the same name (different IDs/sections) and the user specifies which section, fill only the matching one. If the user gives a value with NO section qualifier, apply the same value to ALL fields sharing that name, each as a separate entry.\r\n12. 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"]}
@@ -556,7 +556,7 @@ class OpenAILLMService {
556
556
  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
557
557
  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
558
558
  10. IMPORTANT: Fields marked as "readonly" are presentation elements (headers, labels) that provide context but MUST NOT receive values
559
- 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
559
+ 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. TWO CASES APPLY: (a) The user SPECIFIES a section or instance (e.g., "for the first sub-form", "for the clinical sign", "the second one"): fill ONLY the field that belongs to that section - use readonly headers as structural markers and listen VERY CAREFULLY to contextual clues; (b) The user mentions a field name WITHOUT any section or instance qualifier (e.g., simply "the event date is X"): apply the SAME value to ALL fields sharing that name, each as a separate entry in the response
560
560
  12. Use readonly fields as contextual hints to understand form structure and field grouping, but never fill them
561
561
  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
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
@@ -633,7 +633,7 @@ class OpenAILLMService {
633
633
  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
634
634
  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
635
635
  11. IMPORTANT: Fields marked as "readonly" are presentation elements (headers, labels) that provide context but MUST NOT receive values
636
- 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
636
+ 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. TWO CASES APPLY: (a) The user SPECIFIES a section or instance (e.g., "for the first sub-form", "in the anamnesis section", "for the clinical sign"): fill ONLY the field that belongs to that section - use readonly headers as structural markers and listen VERY CAREFULLY to contextual clues; (b) The user mentions a field name WITHOUT any section or instance qualifier: apply the SAME value to ALL fields sharing that name, each as a separate entry in the response
637
637
  13. Use readonly fields as contextual hints to understand form structure and field grouping, but never fill them
638
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
639
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
@@ -758,7 +758,8 @@ Rules:
758
758
  8. DATE/DATETIME OUT OF RANGE: if a date falls outside min/max constraints, leave the field EMPTY
759
759
  9. PATTERN VALIDATION: if a field has a pattern, the value MUST match it exactly, otherwise leave empty
760
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.
761
+ 11. DUPLICATE FIELD NAMES: if multiple fields share the same name (different IDs/sections) and the user specifies which section, fill only the matching one. If the user gives a value with NO section qualifier, apply the same value to ALL fields sharing that name, each as a separate entry.
762
+ 12. 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.
762
763
  Respond ONLY with valid JSON.`;
763
764
  }
764
765
  }
@@ -822,7 +823,8 @@ Rules:
822
823
  8. DATE/DATETIME OUT OF RANGE: if a date falls outside min/max constraints, leave the field EMPTY
823
824
  9. PATTERN VALIDATION: if a field has a pattern, the value MUST match it exactly, otherwise leave empty
824
825
  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.
826
+ 11. DUPLICATE FIELD NAMES: if multiple fields share the same name (different IDs/sections) and the user specifies which section, fill only the matching one. If the user gives a value with NO section qualifier, apply the same value to ALL fields sharing that name, each as a separate entry.
827
+ 12. 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.
826
828
  Respond ONLY with valid JSON.`;
827
829
  }
828
830
  }
@@ -4811,6 +4813,8 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4811
4813
  if (!originalField.Settings)
4812
4814
  originalField.Settings = {};
4813
4815
  originalField.Settings.Default_Value = field.value;
4816
+ const rawConf = typeof field.confidence === 'number' ? field.confidence : parseFloat(field.confidence);
4817
+ originalField.confidence = isNaN(rawConf) ? null : rawConf;
4814
4818
  }
4815
4819
  });
4816
4820
  }
@@ -4824,6 +4828,8 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4824
4828
  originalField = updatedSchema[1].items.find((child) => child.label === field.name);
4825
4829
  if (originalField && field.value !== undefined && field.value !== null && field.value !== '') {
4826
4830
  updatedSchema[2][originalField.name] = field.value;
4831
+ const rawConf = typeof field.confidence === 'number' ? field.confidence : parseFloat(field.confidence);
4832
+ originalField.confidence = isNaN(rawConf) ? null : rawConf;
4827
4833
  }
4828
4834
  });
4829
4835
  }
@@ -4833,11 +4839,14 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4833
4839
  if (filledData === null || filledData === void 0 ? void 0 : filledData.fields) {
4834
4840
  Object.entries(filledData.fields).forEach(([fieldID, field]) => {
4835
4841
  if (field.value !== undefined && field.value !== null && field.value !== '') {
4842
+ const rawConf = typeof field.confidence === 'number' ? field.confidence : parseFloat(field.confidence);
4843
+ const confidence = isNaN(rawConf) ? null : rawConf;
4836
4844
  if (field.id) {
4837
4845
  const schemaField = updatedSchema.fields[field.id];
4838
4846
  if (schemaField) {
4839
4847
  schemaField.value = field.value;
4840
4848
  schemaField.default = field.value;
4849
+ schemaField.confidence = confidence;
4841
4850
  }
4842
4851
  }
4843
4852
  else {
@@ -4847,6 +4856,7 @@ const VoiceFormRecorder = /*@__PURE__*/ proxyCustomElement(class VoiceFormRecord
4847
4856
  if (schemaField.title === fieldName) {
4848
4857
  schemaField.value = field.value;
4849
4858
  schemaField.default = field.value;
4859
+ schemaField.confidence = confidence;
4850
4860
  break;
4851
4861
  }
4852
4862
  }