@acorex/modules 21.0.0-next.42 → 21.0.0-next.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/fesm2022/acorex-modules-ai-management-agent-registry-tool-configurator-widget-column.component-D0ruV6aJ.mjs.map +1 -1
  2. package/fesm2022/{acorex-modules-ai-management-agent-registry-tool-configurator-widget-edit.component-C7TQMwX4.mjs → acorex-modules-ai-management-agent-registry-tool-configurator-widget-edit.component-C-XsPEIg.mjs} +2 -2
  3. package/fesm2022/acorex-modules-ai-management-agent-registry-tool-configurator-widget-edit.component-C-XsPEIg.mjs.map +1 -0
  4. package/fesm2022/{acorex-modules-ai-management-agent.entity-DwPIKib2.mjs → acorex-modules-ai-management-agent.entity-D6-0_Ms3.mjs} +2 -2
  5. package/fesm2022/acorex-modules-ai-management-agent.entity-D6-0_Ms3.mjs.map +1 -0
  6. package/fesm2022/acorex-modules-ai-management-assist-delegated-agent-configurator-widget-column.component-DSC48iD0.mjs.map +1 -1
  7. package/fesm2022/{acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-BozVAuLO.mjs → acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-u1hZ4P5s.mjs} +2 -2
  8. package/fesm2022/acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-u1hZ4P5s.mjs.map +1 -0
  9. package/fesm2022/{acorex-modules-ai-management-assist.entity-CuToMDS_.mjs → acorex-modules-ai-management-assist.entity-DfW-FFCt.mjs} +2 -2
  10. package/fesm2022/{acorex-modules-ai-management-assist.entity-CuToMDS_.mjs.map → acorex-modules-ai-management-assist.entity-DfW-FFCt.mjs.map} +1 -1
  11. package/fesm2022/{acorex-modules-ai-management-model.entity-vUNlioDw.mjs → acorex-modules-ai-management-model.entity-DiDaXVa3.mjs} +2 -2
  12. package/fesm2022/{acorex-modules-ai-management-model.entity-vUNlioDw.mjs.map → acorex-modules-ai-management-model.entity-DiDaXVa3.mjs.map} +1 -1
  13. package/fesm2022/{acorex-modules-ai-management-open-ai-endpoint.entity-BpxRR5ir.mjs → acorex-modules-ai-management-open-ai-endpoint.entity-CZLNKtl0.mjs} +2 -2
  14. package/fesm2022/{acorex-modules-ai-management-open-ai-endpoint.entity-BpxRR5ir.mjs.map → acorex-modules-ai-management-open-ai-endpoint.entity-CZLNKtl0.mjs.map} +1 -1
  15. package/fesm2022/acorex-modules-ai-management.mjs +4442 -1
  16. package/fesm2022/acorex-modules-ai-management.mjs.map +1 -1
  17. package/fesm2022/{acorex-modules-application-management-features-widget-view.component-DlfkfOay.mjs → acorex-modules-application-management-features-widget-view.component-uc8eGA-k.mjs} +2 -2
  18. package/fesm2022/{acorex-modules-application-management-features-widget-view.component-DlfkfOay.mjs.map → acorex-modules-application-management-features-widget-view.component-uc8eGA-k.mjs.map} +1 -1
  19. package/fesm2022/acorex-modules-application-management.mjs +22 -77
  20. package/fesm2022/acorex-modules-application-management.mjs.map +1 -1
  21. package/fesm2022/{acorex-modules-assessment-management-acorex-modules-assessment-management-CMS2WJDu.mjs → acorex-modules-assessment-management-acorex-modules-assessment-management-c8OrTwDw.mjs} +26 -26
  22. package/fesm2022/{acorex-modules-assessment-management-acorex-modules-assessment-management-CMS2WJDu.mjs.map → acorex-modules-assessment-management-acorex-modules-assessment-management-c8OrTwDw.mjs.map} +1 -1
  23. package/fesm2022/{acorex-modules-assessment-management-assessment-case.entity-C-Q4hu8o.mjs → acorex-modules-assessment-management-assessment-case.entity-DEsJE7x3.mjs} +2 -2
  24. package/fesm2022/{acorex-modules-assessment-management-assessment-case.entity-C-Q4hu8o.mjs.map → acorex-modules-assessment-management-assessment-case.entity-DEsJE7x3.mjs.map} +1 -1
  25. package/fesm2022/{acorex-modules-assessment-management-assessment-session.entity-CQI_FpUd.mjs → acorex-modules-assessment-management-assessment-session.entity-eNFfu-Jq.mjs} +2 -2
  26. package/fesm2022/{acorex-modules-assessment-management-assessment-session.entity-CQI_FpUd.mjs.map → acorex-modules-assessment-management-assessment-session.entity-eNFfu-Jq.mjs.map} +1 -1
  27. package/fesm2022/{acorex-modules-assessment-management-fill-assessment-session.command-Bpvco5iD.mjs → acorex-modules-assessment-management-fill-assessment-session.command-BeSUBkI9.mjs} +2 -2
  28. package/fesm2022/{acorex-modules-assessment-management-fill-assessment-session.command-Bpvco5iD.mjs.map → acorex-modules-assessment-management-fill-assessment-session.command-BeSUBkI9.mjs.map} +1 -1
  29. package/fesm2022/{acorex-modules-assessment-management-index-_fPuBQeK.mjs → acorex-modules-assessment-management-index-3GB9Xkyv.mjs} +4 -4
  30. package/fesm2022/{acorex-modules-assessment-management-index-_fPuBQeK.mjs.map → acorex-modules-assessment-management-index-3GB9Xkyv.mjs.map} +1 -1
  31. package/fesm2022/{acorex-modules-assessment-management-preview-question.command-drR6nq76.mjs → acorex-modules-assessment-management-preview-question.command-QinKZtTz.mjs} +2 -2
  32. package/fesm2022/{acorex-modules-assessment-management-preview-question.command-drR6nq76.mjs.map → acorex-modules-assessment-management-preview-question.command-QinKZtTz.mjs.map} +1 -1
  33. package/fesm2022/{acorex-modules-assessment-management-preview-questionnaire.command-CY8tZWdG.mjs → acorex-modules-assessment-management-preview-questionnaire.command-CKZYSyOv.mjs} +2 -2
  34. package/fesm2022/{acorex-modules-assessment-management-preview-questionnaire.command-CY8tZWdG.mjs.map → acorex-modules-assessment-management-preview-questionnaire.command-CKZYSyOv.mjs.map} +1 -1
  35. package/fesm2022/{acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DV9irFZ0.mjs → acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-qZXANgNr.mjs} +2 -2
  36. package/fesm2022/{acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DV9irFZ0.mjs.map → acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-qZXANgNr.mjs.map} +1 -1
  37. package/fesm2022/{acorex-modules-assessment-management-question-bank-item.entity-DO4bTKKo.mjs → acorex-modules-assessment-management-question-bank-item.entity-Dp4eYR3O.mjs} +2 -2
  38. package/fesm2022/{acorex-modules-assessment-management-question-bank-item.entity-DO4bTKKo.mjs.map → acorex-modules-assessment-management-question-bank-item.entity-Dp4eYR3O.mjs.map} +1 -1
  39. package/fesm2022/{acorex-modules-assessment-management-questionnaire-calculation.entity-B-N0v4zs.mjs → acorex-modules-assessment-management-questionnaire-calculation.entity-BMB9IEIv.mjs} +2 -2
  40. package/fesm2022/{acorex-modules-assessment-management-questionnaire-calculation.entity-B-N0v4zs.mjs.map → acorex-modules-assessment-management-questionnaire-calculation.entity-BMB9IEIv.mjs.map} +1 -1
  41. package/fesm2022/{acorex-modules-assessment-management-questionnaire-viewer-popup.component-Cc-o6qmY.mjs → acorex-modules-assessment-management-questionnaire-viewer-popup.component-DgC1xuH9.mjs} +2 -2
  42. package/fesm2022/{acorex-modules-assessment-management-questionnaire-viewer-popup.component-Cc-o6qmY.mjs.map → acorex-modules-assessment-management-questionnaire-viewer-popup.component-DgC1xuH9.mjs.map} +1 -1
  43. package/fesm2022/{acorex-modules-assessment-management-questionnaire.entity-CJWNlaJs.mjs → acorex-modules-assessment-management-questionnaire.entity-ChUNq9Bc.mjs} +3 -3
  44. package/fesm2022/{acorex-modules-assessment-management-questionnaire.entity-CJWNlaJs.mjs.map → acorex-modules-assessment-management-questionnaire.entity-ChUNq9Bc.mjs.map} +1 -1
  45. package/fesm2022/{acorex-modules-assessment-management-save-questionnaire-questions.command-C3gOkZa5.mjs → acorex-modules-assessment-management-save-questionnaire-questions.command-sji05ut4.mjs} +2 -2
  46. package/fesm2022/{acorex-modules-assessment-management-save-questionnaire-questions.command-C3gOkZa5.mjs.map → acorex-modules-assessment-management-save-questionnaire-questions.command-sji05ut4.mjs.map} +1 -1
  47. package/fesm2022/{acorex-modules-assessment-management-view-session-answers.command-AvTbWvGE.mjs → acorex-modules-assessment-management-view-session-answers.command-BIpotfIE.mjs} +2 -2
  48. package/fesm2022/{acorex-modules-assessment-management-view-session-answers.command-AvTbWvGE.mjs.map → acorex-modules-assessment-management-view-session-answers.command-BIpotfIE.mjs.map} +1 -1
  49. package/fesm2022/acorex-modules-assessment-management.mjs +1 -1
  50. package/fesm2022/{acorex-modules-asset-management-acorex-modules-asset-management-DrIhRaZ6.mjs → acorex-modules-asset-management-acorex-modules-asset-management-fQ0rp8vu.mjs} +765 -131
  51. package/fesm2022/acorex-modules-asset-management-acorex-modules-asset-management-fQ0rp8vu.mjs.map +1 -0
  52. package/fesm2022/acorex-modules-asset-management-asset-rental-history-status.provider-BiWf2TwD.mjs +118 -0
  53. package/fesm2022/acorex-modules-asset-management-asset-rental-history-status.provider-BiWf2TwD.mjs.map +1 -0
  54. package/fesm2022/{acorex-modules-asset-management-asset-system-assignment.entity-HqZtfJpe.mjs → acorex-modules-asset-management-asset-system-assignment.entity-DuFgujR6.mjs} +2 -2
  55. package/fesm2022/{acorex-modules-asset-management-asset-system-assignment.entity-HqZtfJpe.mjs.map → acorex-modules-asset-management-asset-system-assignment.entity-DuFgujR6.mjs.map} +1 -1
  56. package/fesm2022/{acorex-modules-asset-management-asset-system-type.entity-fvrbyjXb.mjs → acorex-modules-asset-management-asset-system-type.entity-sszGMFny.mjs} +2 -2
  57. package/fesm2022/{acorex-modules-asset-management-asset-system-type.entity-fvrbyjXb.mjs.map → acorex-modules-asset-management-asset-system-type.entity-sszGMFny.mjs.map} +1 -1
  58. package/fesm2022/{acorex-modules-asset-management-asset-system.entity-DVAaXNWx.mjs → acorex-modules-asset-management-asset-system.entity-tWUPNYQq.mjs} +2 -2
  59. package/fesm2022/{acorex-modules-asset-management-asset-system.entity-DVAaXNWx.mjs.map → acorex-modules-asset-management-asset-system.entity-tWUPNYQq.mjs.map} +1 -1
  60. package/fesm2022/{acorex-modules-asset-management-asset-type-section-component.entity-n-bxBcGz.mjs → acorex-modules-asset-management-asset-type-section-component.entity-l3xXMo2l.mjs} +32 -31
  61. package/fesm2022/acorex-modules-asset-management-asset-type-section-component.entity-l3xXMo2l.mjs.map +1 -0
  62. package/fesm2022/{acorex-modules-asset-management-asset-type-section.entity-BF7N699p.mjs → acorex-modules-asset-management-asset-type-section.entity-CldvQBUW.mjs} +2 -2
  63. package/fesm2022/{acorex-modules-asset-management-asset-type-section.entity-BF7N699p.mjs.map → acorex-modules-asset-management-asset-type-section.entity-CldvQBUW.mjs.map} +1 -1
  64. package/fesm2022/{acorex-modules-asset-management-asset-type.entity-Dt61Rs4F.mjs → acorex-modules-asset-management-asset-type.entity-CP0dryvp.mjs} +108 -28
  65. package/fesm2022/acorex-modules-asset-management-asset-type.entity-CP0dryvp.mjs.map +1 -0
  66. package/fesm2022/{acorex-modules-asset-management-asset.entity-BzlsaEwC.mjs → acorex-modules-asset-management-asset.entity-Du_fWe9V.mjs} +21 -230
  67. package/fesm2022/acorex-modules-asset-management-asset.entity-Du_fWe9V.mjs.map +1 -0
  68. package/fesm2022/acorex-modules-asset-management.mjs +1 -1
  69. package/fesm2022/{acorex-modules-auth-acorex-modules-auth-BUtk_RQC.mjs → acorex-modules-auth-acorex-modules-auth-CGiDe3e-.mjs} +13 -13
  70. package/fesm2022/{acorex-modules-auth-acorex-modules-auth-BUtk_RQC.mjs.map → acorex-modules-auth-acorex-modules-auth-CGiDe3e-.mjs.map} +1 -1
  71. package/fesm2022/{acorex-modules-auth-app-chooser.component-DnVYLE4q.mjs → acorex-modules-auth-app-chooser.component-Dt_2eXel.mjs} +2 -2
  72. package/fesm2022/{acorex-modules-auth-app-chooser.component-DnVYLE4q.mjs.map → acorex-modules-auth-app-chooser.component-Dt_2eXel.mjs.map} +1 -1
  73. package/fesm2022/{acorex-modules-auth-login.module-Be-fhX-L.mjs → acorex-modules-auth-login.module-Bl8pAhHc.mjs} +4 -4
  74. package/fesm2022/{acorex-modules-auth-login.module-Be-fhX-L.mjs.map → acorex-modules-auth-login.module-Bl8pAhHc.mjs.map} +1 -1
  75. package/fesm2022/{acorex-modules-auth-master.layout-6n06jHF4.mjs → acorex-modules-auth-master.layout-B8GSev0J.mjs} +2 -2
  76. package/fesm2022/{acorex-modules-auth-master.layout-6n06jHF4.mjs.map → acorex-modules-auth-master.layout-B8GSev0J.mjs.map} +1 -1
  77. package/fesm2022/{acorex-modules-auth-oauth-callback.component-B_u8aKEs.mjs → acorex-modules-auth-oauth-callback.component-DleQ24IP.mjs} +3 -3
  78. package/fesm2022/{acorex-modules-auth-oauth-callback.component-B_u8aKEs.mjs.map → acorex-modules-auth-oauth-callback.component-DleQ24IP.mjs.map} +1 -1
  79. package/fesm2022/{acorex-modules-auth-password.component-Bz6qjJ_G.mjs → acorex-modules-auth-password.component-C1GbARlM.mjs} +2 -2
  80. package/fesm2022/{acorex-modules-auth-password.component-Bz6qjJ_G.mjs.map → acorex-modules-auth-password.component-C1GbARlM.mjs.map} +1 -1
  81. package/fesm2022/{acorex-modules-auth-password.component-w9qdHuT5.mjs → acorex-modules-auth-password.component-D6ALMoO4.mjs} +2 -2
  82. package/fesm2022/{acorex-modules-auth-password.component-w9qdHuT5.mjs.map → acorex-modules-auth-password.component-D6ALMoO4.mjs.map} +1 -1
  83. package/fesm2022/{acorex-modules-auth-routes-CUbjrK-J.mjs → acorex-modules-auth-routes-FDp1SEZA.mjs} +2 -2
  84. package/fesm2022/{acorex-modules-auth-routes-CUbjrK-J.mjs.map → acorex-modules-auth-routes-FDp1SEZA.mjs.map} +1 -1
  85. package/fesm2022/{acorex-modules-auth-settings.provider-DkhbuDBO.mjs → acorex-modules-auth-settings.provider-CN7Lb38l.mjs} +26 -31
  86. package/fesm2022/acorex-modules-auth-settings.provider-CN7Lb38l.mjs.map +1 -0
  87. package/fesm2022/{acorex-modules-auth-tenant-chooser.component-D_cV-RUp.mjs → acorex-modules-auth-tenant-chooser.component-o55sauLG.mjs} +2 -2
  88. package/fesm2022/{acorex-modules-auth-tenant-chooser.component-D_cV-RUp.mjs.map → acorex-modules-auth-tenant-chooser.component-o55sauLG.mjs.map} +1 -1
  89. package/fesm2022/{acorex-modules-auth-two-factor.module-ok-nT2VM.mjs → acorex-modules-auth-two-factor.module-CVrYPw5D.mjs} +2 -2
  90. package/fesm2022/{acorex-modules-auth-two-factor.module-ok-nT2VM.mjs.map → acorex-modules-auth-two-factor.module-CVrYPw5D.mjs.map} +1 -1
  91. package/fesm2022/{acorex-modules-auth-user-sessions.component-Cmrx3_vM.mjs → acorex-modules-auth-user-sessions.component-BVglZAnc.mjs} +2 -2
  92. package/fesm2022/{acorex-modules-auth-user-sessions.component-Cmrx3_vM.mjs.map → acorex-modules-auth-user-sessions.component-BVglZAnc.mjs.map} +1 -1
  93. package/fesm2022/acorex-modules-auth.mjs +1 -1
  94. package/fesm2022/{acorex-modules-common-search-popup.component-UIz5Bphx.mjs → acorex-modules-common-search-popup.component-BbRyjGia.mjs} +2 -2
  95. package/fesm2022/{acorex-modules-common-search-popup.component-UIz5Bphx.mjs.map → acorex-modules-common-search-popup.component-BbRyjGia.mjs.map} +1 -1
  96. package/fesm2022/acorex-modules-common.mjs +10 -35
  97. package/fesm2022/acorex-modules-common.mjs.map +1 -1
  98. package/fesm2022/{acorex-modules-content-management-acorex-modules-content-management-of3UnjxP.mjs → acorex-modules-content-management-acorex-modules-content-management-CO8lZb34.mjs} +40 -6
  99. package/fesm2022/acorex-modules-content-management-acorex-modules-content-management-CO8lZb34.mjs.map +1 -0
  100. package/fesm2022/{acorex-modules-content-management-permission-definition.provider-DnjtPg6f.mjs → acorex-modules-content-management-permission-definition.provider-Bcq5uOVH.mjs} +2 -2
  101. package/fesm2022/{acorex-modules-content-management-permission-definition.provider-DnjtPg6f.mjs.map → acorex-modules-content-management-permission-definition.provider-Bcq5uOVH.mjs.map} +1 -1
  102. package/fesm2022/{acorex-modules-content-management-template-content-editor-widget-edit.component-BKHvQiql.mjs → acorex-modules-content-management-template-content-editor-widget-edit.component-D_q_xWeI.mjs} +59 -16
  103. package/fesm2022/acorex-modules-content-management-template-content-editor-widget-edit.component-D_q_xWeI.mjs.map +1 -0
  104. package/fesm2022/{acorex-modules-content-management-template-content-editor-widget-view.component-q1Se62Hd.mjs → acorex-modules-content-management-template-content-editor-widget-view.component-DU5y6UxK.mjs} +15 -5
  105. package/fesm2022/acorex-modules-content-management-template-content-editor-widget-view.component-DU5y6UxK.mjs.map +1 -0
  106. package/fesm2022/acorex-modules-content-management.mjs +1 -1
  107. package/fesm2022/acorex-modules-conversation-acorex-modules-conversation-BJU2_R9O.mjs +6155 -0
  108. package/fesm2022/acorex-modules-conversation-acorex-modules-conversation-BJU2_R9O.mjs.map +1 -0
  109. package/fesm2022/acorex-modules-conversation-assist-delegated-agent-detail-popup.component-DX2JPckF.mjs +324 -0
  110. package/fesm2022/acorex-modules-conversation-assist-delegated-agent-detail-popup.component-DX2JPckF.mjs.map +1 -0
  111. package/fesm2022/{acorex-modules-conversation-comments-page.component-DnAbpVxZ.mjs → acorex-modules-conversation-comments-page.component-Bg6m7UTG.mjs} +2 -2
  112. package/fesm2022/{acorex-modules-conversation-comments-page.component-DnAbpVxZ.mjs.map → acorex-modules-conversation-comments-page.component-Bg6m7UTG.mjs.map} +1 -1
  113. package/fesm2022/acorex-modules-conversation.mjs +1 -7353
  114. package/fesm2022/acorex-modules-conversation.mjs.map +1 -1
  115. package/fesm2022/{acorex-modules-dashboard-management-acorex-modules-dashboard-management-DLndkp6w.mjs → acorex-modules-dashboard-management-acorex-modules-dashboard-management-D11VudG8.mjs} +6 -7
  116. package/fesm2022/acorex-modules-dashboard-management-acorex-modules-dashboard-management-D11VudG8.mjs.map +1 -0
  117. package/fesm2022/{acorex-modules-dashboard-management-index-c8QzHHtG.mjs → acorex-modules-dashboard-management-index-DB3Uh1wL.mjs} +2 -2
  118. package/fesm2022/{acorex-modules-dashboard-management-index-c8QzHHtG.mjs.map → acorex-modules-dashboard-management-index-DB3Uh1wL.mjs.map} +1 -1
  119. package/fesm2022/acorex-modules-dashboard-management.mjs +1 -1
  120. package/fesm2022/acorex-modules-data-management.mjs +4 -4
  121. package/fesm2022/acorex-modules-data-management.mjs.map +1 -1
  122. package/fesm2022/acorex-modules-document-management-large-tiles-view.component-BZWN7WCX.mjs +24 -0
  123. package/fesm2022/acorex-modules-document-management-large-tiles-view.component-BZWN7WCX.mjs.map +1 -0
  124. package/fesm2022/acorex-modules-document-management-small-tiles-view.component-DI6QQ2St.mjs +24 -0
  125. package/fesm2022/acorex-modules-document-management-small-tiles-view.component-DI6QQ2St.mjs.map +1 -0
  126. package/fesm2022/acorex-modules-document-management.mjs +209 -397
  127. package/fesm2022/acorex-modules-document-management.mjs.map +1 -1
  128. package/fesm2022/{acorex-modules-form-template-management-template-picker.component-GHXF4eT3.mjs → acorex-modules-form-template-management-template-picker.component-CtTkFhXf.mjs} +2 -2
  129. package/fesm2022/{acorex-modules-form-template-management-template-picker.component-GHXF4eT3.mjs.map → acorex-modules-form-template-management-template-picker.component-CtTkFhXf.mjs.map} +1 -1
  130. package/fesm2022/acorex-modules-form-template-management.mjs +14 -18
  131. package/fesm2022/acorex-modules-form-template-management.mjs.map +1 -1
  132. package/fesm2022/{acorex-modules-human-capital-management-acorex-modules-human-capital-management-Bgsi3FHG.mjs → acorex-modules-human-capital-management-acorex-modules-human-capital-management-hImDhzkB.mjs} +90 -82
  133. package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-hImDhzkB.mjs.map +1 -0
  134. package/fesm2022/{acorex-modules-human-capital-management-approve-leave-request.command-CxpTmb-1.mjs → acorex-modules-human-capital-management-approve-leave-request.command-DujyJOvo.mjs} +2 -2
  135. package/fesm2022/{acorex-modules-human-capital-management-approve-leave-request.command-CxpTmb-1.mjs.map → acorex-modules-human-capital-management-approve-leave-request.command-DujyJOvo.mjs.map} +1 -1
  136. package/fesm2022/{acorex-modules-human-capital-management-assign-position-assignment.command-jLGe49dJ.mjs → acorex-modules-human-capital-management-assign-position-assignment.command-BPB9vaCn.mjs} +2 -2
  137. package/fesm2022/{acorex-modules-human-capital-management-assign-position-assignment.command-jLGe49dJ.mjs.map → acorex-modules-human-capital-management-assign-position-assignment.command-BPB9vaCn.mjs.map} +1 -1
  138. package/fesm2022/{acorex-modules-human-capital-management-cancel-leave-request.command-ChNGu90e.mjs → acorex-modules-human-capital-management-cancel-leave-request.command-BdPUdhbU.mjs} +2 -2
  139. package/fesm2022/{acorex-modules-human-capital-management-cancel-leave-request.command-ChNGu90e.mjs.map → acorex-modules-human-capital-management-cancel-leave-request.command-BdPUdhbU.mjs.map} +1 -1
  140. package/fesm2022/{acorex-modules-human-capital-management-employee.entity-4k7F7_ON.mjs → acorex-modules-human-capital-management-employee.entity-CgmF-WPf.mjs} +4 -2
  141. package/fesm2022/acorex-modules-human-capital-management-employee.entity-CgmF-WPf.mjs.map +1 -0
  142. package/fesm2022/{acorex-modules-human-capital-management-employment-type.entity-Jo2fB9R3.mjs → acorex-modules-human-capital-management-employment-type.entity-Chio_E9S.mjs} +2 -2
  143. package/fesm2022/{acorex-modules-human-capital-management-employment-type.entity-Jo2fB9R3.mjs.map → acorex-modules-human-capital-management-employment-type.entity-Chio_E9S.mjs.map} +1 -1
  144. package/fesm2022/{acorex-modules-human-capital-management-leave-request.entity-DhLUXnJu.mjs → acorex-modules-human-capital-management-leave-request.entity--9iGu0H7.mjs} +2 -2
  145. package/fesm2022/{acorex-modules-human-capital-management-leave-request.entity-DhLUXnJu.mjs.map → acorex-modules-human-capital-management-leave-request.entity--9iGu0H7.mjs.map} +1 -1
  146. package/fesm2022/{acorex-modules-human-capital-management-leave-type.entity-C-lN2bb0.mjs → acorex-modules-human-capital-management-leave-type.entity-O0j4P2oU.mjs} +2 -2
  147. package/fesm2022/{acorex-modules-human-capital-management-leave-type.entity-C-lN2bb0.mjs.map → acorex-modules-human-capital-management-leave-type.entity-O0j4P2oU.mjs.map} +1 -1
  148. package/fesm2022/{acorex-modules-human-capital-management-position-assignment.entity-BD1jN4Mx.mjs → acorex-modules-human-capital-management-position-assignment.entity-Bg6omEy_.mjs} +2 -2
  149. package/fesm2022/{acorex-modules-human-capital-management-position-assignment.entity-BD1jN4Mx.mjs.map → acorex-modules-human-capital-management-position-assignment.entity-Bg6omEy_.mjs.map} +1 -1
  150. package/fesm2022/{acorex-modules-human-capital-management-reject-leave-request.command-D0G6UrqI.mjs → acorex-modules-human-capital-management-reject-leave-request.command-ZNGufyB1.mjs} +2 -2
  151. package/fesm2022/{acorex-modules-human-capital-management-reject-leave-request.command-D0G6UrqI.mjs.map → acorex-modules-human-capital-management-reject-leave-request.command-ZNGufyB1.mjs.map} +1 -1
  152. package/fesm2022/{acorex-modules-human-capital-management-revoke-position-assignment.command-CYzqQXja.mjs → acorex-modules-human-capital-management-revoke-position-assignment.command-C8pwJExa.mjs} +28 -17
  153. package/fesm2022/acorex-modules-human-capital-management-revoke-position-assignment.command-C8pwJExa.mjs.map +1 -0
  154. package/fesm2022/acorex-modules-human-capital-management.mjs +1 -1
  155. package/fesm2022/acorex-modules-locale-management.mjs +72 -70
  156. package/fesm2022/acorex-modules-locale-management.mjs.map +1 -1
  157. package/fesm2022/acorex-modules-location-management.mjs +20 -10
  158. package/fesm2022/acorex-modules-location-management.mjs.map +1 -1
  159. package/fesm2022/{acorex-modules-maintenance-management-acorex-modules-maintenance-management-B5wf4zMI.mjs → acorex-modules-maintenance-management-acorex-modules-maintenance-management-C0LLBxMR.mjs} +40 -38
  160. package/fesm2022/acorex-modules-maintenance-management-acorex-modules-maintenance-management-C0LLBxMR.mjs.map +1 -0
  161. package/fesm2022/{acorex-modules-maintenance-management-failure-effect.entity-Cv5KnboB.mjs → acorex-modules-maintenance-management-failure-effect.entity-D8yOqKWQ.mjs} +2 -2
  162. package/fesm2022/{acorex-modules-maintenance-management-failure-effect.entity-Cv5KnboB.mjs.map → acorex-modules-maintenance-management-failure-effect.entity-D8yOqKWQ.mjs.map} +1 -1
  163. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-asset-type.entity-BBL3-hfv.mjs → acorex-modules-maintenance-management-failure-mode-asset-type.entity-CHXkbEHG.mjs} +2 -2
  164. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-asset-type.entity-BBL3-hfv.mjs.map → acorex-modules-maintenance-management-failure-mode-asset-type.entity-CHXkbEHG.mjs.map} +1 -1
  165. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-mechanism.entity-nxOdHZxu.mjs → acorex-modules-maintenance-management-failure-mode-mechanism.entity-yR11e9TU.mjs} +2 -2
  166. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-mechanism.entity-nxOdHZxu.mjs.map → acorex-modules-maintenance-management-failure-mode-mechanism.entity-yR11e9TU.mjs.map} +1 -1
  167. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-solution.entity-ApD80Scc.mjs → acorex-modules-maintenance-management-failure-mode-solution.entity-BD4Uz6G-.mjs} +2 -2
  168. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-solution.entity-ApD80Scc.mjs.map → acorex-modules-maintenance-management-failure-mode-solution.entity-BD4Uz6G-.mjs.map} +1 -1
  169. package/fesm2022/{acorex-modules-maintenance-management-failure-register-cause.entity-CibfwJLG.mjs → acorex-modules-maintenance-management-failure-register-cause.entity-CZFgl-t4.mjs} +2 -2
  170. package/fesm2022/{acorex-modules-maintenance-management-failure-register-cause.entity-CibfwJLG.mjs.map → acorex-modules-maintenance-management-failure-register-cause.entity-CZFgl-t4.mjs.map} +1 -1
  171. package/fesm2022/{acorex-modules-maintenance-management-failure-register-effect.entity-DpoqULBf.mjs → acorex-modules-maintenance-management-failure-register-effect.entity-DQE5nqiN.mjs} +2 -2
  172. package/fesm2022/{acorex-modules-maintenance-management-failure-register-effect.entity-DpoqULBf.mjs.map → acorex-modules-maintenance-management-failure-register-effect.entity-DQE5nqiN.mjs.map} +1 -1
  173. package/fesm2022/{acorex-modules-maintenance-management-failure-register-mechanism.entity-0-J2Hkmn.mjs → acorex-modules-maintenance-management-failure-register-mechanism.entity-C6mhbWzU.mjs} +2 -2
  174. package/fesm2022/{acorex-modules-maintenance-management-failure-register-mechanism.entity-0-J2Hkmn.mjs.map → acorex-modules-maintenance-management-failure-register-mechanism.entity-C6mhbWzU.mjs.map} +1 -1
  175. package/fesm2022/{acorex-modules-maintenance-management-failure-register.entity-C4Az4Rr9.mjs → acorex-modules-maintenance-management-failure-register.entity-DSnrVaWI.mjs} +2 -2
  176. package/fesm2022/{acorex-modules-maintenance-management-failure-register.entity-C4Az4Rr9.mjs.map → acorex-modules-maintenance-management-failure-register.entity-DSnrVaWI.mjs.map} +1 -1
  177. package/fesm2022/{acorex-modules-maintenance-management-failure-severity.entity-BZo6UUun.mjs → acorex-modules-maintenance-management-failure-severity.entity-DZoMhgW7.mjs} +2 -2
  178. package/fesm2022/{acorex-modules-maintenance-management-failure-severity.entity-BZo6UUun.mjs.map → acorex-modules-maintenance-management-failure-severity.entity-DZoMhgW7.mjs.map} +1 -1
  179. package/fesm2022/{acorex-modules-maintenance-management-maintenance-template.entity-DxYY0hpG.mjs → acorex-modules-maintenance-management-maintenance-template.entity-qf2WNKB_.mjs} +2 -2
  180. package/fesm2022/{acorex-modules-maintenance-management-maintenance-template.entity-DxYY0hpG.mjs.map → acorex-modules-maintenance-management-maintenance-template.entity-qf2WNKB_.mjs.map} +1 -1
  181. package/fesm2022/acorex-modules-maintenance-management.mjs +1 -1
  182. package/fesm2022/{acorex-modules-notification-management-notification-page.component-D0we6H1f.mjs → acorex-modules-notification-management-notification-page.component-B017YY1H.mjs} +2 -2
  183. package/fesm2022/{acorex-modules-notification-management-notification-page.component-D0we6H1f.mjs.map → acorex-modules-notification-management-notification-page.component-B017YY1H.mjs.map} +1 -1
  184. package/fesm2022/acorex-modules-notification-management.mjs +369 -45
  185. package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
  186. package/fesm2022/{acorex-modules-order-management-settings.provider-BzNJIZCu.mjs → acorex-modules-order-management-settings.provider-DF8JQ1PZ.mjs} +6 -11
  187. package/fesm2022/acorex-modules-order-management-settings.provider-DF8JQ1PZ.mjs.map +1 -0
  188. package/fesm2022/acorex-modules-order-management.mjs +2 -2
  189. package/fesm2022/{acorex-modules-organization-management-acorex-modules-organization-management-Bu8fRj_5.mjs → acorex-modules-organization-management-acorex-modules-organization-management-CGzZcKEy.mjs} +256 -303
  190. package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-CGzZcKEy.mjs.map +1 -0
  191. package/fesm2022/acorex-modules-organization-management-add-business-unit-to-business-unit.command-BEJyfR3P.mjs +165 -0
  192. package/fesm2022/acorex-modules-organization-management-add-business-unit-to-business-unit.command-BEJyfR3P.mjs.map +1 -0
  193. package/fesm2022/{acorex-modules-organization-management-add-position-to-business-unit.command-Qej_boIY.mjs → acorex-modules-organization-management-add-position-to-business-unit.command-DKgxg9q5.mjs} +32 -2
  194. package/fesm2022/acorex-modules-organization-management-add-position-to-business-unit.command-DKgxg9q5.mjs.map +1 -0
  195. package/fesm2022/acorex-modules-organization-management-add-team-to-business-unit.command-DJJT7BXT.mjs +130 -0
  196. package/fesm2022/acorex-modules-organization-management-add-team-to-business-unit.command-DJJT7BXT.mjs.map +1 -0
  197. package/fesm2022/{acorex-modules-organization-management-business-unit.entity-BfQ_7JAq.mjs → acorex-modules-organization-management-business-unit.entity-BAp38sib.mjs} +38 -5
  198. package/fesm2022/acorex-modules-organization-management-business-unit.entity-BAp38sib.mjs.map +1 -0
  199. package/fesm2022/{acorex-modules-organization-management-chart.entity-CNQGGfHV.mjs → acorex-modules-organization-management-chart.entity-WfmpWj8R.mjs} +2 -2
  200. package/fesm2022/{acorex-modules-organization-management-chart.entity-CNQGGfHV.mjs.map → acorex-modules-organization-management-chart.entity-WfmpWj8R.mjs.map} +1 -1
  201. package/fesm2022/{acorex-modules-organization-management-company.entity-D_nTKLzu.mjs → acorex-modules-organization-management-company.entity-BUVLrwjq.mjs} +2 -2
  202. package/fesm2022/{acorex-modules-organization-management-company.entity-D_nTKLzu.mjs.map → acorex-modules-organization-management-company.entity-BUVLrwjq.mjs.map} +1 -1
  203. package/fesm2022/{acorex-modules-organization-management-entity.provider-B4uYixLQ.mjs → acorex-modules-organization-management-entity.provider-DH3eUGTu.mjs} +15 -15
  204. package/fesm2022/{acorex-modules-organization-management-entity.provider-B4uYixLQ.mjs.map → acorex-modules-organization-management-entity.provider-DH3eUGTu.mjs.map} +1 -1
  205. package/fesm2022/{acorex-modules-organization-management-feature-definition.provider-COjc6knz.mjs → acorex-modules-organization-management-feature-definition.provider-DuScrBze.mjs} +2 -2
  206. package/fesm2022/{acorex-modules-organization-management-feature-definition.provider-COjc6knz.mjs.map → acorex-modules-organization-management-feature-definition.provider-DuScrBze.mjs.map} +1 -1
  207. package/fesm2022/{acorex-modules-organization-management-job-definition-pages-component.provider-gDpII9TZ.mjs → acorex-modules-organization-management-job-definition-pages-component.provider-D-J9JCsU.mjs} +3 -3
  208. package/fesm2022/{acorex-modules-organization-management-job-definition-pages-component.provider-gDpII9TZ.mjs.map → acorex-modules-organization-management-job-definition-pages-component.provider-D-J9JCsU.mjs.map} +1 -1
  209. package/fesm2022/{acorex-modules-organization-management-job-definition-responsibilities-page.component-CjXV4wrM.mjs → acorex-modules-organization-management-job-definition-responsibilities-page.component-Dsy5rFGw.mjs} +3 -3
  210. package/fesm2022/{acorex-modules-organization-management-job-definition-responsibilities-page.component-CjXV4wrM.mjs.map → acorex-modules-organization-management-job-definition-responsibilities-page.component-Dsy5rFGw.mjs.map} +1 -1
  211. package/fesm2022/{acorex-modules-organization-management-job-definition-skills-page.component-2XBgMms-.mjs → acorex-modules-organization-management-job-definition-skills-page.component-B73wLPby.mjs} +2 -2
  212. package/fesm2022/{acorex-modules-organization-management-job-definition-skills-page.component-2XBgMms-.mjs.map → acorex-modules-organization-management-job-definition-skills-page.component-B73wLPby.mjs.map} +1 -1
  213. package/fesm2022/{acorex-modules-organization-management-job-definition.entity-f0JnkdjP.mjs → acorex-modules-organization-management-job-definition.entity-B7mWKYqb.mjs} +2 -2
  214. package/fesm2022/{acorex-modules-organization-management-job-definition.entity-f0JnkdjP.mjs.map → acorex-modules-organization-management-job-definition.entity-B7mWKYqb.mjs.map} +1 -1
  215. package/fesm2022/{acorex-modules-organization-management-job-level.datasource-ByHluGvc.mjs → acorex-modules-organization-management-job-level.datasource-DibRoKXR.mjs} +2 -2
  216. package/fesm2022/{acorex-modules-organization-management-job-level.datasource-ByHluGvc.mjs.map → acorex-modules-organization-management-job-level.datasource-DibRoKXR.mjs.map} +1 -1
  217. package/fesm2022/{acorex-modules-organization-management-job-level.entity-BJJJQxCp.mjs → acorex-modules-organization-management-job-level.entity-C_MzeTw5.mjs} +2 -2
  218. package/fesm2022/{acorex-modules-organization-management-job-level.entity-BJJJQxCp.mjs.map → acorex-modules-organization-management-job-level.entity-C_MzeTw5.mjs.map} +1 -1
  219. package/fesm2022/{acorex-modules-organization-management-menu.provider-Dd_Z58sY.mjs → acorex-modules-organization-management-menu.provider-CQeJINzl.mjs} +3 -2
  220. package/fesm2022/{acorex-modules-organization-management-menu.provider-Dd_Z58sY.mjs.map → acorex-modules-organization-management-menu.provider-CQeJINzl.mjs.map} +1 -1
  221. package/fesm2022/acorex-modules-organization-management-org-chart-default-node-contribution.provider-D3hCHSr_.mjs +228 -0
  222. package/fesm2022/acorex-modules-organization-management-org-chart-default-node-contribution.provider-D3hCHSr_.mjs.map +1 -0
  223. package/fesm2022/acorex-modules-organization-management-org-chart-employee-flyout-contribution.provider-Bv0I-45L.mjs +182 -0
  224. package/fesm2022/acorex-modules-organization-management-org-chart-employee-flyout-contribution.provider-Bv0I-45L.mjs.map +1 -0
  225. package/fesm2022/acorex-modules-organization-management-org-chart-position-employee-node-contribution.provider-DbfYza8q.mjs +170 -0
  226. package/fesm2022/acorex-modules-organization-management-org-chart-position-employee-node-contribution.provider-DbfYza8q.mjs.map +1 -0
  227. package/fesm2022/acorex-modules-organization-management-org-chart-ux-node-contribution.provider-C9APxguL.mjs +334 -0
  228. package/fesm2022/acorex-modules-organization-management-org-chart-ux-node-contribution.provider-C9APxguL.mjs.map +1 -0
  229. package/fesm2022/{acorex-modules-organization-management-org-chart.page-fudrNddI.mjs → acorex-modules-organization-management-org-chart.page-BcHO5kKP.mjs} +135 -63
  230. package/fesm2022/acorex-modules-organization-management-org-chart.page-BcHO5kKP.mjs.map +1 -0
  231. package/fesm2022/{acorex-modules-organization-management-permission-definition.provider-CoB_RGSa.mjs → acorex-modules-organization-management-permission-definition.provider-BcIRJpBt.mjs} +3 -2
  232. package/fesm2022/{acorex-modules-organization-management-permission-definition.provider-CoB_RGSa.mjs.map → acorex-modules-organization-management-permission-definition.provider-BcIRJpBt.mjs.map} +1 -1
  233. package/fesm2022/acorex-modules-organization-management-permission.keys-DwZNBc12.mjs +56 -0
  234. package/fesm2022/acorex-modules-organization-management-permission.keys-DwZNBc12.mjs.map +1 -0
  235. package/fesm2022/{acorex-modules-organization-management-position.entity-T1DY1fZn.mjs → acorex-modules-organization-management-position.entity-DBOpLtSI.mjs} +6 -2
  236. package/fesm2022/acorex-modules-organization-management-position.entity-DBOpLtSI.mjs.map +1 -0
  237. package/fesm2022/acorex-modules-organization-management-remove-position-from-business-unit.command-TqYgfnsy.mjs +92 -0
  238. package/fesm2022/acorex-modules-organization-management-remove-position-from-business-unit.command-TqYgfnsy.mjs.map +1 -0
  239. package/fesm2022/acorex-modules-organization-management-replace-position-assignee.command-BJ2gn0-A.mjs +66 -0
  240. package/fesm2022/acorex-modules-organization-management-replace-position-assignee.command-BJ2gn0-A.mjs.map +1 -0
  241. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CIPzMi3d.mjs → acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CZdMLIL-.mjs} +2 -2
  242. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CIPzMi3d.mjs.map → acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CZdMLIL-.mjs.map} +1 -1
  243. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-view.component-DzdTNVP6.mjs → acorex-modules-organization-management-responsibilities-matrix-widget-view.component-BBo97rDN.mjs} +2 -2
  244. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-view.component-DzdTNVP6.mjs.map → acorex-modules-organization-management-responsibilities-matrix-widget-view.component-BBo97rDN.mjs.map} +1 -1
  245. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix.component-C850Dz47.mjs → acorex-modules-organization-management-responsibilities-matrix.component-D9oH_Fbb.mjs} +2 -2
  246. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix.component-C850Dz47.mjs.map → acorex-modules-organization-management-responsibilities-matrix.component-D9oH_Fbb.mjs.map} +1 -1
  247. package/fesm2022/{acorex-modules-organization-management-responsibility-level.entity-CVxWva5x.mjs → acorex-modules-organization-management-responsibility-level.entity-D6IG9Zc7.mjs} +2 -2
  248. package/fesm2022/{acorex-modules-organization-management-responsibility-level.entity-CVxWva5x.mjs.map → acorex-modules-organization-management-responsibility-level.entity-D6IG9Zc7.mjs.map} +1 -1
  249. package/fesm2022/{acorex-modules-organization-management-responsibility.entity-BmDZhqNl.mjs → acorex-modules-organization-management-responsibility.entity-BosNxYjW.mjs} +2 -2
  250. package/fesm2022/{acorex-modules-organization-management-responsibility.entity-BmDZhqNl.mjs.map → acorex-modules-organization-management-responsibility.entity-BosNxYjW.mjs.map} +1 -1
  251. package/fesm2022/{acorex-modules-organization-management-settings.provider-wwGKyBrV.mjs → acorex-modules-organization-management-settings.provider-CL9C9UXA.mjs} +21 -24
  252. package/fesm2022/acorex-modules-organization-management-settings.provider-CL9C9UXA.mjs.map +1 -0
  253. package/fesm2022/{acorex-modules-organization-management-team-business-unit.entity-BmXLb4RI.mjs → acorex-modules-organization-management-team-business-unit.entity-CYFGTcHe.mjs} +2 -2
  254. package/fesm2022/{acorex-modules-organization-management-team-business-unit.entity-BmXLb4RI.mjs.map → acorex-modules-organization-management-team-business-unit.entity-CYFGTcHe.mjs.map} +1 -1
  255. package/fesm2022/{acorex-modules-organization-management-team-member-role.entity-C4DGSm2r.mjs → acorex-modules-organization-management-team-member-role.entity-B5vNDne0.mjs} +2 -2
  256. package/fesm2022/{acorex-modules-organization-management-team-member-role.entity-C4DGSm2r.mjs.map → acorex-modules-organization-management-team-member-role.entity-B5vNDne0.mjs.map} +1 -1
  257. package/fesm2022/{acorex-modules-organization-management-team-member.entity-CvVHEzIU.mjs → acorex-modules-organization-management-team-member.entity-DsKuxCRB.mjs} +14 -2
  258. package/fesm2022/acorex-modules-organization-management-team-member.entity-DsKuxCRB.mjs.map +1 -0
  259. package/fesm2022/{acorex-modules-organization-management-team.entity-urjULfNp.mjs → acorex-modules-organization-management-team.entity-Cg30cho_.mjs} +3 -2
  260. package/fesm2022/acorex-modules-organization-management-team.entity-Cg30cho_.mjs.map +1 -0
  261. package/fesm2022/acorex-modules-organization-management.mjs +1 -1
  262. package/fesm2022/acorex-modules-person-core-gender.entity-DQVC2nR1.mjs +121 -0
  263. package/fesm2022/acorex-modules-person-core-gender.entity-DQVC2nR1.mjs.map +1 -0
  264. package/fesm2022/acorex-modules-person-core-marital-status.entity-Bcrni-xU.mjs +121 -0
  265. package/fesm2022/acorex-modules-person-core-marital-status.entity-Bcrni-xU.mjs.map +1 -0
  266. package/fesm2022/acorex-modules-person-core-person-title.entity-h53llLF9.mjs +121 -0
  267. package/fesm2022/acorex-modules-person-core-person-title.entity-h53llLF9.mjs.map +1 -0
  268. package/fesm2022/acorex-modules-person-core.mjs +151 -295
  269. package/fesm2022/acorex-modules-person-core.mjs.map +1 -1
  270. package/fesm2022/{acorex-modules-platform-dev-tools-settings.provider-CGyf-4eq.mjs → acorex-modules-platform-dev-tools-settings.provider-DKmgBUYt.mjs} +2 -2
  271. package/fesm2022/acorex-modules-platform-dev-tools-settings.provider-DKmgBUYt.mjs.map +1 -0
  272. package/fesm2022/acorex-modules-platform-dev-tools.mjs +2 -2
  273. package/fesm2022/{acorex-modules-platform-management-acorex-modules-platform-management-CZMqG3Eq.mjs → acorex-modules-platform-management-acorex-modules-platform-management-DkOzj2Oy.mjs} +12 -4
  274. package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-DkOzj2Oy.mjs.map +1 -0
  275. package/fesm2022/acorex-modules-platform-management-entity-master-actions-for-ai.util-OCk5eqQz.mjs +56 -0
  276. package/fesm2022/acorex-modules-platform-management-entity-master-actions-for-ai.util-OCk5eqQz.mjs.map +1 -0
  277. package/fesm2022/acorex-modules-platform-management-list-platform-navigation-for-ai.query-C3-eBMwF.mjs +198 -0
  278. package/fesm2022/acorex-modules-platform-management-list-platform-navigation-for-ai.query-C3-eBMwF.mjs.map +1 -0
  279. package/fesm2022/{acorex-modules-platform-management-list-registered-entities.query-B6-zV_Ml.mjs → acorex-modules-platform-management-list-registered-entities.query-BZVD9YPU.mjs} +26 -4
  280. package/fesm2022/acorex-modules-platform-management-list-registered-entities.query-BZVD9YPU.mjs.map +1 -0
  281. package/fesm2022/{acorex-modules-platform-management-menu-list.component-BRA7Q50z.mjs → acorex-modules-platform-management-menu-list.component-agWZWchQ.mjs} +3 -3
  282. package/fesm2022/{acorex-modules-platform-management-menu-list.component-BRA7Q50z.mjs.map → acorex-modules-platform-management-menu-list.component-agWZWchQ.mjs.map} +1 -1
  283. package/fesm2022/acorex-modules-platform-management.mjs +1 -1
  284. package/fesm2022/{acorex-modules-report-management-report-runner-root-page.component-BjKrHoBg.mjs → acorex-modules-report-management-report-runner-root-page.component-B-NoGoOJ.mjs} +2 -2
  285. package/fesm2022/{acorex-modules-report-management-report-runner-root-page.component-BjKrHoBg.mjs.map → acorex-modules-report-management-report-runner-root-page.component-B-NoGoOJ.mjs.map} +1 -1
  286. package/fesm2022/acorex-modules-report-management.mjs +7 -7
  287. package/fesm2022/acorex-modules-report-management.mjs.map +1 -1
  288. package/fesm2022/acorex-modules-security-management.mjs +1 -1
  289. package/fesm2022/acorex-modules-security-management.mjs.map +1 -1
  290. package/fesm2022/{acorex-modules-settings-management-acorex-modules-settings-management-BaDnebTm.mjs → acorex-modules-settings-management-acorex-modules-settings-management-oArHHeSx.mjs} +88 -13
  291. package/fesm2022/acorex-modules-settings-management-acorex-modules-settings-management-oArHHeSx.mjs.map +1 -0
  292. package/fesm2022/{acorex-modules-settings-management-permission-definition.provider-cuuhKUJ1.mjs → acorex-modules-settings-management-permission-definition.provider-BsFyZ-gS.mjs} +2 -2
  293. package/fesm2022/{acorex-modules-settings-management-permission-definition.provider-cuuhKUJ1.mjs.map → acorex-modules-settings-management-permission-definition.provider-BsFyZ-gS.mjs.map} +1 -1
  294. package/fesm2022/{acorex-modules-settings-management-setting-page.component-CWIs93_1.mjs → acorex-modules-settings-management-setting-page.component-BftWms4f.mjs} +5 -4
  295. package/fesm2022/acorex-modules-settings-management-setting-page.component-BftWms4f.mjs.map +1 -0
  296. package/fesm2022/{acorex-modules-settings-management-setting-view.component-BTexlmU1.mjs → acorex-modules-settings-management-setting-view.component-paKdiSEr.mjs} +2 -2
  297. package/fesm2022/{acorex-modules-settings-management-setting-view.component-BTexlmU1.mjs.map → acorex-modules-settings-management-setting-view.component-paKdiSEr.mjs.map} +1 -1
  298. package/fesm2022/acorex-modules-settings-management.mjs +1 -1
  299. package/fesm2022/{acorex-modules-task-management-acorex-modules-task-management-it-Lf0L_.mjs → acorex-modules-task-management-acorex-modules-task-management-DDUq9FpA.mjs} +202 -41
  300. package/fesm2022/acorex-modules-task-management-acorex-modules-task-management-DDUq9FpA.mjs.map +1 -0
  301. package/fesm2022/{acorex-modules-task-management-task-board.page-DF4XWz_0.mjs → acorex-modules-task-management-task-board.page-C6j-_aSD.mjs} +107 -69
  302. package/fesm2022/acorex-modules-task-management-task-board.page-C6j-_aSD.mjs.map +1 -0
  303. package/fesm2022/acorex-modules-task-management.mjs +1 -1
  304. package/fesm2022/acorex-modules-tenant-management.mjs +3 -7
  305. package/fesm2022/acorex-modules-tenant-management.mjs.map +1 -1
  306. package/organization-management/README.md +1 -1
  307. package/package.json +2 -2
  308. package/platform-management/README.md +4 -0
  309. package/types/acorex-modules-ai-management.d.ts +158 -577
  310. package/types/acorex-modules-application-management.d.ts +5 -2
  311. package/types/acorex-modules-asset-management.d.ts +19 -87
  312. package/types/acorex-modules-common.d.ts +3 -6
  313. package/types/acorex-modules-content-management.d.ts +22 -5
  314. package/types/acorex-modules-conversation.d.ts +60 -4
  315. package/types/acorex-modules-document-management.d.ts +53 -22
  316. package/types/acorex-modules-human-capital-management.d.ts +15 -10
  317. package/types/acorex-modules-location-management.d.ts +9 -1
  318. package/types/acorex-modules-maintenance-management.d.ts +0 -2
  319. package/types/acorex-modules-notification-management.d.ts +68 -6
  320. package/types/acorex-modules-organization-management.d.ts +145 -44
  321. package/types/acorex-modules-person-core.d.ts +61 -4
  322. package/types/acorex-modules-settings-management.d.ts +3 -0
  323. package/types/acorex-modules-task-management.d.ts +12 -2
  324. package/types/acorex-modules-tenant-management.d.ts +0 -1
  325. package/fesm2022/acorex-modules-ai-management-acorex-modules-ai-management-D7_4LOGV.mjs +0 -8666
  326. package/fesm2022/acorex-modules-ai-management-acorex-modules-ai-management-D7_4LOGV.mjs.map +0 -1
  327. package/fesm2022/acorex-modules-ai-management-agent-registry-tool-configurator-widget-edit.component-C7TQMwX4.mjs.map +0 -1
  328. package/fesm2022/acorex-modules-ai-management-agent.entity-DwPIKib2.mjs.map +0 -1
  329. package/fesm2022/acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-D2GJ5qD1.mjs +0 -1254
  330. package/fesm2022/acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-D2GJ5qD1.mjs.map +0 -1
  331. package/fesm2022/acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-BozVAuLO.mjs.map +0 -1
  332. package/fesm2022/acorex-modules-ai-management-index-DaGJVOFw.mjs +0 -2
  333. package/fesm2022/acorex-modules-ai-management-index-DaGJVOFw.mjs.map +0 -1
  334. package/fesm2022/acorex-modules-asset-management-acorex-modules-asset-management-DrIhRaZ6.mjs.map +0 -1
  335. package/fesm2022/acorex-modules-asset-management-asset-rental-history.entity-95NBXoex.mjs +0 -302
  336. package/fesm2022/acorex-modules-asset-management-asset-rental-history.entity-95NBXoex.mjs.map +0 -1
  337. package/fesm2022/acorex-modules-asset-management-asset-state-history.entity-C-z103la.mjs +0 -258
  338. package/fesm2022/acorex-modules-asset-management-asset-state-history.entity-C-z103la.mjs.map +0 -1
  339. package/fesm2022/acorex-modules-asset-management-asset-status.rules-B7KwWQEe.mjs +0 -98
  340. package/fesm2022/acorex-modules-asset-management-asset-status.rules-B7KwWQEe.mjs.map +0 -1
  341. package/fesm2022/acorex-modules-asset-management-asset-type-section-component.entity-n-bxBcGz.mjs.map +0 -1
  342. package/fesm2022/acorex-modules-asset-management-asset-type.entity-Dt61Rs4F.mjs.map +0 -1
  343. package/fesm2022/acorex-modules-asset-management-asset.entity-BzlsaEwC.mjs.map +0 -1
  344. package/fesm2022/acorex-modules-asset-management-assetLifecycle-state.provider-DZ5r2zx7.mjs +0 -192
  345. package/fesm2022/acorex-modules-asset-management-assetLifecycle-state.provider-DZ5r2zx7.mjs.map +0 -1
  346. package/fesm2022/acorex-modules-asset-management-status.provider-C41t4e2U.mjs +0 -363
  347. package/fesm2022/acorex-modules-asset-management-status.provider-C41t4e2U.mjs.map +0 -1
  348. package/fesm2022/acorex-modules-auth-settings.provider-DkhbuDBO.mjs.map +0 -1
  349. package/fesm2022/acorex-modules-content-management-acorex-modules-content-management-of3UnjxP.mjs.map +0 -1
  350. package/fesm2022/acorex-modules-content-management-template-content-editor-widget-edit.component-BKHvQiql.mjs.map +0 -1
  351. package/fesm2022/acorex-modules-content-management-template-content-editor-widget-view.component-q1Se62Hd.mjs.map +0 -1
  352. package/fesm2022/acorex-modules-dashboard-management-acorex-modules-dashboard-management-DLndkp6w.mjs.map +0 -1
  353. package/fesm2022/acorex-modules-document-management-large-tiles-view.component-CSHUgcLx.mjs +0 -24
  354. package/fesm2022/acorex-modules-document-management-large-tiles-view.component-CSHUgcLx.mjs.map +0 -1
  355. package/fesm2022/acorex-modules-document-management-small-tiles-view.component-BQSgUw6o.mjs +0 -24
  356. package/fesm2022/acorex-modules-document-management-small-tiles-view.component-BQSgUw6o.mjs.map +0 -1
  357. package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-Bgsi3FHG.mjs.map +0 -1
  358. package/fesm2022/acorex-modules-human-capital-management-employee.entity-4k7F7_ON.mjs.map +0 -1
  359. package/fesm2022/acorex-modules-human-capital-management-revoke-position-assignment.command-CYzqQXja.mjs.map +0 -1
  360. package/fesm2022/acorex-modules-maintenance-management-acorex-modules-maintenance-management-B5wf4zMI.mjs.map +0 -1
  361. package/fesm2022/acorex-modules-order-management-settings.provider-BzNJIZCu.mjs.map +0 -1
  362. package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-Bu8fRj_5.mjs.map +0 -1
  363. package/fesm2022/acorex-modules-organization-management-add-position-to-business-unit.command-Qej_boIY.mjs.map +0 -1
  364. package/fesm2022/acorex-modules-organization-management-business-unit.entity-BfQ_7JAq.mjs.map +0 -1
  365. package/fesm2022/acorex-modules-organization-management-org-chart.page-fudrNddI.mjs.map +0 -1
  366. package/fesm2022/acorex-modules-organization-management-position.entity-T1DY1fZn.mjs.map +0 -1
  367. package/fesm2022/acorex-modules-organization-management-settings.provider-wwGKyBrV.mjs.map +0 -1
  368. package/fesm2022/acorex-modules-organization-management-team-member.entity-CvVHEzIU.mjs.map +0 -1
  369. package/fesm2022/acorex-modules-organization-management-team.entity-urjULfNp.mjs.map +0 -1
  370. package/fesm2022/acorex-modules-platform-dev-tools-settings.provider-CGyf-4eq.mjs.map +0 -1
  371. package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-CZMqG3Eq.mjs.map +0 -1
  372. package/fesm2022/acorex-modules-platform-management-list-registered-entities.query-B6-zV_Ml.mjs.map +0 -1
  373. package/fesm2022/acorex-modules-settings-management-acorex-modules-settings-management-BaDnebTm.mjs.map +0 -1
  374. package/fesm2022/acorex-modules-settings-management-setting-page.component-CWIs93_1.mjs.map +0 -1
  375. package/fesm2022/acorex-modules-task-management-acorex-modules-task-management-it-Lf0L_.mjs.map +0 -1
  376. package/fesm2022/acorex-modules-task-management-task-board.page-DF4XWz_0.mjs.map +0 -1
@@ -1,2 +1,4443 @@
1
- export { e as AIMANAGEMENT_CHAT_GENERATE_IMAGE_COMMAND_KEY, d as AIMANAGEMENT_CHAT_SYNTHESIZE_SPEECH_COMMAND_KEY, m as AIMANAGEMENT_CHAT_TRANSCRIBE_SPEECH_COMMAND_KEY, n as AIMANAGEMENT_EXTRACT_DOCUMENT_TEXT_COMMAND_KEY, o as AIMANAGEMENT_STRUCTURED_TEXT_COMPLETION_COMMAND_KEY, l as AI_AGENT_CATALOG_DATASOURCE_NAME, q as AI_CHAT_ATTACHMENT_CATEGORY, r as AI_CHAT_ATTACHMENT_REF_TYPE, s as AI_CHAT_GENERATED_IMAGE_REF_TYPE, t as AI_CHAT_GENERATED_SPEECH_REF_TYPE, k as AI_COMMAND_REGISTRY_CATALOG_DATASOURCE_NAME, u as AI_GENERATED_IMAGE_MAX_REMOTE_URL_IN_TOOL, v as AI_MODEL_CATALOG_DATASOURCE_NAME, w as AI_MODEL_IMAGE_CATALOG_DATASOURCE_NAME, x as AI_MODEL_SPEECH_CATALOG_DATASOURCE_NAME, y as AI_MODEL_TTS_CATALOG_DATASOURCE_NAME, j as AI_QUERY_REGISTRY_CATALOG_DATASOURCE_NAME, z as AXMAiAgentCatalogDataSourceDefinition, B as AXMAiAssistPromptBottomPanelComponent, C as AXMAiAssistPromptBottomPanelService, D as AXMAiAssistPromptPopupComponent, i as AXMAiChatPageComponent, A as AXMAiChatToolExecuteService, E as AXMAiCommandRegistryCatalogDataSourceDefinition, F as AXMAiManagementEntityProvider, G as AXMAiManagementMenuProvider, H as AXMAiManagementModule, I as AXMAiModelCatalogDataSourceDefinition, J as AXMAiQueryRegistryCatalogDataSourceDefinition, K as AXPAI_DELEGATED_AGENT_DEFAULT_MAX_STEPS, L as AXPAI_DOCUMENT_VISION_DEFAULT_USER_INSTRUCTION, M as AXPAI_DOCUMENT_VISION_EXTRACTION_SYSTEM, N as AXPAI_ENGINE_DEFAULT_MAX_STEPS, O as AXPAI_SUPERVISOR_AGENT_TOOL_PREFIX, P as AXPAiAssistChatModelCatalogService, Q as AXPAiAssistDefaultMaxStructuredRetries, S as AXPAiAssistDefaultStructuredMaxTokens, T as AXPAiAssistService, U as AXPAiChatToolRunContextService, V as AXPAiEngine, W as AXPAiManagementMenuKeys, X as AXPAiManagementSettings, Y as AXPAiManagerService, Z as AXPAiPlatformRuntimeContextBuilder, _ as AXPAiStructuredOutputError, $ as AiManagementManifest, R as RootConfig, a0 as axpAiAssistInitialMessagesToTranscript, a1 as axpAiChatAgentResultMessage, a2 as axpAiChatDelegatedReflectionAssistantMessage, c as axpAiChatMessageGetText, a3 as axpAiChatMessageIsDelegatedReflectionExcluded, a4 as axpAiChatMessagesFromProviderAssistant, a5 as axpAiChatTextMessage, f as axpAiChatToolOrAgentResultBodyJson, a6 as axpAiChatToolResultBodyJson, a7 as axpAiChatToolResultMessage, a8 as axpAiChatUserMessage, a9 as axpAiCoercePlanningAssistantTextToThink, aa as axpAiDelegatedAgentPromptPreview, ab as axpAiMergePlainAssistantTextTurn, ac as axpAiNormalizeHandlerResultToToolBody, ad as axpAiParseSupervisorAgentToolName, ae as axpAiPruneAssistantPiecesToFirstToolOnly, af as axpAiStripAssistInitialHtmlToPlain, ag as axpAiSupervisorAgentToolName, ah as axpAiToolCallFromAssistantToolMessage, ai as blobOrFileFromImageResult, aj as getAiChatCommandLlmParametersOverride, ak as isChatPurposeModelRow, al as isImagePurposeModelRow, am as isSpeechPurposeModelRow, an as isTtsPurposeModelRow, ao as modelRowHasPurpose, ap as normalizeAiToolCommandArgs, aq as normalizeModelPurposes, ar as persistAiChatAttachmentImage, as as persistAiGeneratedImage, at as persistAiGeneratedSpeech } from './acorex-modules-ai-management-acorex-modules-ai-management-D7_4LOGV.mjs';
1
+ import { AXPSettingsService, AXPRegionalSetting, AXPFileStorageStatus, AXPFileStorageService, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER } from '@acorex/platform/common';
2
+ import * as i1$1 from '@acorex/platform/core';
3
+ import { objectKeyValueTransforms, AXPTagProvider, AXPPlatformScope, AXPComponentSlotModule, AXP_MODULE_MANIFEST_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXP_TAG_PROVIDER } from '@acorex/platform/core';
4
+ import { AXPEntityService, AXP_ENTITY_DEFINITION_LOADER, axpCreateEntityAiToolInputDefaults } from '@acorex/platform/layout/entity';
5
+ import { AXPWidgetsCatalog, AXPWidgetGroupEnum, AXP_WIDGETS_EDITOR_CATEGORY, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex/platform/layout/widget-core';
6
+ import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXPWidgetsModule } from '@acorex/platform/layout/widgets';
7
+ import * as i0 from '@angular/core';
8
+ import { Injectable, inject, PLATFORM_ID, input, signal, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, LOCALE_ID, NgModule } from '@angular/core';
9
+ import { ROUTES } from '@angular/router';
10
+ import { AXPCommonMenuKeys, AXPWidgetsList } from '@acorex/modules/common';
11
+ import { AXDataSource } from '@acorex/cdk/common';
12
+ import { RootConfig as RootConfig$1 } from '@acorex/modules/platform-management';
13
+ import { AXLoadingDialogService } from '@acorex/components/loading-dialog';
14
+ import * as i7 from '@acorex/core/translation';
15
+ import { AXTranslationService, AXTranslationModule, resolveMultiLanguageString } from '@acorex/core/translation';
16
+ import { AXPSessionService } from '@acorex/platform/auth';
17
+ import * as i2 from '@acorex/components/button';
18
+ import { AXButtonModule } from '@acorex/components/button';
19
+ import * as i3 from '@acorex/components/decorators';
20
+ import { AXDecoratorModule } from '@acorex/components/decorators';
21
+ import * as i4 from '@acorex/components/dropdown';
22
+ import { AXDropdownModule } from '@acorex/components/dropdown';
23
+ import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
24
+ import * as i5 from '@acorex/components/text-area';
25
+ import { AXTextAreaModule } from '@acorex/components/text-area';
26
+ import { AXToastService } from '@acorex/components/toast';
27
+ import { AXFileService } from '@acorex/core/file';
28
+ import * as i6 from '@angular/common';
29
+ import { isPlatformBrowser, CommonModule } from '@angular/common';
30
+ import * as i1 from '@angular/forms';
31
+ import { FormsModule } from '@angular/forms';
32
+ import { AXOverlayService } from '@acorex/cdk/overlay';
33
+ import { defineCommand, AXP_COMMAND_DEFINITION_CATEGORY_AI_TOOLS } from '@acorex/platform/runtime';
34
+
35
+ //#region ---- Module Config ----
36
+ const config = {
37
+ i18n: 'ai-management',
38
+ module: 'AiManagement',
39
+ route: 'ai-management',
40
+ };
41
+ const RootConfig = {
42
+ config,
43
+ module: {
44
+ name: config.module,
45
+ route: config.route,
46
+ title: `@${config.i18n}:module.title`,
47
+ icon: 'fa-light fa-robot',
48
+ },
49
+ entities: {
50
+ model: {
51
+ name: 'AiModel',
52
+ fullName: `${config.module}.AiModel`,
53
+ title: '@ai-management:models.entities.model.title',
54
+ titlePlural: '@ai-management:models.entities.model.plural',
55
+ icon: 'fa-light fa-microchip',
56
+ },
57
+ assist: {
58
+ name: 'Assist',
59
+ fullName: `${config.module}.Assist`,
60
+ title: '@ai-management:assists.entities.assist.title',
61
+ titlePlural: '@ai-management:assists.entities.assist.plural',
62
+ icon: 'fa-light fa-user-robot',
63
+ },
64
+ agent: {
65
+ name: 'AiAgent',
66
+ fullName: `${config.module}.AiAgent`,
67
+ title: '@ai-management:agents.entities.agent.title',
68
+ titlePlural: '@ai-management:agents.entities.agent.plural',
69
+ icon: 'fa-light fa-people-group',
70
+ },
71
+ openAiEndpoint: {
72
+ name: 'OpenAiEndpoint',
73
+ fullName: `${config.module}.OpenAiEndpoint`,
74
+ title: '@ai-management:open-ai-endpoints.entities.endpoint.title',
75
+ titlePlural: '@ai-management:open-ai-endpoints.entities.endpoint.plural',
76
+ icon: 'fa-light fa-plug',
77
+ },
78
+ },
79
+ };
80
+ //#endregion
81
+
82
+ //#region ---- Imports ----
83
+ //#endregion
84
+ //#region ---- Manifest Definition ----
85
+ /**
86
+ * AI Management Module Manifest.
87
+ * Defines module metadata for AI provider and API key management.
88
+ */
89
+ const AiManagementManifest = {
90
+ name: RootConfig.module.name,
91
+ version: '1.0.0',
92
+ title: RootConfig.module.title,
93
+ icon: RootConfig.module.icon,
94
+ i18n: RootConfig.config.i18n,
95
+ dependencies: [],
96
+ };
97
+ //#endregion
98
+
99
+ //#endregion
100
+ //#region ---- Entity Provider ----
101
+ class AXMAiManagementEntityProvider {
102
+ preload() {
103
+ const module = RootConfig.module.name;
104
+ return Object.values(RootConfig.entities).map((entity) => ({
105
+ module,
106
+ entity: entity.name,
107
+ }));
108
+ }
109
+ async get(moduleName, entityName) {
110
+ if (moduleName !== RootConfig.module.name)
111
+ return null;
112
+ switch (entityName) {
113
+ case RootConfig.entities.model.name:
114
+ return (await import('./acorex-modules-ai-management-model.entity-DiDaXVa3.mjs')).factory();
115
+ case RootConfig.entities.assist.name:
116
+ return (await import('./acorex-modules-ai-management-assist.entity-DfW-FFCt.mjs')).assistFactory();
117
+ case RootConfig.entities.agent.name:
118
+ return (await import('./acorex-modules-ai-management-agent.entity-D6-0_Ms3.mjs')).agentFactory();
119
+ case RootConfig.entities.openAiEndpoint.name:
120
+ return (await import('./acorex-modules-ai-management-open-ai-endpoint.entity-CZLNKtl0.mjs')).openAiEndpointFactory();
121
+ default:
122
+ return null;
123
+ }
124
+ }
125
+ async list() {
126
+ const m = RootConfig.module.name;
127
+ return Promise.resolve(Object.values(RootConfig.entities).map((e) => ({ name: e.name, module: m })));
128
+ }
129
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementEntityProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
130
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementEntityProvider }); }
131
+ }
132
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementEntityProvider, decorators: [{
133
+ type: Injectable
134
+ }] });
135
+
136
+ //#region ---- Menu Keys ----
137
+ /**
138
+ * AI Management menu keys.
139
+ * Pattern: AiManagement:Menu:{Path}
140
+ */
141
+ const AXPAiManagementMenuKeys = {
142
+ /** OpenAI-compatible HTTP endpoints (base URL + API key). */
143
+ OpenAiEndpoints: 'AiManagement:Menu:OpenAiEndpoints',
144
+ /** List of AI models (from providers). */
145
+ Models: 'AiManagement:Menu:Models',
146
+ /** List of Assists. */
147
+ Assists: 'AiManagement:Menu:Assists',
148
+ /** Delegated specialist agents (supervisor routing). */
149
+ Agents: 'AiManagement:Menu:Agents',
150
+ };
151
+ //#endregion
152
+
153
+ //#region ---- Imports ----
154
+ //#endregion
155
+ //#region ---- Menu Provider ----
156
+ class AXMAiManagementMenuProvider {
157
+ constructor() {
158
+ this.entityService = inject(AXPEntityService);
159
+ }
160
+ async provide(context) {
161
+ const module = RootConfig.module;
162
+ //#region ---- Configuration > AI Management (assists, models) ----
163
+ const aiManagementConfigMenu = context.find(AXPCommonMenuKeys.AiManagementConfig);
164
+ if (!aiManagementConfigMenu.exists) {
165
+ context.find(AXPCommonMenuKeys.Configuration).addItems([
166
+ {
167
+ name: AXPCommonMenuKeys.AiManagementConfig,
168
+ text: '@general:menus.ai-management.title',
169
+ icon: module.icon,
170
+ type: 'menu',
171
+ priority: 8941,
172
+ children: [],
173
+ },
174
+ ]);
175
+ }
176
+ context.find(AXPCommonMenuKeys.AiManagementConfig).addItems([
177
+ {
178
+ name: AXPAiManagementMenuKeys.Agents,
179
+ text: '@ai-management:module.menus.agents.title',
180
+ path: this.entityService.createPath(module.name, RootConfig.entities.agent.name),
181
+ icon: RootConfig.entities.agent.icon,
182
+ priority: -1,
183
+ },
184
+ {
185
+ name: AXPAiManagementMenuKeys.Assists,
186
+ text: '@ai-management:module.menus.assists.title',
187
+ path: this.entityService.createPath(module.name, RootConfig.entities.assist.name),
188
+ icon: RootConfig.entities.assist.icon,
189
+ priority: 0,
190
+ },
191
+ {
192
+ name: AXPAiManagementMenuKeys.OpenAiEndpoints,
193
+ text: '@ai-management:module.menus.open-ai-endpoints.title',
194
+ path: this.entityService.createPath(module.name, RootConfig.entities.openAiEndpoint.name),
195
+ icon: RootConfig.entities.openAiEndpoint.icon,
196
+ priority: 2,
197
+ },
198
+ {
199
+ name: AXPAiManagementMenuKeys.Models,
200
+ text: '@ai-management:module.menus.models.title',
201
+ path: this.entityService.createPath(module.name, RootConfig.entities.model.name),
202
+ icon: RootConfig.entities.model.icon,
203
+ priority: 1,
204
+ },
205
+ ]);
206
+ //#endregion
207
+ }
208
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementMenuProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
209
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementMenuProvider }); }
210
+ }
211
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementMenuProvider, decorators: [{
212
+ type: Injectable
213
+ }] });
214
+
215
+ //#region ---- Setting Keys ----
216
+ /**
217
+ * AI Management setting keys.
218
+ * Pattern: AiManagement:Setting:{Path}
219
+ */
220
+ const AXPAiManagementSettings = {
221
+ /** Assist primary key (`id`) used when no assist is explicitly selected (tenant-scoped). */
222
+ DefaultAssistId: 'AiManagement:Setting:DefaultAssistId',
223
+ /**
224
+ * Optional catalog `AiModel` row id (`id`) used as a tenant-wide fallback when a feature does not
225
+ * receive an explicit model (e.g. chat picker, vision/OCR pipeline, image, speech, TTS).
226
+ */
227
+ DefaultModelChat: 'AiManagement:Setting:DefaultModel.Chat',
228
+ /** Preferred model for document/vision extraction and similar OCR-style tasks. */
229
+ DefaultModelVision: 'AiManagement:Setting:DefaultModel.Vision',
230
+ DefaultModelImage: 'AiManagement:Setting:DefaultModel.Image',
231
+ DefaultModelSpeech: 'AiManagement:Setting:DefaultModel.Speech',
232
+ DefaultModelTts: 'AiManagement:Setting:DefaultModel.Tts',
233
+ Providers: {
234
+ Gemini: {
235
+ ApiKey: 'AiManagement:Setting:Providers.Gemini.ApiKey',
236
+ },
237
+ Demis: {
238
+ BearerToken: 'AiManagement:Setting:Providers.Demis.BearerToken',
239
+ /** AiAgent catalog `name` (slug) used as Demisco `agent_uuid` when no agent run context exists. */
240
+ DefaultAgentName: 'AiManagement:Setting:Providers.Demis.DefaultAgentName',
241
+ },
242
+ },
243
+ };
244
+ //#endregion
245
+
246
+ //#region ---- Imports ----
247
+ //#endregion
248
+ //#region ---- Settings Provider ----
249
+ const I18N = '@ai-management:settings';
250
+ class AXMAiManagementSettingProvider {
251
+ async provide(context) {
252
+ context
253
+ .addGroup('ai-settings', `${I18N}.group.nav-title`, `${I18N}.group.description`, 'fa-light fa-robot', `${I18N}.group.title`)
254
+ .addSection('default-assist', `${I18N}.section.default-assist.title`, `${I18N}.section.default-assist.description`)
255
+ .addSetting({
256
+ key: AXPAiManagementSettings.DefaultAssistId,
257
+ title: `${I18N}.default-assist.name.title`,
258
+ scope: 'T',
259
+ isInherited: true,
260
+ valueTransforms: objectKeyValueTransforms('name'),
261
+ widget: {
262
+ type: AXPWidgetsList.Editors.LookupBox,
263
+ options: {
264
+ entity: `${RootConfig.module.name}.${RootConfig.entities.assist.name}`,
265
+ look: 'select',
266
+ multiple: false,
267
+ textField: 'title',
268
+ valueField: 'name',
269
+ hasClearButton: true,
270
+ },
271
+ },
272
+ description: `${I18N}.default-assist.name.description`,
273
+ })
274
+ .endSection()
275
+ .addSection('default-models', `${I18N}.section.default-models.title`, `${I18N}.section.default-models.description`)
276
+ .addSetting({
277
+ key: AXPAiManagementSettings.DefaultModelChat,
278
+ title: `${I18N}.default-models.chat.title`,
279
+ scope: 'T',
280
+ isInherited: true,
281
+ defaultValue: '',
282
+ widget: {
283
+ type: AXPWidgetsList.Editors.LookupBox,
284
+ options: {
285
+ entity: `${RootConfig.module.name}.${RootConfig.entities.model.name}`,
286
+ look: 'select',
287
+ multiple: false,
288
+ textField: 'title',
289
+ valueField: 'id',
290
+ hasClearButton: true,
291
+ },
292
+ },
293
+ description: `${I18N}.default-models.chat.description`,
294
+ })
295
+ .addSetting({
296
+ key: AXPAiManagementSettings.DefaultModelVision,
297
+ title: `${I18N}.default-models.vision.title`,
298
+ scope: 'T',
299
+ isInherited: true,
300
+ defaultValue: '',
301
+ widget: {
302
+ type: AXPWidgetsList.Editors.LookupBox,
303
+ options: {
304
+ entity: `${RootConfig.module.name}.${RootConfig.entities.model.name}`,
305
+ look: 'select',
306
+ multiple: false,
307
+ textField: 'title',
308
+ valueField: 'id',
309
+ hasClearButton: true,
310
+ },
311
+ },
312
+ description: `${I18N}.default-models.vision.description`,
313
+ })
314
+ .addSetting({
315
+ key: AXPAiManagementSettings.DefaultModelImage,
316
+ title: `${I18N}.default-models.image.title`,
317
+ scope: 'T',
318
+ isInherited: true,
319
+ defaultValue: '',
320
+ widget: {
321
+ type: AXPWidgetsList.Editors.LookupBox,
322
+ options: {
323
+ entity: `${RootConfig.module.name}.${RootConfig.entities.model.name}`,
324
+ look: 'select',
325
+ multiple: false,
326
+ textField: 'title',
327
+ valueField: 'id',
328
+ hasClearButton: true,
329
+ },
330
+ },
331
+ description: `${I18N}.default-models.image.description`,
332
+ })
333
+ .addSetting({
334
+ key: AXPAiManagementSettings.DefaultModelSpeech,
335
+ title: `${I18N}.default-models.speech.title`,
336
+ scope: 'T',
337
+ isInherited: true,
338
+ defaultValue: '',
339
+ widget: {
340
+ type: AXPWidgetsList.Editors.LookupBox,
341
+ options: {
342
+ entity: `${RootConfig.module.name}.${RootConfig.entities.model.name}`,
343
+ look: 'select',
344
+ multiple: false,
345
+ textField: 'title',
346
+ valueField: 'id',
347
+ hasClearButton: true,
348
+ },
349
+ },
350
+ description: `${I18N}.default-models.speech.description`,
351
+ })
352
+ .addSetting({
353
+ key: AXPAiManagementSettings.DefaultModelTts,
354
+ title: `${I18N}.default-models.tts.title`,
355
+ scope: 'T',
356
+ isInherited: true,
357
+ defaultValue: '',
358
+ widget: {
359
+ type: AXPWidgetsList.Editors.LookupBox,
360
+ options: {
361
+ entity: `${RootConfig.module.name}.${RootConfig.entities.model.name}`,
362
+ look: 'select',
363
+ multiple: false,
364
+ textField: 'title',
365
+ valueField: 'id',
366
+ hasClearButton: true,
367
+ },
368
+ },
369
+ description: `${I18N}.default-models.tts.description`,
370
+ })
371
+ .endSection()
372
+ .addSection('gemini', `${I18N}.section.gemini.title`, `${I18N}.section.gemini.description`)
373
+ .addSetting({
374
+ key: AXPAiManagementSettings.Providers.Gemini.ApiKey,
375
+ title: `${I18N}.gemini.api-key.title`,
376
+ scope: 'T',
377
+ isInherited: true,
378
+ defaultValue: '',
379
+ widget: {
380
+ type: AXPWidgetsList.Editors.TextBox,
381
+ options: {
382
+ placeholder: `${I18N}.gemini.api-key.placeholder`,
383
+ },
384
+ },
385
+ description: `${I18N}.gemini.api-key.description`,
386
+ })
387
+ .endSection()
388
+ .addSection('demis', `${I18N}.section.demis.title`, `${I18N}.section.demis.description`)
389
+ .addSetting({
390
+ key: AXPAiManagementSettings.Providers.Demis.BearerToken,
391
+ title: `${I18N}.demis.bearer-token.title`,
392
+ scope: 'T',
393
+ isInherited: true,
394
+ defaultValue: '',
395
+ widget: {
396
+ type: AXPWidgetsList.Editors.TextBox,
397
+ options: {
398
+ placeholder: `${I18N}.demis.bearer-token.placeholder`,
399
+ },
400
+ },
401
+ description: `${I18N}.demis.bearer-token.description`,
402
+ })
403
+ .addSetting({
404
+ key: AXPAiManagementSettings.Providers.Demis.DefaultAgentName,
405
+ title: `${I18N}.demis.default-agent-name.title`,
406
+ scope: 'T',
407
+ isInherited: true,
408
+ defaultValue: '',
409
+ widget: {
410
+ type: AXPWidgetsList.Editors.TextBox,
411
+ options: {
412
+ placeholder: `${I18N}.demis.default-agent-name.placeholder`,
413
+ },
414
+ },
415
+ description: `${I18N}.demis.default-agent-name.description`,
416
+ })
417
+ .endSection()
418
+ .endGroup();
419
+ }
420
+ }
421
+ //#endregion
422
+
423
+ //#region ---- Imports ----
424
+ //#endregion
425
+ /** Registry name for AiAgent catalog rows (delegated specialist definitions). */
426
+ const AI_AGENT_CATALOG_DATASOURCE_NAME = 'ai-management-agent-catalog';
427
+ //#region ---- Provider ----
428
+ class AXMAiAgentCatalogDataSourceDefinition {
429
+ constructor() {
430
+ this.entityService = inject(AXPEntityService);
431
+ }
432
+ items() {
433
+ const accessor = this.entityService
434
+ .withEntity(RootConfig.module.name, RootConfig.entities.agent.name)
435
+ .data();
436
+ const columns = [
437
+ { name: 'id', title: 'ID', datatype: 'uuid', type: AXPWidgetsList.Editors.TextBox },
438
+ { name: 'title', title: 'Title', datatype: 'string', type: AXPWidgetsList.Editors.TextBox },
439
+ { name: 'name', title: 'Name', datatype: 'string', type: AXPWidgetsList.Editors.TextBox },
440
+ ];
441
+ const filters = [
442
+ {
443
+ field: 'title',
444
+ title: 'Title',
445
+ operator: { type: 'contains' },
446
+ widget: { type: AXPWidgetsList.Editors.TextBox },
447
+ filterType: { advance: true, inline: true },
448
+ },
449
+ ];
450
+ return Promise.resolve([
451
+ {
452
+ name: AI_AGENT_CATALOG_DATASOURCE_NAME,
453
+ title: 'AI Agents (delegated specialists)',
454
+ source: () => {
455
+ return new AXDataSource({
456
+ key: 'id',
457
+ load: async (e) => {
458
+ const res = await accessor.query({
459
+ skip: e?.skip ?? 0,
460
+ take: e?.take ?? 500,
461
+ sort: [{ field: 'title', dir: 'asc' }],
462
+ });
463
+ return {
464
+ items: (res.items ?? []),
465
+ total: res.total ?? (res.items?.length ?? 0),
466
+ };
467
+ },
468
+ byKey: async (key) => {
469
+ return (await accessor.byKey(key));
470
+ },
471
+ pageSize: 500,
472
+ });
473
+ },
474
+ columns,
475
+ filters,
476
+ textField: { name: 'title', title: 'Title' },
477
+ valueField: { name: 'id', title: 'ID' },
478
+ },
479
+ ]);
480
+ }
481
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiAgentCatalogDataSourceDefinition, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
482
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiAgentCatalogDataSourceDefinition }); }
483
+ }
484
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiAgentCatalogDataSourceDefinition, decorators: [{
485
+ type: Injectable
486
+ }] });
487
+
488
+ //#region ---- Imports ----
489
+ //#endregion
490
+ //#region ---- Constants ----
491
+ /** AI-capable command definitions for specialist registry scope (matches AiAgent entity lookup filter). */
492
+ const AI_COMMAND_REGISTRY_CATALOG_DATASOURCE_NAME = 'ai-management-command-registry-catalog';
493
+ /** AI-capable query definitions for specialist registry scope. */
494
+ const AI_QUERY_REGISTRY_CATALOG_DATASOURCE_NAME = 'ai-management-query-registry-catalog';
495
+ /** Typed so nested `operator.type` literals are not widened to `string` (required by {@link AXDataSourceFilterOption}). */
496
+ const AI_CAPABILITY_FILTER = {
497
+ logic: 'and',
498
+ filters: [
499
+ { field: 'active', operator: { type: 'equal' }, value: true },
500
+ {
501
+ logic: 'or',
502
+ filters: [
503
+ { field: 'capabilities', operator: { type: 'equal' }, value: 'ai' },
504
+ { field: 'capabilities', operator: { type: 'startsWith' }, value: 'ai,' },
505
+ { field: 'capabilities', operator: { type: 'contains' }, value: ', ai' },
506
+ ],
507
+ },
508
+ ],
509
+ };
510
+ //#endregion
511
+ //#region ---- Command catalog ----
512
+ class AXMAiCommandRegistryCatalogDataSourceDefinition {
513
+ constructor() {
514
+ this.entityService = inject(AXPEntityService);
515
+ }
516
+ items() {
517
+ const accessor = this.entityService
518
+ .withEntity(RootConfig$1.module.name, RootConfig$1.entities.commandDefinition.name)
519
+ .data();
520
+ const columns = [
521
+ { name: 'id', title: 'ID', datatype: 'uuid', type: AXPWidgetsCatalog.text },
522
+ { name: 'catalogTitle', title: 'Title', datatype: 'string', type: AXPWidgetsCatalog.text },
523
+ { name: 'name', title: 'Name', datatype: 'string', type: AXPWidgetsCatalog.text },
524
+ ];
525
+ const filters = [
526
+ {
527
+ field: 'catalogTitle',
528
+ title: 'Title',
529
+ operator: { type: 'contains' },
530
+ widget: { type: AXPWidgetsCatalog.text },
531
+ filterType: { advance: true, inline: true },
532
+ },
533
+ ];
534
+ return Promise.resolve([
535
+ {
536
+ name: AI_COMMAND_REGISTRY_CATALOG_DATASOURCE_NAME,
537
+ title: 'Command definitions (AI registry)',
538
+ source: () => {
539
+ return new AXDataSource({
540
+ key: 'id',
541
+ load: async (e) => {
542
+ const request = {
543
+ skip: e?.skip ?? 0,
544
+ take: e?.take ?? 500,
545
+ sort: [{ field: 'catalogTitle', dir: 'asc' }],
546
+ filter: AI_CAPABILITY_FILTER,
547
+ };
548
+ const res = await accessor.query(request);
549
+ return {
550
+ items: (res.items ?? []),
551
+ total: res.total ?? (res.items?.length ?? 0),
552
+ };
553
+ },
554
+ byKey: async (key) => {
555
+ return (await accessor.byKey(key));
556
+ },
557
+ pageSize: 500,
558
+ });
559
+ },
560
+ columns,
561
+ filters,
562
+ textField: { name: 'catalogTitle', title: 'Title' },
563
+ valueField: { name: 'id', title: 'ID' },
564
+ },
565
+ ]);
566
+ }
567
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiCommandRegistryCatalogDataSourceDefinition, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
568
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiCommandRegistryCatalogDataSourceDefinition }); }
569
+ }
570
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiCommandRegistryCatalogDataSourceDefinition, decorators: [{
571
+ type: Injectable
572
+ }] });
573
+ //#endregion
574
+ //#region ---- Query catalog ----
575
+ class AXMAiQueryRegistryCatalogDataSourceDefinition {
576
+ constructor() {
577
+ this.entityService = inject(AXPEntityService);
578
+ }
579
+ items() {
580
+ const accessor = this.entityService
581
+ .withEntity(RootConfig$1.module.name, RootConfig$1.entities.queryDefinition.name)
582
+ .data();
583
+ const columns = [
584
+ { name: 'id', title: 'ID', datatype: 'uuid', type: AXPWidgetsCatalog.text },
585
+ { name: 'catalogTitle', title: 'Title', datatype: 'string', type: AXPWidgetsCatalog.text },
586
+ { name: 'name', title: 'Name', datatype: 'string', type: AXPWidgetsCatalog.text },
587
+ ];
588
+ const filters = [
589
+ {
590
+ field: 'catalogTitle',
591
+ title: 'Title',
592
+ operator: { type: 'contains' },
593
+ widget: { type: AXPWidgetsCatalog.text },
594
+ filterType: { advance: true, inline: true },
595
+ },
596
+ ];
597
+ return Promise.resolve([
598
+ {
599
+ name: AI_QUERY_REGISTRY_CATALOG_DATASOURCE_NAME,
600
+ title: 'Query definitions (AI registry)',
601
+ source: () => {
602
+ return new AXDataSource({
603
+ key: 'id',
604
+ load: async (e) => {
605
+ const request = {
606
+ skip: e?.skip ?? 0,
607
+ take: e?.take ?? 500,
608
+ sort: [{ field: 'catalogTitle', dir: 'asc' }],
609
+ filter: AI_CAPABILITY_FILTER,
610
+ };
611
+ const res = await accessor.query(request);
612
+ return {
613
+ items: (res.items ?? []),
614
+ total: res.total ?? (res.items?.length ?? 0),
615
+ };
616
+ },
617
+ byKey: async (key) => {
618
+ return (await accessor.byKey(key));
619
+ },
620
+ pageSize: 500,
621
+ });
622
+ },
623
+ columns,
624
+ filters,
625
+ textField: { name: 'catalogTitle', title: 'Title' },
626
+ valueField: { name: 'id', title: 'ID' },
627
+ },
628
+ ]);
629
+ }
630
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiQueryRegistryCatalogDataSourceDefinition, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
631
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiQueryRegistryCatalogDataSourceDefinition }); }
632
+ }
633
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiQueryRegistryCatalogDataSourceDefinition, decorators: [{
634
+ type: Injectable
635
+ }] });
636
+
637
+ //#region ---- Imports ----
638
+ //#endregion
639
+ /**
640
+ * Full AI model catalog for chat (rows that include `chat` or `vision` in `modelPurposes`).
641
+ * Registry name: {@link AI_MODEL_CATALOG_DATASOURCE_NAME}.
642
+ */
643
+ const AI_MODEL_CATALOG_DATASOURCE_NAME = 'ai-management-model-catalog';
644
+ /**
645
+ * Image-generation models only (`modelPurposes` includes `image`).
646
+ * Registry name: {@link AI_MODEL_IMAGE_CATALOG_DATASOURCE_NAME}.
647
+ */
648
+ const AI_MODEL_IMAGE_CATALOG_DATASOURCE_NAME = 'ai-management-model-catalog-image';
649
+ /**
650
+ * Speech-to-text models only (`modelPurposes` includes `speech`).
651
+ * Registry name: {@link AI_MODEL_SPEECH_CATALOG_DATASOURCE_NAME}.
652
+ */
653
+ const AI_MODEL_SPEECH_CATALOG_DATASOURCE_NAME = 'ai-management-model-catalog-speech';
654
+ /**
655
+ * Text-to-speech models only (`modelPurposes` includes `tts`).
656
+ * Registry name: {@link AI_MODEL_TTS_CATALOG_DATASOURCE_NAME}.
657
+ */
658
+ const AI_MODEL_TTS_CATALOG_DATASOURCE_NAME = 'ai-management-model-catalog-tts';
659
+ /** Normalizes `modelPurposes` (and legacy `modelPurpose`) to unique non-empty slugs. */
660
+ function normalizeModelPurposes(row) {
661
+ if (!row) {
662
+ return ['chat'];
663
+ }
664
+ const multi = row['modelPurposes'];
665
+ if (Array.isArray(multi) && multi.length > 0) {
666
+ const out = multi
667
+ .map((x) => String(x).trim())
668
+ .filter((x) => x.length > 0);
669
+ return [...new Set(out)];
670
+ }
671
+ const legacy = row['modelPurpose'];
672
+ if (legacy == null || legacy === '') {
673
+ return ['chat'];
674
+ }
675
+ return [String(legacy)];
676
+ }
677
+ function modelRowHasPurpose(row, purpose) {
678
+ return normalizeModelPurposes(row).includes(purpose);
679
+ }
680
+ /** Rows usable in chat / completion pickers: include `chat` or `vision`; not image/speech/tts-only. */
681
+ function isChatPurposeModelRow(row) {
682
+ const p = normalizeModelPurposes(row);
683
+ return p.includes('chat') || p.includes('vision');
684
+ }
685
+ function isImagePurposeModelRow(row) {
686
+ return modelRowHasPurpose(row, 'image');
687
+ }
688
+ function isSpeechPurposeModelRow(row) {
689
+ return modelRowHasPurpose(row, 'speech');
690
+ }
691
+ function isTtsPurposeModelRow(row) {
692
+ return modelRowHasPurpose(row, 'tts');
693
+ }
694
+ //#region ---- Provider ----
695
+ class AXMAiModelCatalogDataSourceDefinition {
696
+ constructor() {
697
+ this.entityService = inject(AXPEntityService);
698
+ }
699
+ items() {
700
+ const accessor = this.entityService
701
+ .withEntity(RootConfig.module.name, RootConfig.entities.model.name)
702
+ .data();
703
+ const columns = [
704
+ {
705
+ name: 'id',
706
+ title: 'ID',
707
+ datatype: 'uuid',
708
+ type: AXPWidgetsList.Editors.TextBox,
709
+ },
710
+ {
711
+ name: 'title',
712
+ title: 'Title',
713
+ datatype: 'string',
714
+ type: AXPWidgetsList.Editors.TextBox,
715
+ },
716
+ ];
717
+ const filters = [
718
+ {
719
+ field: 'title',
720
+ title: 'Title',
721
+ operator: { type: 'contains' },
722
+ widget: { type: AXPWidgetsList.Editors.TextBox },
723
+ filterType: { advance: true, inline: true },
724
+ },
725
+ ];
726
+ const loadFiltered = async (e, keep) => {
727
+ const res = await accessor.query({
728
+ skip: e?.skip ?? 0,
729
+ take: e?.take ?? 500,
730
+ sort: [{ field: 'title', dir: 'asc' }],
731
+ });
732
+ const all = (res.items ?? []);
733
+ const items = all.filter(keep);
734
+ return {
735
+ items,
736
+ total: items.length,
737
+ };
738
+ };
739
+ return Promise.resolve([
740
+ {
741
+ name: AI_MODEL_CATALOG_DATASOURCE_NAME,
742
+ title: 'AI Models (chat)',
743
+ source: () => {
744
+ return new AXDataSource({
745
+ key: 'id',
746
+ load: async (e) => loadFiltered(e, isChatPurposeModelRow),
747
+ byKey: async (key) => {
748
+ const row = (await accessor.byKey(key));
749
+ if (!row || !isChatPurposeModelRow(row)) {
750
+ return null;
751
+ }
752
+ return row;
753
+ },
754
+ pageSize: 500,
755
+ });
756
+ },
757
+ columns,
758
+ filters,
759
+ textField: { name: 'title', title: 'Title' },
760
+ valueField: { name: 'id', title: 'ID' },
761
+ },
762
+ {
763
+ name: AI_MODEL_IMAGE_CATALOG_DATASOURCE_NAME,
764
+ title: 'AI Models (image)',
765
+ source: () => {
766
+ return new AXDataSource({
767
+ key: 'id',
768
+ load: async (e) => loadFiltered(e, (row) => isImagePurposeModelRow(row)),
769
+ byKey: async (key) => {
770
+ const row = (await accessor.byKey(key));
771
+ if (!row || !isImagePurposeModelRow(row)) {
772
+ return null;
773
+ }
774
+ return row;
775
+ },
776
+ pageSize: 500,
777
+ });
778
+ },
779
+ columns,
780
+ filters,
781
+ textField: { name: 'title', title: 'Title' },
782
+ valueField: { name: 'id', title: 'ID' },
783
+ },
784
+ {
785
+ name: AI_MODEL_SPEECH_CATALOG_DATASOURCE_NAME,
786
+ title: 'AI Models (speech)',
787
+ source: () => {
788
+ return new AXDataSource({
789
+ key: 'id',
790
+ load: async (e) => loadFiltered(e, (row) => isSpeechPurposeModelRow(row)),
791
+ byKey: async (key) => {
792
+ const row = (await accessor.byKey(key));
793
+ if (!row || !isSpeechPurposeModelRow(row)) {
794
+ return null;
795
+ }
796
+ return row;
797
+ },
798
+ pageSize: 500,
799
+ });
800
+ },
801
+ columns,
802
+ filters,
803
+ textField: { name: 'title', title: 'Title' },
804
+ valueField: { name: 'id', title: 'ID' },
805
+ },
806
+ {
807
+ name: AI_MODEL_TTS_CATALOG_DATASOURCE_NAME,
808
+ title: 'AI Models (text-to-speech)',
809
+ source: () => {
810
+ return new AXDataSource({
811
+ key: 'id',
812
+ load: async (e) => loadFiltered(e, (row) => isTtsPurposeModelRow(row)),
813
+ byKey: async (key) => {
814
+ const row = (await accessor.byKey(key));
815
+ if (!row || !isTtsPurposeModelRow(row)) {
816
+ return null;
817
+ }
818
+ return row;
819
+ },
820
+ pageSize: 500,
821
+ });
822
+ },
823
+ columns,
824
+ filters,
825
+ textField: { name: 'title', title: 'Title' },
826
+ valueField: { name: 'id', title: 'ID' },
827
+ },
828
+ ]);
829
+ }
830
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiModelCatalogDataSourceDefinition, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
831
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiModelCatalogDataSourceDefinition }); }
832
+ }
833
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiModelCatalogDataSourceDefinition, decorators: [{
834
+ type: Injectable
835
+ }] });
836
+
837
+ //#region ---- Imports ----
838
+ //#endregion
839
+ /**
840
+ * System tags for the AiModel entity `modelPurposes` field (tag-editor).
841
+ * `title` values are stored as-is on the entity; keep them stable slugs.
842
+ */
843
+ const AI_MODEL_PURPOSE_TAGS = [
844
+ {
845
+ id: 'ai-model-purpose-chat',
846
+ title: 'chat',
847
+ color: '#0284c7',
848
+ description: 'Chat / text completion',
849
+ scope: 'system',
850
+ },
851
+ {
852
+ id: 'ai-model-purpose-vision',
853
+ title: 'vision',
854
+ color: '#7c3aed',
855
+ description: 'Multimodal (image input in chat)',
856
+ scope: 'system',
857
+ },
858
+ {
859
+ id: 'ai-model-purpose-image',
860
+ title: 'image',
861
+ color: '#db2777',
862
+ description: 'Image generation',
863
+ scope: 'system',
864
+ },
865
+ {
866
+ id: 'ai-model-purpose-speech',
867
+ title: 'speech',
868
+ color: '#16a34a',
869
+ description: 'Speech to text',
870
+ scope: 'system',
871
+ },
872
+ {
873
+ id: 'ai-model-purpose-tts',
874
+ title: 'tts',
875
+ color: '#ea580c',
876
+ description: 'Text to speech',
877
+ scope: 'system',
878
+ },
879
+ ];
880
+ //#region ---- Provider ----
881
+ class AXMAiModelPurposeTagProvider extends AXPTagProvider {
882
+ constructor() {
883
+ super(...arguments);
884
+ this.name = 'ai-model-purpose';
885
+ }
886
+ provide() {
887
+ return Promise.resolve(AI_MODEL_PURPOSE_TAGS);
888
+ }
889
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiModelPurposeTagProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
890
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiModelPurposeTagProvider }); }
891
+ }
892
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiModelPurposeTagProvider, decorators: [{
893
+ type: Injectable
894
+ }] });
895
+
896
+ //#region ---- Imports ----
897
+ //#endregion
898
+ //#region ---- Abstract token ----
899
+ /**
900
+ * Optional cross-cutting AI assist: programmatic {@link run} and dialog {@link show}.
901
+ * Implemented by {@link AXPAiManagerService}. Consumers outside ai-management should prefer hooks or optional injection.
902
+ */
903
+ class AXPAiAssistService {
904
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiAssistService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
905
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiAssistService }); }
906
+ }
907
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiAssistService, decorators: [{
908
+ type: Injectable
909
+ }] });
910
+
911
+ //#region ---- Structured output ----
912
+ /** Default max completion tokens when the AiModel row has no `maxOutputTokens` and the caller omits `maxTokens`. */
913
+ const AXPAiAssistDefaultStructuredMaxTokens = 128_000;
914
+ /** Default maximum follow-up turns after the first model response when validating structured JSON (implementation may use this). */
915
+ const AXPAiAssistDefaultMaxStructuredRetries = 3;
916
+ /**
917
+ * Thrown when {@link AXPAiAssistRunInput.expectStructuredOutput} is true but the assistant output could not be
918
+ * parsed and optionally validated after all attempts.
919
+ */
920
+ class AXPAiStructuredOutputError extends Error {
921
+ constructor(options) {
922
+ super(options.message, options.cause !== undefined ? { cause: options.cause } : undefined);
923
+ this.name = 'AXPAiStructuredOutputError';
924
+ this.attempts = options.attempts;
925
+ this.lastAssistantText = options.lastAssistantText;
926
+ this.validationMessage = options.validationMessage;
927
+ this.code = options.code;
928
+ }
929
+ }
930
+ //#endregion
931
+
932
+ //#region ---- Imports ----
933
+ //#endregion
934
+ //#region ---- Engine (abstract service) ----
935
+ /**
936
+ * Backend boundary for AI assist runs (chat + tool rounds). Connectivity implementations execute registry
937
+ * commands/queries during the run loop.
938
+ * Wire a concrete implementation via Angular providers (for example `provide: AXPAiEngine` with `useClass`).
939
+ */
940
+ class AXPAiEngine {
941
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiEngine, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
942
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiEngine }); }
943
+ }
944
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiEngine, decorators: [{
945
+ type: Injectable
946
+ }] });
947
+
948
+ //#region ---- Imports ----
949
+ //#endregion
950
+ //#region ---- Constants ----
951
+ /** Prefix for supervisor-delegated specialist tools (`${AXPAI_SUPERVISOR_AGENT_TOOL_PREFIX}${agentId}`). */
952
+ const AXPAI_SUPERVISOR_AGENT_TOOL_PREFIX = 'agent:';
953
+ /** Default cap for main assist / direct-agent chat tool rounds (one provider call per step). */
954
+ const AXPAI_ENGINE_DEFAULT_MAX_STEPS = 16;
955
+ /** Default cap for delegated specialist sub-runs when the agent row has no positive `maxSteps`. */
956
+ const AXPAI_DELEGATED_AGENT_DEFAULT_MAX_STEPS = 8;
957
+ /** System prompt for vision OCR / document text extraction. */
958
+ const AXPAI_DOCUMENT_VISION_EXTRACTION_SYSTEM = 'You are a precise document-reading assistant. Extract readable plain text from the attached file. Preserve headings and lists where obvious. If the content is unreadable, return a short explanation. Output plain text only, no markdown code fences.';
959
+ /** Default user line when the caller passes an empty instruction for vision extraction. */
960
+ const AXPAI_DOCUMENT_VISION_DEFAULT_USER_INSTRUCTION = 'Extract all readable text from this document. Return plain text only.';
961
+ //#endregion
962
+ //#region ---- Transcript helpers ----
963
+ /**
964
+ * Reads a stored-file artifact from a normalized tool handler body (`{ success, data }`) or a flat `data` object.
965
+ */
966
+ function axpAiExtractStoredFileArtifactFromUnknown(content) {
967
+ if (content == null || typeof content !== 'object' || Array.isArray(content)) {
968
+ return null;
969
+ }
970
+ const o = content;
971
+ const dataRaw = o['data'];
972
+ if (o['success'] === true && dataRaw != null && typeof dataRaw === 'object' && !Array.isArray(dataRaw)) {
973
+ return axpAiExtractStoredFileArtifactFromDataRecord(dataRaw);
974
+ }
975
+ return axpAiExtractStoredFileArtifactFromDataRecord(o);
976
+ }
977
+ function axpAiExtractStoredFileArtifactFromDataRecord(d) {
978
+ const fileId = typeof d['fileId'] === 'string' ? d['fileId'].trim() : '';
979
+ const mimeType = typeof d['mimeType'] === 'string' ? d['mimeType'].trim() : '';
980
+ if (!fileId || !mimeType) {
981
+ return null;
982
+ }
983
+ const nameRaw = d['name'];
984
+ const name = typeof nameRaw === 'string' && nameRaw.trim() ? nameRaw.trim() : undefined;
985
+ return { fileId, mimeType, ...(name ? { name } : {}) };
986
+ }
987
+ /**
988
+ * Returns the last stored-file artifact announced in any `tool` → `tool_result` segment (delegated sub-runs, main chat).
989
+ */
990
+ function axpAiExtractLastStoredFileArtifactFromChatMessages(messages) {
991
+ let last = null;
992
+ for (const m of messages) {
993
+ if (m.role !== 'tool') {
994
+ continue;
995
+ }
996
+ for (const r of m.responses) {
997
+ if (r.type !== 'tool_result') {
998
+ continue;
999
+ }
1000
+ const hit = axpAiExtractStoredFileArtifactFromUnknown(r.content);
1001
+ if (hit) {
1002
+ last = hit;
1003
+ }
1004
+ }
1005
+ }
1006
+ return last;
1007
+ }
1008
+ function axpAiCloneChatMessages(messages) {
1009
+ try {
1010
+ return structuredClone(messages);
1011
+ }
1012
+ catch {
1013
+ return JSON.parse(JSON.stringify(messages));
1014
+ }
1015
+ }
1016
+ /**
1017
+ * Ensures the delegated specialist transcript replays stored files in assistant `responses`
1018
+ * (not only prose that points at tool JSON).
1019
+ */
1020
+ function axpAiDelegatedSubTranscriptAppendFileArtifactFromToolResults(messages) {
1021
+ const artifact = axpAiExtractLastStoredFileArtifactFromChatMessages(messages);
1022
+ if (!artifact) {
1023
+ return messages;
1024
+ }
1025
+ const out = axpAiCloneChatMessages(messages);
1026
+ let lastAssistant = -1;
1027
+ for (let i = out.length - 1; i >= 0; i--) {
1028
+ if (out[i].role === 'assistant') {
1029
+ lastAssistant = i;
1030
+ break;
1031
+ }
1032
+ }
1033
+ if (lastAssistant < 0) {
1034
+ return out;
1035
+ }
1036
+ const msg = out[lastAssistant];
1037
+ const duplicate = msg.responses.some((r) => r.type === 'file' && r.content.fileId === artifact.fileId && r.content.mimeType === artifact.mimeType);
1038
+ if (duplicate) {
1039
+ return out;
1040
+ }
1041
+ out[lastAssistant] = {
1042
+ ...msg,
1043
+ responses: [...msg.responses, { type: 'file', content: artifact }],
1044
+ };
1045
+ return out;
1046
+ }
1047
+ function axpAiIsDelegatedAgentResultSegment(value) {
1048
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
1049
+ return false;
1050
+ }
1051
+ const o = value;
1052
+ const t = o['type'];
1053
+ if (t === 'text' && typeof o['content'] === 'string') {
1054
+ return true;
1055
+ }
1056
+ if (t === 'think' && typeof o['content'] === 'string') {
1057
+ return true;
1058
+ }
1059
+ if (t === 'node') {
1060
+ return 'content' in o;
1061
+ }
1062
+ if (t === 'file' && o['content'] != null && typeof o['content'] === 'object' && !Array.isArray(o['content'])) {
1063
+ const c = o['content'];
1064
+ return typeof c['fileId'] === 'string' && typeof c['mimeType'] === 'string';
1065
+ }
1066
+ return false;
1067
+ }
1068
+ /**
1069
+ * Parses a JSON-like array of specialist segments (e.g. from persisted tool output). Invalid entries are skipped.
1070
+ */
1071
+ function axpAiParseDelegatedAgentResultSegmentsFromUnknown(raw) {
1072
+ if (!Array.isArray(raw)) {
1073
+ return [];
1074
+ }
1075
+ const out = [];
1076
+ for (const item of raw) {
1077
+ if (axpAiIsDelegatedAgentResultSegment(item)) {
1078
+ out.push(item);
1079
+ }
1080
+ }
1081
+ return out;
1082
+ }
1083
+ /**
1084
+ * Collects ordered {@link AXPAiDelegatedAgentResultSegment} from a delegated sub-run transcript
1085
+ * (excludes {@link AXPAiChatMessage.delegatedReflection} lines).
1086
+ */
1087
+ function axpAiCollectDelegatedAgentOutcomeResponses(messages) {
1088
+ const out = [];
1089
+ for (const m of messages) {
1090
+ if (m.role !== 'assistant' || axpAiChatMessageIsDelegatedReflectionExcluded(m)) {
1091
+ continue;
1092
+ }
1093
+ for (const r of m.responses) {
1094
+ if (r.type === 'text' || r.type === 'think' || r.type === 'file' || r.type === 'node') {
1095
+ out.push(r);
1096
+ }
1097
+ }
1098
+ }
1099
+ return out;
1100
+ }
1101
+ /**
1102
+ * Plain text from {@link AXPAiDelegatedAgentResultSegment} (text + think only; for provider hints / markdown fallbacks).
1103
+ */
1104
+ function axpAiDelegatedAgentOutcomeResponsesPlainText(segments) {
1105
+ const parts = [];
1106
+ for (const s of segments) {
1107
+ if (s.type === 'text' || s.type === 'think') {
1108
+ const t = s.content.trim();
1109
+ if (t.length > 0) {
1110
+ parts.push(t);
1111
+ }
1112
+ }
1113
+ }
1114
+ return parts.join('\n\n').trim();
1115
+ }
1116
+ function axpAiChatTextMessage(role, text) {
1117
+ return {
1118
+ role,
1119
+ responses: [{ type: 'text', content: text }],
1120
+ };
1121
+ }
1122
+ function axpAiChatUserMessage(responses) {
1123
+ return {
1124
+ role: 'user',
1125
+ responses,
1126
+ };
1127
+ }
1128
+ function axpAiChatMessageGetText(message) {
1129
+ const parts = [];
1130
+ for (const r of message.responses) {
1131
+ if (r.type === 'text') {
1132
+ parts.push(r.content);
1133
+ }
1134
+ else if (r.type === 'node') {
1135
+ try {
1136
+ parts.push(JSON.stringify({ type: 'node', content: r.content }));
1137
+ }
1138
+ catch {
1139
+ parts.push('[node]');
1140
+ }
1141
+ }
1142
+ }
1143
+ return parts.join('\n\n');
1144
+ }
1145
+ /**
1146
+ * Planning-only assistant output is always internal reasoning. Provider text may be untagged;
1147
+ * the engine maps `text` responses to `think` so the transcript and UI are correct without
1148
+ * requiring `<think>` / `<think>` in the model output.
1149
+ */
1150
+ function axpAiCoercePlanningAssistantTextToThink(planningMessages) {
1151
+ return planningMessages.map((m) => {
1152
+ if (m.role !== 'assistant') {
1153
+ return m;
1154
+ }
1155
+ return {
1156
+ ...m,
1157
+ responses: m.responses.map((r) => {
1158
+ if (r.type === 'text') {
1159
+ return { type: 'think', content: r.content };
1160
+ }
1161
+ return r;
1162
+ }),
1163
+ };
1164
+ });
1165
+ }
1166
+ //#region ---- Assistant plain text: embedded node JSON envelopes ----
1167
+ function isAssistantNodeTypeEnvelope(o) {
1168
+ if (!o || typeof o !== 'object' || Array.isArray(o)) {
1169
+ return false;
1170
+ }
1171
+ const r = o;
1172
+ return r['type'] === 'node' && 'content' in r;
1173
+ }
1174
+ /**
1175
+ * Parses one balanced `{ ... }` JSON object starting at `start` (must point at `{`).
1176
+ */
1177
+ function tryParseBalancedJsonObjectAt$1(s, start) {
1178
+ if (s[start] !== '{') {
1179
+ return null;
1180
+ }
1181
+ let depth = 0;
1182
+ let inString = false;
1183
+ let escape = false;
1184
+ for (let i = start; i < s.length; i++) {
1185
+ const c = s[i];
1186
+ if (inString) {
1187
+ if (escape) {
1188
+ escape = false;
1189
+ continue;
1190
+ }
1191
+ if (c === '\\') {
1192
+ escape = true;
1193
+ continue;
1194
+ }
1195
+ if (c === '"') {
1196
+ inString = false;
1197
+ }
1198
+ continue;
1199
+ }
1200
+ if (c === '"') {
1201
+ inString = true;
1202
+ continue;
1203
+ }
1204
+ if (c === '{') {
1205
+ depth++;
1206
+ }
1207
+ else if (c === '}') {
1208
+ depth--;
1209
+ if (depth === 0) {
1210
+ const slice = s.slice(start, i + 1);
1211
+ try {
1212
+ return { value: JSON.parse(slice), end: i + 1 };
1213
+ }
1214
+ catch {
1215
+ return null;
1216
+ }
1217
+ }
1218
+ }
1219
+ }
1220
+ return null;
1221
+ }
1222
+ function mergeAdjacentAssistantTextResponses(seq) {
1223
+ const out = [];
1224
+ for (const r of seq) {
1225
+ if (r.type !== 'text') {
1226
+ out.push(r);
1227
+ continue;
1228
+ }
1229
+ const prev = out[out.length - 1];
1230
+ const v = r.content.trim();
1231
+ if (!v.length) {
1232
+ continue;
1233
+ }
1234
+ if (prev && prev.type === 'text') {
1235
+ const joined = `${prev.content}\n\n${v}`.trim();
1236
+ out[out.length - 1] = { type: 'text', content: joined };
1237
+ }
1238
+ else {
1239
+ out.push({ type: 'text', content: v });
1240
+ }
1241
+ }
1242
+ return out;
1243
+ }
1244
+ /**
1245
+ * Splits raw assistant prose into ordered `text` / `node` responses by detecting JSON objects
1246
+ * shaped like `{ "type": "node", "content": <AXPWidgetNode> }` anywhere in the string.
1247
+ */
1248
+ function axpAiExpandPlainAssistantTextToResponses(raw) {
1249
+ const parts = [];
1250
+ let i = 0;
1251
+ const pushText = (value) => {
1252
+ const v = value.trim();
1253
+ if (v.length > 0) {
1254
+ parts.push({ type: 'text', content: v });
1255
+ }
1256
+ };
1257
+ while (i < raw.length) {
1258
+ const braceIdx = raw.indexOf('{', i);
1259
+ if (braceIdx < 0) {
1260
+ pushText(raw.slice(i));
1261
+ break;
1262
+ }
1263
+ pushText(raw.slice(i, braceIdx));
1264
+ const parsed = tryParseBalancedJsonObjectAt$1(raw, braceIdx);
1265
+ if (parsed && isAssistantNodeTypeEnvelope(parsed.value)) {
1266
+ parts.push({ type: 'node', content: parsed.value.content });
1267
+ i = parsed.end;
1268
+ }
1269
+ else if (parsed) {
1270
+ pushText(raw.slice(braceIdx, parsed.end));
1271
+ i = parsed.end;
1272
+ }
1273
+ else {
1274
+ pushText(raw.slice(braceIdx, braceIdx + 1));
1275
+ i = braceIdx + 1;
1276
+ }
1277
+ }
1278
+ return mergeAdjacentAssistantTextResponses(parts);
1279
+ }
1280
+ //#endregion
1281
+ function axpAiChatMessagesFromProviderAssistant(text, toolCalls) {
1282
+ const normalizeThinkingTags = (raw) => raw
1283
+ .replace(/&lt;(\/?redacted_thinking)&gt;/gi, '<$1>')
1284
+ .replace(/&lt;(\/?think)&gt;/gi, '<$1>');
1285
+ const splitAssistantResponses = (raw) => {
1286
+ const normalized = normalizeThinkingTags(raw ?? '');
1287
+ if (!normalized) {
1288
+ return [];
1289
+ }
1290
+ const out = [];
1291
+ const appendPlainSlice = (value) => {
1292
+ out.push(...axpAiExpandPlainAssistantTextToResponses(value));
1293
+ };
1294
+ const pushThink = (value) => {
1295
+ const v = value.trim();
1296
+ if (v.length > 0) {
1297
+ out.push({ type: 'think', content: v });
1298
+ }
1299
+ };
1300
+ const thinkRe = /<(redacted_thinking|think)>([\s\S]*?)<\/\1>/gi;
1301
+ let last = 0;
1302
+ let m;
1303
+ while ((m = thinkRe.exec(normalized)) !== null) {
1304
+ appendPlainSlice(normalized.slice(last, m.index));
1305
+ pushThink(m[2] ?? '');
1306
+ last = m.index + m[0].length;
1307
+ }
1308
+ appendPlainSlice(normalized.slice(last));
1309
+ return mergeAdjacentAssistantTextResponses(out);
1310
+ };
1311
+ const parsedResponses = splitAssistantResponses(text);
1312
+ const calls = toolCalls ?? [];
1313
+ const out = [];
1314
+ if (parsedResponses.length > 0) {
1315
+ out.push({
1316
+ role: 'assistant',
1317
+ responses: parsedResponses,
1318
+ });
1319
+ }
1320
+ for (const tc of calls) {
1321
+ const isDelegatedAgent = axpAiParseSupervisorAgentToolName(tc.name) != null;
1322
+ out.push({
1323
+ role: 'assistant',
1324
+ responses: [
1325
+ isDelegatedAgent
1326
+ ? {
1327
+ type: 'agent',
1328
+ content: {
1329
+ command: tc.name,
1330
+ arguments: tc.arguments,
1331
+ },
1332
+ callId: tc.id,
1333
+ }
1334
+ : {
1335
+ type: 'tool',
1336
+ content: {
1337
+ command: tc.name,
1338
+ arguments: tc.arguments,
1339
+ },
1340
+ callId: tc.id,
1341
+ },
1342
+ ],
1343
+ });
1344
+ }
1345
+ if (out.length === 0) {
1346
+ out.push(axpAiChatTextMessage('assistant', ''));
1347
+ }
1348
+ return out;
1349
+ }
1350
+ function axpAiToolCallFromAssistantToolMessage(message) {
1351
+ if (message.role !== 'assistant') {
1352
+ return null;
1353
+ }
1354
+ for (const r of message.responses) {
1355
+ if (r.type === 'tool' || r.type === 'agent') {
1356
+ const callId = r.callId?.trim() ?? '';
1357
+ const command = r.content.command?.trim() ?? '';
1358
+ if (!command) {
1359
+ return null;
1360
+ }
1361
+ return {
1362
+ id: callId || `call_${command}`,
1363
+ name: command,
1364
+ arguments: r.content.arguments,
1365
+ };
1366
+ }
1367
+ }
1368
+ return null;
1369
+ }
1370
+ function axpAiChatToolResultMessage(callId, content, toolName) {
1371
+ const id = callId.trim();
1372
+ return {
1373
+ role: 'tool',
1374
+ ...(toolName?.trim() ? { name: toolName.trim() } : {}),
1375
+ responses: [
1376
+ {
1377
+ type: 'tool_result',
1378
+ callId: id,
1379
+ content,
1380
+ },
1381
+ ],
1382
+ };
1383
+ }
1384
+ function axpAiChatAgentResultMessage(callId, content, toolName) {
1385
+ const id = callId.trim();
1386
+ return {
1387
+ role: 'tool',
1388
+ ...(toolName?.trim() ? { name: toolName.trim() } : {}),
1389
+ responses: [
1390
+ {
1391
+ type: 'agent_result',
1392
+ callId: id,
1393
+ content,
1394
+ },
1395
+ ],
1396
+ };
1397
+ }
1398
+ function axpAiNormalizeHandlerResultToToolBody(handlerResult) {
1399
+ if (handlerResult === undefined || handlerResult === null) {
1400
+ return { success: false, error: 'Tool returned no result.' };
1401
+ }
1402
+ if (typeof handlerResult === 'string') {
1403
+ const t = handlerResult.trim();
1404
+ if (!t) {
1405
+ return { success: false, error: 'Tool returned an empty string.' };
1406
+ }
1407
+ try {
1408
+ return JSON.parse(t);
1409
+ }
1410
+ catch {
1411
+ return { success: true, data: handlerResult };
1412
+ }
1413
+ }
1414
+ if (typeof handlerResult === 'object' && !Array.isArray(handlerResult)) {
1415
+ return handlerResult;
1416
+ }
1417
+ return { success: true, data: handlerResult };
1418
+ }
1419
+ function axpAiChatToolOrAgentResultBodyJson(message) {
1420
+ const tr = message.responses.find((r) => r.type === 'tool_result' || r.type === 'agent_result');
1421
+ if (!tr || (tr.type !== 'tool_result' && tr.type !== 'agent_result')) {
1422
+ return '';
1423
+ }
1424
+ try {
1425
+ return JSON.stringify(tr.content);
1426
+ }
1427
+ catch {
1428
+ return String(tr.content);
1429
+ }
1430
+ }
1431
+ /**
1432
+ * Compact JSON string of a tool-role message’s `tool_result` body (transcript tail / logs).
1433
+ */
1434
+ function axpAiChatToolResultBodyJson(message) {
1435
+ return axpAiChatToolOrAgentResultBodyJson(message);
1436
+ }
1437
+ //#endregion
1438
+ //#region ---- Supervisor delegated-agent helpers ----
1439
+ function axpAiSupervisorAgentToolName(agentCatalogId) {
1440
+ return `${AXPAI_SUPERVISOR_AGENT_TOOL_PREFIX}${agentCatalogId.trim()}`;
1441
+ }
1442
+ function axpAiParseSupervisorAgentToolName(toolName) {
1443
+ const n = toolName.trim();
1444
+ if (!n.startsWith(AXPAI_SUPERVISOR_AGENT_TOOL_PREFIX)) {
1445
+ return null;
1446
+ }
1447
+ const id = n.slice(AXPAI_SUPERVISOR_AGENT_TOOL_PREFIX.length).trim();
1448
+ return id.length > 0 ? id : null;
1449
+ }
1450
+ //#endregion
1451
+ //#region ---- Assistant message transforms (delegated sub-run) ----
1452
+ function axpAiMergePlainAssistantTextTurn(messages) {
1453
+ const chunks = [];
1454
+ for (const m of messages) {
1455
+ if (m.role !== 'assistant') {
1456
+ continue;
1457
+ }
1458
+ const mergable = m.responses.every((r) => r.type === 'text' || r.type === 'think');
1459
+ if (!mergable) {
1460
+ continue;
1461
+ }
1462
+ const textParts = m.responses
1463
+ .filter((r) => r.type === 'text')
1464
+ .map((r) => r.content.trim())
1465
+ .filter((s) => s.length > 0);
1466
+ const thinkParts = m.responses
1467
+ .filter((r) => r.type === 'think')
1468
+ .map((r) => r.content.trim())
1469
+ .filter((s) => s.length > 0);
1470
+ const t = textParts.length > 0 ? textParts.join('\n\n').trim() : thinkParts.join('\n\n').trim();
1471
+ if (t.length > 0) {
1472
+ chunks.push(t);
1473
+ }
1474
+ }
1475
+ const joined = chunks.join('\n\n').trim();
1476
+ if (!joined) {
1477
+ return [];
1478
+ }
1479
+ return [axpAiChatTextMessage('assistant', joined)];
1480
+ }
1481
+ function axpAiPruneAssistantPiecesToFirstToolOnly(messages) {
1482
+ const out = [];
1483
+ let keptTool = false;
1484
+ for (const m of messages) {
1485
+ if (m.role !== 'assistant') {
1486
+ out.push(m);
1487
+ continue;
1488
+ }
1489
+ const idx = m.responses.findIndex((r) => r.type === 'tool' || r.type === 'agent');
1490
+ if (idx < 0) {
1491
+ out.push(m);
1492
+ continue;
1493
+ }
1494
+ if (!keptTool) {
1495
+ out.push({
1496
+ ...m,
1497
+ responses: m.responses.slice(0, idx + 1),
1498
+ });
1499
+ keptTool = true;
1500
+ }
1501
+ }
1502
+ return out;
1503
+ }
1504
+ function axpAiChatDelegatedReflectionAssistantMessage(reflectionText) {
1505
+ return {
1506
+ role: 'assistant',
1507
+ delegatedReflection: true,
1508
+ responses: [{ type: 'text', content: reflectionText }],
1509
+ };
1510
+ }
1511
+ function axpAiChatMessageIsDelegatedReflectionExcluded(message) {
1512
+ return message.delegatedReflection === true;
1513
+ }
1514
+ //#endregion
1515
+
1516
+ //#region ---- Imports ----
1517
+ //#endregion
1518
+ //#region ---- Local time formatting ----
1519
+ /**
1520
+ * Formats {@link now} in {@link ianaTimeZone} for English system prompts; falls back to UTC on invalid zone.
1521
+ */
1522
+ function formatNowForRuntimeContext(now, ianaTimeZone) {
1523
+ const tz = ianaTimeZone?.trim() || 'UTC';
1524
+ try {
1525
+ return (now.toLocaleString('en-US', {
1526
+ timeZone: tz,
1527
+ dateStyle: 'full',
1528
+ timeStyle: 'long',
1529
+ }) + ` (${tz})`);
1530
+ }
1531
+ catch {
1532
+ return now.toISOString() + ' (UTC)';
1533
+ }
1534
+ }
1535
+ //#endregion
1536
+ //#region ---- Builder ----
1537
+ /**
1538
+ * Builds {@link AXPAiPlatformRuntimeContext} from session and user-scoped regional settings.
1539
+ */
1540
+ class AXPAiPlatformRuntimeContextBuilder {
1541
+ constructor() {
1542
+ //#region ---- Services & Dependencies ----
1543
+ this.session = inject(AXPSessionService);
1544
+ this.settings = inject(AXPSettingsService);
1545
+ this.translation = inject(AXTranslationService);
1546
+ }
1547
+ //#endregion
1548
+ //#region ---- Public API ----
1549
+ /**
1550
+ * Resolves current user, tenant, application, UI language, and regional preferences from storage.
1551
+ */
1552
+ async build() {
1553
+ const user = this.session.user;
1554
+ const tenant = this.session.tenant;
1555
+ const application = this.session.application;
1556
+ const userScope = this.settings.scope(AXPPlatformScope.User);
1557
+ const [calendarRaw, tzRaw, countryRaw] = await Promise.all([
1558
+ userScope.get(AXPRegionalSetting.Calendar),
1559
+ userScope.get(AXPRegionalSetting.TimeZone),
1560
+ userScope.get(AXPRegionalSetting.Country),
1561
+ ]);
1562
+ const calendarSystem = typeof calendarRaw === 'string' && calendarRaw.trim() ? calendarRaw.trim() : undefined;
1563
+ const timeZone = typeof tzRaw === 'string' && tzRaw.trim() ? tzRaw.trim() : undefined;
1564
+ const country = typeof countryRaw === 'string' && countryRaw.trim() ? countryRaw.trim() : undefined;
1565
+ const locale = this.translation.getActiveLang();
1566
+ const now = new Date();
1567
+ return {
1568
+ userId: user?.id,
1569
+ userDisplayName: [user?.name?.trim(), user?.title?.trim()].find((s) => s && s.length > 0),
1570
+ tenantId: tenant?.id,
1571
+ tenantTitle: tenant?.title?.trim() || tenant?.name?.trim(),
1572
+ applicationId: application?.id,
1573
+ applicationTitle: application?.title?.trim() || application?.name?.trim(),
1574
+ locale,
1575
+ calendarSystem,
1576
+ timeZone,
1577
+ country,
1578
+ currentInstant: now.toISOString(),
1579
+ currentLocalDateTime: formatNowForRuntimeContext(now, timeZone),
1580
+ };
1581
+ }
1582
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiPlatformRuntimeContextBuilder, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1583
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiPlatformRuntimeContextBuilder, providedIn: 'root' }); }
1584
+ }
1585
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiPlatformRuntimeContextBuilder, decorators: [{
1586
+ type: Injectable,
1587
+ args: [{ providedIn: 'root' }]
1588
+ }] });
1589
+
1590
+ //#region ---- Imports ----
1591
+ //#endregion
1592
+ //#region ---- Constants ----
1593
+ /** Max length for relaying an https image URL in tool_result when persistence fails (CORS, etc.). */
1594
+ const AI_GENERATED_IMAGE_MAX_REMOTE_URL_IN_TOOL = 2048;
1595
+ /** refType for files created from in-chat image tool output. */
1596
+ const AI_CHAT_GENERATED_IMAGE_REF_TYPE = `${RootConfig.module.name}.AiChatGeneratedImage`;
1597
+ /** refType for files created from in-chat text-to-speech tool output. */
1598
+ const AI_CHAT_GENERATED_SPEECH_REF_TYPE = `${RootConfig.module.name}.AiChatGeneratedSpeech`;
1599
+ /** refType for user-attached images in AI chat; {@link persistAiChatAttachmentImage} uses a batch ref id. */
1600
+ const AI_CHAT_ATTACHMENT_REF_TYPE = `${RootConfig.module.name}.AiChatAttachment`;
1601
+ /** File storage category for user chat image attachments. */
1602
+ const AI_CHAT_ATTACHMENT_CATEGORY = 'ai-chat-attachment';
1603
+ //#endregion
1604
+ //#region ---- URL / File conversion ----
1605
+ /**
1606
+ * Builds a File from a vendor image URL (https) or data URL (base64 image).
1607
+ */
1608
+ async function blobOrFileFromImageResult(imageUrl, defaultName = 'ai-generated.png') {
1609
+ const trimmed = imageUrl.trim();
1610
+ if (!trimmed) {
1611
+ throw new Error('Image URL is empty.');
1612
+ }
1613
+ if (trimmed.startsWith('data:')) {
1614
+ const res = await fetch(trimmed);
1615
+ if (!res.ok) {
1616
+ throw new Error(`Failed to read data URL (${res.status}).`);
1617
+ }
1618
+ const blob = await res.blob();
1619
+ const mime = blob.type || parseDataUrlMime(trimmed) || 'image/png';
1620
+ return new File([blob], defaultName, { type: mime });
1621
+ }
1622
+ if (trimmed.startsWith('https://') || trimmed.startsWith('http://')) {
1623
+ const res = await fetch(trimmed);
1624
+ if (!res.ok) {
1625
+ throw new Error(`Failed to fetch image (${res.status}).`);
1626
+ }
1627
+ const blob = await res.blob();
1628
+ const mime = blob.type ||
1629
+ res.headers.get('Content-Type')?.split(';')[0]?.trim() ||
1630
+ 'image/png';
1631
+ const ext = mime.includes('jpeg') || mime.includes('jpg') ? 'jpg' : mime.includes('webp') ? 'webp' : 'png';
1632
+ return new File([blob], defaultName.replace(/\.[^.]+$/, '') + '.' + ext, { type: mime });
1633
+ }
1634
+ throw new Error('Unsupported image URL scheme (expected https: or data:).');
1635
+ }
1636
+ function parseDataUrlMime(dataUrl) {
1637
+ const m = /^data:([^;,]+)[;,]/.exec(dataUrl);
1638
+ return m?.[1]?.trim();
1639
+ }
1640
+ //#endregion
1641
+ //#region ---- Persistence ----
1642
+ /**
1643
+ * Saves the file and commits it so it appears in storage queries as committed.
1644
+ */
1645
+ async function persistAiGeneratedImage(fileStorage, file, ref) {
1646
+ const info = await fileStorage.save({
1647
+ file,
1648
+ name: file.name,
1649
+ refId: ref.refId,
1650
+ refType: ref.refType,
1651
+ category: 'ai-generated-image',
1652
+ status: AXPFileStorageStatus.Temporary,
1653
+ });
1654
+ const fileId = info.fileId?.trim();
1655
+ if (!fileId) {
1656
+ throw new Error('File storage did not return a fileId.');
1657
+ }
1658
+ await fileStorage.commit(fileId);
1659
+ return { fileId };
1660
+ }
1661
+ /**
1662
+ * Persists a user-selected chat image; refId groups files uploaded in the same composer batch.
1663
+ */
1664
+ async function persistAiChatAttachmentImage(fileStorage, file, refId) {
1665
+ const trimmed = refId.trim();
1666
+ if (!trimmed) {
1667
+ throw new Error('refId is required for chat attachment persistence.');
1668
+ }
1669
+ const info = await fileStorage.save({
1670
+ file,
1671
+ name: file.name,
1672
+ refId: trimmed,
1673
+ refType: AI_CHAT_ATTACHMENT_REF_TYPE,
1674
+ category: AI_CHAT_ATTACHMENT_CATEGORY,
1675
+ status: AXPFileStorageStatus.Temporary,
1676
+ });
1677
+ const fileId = info.fileId?.trim();
1678
+ if (!fileId) {
1679
+ throw new Error('File storage did not return a fileId.');
1680
+ }
1681
+ await fileStorage.commit(fileId);
1682
+ return { fileId };
1683
+ }
1684
+ /**
1685
+ * Saves synthesized speech bytes and commits so the file id can be replayed in chat.
1686
+ */
1687
+ async function persistAiGeneratedSpeech(fileStorage, file, ref) {
1688
+ const info = await fileStorage.save({
1689
+ file,
1690
+ name: file.name,
1691
+ refId: ref.refId,
1692
+ refType: ref.refType,
1693
+ category: 'ai-generated-speech',
1694
+ status: AXPFileStorageStatus.Temporary,
1695
+ });
1696
+ const fileId = info.fileId?.trim();
1697
+ if (!fileId) {
1698
+ throw new Error('File storage did not return a fileId.');
1699
+ }
1700
+ await fileStorage.commit(fileId);
1701
+ return { fileId };
1702
+ }
1703
+ //#endregion
1704
+
1705
+ //#region ---- Limits ----
1706
+ /** Max image file size for AI chat / assist composer attachments (bytes). */
1707
+ const AXM_AI_CHAT_COMPOSER_MAX_IMAGE_BYTES = 20 * 1024 * 1024;
1708
+ /** Max images per composer batch (same cap as chat page). */
1709
+ const AXM_AI_CHAT_COMPOSER_MAX_IMAGES_PER_TURN = 20;
1710
+ /** Max audio file size (bytes). */
1711
+ const AXM_AI_CHAT_COMPOSER_MAX_AUDIO_BYTES = 25 * 1024 * 1024;
1712
+ /** Max audio files per composer batch. */
1713
+ const AXM_AI_CHAT_COMPOSER_MAX_AUDIO_PER_TURN = 5;
1714
+ /** Max document file size for PDF / text / office-style attachments (bytes). */
1715
+ const AXM_AI_CHAT_COMPOSER_MAX_DOCUMENT_BYTES = 35 * 1024 * 1024;
1716
+ /** Max document files per composer batch. */
1717
+ const AXM_AI_CHAT_COMPOSER_MAX_DOCUMENTS_PER_TURN = 10;
1718
+ //#endregion
1719
+ //#region ---- Patterns ----
1720
+ const CHAT_IMAGE_NAME_EXT_PATTERN = /\.(png|jpe?g|gif|webp|bmp|svg|ico|heic|heif)$/i;
1721
+ const CHAT_AUDIO_NAME_EXT_PATTERN = /\.(mp3|m4a|aac|wav|webm|ogg|opus|flac)$/i;
1722
+ const CHAT_DOCUMENT_NAME_EXT_PATTERN = /\.(pdf|txt|md|markdown|csv|tsv|json|jsonl|xml|html?|yaml|yml|log|rtf|docx?|xlsx?|pptx?|odt|ods|odp)$/i;
1723
+ //#endregion
1724
+ //#region ---- Public API ----
1725
+ /**
1726
+ * Returns true for normal `image/*` types and for empty/octet-stream when the file name looks like an image.
1727
+ */
1728
+ function axmIsLikelyChatImageFile(file) {
1729
+ const t = file.type?.trim() ?? '';
1730
+ if (t.startsWith('image/')) {
1731
+ return true;
1732
+ }
1733
+ if (t === 'application/octet-stream' || t === '') {
1734
+ return CHAT_IMAGE_NAME_EXT_PATTERN.test(file.name);
1735
+ }
1736
+ return false;
1737
+ }
1738
+ /**
1739
+ * Returns true for normal `audio/*` types and for empty/octet-stream when the file name looks like audio.
1740
+ */
1741
+ function axmIsLikelyChatAudioFile(file) {
1742
+ const t = file.type?.trim() ?? '';
1743
+ if (t.startsWith('audio/')) {
1744
+ return true;
1745
+ }
1746
+ if (t === 'application/octet-stream' || t === '') {
1747
+ return CHAT_AUDIO_NAME_EXT_PATTERN.test(file.name);
1748
+ }
1749
+ return false;
1750
+ }
1751
+ /**
1752
+ * Returns true for PDF, plain text, common code/markup, CSV, and typical Office/OpenDocument uploads.
1753
+ */
1754
+ function axmIsLikelyChatDocumentFile(file) {
1755
+ const t = file.type?.trim().toLowerCase() ?? '';
1756
+ if (t === 'application/pdf' || t.startsWith('text/')) {
1757
+ return true;
1758
+ }
1759
+ if (t === 'application/json' ||
1760
+ t === 'application/xml' ||
1761
+ t === 'application/javascript' ||
1762
+ t === 'application/typescript' ||
1763
+ t === 'text/csv' ||
1764
+ t === 'application/csv' ||
1765
+ t === 'text/tsv' ||
1766
+ t === 'application/rtf' ||
1767
+ t === 'text/rtf' ||
1768
+ t.includes('wordprocessingml') ||
1769
+ t.includes('spreadsheetml') ||
1770
+ t.includes('presentationml') ||
1771
+ t.includes('msword') ||
1772
+ t.includes('ms-excel') ||
1773
+ t.includes('ms-powerpoint') ||
1774
+ t.includes('opendocument')) {
1775
+ return true;
1776
+ }
1777
+ if (t === 'application/octet-stream' || t === '') {
1778
+ return CHAT_DOCUMENT_NAME_EXT_PATTERN.test(file.name);
1779
+ }
1780
+ return false;
1781
+ }
1782
+ /**
1783
+ * MIME for storage/API when the browser omits or misreports `file.type` (images and common audio extensions).
1784
+ */
1785
+ function axmMimeTypeForChatAttachment(file) {
1786
+ const t = file.type?.trim() ?? '';
1787
+ if (t.startsWith('image/')) {
1788
+ return t;
1789
+ }
1790
+ if (t.startsWith('audio/')) {
1791
+ return t;
1792
+ }
1793
+ if (t.startsWith('text/') || t === 'application/pdf' || t === 'application/json' || t === 'application/xml') {
1794
+ return t;
1795
+ }
1796
+ const m = /\.([^.]+)$/i.exec(file.name);
1797
+ const ext = (m?.[1] ?? '').toLowerCase();
1798
+ const imageByExt = {
1799
+ png: 'image/png',
1800
+ jpg: 'image/jpeg',
1801
+ jpeg: 'image/jpeg',
1802
+ gif: 'image/gif',
1803
+ webp: 'image/webp',
1804
+ bmp: 'image/bmp',
1805
+ svg: 'image/svg+xml',
1806
+ ico: 'image/x-icon',
1807
+ heic: 'image/heic',
1808
+ heif: 'image/heif',
1809
+ };
1810
+ const audioByExt = {
1811
+ mp3: 'audio/mpeg',
1812
+ m4a: 'audio/mp4',
1813
+ aac: 'audio/aac',
1814
+ wav: 'audio/wav',
1815
+ webm: 'audio/webm',
1816
+ ogg: 'audio/ogg',
1817
+ opus: 'audio/opus',
1818
+ flac: 'audio/flac',
1819
+ };
1820
+ const docByExt = {
1821
+ pdf: 'application/pdf',
1822
+ txt: 'text/plain',
1823
+ md: 'text/markdown',
1824
+ markdown: 'text/markdown',
1825
+ csv: 'text/csv',
1826
+ tsv: 'text/tab-separated-values',
1827
+ json: 'application/json',
1828
+ jsonl: 'application/jsonl',
1829
+ xml: 'application/xml',
1830
+ html: 'text/html',
1831
+ htm: 'text/html',
1832
+ yaml: 'text/yaml',
1833
+ yml: 'text/yaml',
1834
+ log: 'text/plain',
1835
+ rtf: 'application/rtf',
1836
+ doc: 'application/msword',
1837
+ docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
1838
+ xls: 'application/vnd.ms-excel',
1839
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
1840
+ ppt: 'application/vnd.ms-powerpoint',
1841
+ pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
1842
+ odt: 'application/vnd.oasis.opendocument.text',
1843
+ ods: 'application/vnd.oasis.opendocument.spreadsheet',
1844
+ odp: 'application/vnd.oasis.opendocument.presentation',
1845
+ };
1846
+ return imageByExt[ext] ?? audioByExt[ext] ?? docByExt[ext] ?? 'application/octet-stream';
1847
+ }
1848
+ //#endregion
1849
+
1850
+ //#region ---- Imports ----
1851
+ //#endregion
1852
+ //#region ---- Component ----
1853
+ /**
1854
+ * Floating prompt UI for AI assist: gradient chrome, inner composer, and image/audio/document attachments. Target assist/agent comes from optional initial ids on open.
1855
+ */
1856
+ class AXMAiAssistPromptBoxComponent {
1857
+ constructor() {
1858
+ //#region ---- Services & Dependencies ----
1859
+ this.toastService = inject(AXToastService);
1860
+ this.translation = inject(AXTranslationService);
1861
+ this.fileStorage = inject(AXPFileStorageService);
1862
+ this.fileService = inject(AXFileService);
1863
+ this.platformId = inject(PLATFORM_ID);
1864
+ //#endregion
1865
+ //#region ---- Inputs ----
1866
+ this.title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
1867
+ this.placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
1868
+ this.initialPrompt = input('', ...(ngDevMode ? [{ debugName: "initialPrompt" }] : /* istanbul ignore next */ []));
1869
+ this.contentMaxWidthPx = input(680, ...(ngDevMode ? [{ debugName: "contentMaxWidthPx" }] : /* istanbul ignore next */ []));
1870
+ this.initialAssistId = input(undefined, ...(ngDevMode ? [{ debugName: "initialAssistId" }] : /* istanbul ignore next */ []));
1871
+ this.initialDirectAgentId = input(undefined, ...(ngDevMode ? [{ debugName: "initialDirectAgentId" }] : /* istanbul ignore next */ []));
1872
+ this.runPrompt = input.required(...(ngDevMode ? [{ debugName: "runPrompt" }] : /* istanbul ignore next */ []));
1873
+ this.requestClose = input.required(...(ngDevMode ? [{ debugName: "requestClose" }] : /* istanbul ignore next */ []));
1874
+ //#endregion
1875
+ //#region ---- State ----
1876
+ this.promptDraft = signal('', ...(ngDevMode ? [{ debugName: "promptDraft" }] : /* istanbul ignore next */ []));
1877
+ this.busy = signal(false, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
1878
+ this.isComposerSaving = signal(false, ...(ngDevMode ? [{ debugName: "isComposerSaving" }] : /* istanbul ignore next */ []));
1879
+ this.draftAttachmentGroupId = signal(null, ...(ngDevMode ? [{ debugName: "draftAttachmentGroupId" }] : /* istanbul ignore next */ []));
1880
+ this.draftComposerImages = signal([], ...(ngDevMode ? [{ debugName: "draftComposerImages" }] : /* istanbul ignore next */ []));
1881
+ this.draftComposerAudios = signal([], ...(ngDevMode ? [{ debugName: "draftComposerAudios" }] : /* istanbul ignore next */ []));
1882
+ this.draftComposerFiles = signal([], ...(ngDevMode ? [{ debugName: "draftComposerFiles" }] : /* istanbul ignore next */ []));
1883
+ this.assistTargetKey = signal('', ...(ngDevMode ? [{ debugName: "assistTargetKey" }] : /* istanbul ignore next */ []));
1884
+ //#endregion
1885
+ //#region ---- Computed ----
1886
+ this.canSend = computed(() => {
1887
+ if (this.busy() || this.isComposerSaving()) {
1888
+ return false;
1889
+ }
1890
+ const textOk = this.promptDraft().trim().length > 0;
1891
+ const draftImg = this.draftComposerImages();
1892
+ const draftAud = this.draftComposerAudios();
1893
+ const draftFiles = this.draftComposerFiles();
1894
+ const allImagesSaved = draftImg.length === 0 || draftImg.every((s) => Boolean(s.fileId?.trim()));
1895
+ const allAudiosSaved = draftAud.length === 0 || draftAud.every((s) => Boolean(s.fileId?.trim()));
1896
+ const allFilesSaved = draftFiles.length === 0 || draftFiles.every((s) => Boolean(s.fileId?.trim()));
1897
+ if (!allImagesSaved || !allAudiosSaved || !allFilesSaved) {
1898
+ return false;
1899
+ }
1900
+ if (draftImg.length === 0 && draftAud.length === 0 && draftFiles.length === 0) {
1901
+ return textOk;
1902
+ }
1903
+ return textOk || draftImg.length > 0 || draftAud.length > 0 || draftFiles.length > 0;
1904
+ }, ...(ngDevMode ? [{ debugName: "canSend" }] : /* istanbul ignore next */ []));
1905
+ }
1906
+ //#endregion
1907
+ //#region ---- Lifecycle ----
1908
+ async ngOnInit() {
1909
+ this.promptDraft.set(this.initialPrompt().trim());
1910
+ const d = this.initialDirectAgentId()?.trim();
1911
+ const a = this.initialAssistId()?.trim();
1912
+ if (d) {
1913
+ this.assistTargetKey.set(`agent:${d}`);
1914
+ }
1915
+ else if (a) {
1916
+ this.assistTargetKey.set(`assist:${a}`);
1917
+ }
1918
+ else {
1919
+ this.assistTargetKey.set('');
1920
+ }
1921
+ }
1922
+ ngOnDestroy() {
1923
+ for (const s of this.draftComposerImages()) {
1924
+ URL.revokeObjectURL(s.previewUrl);
1925
+ }
1926
+ }
1927
+ //#endregion
1928
+ //#region ---- UI Handlers ----
1929
+ onPromptDraftChange(value) {
1930
+ this.promptDraft.set((value ?? '').toString());
1931
+ }
1932
+ /**
1933
+ * Enter sends; Shift+Enter inserts a newline. IME composition Enter is left unchanged.
1934
+ */
1935
+ onPromptKeydown(event) {
1936
+ if (event.key !== 'Enter' || event.shiftKey || event.isComposing) {
1937
+ return;
1938
+ }
1939
+ event.preventDefault();
1940
+ void this.onSend();
1941
+ }
1942
+ onCancel() {
1943
+ this.requestClose()(null);
1944
+ }
1945
+ onMenuCancel(panel) {
1946
+ panel.close();
1947
+ if (this.busy()) {
1948
+ return;
1949
+ }
1950
+ this.onCancel();
1951
+ }
1952
+ /**
1953
+ * Dismisses the prompt box like Cancel (disabled while a run is in flight, same as footer Cancel).
1954
+ */
1955
+ onDocumentEscape() {
1956
+ if (!isPlatformBrowser(this.platformId) || this.busy()) {
1957
+ return;
1958
+ }
1959
+ this.onCancel();
1960
+ }
1961
+ openImagePicker() {
1962
+ void this.pickComposerImages();
1963
+ }
1964
+ openAudioPicker() {
1965
+ void this.pickComposerAudios();
1966
+ }
1967
+ openDocumentPicker() {
1968
+ void this.pickComposerDocuments();
1969
+ }
1970
+ async onSend() {
1971
+ if (!this.canSend()) {
1972
+ return;
1973
+ }
1974
+ const text = this.promptDraft().trim();
1975
+ const draftImg = this.draftComposerImages();
1976
+ const draftAud = this.draftComposerAudios();
1977
+ const draftFiles = this.draftComposerFiles();
1978
+ for (const s of draftImg) {
1979
+ if (!s.fileId?.trim()) {
1980
+ const errTitle = await this.translation.translateAsync('@general:messages.error.title');
1981
+ const msg = await this.translation.translateAsync('@ai-management:chat.images-still-saving');
1982
+ await this.toastService.show({ color: 'warning', title: errTitle, content: msg });
1983
+ return;
1984
+ }
1985
+ }
1986
+ for (const s of draftAud) {
1987
+ if (!s.fileId?.trim()) {
1988
+ const errTitle = await this.translation.translateAsync('@general:messages.error.title');
1989
+ const msg = await this.translation.translateAsync('@ai-management:chat.audio-still-saving');
1990
+ await this.toastService.show({ color: 'warning', title: errTitle, content: msg });
1991
+ return;
1992
+ }
1993
+ }
1994
+ for (const s of draftFiles) {
1995
+ if (!s.fileId?.trim()) {
1996
+ const errTitle = await this.translation.translateAsync('@general:messages.error.title');
1997
+ const msg = await this.translation.translateAsync('@ai-management:chat.documents-still-saving');
1998
+ await this.toastService.show({ color: 'warning', title: errTitle, content: msg });
1999
+ return;
2000
+ }
2001
+ }
2002
+ const key = this.assistTargetKey().trim();
2003
+ let assistId;
2004
+ let directAgentId;
2005
+ if (key.startsWith('assist:')) {
2006
+ assistId = key.slice('assist:'.length).trim() || undefined;
2007
+ }
2008
+ else if (key.startsWith('agent:')) {
2009
+ directAgentId = key.slice('agent:'.length).trim() || undefined;
2010
+ }
2011
+ const userMediaAttachments = [
2012
+ ...draftImg.map((s) => ({
2013
+ kind: 'image',
2014
+ fileId: s.fileId.trim(),
2015
+ mimeType: s.mimeType.trim(),
2016
+ ...(s.name?.trim() ? { name: s.name.trim() } : {}),
2017
+ })),
2018
+ ...draftAud.map((s) => ({
2019
+ kind: 'audio',
2020
+ fileId: s.fileId.trim(),
2021
+ mimeType: s.mimeType.trim(),
2022
+ ...(s.name?.trim() ? { name: s.name.trim() } : {}),
2023
+ })),
2024
+ ...draftFiles.map((s) => ({
2025
+ kind: 'file',
2026
+ fileId: s.fileId.trim(),
2027
+ mimeType: s.mimeType.trim(),
2028
+ ...(s.name?.trim() ? { name: s.name.trim() } : {}),
2029
+ })),
2030
+ ];
2031
+ const payload = {
2032
+ prompt: text,
2033
+ assistId,
2034
+ directAgentId,
2035
+ userMediaAttachments,
2036
+ };
2037
+ this.busy.set(true);
2038
+ try {
2039
+ const result = await this.runPrompt()(payload);
2040
+ this.requestClose()(result);
2041
+ }
2042
+ catch (err) {
2043
+ const errTitle = await this.translation.translateAsync('@general:messages.error.title');
2044
+ const fallback = await this.translation.translateAsync('@ai-management:assist-popup.run-error');
2045
+ const content = err instanceof Error ? err.message : fallback;
2046
+ await this.toastService.show({ color: 'danger', title: errTitle, content });
2047
+ }
2048
+ finally {
2049
+ this.busy.set(false);
2050
+ }
2051
+ }
2052
+ removeDraftImage(clientId) {
2053
+ const id = clientId.trim();
2054
+ if (!id) {
2055
+ return;
2056
+ }
2057
+ this.draftComposerImages.update((prev) => {
2058
+ const slot = prev.find((s) => s.clientId === id);
2059
+ if (slot) {
2060
+ URL.revokeObjectURL(slot.previewUrl);
2061
+ }
2062
+ const next = prev.filter((s) => s.clientId !== id);
2063
+ if (next.length === 0 &&
2064
+ this.draftComposerAudios().length === 0 &&
2065
+ this.draftComposerFiles().length === 0) {
2066
+ this.draftAttachmentGroupId.set(null);
2067
+ }
2068
+ return next;
2069
+ });
2070
+ }
2071
+ removeDraftAudio(clientId) {
2072
+ const id = clientId.trim();
2073
+ if (!id) {
2074
+ return;
2075
+ }
2076
+ this.draftComposerAudios.update((prev) => {
2077
+ const next = prev.filter((s) => s.clientId !== id);
2078
+ if (next.length === 0 &&
2079
+ this.draftComposerImages().length === 0 &&
2080
+ this.draftComposerFiles().length === 0) {
2081
+ this.draftAttachmentGroupId.set(null);
2082
+ }
2083
+ return next;
2084
+ });
2085
+ }
2086
+ removeDraftFile(clientId) {
2087
+ const id = clientId.trim();
2088
+ if (!id) {
2089
+ return;
2090
+ }
2091
+ this.draftComposerFiles.update((prev) => {
2092
+ const next = prev.filter((s) => s.clientId !== id);
2093
+ if (next.length === 0 &&
2094
+ this.draftComposerImages().length === 0 &&
2095
+ this.draftComposerAudios().length === 0) {
2096
+ this.draftAttachmentGroupId.set(null);
2097
+ }
2098
+ return next;
2099
+ });
2100
+ }
2101
+ //#endregion
2102
+ //#region ---- Composer media (mirrors chat page) ----
2103
+ async pickComposerImages() {
2104
+ if (!isPlatformBrowser(this.platformId)) {
2105
+ return;
2106
+ }
2107
+ if (this.busy() || this.isComposerSaving()) {
2108
+ return;
2109
+ }
2110
+ try {
2111
+ const files = await this.fileService.choose({
2112
+ multiple: true,
2113
+ accept: 'image/*',
2114
+ });
2115
+ if (files.length === 0) {
2116
+ return;
2117
+ }
2118
+ await this.processComposerImageFiles(files);
2119
+ }
2120
+ catch {
2121
+ /* user cancelled */
2122
+ }
2123
+ }
2124
+ async pickComposerAudios() {
2125
+ if (!isPlatformBrowser(this.platformId)) {
2126
+ return;
2127
+ }
2128
+ if (this.busy() || this.isComposerSaving()) {
2129
+ return;
2130
+ }
2131
+ try {
2132
+ const files = await this.fileService.choose({
2133
+ multiple: true,
2134
+ accept: 'audio/*',
2135
+ });
2136
+ if (files.length === 0) {
2137
+ return;
2138
+ }
2139
+ await this.processComposerAudioFiles(files);
2140
+ }
2141
+ catch {
2142
+ /* user cancelled */
2143
+ }
2144
+ }
2145
+ async pickComposerDocuments() {
2146
+ if (!isPlatformBrowser(this.platformId)) {
2147
+ return;
2148
+ }
2149
+ if (this.busy() || this.isComposerSaving()) {
2150
+ return;
2151
+ }
2152
+ try {
2153
+ const files = await this.fileService.choose({
2154
+ multiple: true,
2155
+ accept: '.pdf,.txt,.md,.csv,.tsv,.json,.jsonl,.xml,.html,.htm,.yaml,.yml,.log,.rtf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.odt,.ods,.odp,application/pdf,text/*,application/json',
2156
+ });
2157
+ if (files.length === 0) {
2158
+ return;
2159
+ }
2160
+ await this.processComposerDocumentFiles(files);
2161
+ }
2162
+ catch {
2163
+ /* user cancelled */
2164
+ }
2165
+ }
2166
+ async processComposerImageFiles(files) {
2167
+ if (!isPlatformBrowser(this.platformId)) {
2168
+ return;
2169
+ }
2170
+ let groupId = this.draftAttachmentGroupId();
2171
+ if (!groupId?.trim()) {
2172
+ groupId = globalThis.crypto.randomUUID();
2173
+ this.draftAttachmentGroupId.set(groupId);
2174
+ }
2175
+ const gid = groupId.trim();
2176
+ const existing = this.draftComposerImages().length;
2177
+ if (existing + files.length > AXM_AI_CHAT_COMPOSER_MAX_IMAGES_PER_TURN) {
2178
+ await this.showUploadWarning('@ai-management:chat.upload-too-many');
2179
+ return;
2180
+ }
2181
+ const newSlots = [];
2182
+ const filesForPersist = [];
2183
+ for (const file of files) {
2184
+ if (!axmIsLikelyChatImageFile(file)) {
2185
+ await this.showUploadWarning('@ai-management:chat.upload-invalid-type');
2186
+ return;
2187
+ }
2188
+ if (file.size > AXM_AI_CHAT_COMPOSER_MAX_IMAGE_BYTES) {
2189
+ await this.showUploadWarning('@ai-management:chat.upload-too-large');
2190
+ return;
2191
+ }
2192
+ const mimeType = axmMimeTypeForChatAttachment(file);
2193
+ const fileForStorage = file.type.trim().startsWith('image/') && file.type.trim().length > 0
2194
+ ? file
2195
+ : new File([file], file.name, { type: mimeType });
2196
+ newSlots.push({
2197
+ clientId: globalThis.crypto.randomUUID(),
2198
+ previewUrl: URL.createObjectURL(file),
2199
+ mimeType,
2200
+ name: file.name,
2201
+ });
2202
+ filesForPersist.push(fileForStorage);
2203
+ }
2204
+ this.draftComposerImages.update((prev) => [...prev, ...newSlots]);
2205
+ this.isComposerSaving.set(true);
2206
+ try {
2207
+ for (let i = 0; i < filesForPersist.length; i++) {
2208
+ const file = filesForPersist[i];
2209
+ const clientId = newSlots[i].clientId;
2210
+ try {
2211
+ const { fileId } = await persistAiChatAttachmentImage(this.fileStorage, file, gid);
2212
+ this.draftComposerImages.update((prev) => prev.map((s) => (s.clientId === clientId ? { ...s, fileId } : s)));
2213
+ }
2214
+ catch (e) {
2215
+ const msg = e instanceof Error ? e.message : String(e);
2216
+ this.draftComposerImages.update((prev) => {
2217
+ const slot = prev.find((s) => s.clientId === clientId);
2218
+ if (slot) {
2219
+ URL.revokeObjectURL(slot.previewUrl);
2220
+ }
2221
+ return prev.filter((s) => s.clientId !== clientId);
2222
+ });
2223
+ if (this.draftComposerImages().length === 0 &&
2224
+ this.draftComposerAudios().length === 0 &&
2225
+ this.draftComposerFiles().length === 0) {
2226
+ this.draftAttachmentGroupId.set(null);
2227
+ }
2228
+ const errTitle = await this.translation.translateAsync('@general:messages.error.title');
2229
+ const uploadFailed = await this.translation.translateAsync('@ai-management:chat.upload-error');
2230
+ await this.toastService.show({
2231
+ color: 'danger',
2232
+ title: errTitle,
2233
+ content: `${uploadFailed} ${msg}`,
2234
+ });
2235
+ return;
2236
+ }
2237
+ }
2238
+ }
2239
+ finally {
2240
+ this.isComposerSaving.set(false);
2241
+ }
2242
+ }
2243
+ async processComposerAudioFiles(files) {
2244
+ if (!isPlatformBrowser(this.platformId)) {
2245
+ return;
2246
+ }
2247
+ let groupId = this.draftAttachmentGroupId();
2248
+ if (!groupId?.trim()) {
2249
+ groupId = globalThis.crypto.randomUUID();
2250
+ this.draftAttachmentGroupId.set(groupId);
2251
+ }
2252
+ const gid = groupId.trim();
2253
+ const existing = this.draftComposerAudios().length;
2254
+ if (existing + files.length > AXM_AI_CHAT_COMPOSER_MAX_AUDIO_PER_TURN) {
2255
+ await this.showUploadWarning('@ai-management:chat.upload-audio-too-many');
2256
+ return;
2257
+ }
2258
+ const newSlots = [];
2259
+ const filesForPersist = [];
2260
+ for (const file of files) {
2261
+ if (!axmIsLikelyChatAudioFile(file)) {
2262
+ await this.showUploadWarning('@ai-management:chat.upload-audio-invalid-type');
2263
+ return;
2264
+ }
2265
+ if (file.size > AXM_AI_CHAT_COMPOSER_MAX_AUDIO_BYTES) {
2266
+ await this.showUploadWarning('@ai-management:chat.upload-audio-too-large');
2267
+ return;
2268
+ }
2269
+ const mimeType = axmMimeTypeForChatAttachment(file);
2270
+ const fileForStorage = file.type.trim().startsWith('audio/') && file.type.trim().length > 0
2271
+ ? file
2272
+ : new File([file], file.name, { type: mimeType });
2273
+ newSlots.push({
2274
+ clientId: globalThis.crypto.randomUUID(),
2275
+ mimeType,
2276
+ name: file.name,
2277
+ });
2278
+ filesForPersist.push(fileForStorage);
2279
+ }
2280
+ this.draftComposerAudios.update((prev) => [...prev, ...newSlots]);
2281
+ this.isComposerSaving.set(true);
2282
+ try {
2283
+ for (let i = 0; i < filesForPersist.length; i++) {
2284
+ const file = filesForPersist[i];
2285
+ const clientId = newSlots[i].clientId;
2286
+ try {
2287
+ const { fileId } = await persistAiChatAttachmentImage(this.fileStorage, file, gid);
2288
+ this.draftComposerAudios.update((prev) => prev.map((s) => (s.clientId === clientId ? { ...s, fileId } : s)));
2289
+ }
2290
+ catch (e) {
2291
+ const msg = e instanceof Error ? e.message : String(e);
2292
+ this.draftComposerAudios.update((prev) => prev.filter((s) => s.clientId !== clientId));
2293
+ if (this.draftComposerAudios().length === 0 &&
2294
+ this.draftComposerImages().length === 0 &&
2295
+ this.draftComposerFiles().length === 0) {
2296
+ this.draftAttachmentGroupId.set(null);
2297
+ }
2298
+ const errTitle = await this.translation.translateAsync('@general:messages.error.title');
2299
+ const uploadFailed = await this.translation.translateAsync('@ai-management:chat.upload-audio-error');
2300
+ await this.toastService.show({
2301
+ color: 'danger',
2302
+ title: errTitle,
2303
+ content: `${uploadFailed} ${msg}`,
2304
+ });
2305
+ return;
2306
+ }
2307
+ }
2308
+ }
2309
+ finally {
2310
+ this.isComposerSaving.set(false);
2311
+ }
2312
+ }
2313
+ async processComposerDocumentFiles(files) {
2314
+ if (!isPlatformBrowser(this.platformId)) {
2315
+ return;
2316
+ }
2317
+ let groupId = this.draftAttachmentGroupId();
2318
+ if (!groupId?.trim()) {
2319
+ groupId = globalThis.crypto.randomUUID();
2320
+ this.draftAttachmentGroupId.set(groupId);
2321
+ }
2322
+ const gid = groupId.trim();
2323
+ const existing = this.draftComposerFiles().length;
2324
+ if (existing + files.length > AXM_AI_CHAT_COMPOSER_MAX_DOCUMENTS_PER_TURN) {
2325
+ await this.showUploadWarning('@ai-management:chat.upload-documents-too-many');
2326
+ return;
2327
+ }
2328
+ const newSlots = [];
2329
+ const filesForPersist = [];
2330
+ for (const file of files) {
2331
+ if (!axmIsLikelyChatDocumentFile(file)) {
2332
+ await this.showUploadWarning('@ai-management:chat.upload-documents-invalid-type');
2333
+ return;
2334
+ }
2335
+ if (file.size > AXM_AI_CHAT_COMPOSER_MAX_DOCUMENT_BYTES) {
2336
+ await this.showUploadWarning('@ai-management:chat.upload-documents-too-large');
2337
+ return;
2338
+ }
2339
+ const mimeType = axmMimeTypeForChatAttachment(file);
2340
+ const fileForStorage = file.type.trim().length > 0 && file.type.trim() !== 'application/octet-stream'
2341
+ ? file
2342
+ : new File([file], file.name, { type: mimeType });
2343
+ newSlots.push({
2344
+ clientId: globalThis.crypto.randomUUID(),
2345
+ mimeType,
2346
+ name: file.name,
2347
+ });
2348
+ filesForPersist.push(fileForStorage);
2349
+ }
2350
+ this.draftComposerFiles.update((prev) => [...prev, ...newSlots]);
2351
+ this.isComposerSaving.set(true);
2352
+ try {
2353
+ for (let i = 0; i < filesForPersist.length; i++) {
2354
+ const file = filesForPersist[i];
2355
+ const clientId = newSlots[i].clientId;
2356
+ try {
2357
+ const { fileId } = await persistAiChatAttachmentImage(this.fileStorage, file, gid);
2358
+ this.draftComposerFiles.update((prev) => prev.map((s) => (s.clientId === clientId ? { ...s, fileId } : s)));
2359
+ }
2360
+ catch (e) {
2361
+ const msg = e instanceof Error ? e.message : String(e);
2362
+ this.draftComposerFiles.update((prev) => prev.filter((s) => s.clientId !== clientId));
2363
+ if (this.draftComposerFiles().length === 0 &&
2364
+ this.draftComposerImages().length === 0 &&
2365
+ this.draftComposerAudios().length === 0) {
2366
+ this.draftAttachmentGroupId.set(null);
2367
+ }
2368
+ const errTitle = await this.translation.translateAsync('@general:messages.error.title');
2369
+ const uploadFailed = await this.translation.translateAsync('@ai-management:chat.upload-documents-error');
2370
+ await this.toastService.show({
2371
+ color: 'danger',
2372
+ title: errTitle,
2373
+ content: `${uploadFailed} ${msg}`,
2374
+ });
2375
+ return;
2376
+ }
2377
+ }
2378
+ }
2379
+ finally {
2380
+ this.isComposerSaving.set(false);
2381
+ }
2382
+ }
2383
+ async showUploadWarning(translationKey) {
2384
+ const errTitle = await this.translation.translateAsync('@general:messages.error.title');
2385
+ const content = await this.translation.translateAsync(translationKey);
2386
+ await this.toastService.show({ color: 'warning', title: errTitle, content });
2387
+ }
2388
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiAssistPromptBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2389
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXMAiAssistPromptBoxComponent, isStandalone: true, selector: "axm-ai-assist-prompt-box", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, initialPrompt: { classPropertyName: "initialPrompt", publicName: "initialPrompt", isSignal: true, isRequired: false, transformFunction: null }, contentMaxWidthPx: { classPropertyName: "contentMaxWidthPx", publicName: "contentMaxWidthPx", isSignal: true, isRequired: false, transformFunction: null }, initialAssistId: { classPropertyName: "initialAssistId", publicName: "initialAssistId", isSignal: true, isRequired: false, transformFunction: null }, initialDirectAgentId: { classPropertyName: "initialDirectAgentId", publicName: "initialDirectAgentId", isSignal: true, isRequired: false, transformFunction: null }, runPrompt: { classPropertyName: "runPrompt", publicName: "runPrompt", isSignal: true, isRequired: true, transformFunction: null }, requestClose: { classPropertyName: "requestClose", publicName: "requestClose", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onDocumentEscape()" } }, ngImport: i0, template: "<div class=\"axm-ai-assist-prompt-box ax-flex ax-flex-col ax-gap-2.5 ax-min-h-0 ax-w-full\"\n [style.max-width.px]=\"contentMaxWidthPx()\">\n <div\n class=\"axm-ai-assist-prompt-box__eyebrow ax-flex ax-items-center ax-justify-between ax-gap-3 ax-shrink-0 ax-px-0.5\">\n <div class=\"axm-ai-assist-prompt-box__brand ax-inline-flex ax-min-w-0 ax-items-center ax-gap-2\">\n <span class=\"axm-ai-assist-prompt-box__brand-mark\" aria-hidden=\"true\">\n <i class=\"fa-light fa-sparkles\" aria-hidden=\"true\"></i>\n </span>\n <span class=\"axm-ai-assist-prompt-box__brand-title ax-truncate\">{{ title() }}</span>\n </div>\n <ax-button class=\"ax-shrink-0 ax-xs\" look=\"blank\" color=\"default\" type=\"button\" [iconOnly]=\"true\"\n [disabled]=\"busy()\" [attr.aria-label]=\"('@general:actions.close.title' | translate | async) ?? ''\"\n (onClick)=\"onCancel()\">\n <ax-prefix>\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button>\n </div>\n\n <div class=\"axm-ai-assist-prompt-box__sheet ax-flex ax-min-h-0 ax-flex-col ax-gap-2\">\n @if (\n draftComposerImages().length > 0 ||\n draftComposerAudios().length > 0 ||\n draftComposerFiles().length > 0 ||\n isComposerSaving()\n ) {\n <div\n class=\"ax-shrink-0 ax-rounded-xl ax-border ax-border-default/45 dark:ax-border-darker ax-bg-lightest/90 ax-p-1.5 ax-flex ax-flex-col ax-gap-1.5\"\n [attr.aria-label]=\"('@ai-management:chat.composer-attachments-region' | translate | async) ?? ''\">\n <div class=\"ax-flex ax-flex-wrap ax-items-center ax-justify-between ax-gap-1.5 ax-text-[0.65rem] ax-text-muted\">\n <span>\n @if (isComposerSaving()) {\n {{ '@ai-management:chat.composer-uploading' | translate | async }}\n } @else {\n @if (draftComposerImages().length > 0) {\n <span>{{ draftComposerImages().length }}\n {{ '@ai-management:chat.composer-images-count' | translate | async }}</span>\n }\n @if (draftComposerImages().length > 0 && draftComposerAudios().length > 0) {\n <span class=\"ax-mx-1\">\u00B7</span>\n }\n @if (draftComposerAudios().length > 0) {\n <span>{{ draftComposerAudios().length }}\n {{ '@ai-management:chat.composer-audio-count' | translate | async }}</span>\n }\n @if (draftComposerFiles().length > 0) {\n @if (draftComposerImages().length > 0 || draftComposerAudios().length > 0) {\n <span class=\"ax-mx-1\">\u00B7</span>\n }\n <span>{{ draftComposerFiles().length }}\n {{ '@ai-management:chat.composer-documents-count' | translate | async }}</span>\n }\n }\n </span>\n </div>\n @if (draftComposerImages().length > 0) {\n <div class=\"ax-flex ax-flex-wrap ax-gap-1.5\">\n @for (slot of draftComposerImages(); track slot.clientId) {\n <div\n class=\"ax-relative ax-h-12 ax-w-12 ax-shrink-0 ax-overflow-hidden ax-rounded-md ax-border ax-border-default/60 dark:ax-border-darker ax-bg-lightest\">\n <img [src]=\"slot.previewUrl\" [alt]=\"slot.name ?? ''\" class=\"ax-h-full ax-w-full ax-object-cover\" />\n @if (!slot.fileId) {\n <span\n class=\"ax-absolute ax-inset-0 ax-flex ax-items-center ax-justify-center ax-bg-default/40 ax-text-[0.6rem] ax-font-medium ax-text-on-lightest\">\u2026</span>\n }\n <button type=\"button\"\n class=\"ax-absolute ax-end-0.5 ax-top-0.5 ax-flex ax-h-4 ax-w-4 ax-items-center ax-justify-center ax-rounded ax-bg-default/80 ax-text-[0.65rem] ax-leading-none ax-text-on-lightest hover:ax-bg-default focus-visible:ax-outline-none focus-visible:ax-ring-2 focus-visible:ax-ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"('@ai-management:chat.remove-draft-image' | translate | async) ?? ''\"\n (click)=\"removeDraftImage(slot.clientId)\">\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n @if (draftComposerAudios().length > 0) {\n <div class=\"ax-flex ax-flex-col ax-gap-1\">\n @for (slot of draftComposerAudios(); track slot.clientId) {\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1.5 ax-rounded ax-border ax-border-default/60 dark:ax-border-darker ax-bg-lightest ax-px-1.5 ax-py-1 ax-text-[0.65rem] ax-min-w-0\">\n <span class=\"ax-truncate ax-text-on-lightest\" [attr.title]=\"slot.name ?? ''\">\n {{ '@ai-management:chat.attached-audio-label' | translate | async }}:\n {{ slot.name?.trim() || ('@ai-management:chat.audio-untitled' | translate | async) }}\n </span>\n @if (!slot.fileId) {\n <span class=\"ax-text-muted ax-shrink-0\">\u2026</span>\n }\n <button type=\"button\"\n class=\"ax-shrink-0 ax-flex ax-h-5 ax-w-5 ax-items-center ax-justify-center ax-rounded ax-bg-default/80 ax-text-[0.75rem] ax-leading-none ax-text-on-lightest hover:ax-bg-default focus-visible:ax-outline-none focus-visible:ax-ring-2 focus-visible:ax-ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"('@ai-management:chat.remove-draft-audio' | translate | async) ?? ''\"\n (click)=\"removeDraftAudio(slot.clientId)\">\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n @if (draftComposerFiles().length > 0) {\n <div class=\"ax-flex ax-flex-col ax-gap-1\">\n @for (slot of draftComposerFiles(); track slot.clientId) {\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1.5 ax-rounded ax-border ax-border-default/60 dark:ax-border-darker ax-bg-lightest ax-px-1.5 ax-py-1 ax-text-[0.65rem] ax-min-w-0\">\n <span class=\"ax-truncate ax-text-on-lightest\" [attr.title]=\"slot.name ?? ''\">\n {{ '@ai-management:chat.attached-document-label' | translate | async }}:\n {{ slot.name?.trim() || ('@ai-management:chat.document-untitled' | translate | async) }}\n </span>\n @if (!slot.fileId) {\n <span class=\"ax-text-muted ax-shrink-0\">\u2026</span>\n }\n <button type=\"button\"\n class=\"ax-shrink-0 ax-flex ax-h-5 ax-w-5 ax-items-center ax-justify-center ax-rounded ax-bg-default/80 ax-text-[0.75rem] ax-leading-none ax-text-on-lightest hover:ax-bg-default focus-visible:ax-outline-none focus-visible:ax-ring-2 focus-visible:ax-ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"('@ai-management:chat.remove-draft-document' | translate | async) ?? ''\"\n (click)=\"removeDraftFile(slot.clientId)\">\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"axm-ai-assist-prompt-box__body ax-flex ax-min-h-0 ax-flex-col\">\n <ax-text-area class=\"axm-ai-assist-prompt-box__prompt-input ax-w-full ax-min-h-0\" [rows]=\"3\"\n [disabled]=\"busy()\" [ngModel]=\"promptDraft()\" (ngModelChange)=\"onPromptDraftChange($event)\"\n (keydown)=\"onPromptKeydown($event)\" [placeholder]=\"\n placeholder().trim().length > 0\n ? placeholder()\n : ((('@ai-management:assist-popup.placeholder' | translate | async) ?? ''))\n \"></ax-text-area>\n </div>\n\n <div\n class=\"axm-ai-assist-prompt-box__footer ax-flex ax-shrink-0 ax-items-center ax-justify-between ax-gap-2\">\n <ax-button class=\"axm-ai-assist-prompt-box__menu-trigger\" look=\"solid\" color=\"primary\" type=\"button\"\n [iconOnly]=\"true\" [disabled]=\"busy()\"\n [attr.aria-label]=\"('@ai-management:assist-popup.composer-menu-aria' | translate | async) ?? ''\">\n <ax-prefix>\n <i class=\"fa-light fa-plus ax-text-sm\" aria-hidden=\"true\"></i>\n </ax-prefix>\n <ax-dropdown-panel #composerMenu>\n <ax-button-item-list class=\"ax-min-w-56\">\n <ax-button-item [text]=\"('@ai-management:chat.upload-images' | translate | async) ?? ''\"\n [attr.aria-label]=\"('@ai-management:chat.upload-images-aria' | translate | async) ?? ''\"\n (onClick)=\"openImagePicker(); composerMenu.close()\">\n <ax-prefix>\n <i class=\"fa-light fa-image ax-size-4 ax-text-center\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item [text]=\"('@ai-management:chat.upload-audio' | translate | async) ?? ''\"\n [attr.aria-label]=\"('@ai-management:chat.upload-audio-aria' | translate | async) ?? ''\"\n (onClick)=\"openAudioPicker(); composerMenu.close()\">\n <ax-prefix>\n <i class=\"fa-light fa-microphone ax-size-4 ax-text-center\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item [text]=\"('@ai-management:chat.upload-documents' | translate | async) ?? ''\"\n [attr.aria-label]=\"('@ai-management:chat.upload-documents-aria' | translate | async) ?? ''\"\n (onClick)=\"openDocumentPicker(); composerMenu.close()\">\n <ax-prefix>\n <i class=\"fa-light fa-paperclip ax-size-4 ax-text-center\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n\n <ax-button class=\"axm-ai-assist-prompt-box__send axm-ai-assist-prompt-box__send-gradient\"\n color=\"primary\" type=\"button\" [disabled]=\"busy() || !canSend()\" [text]=\"\n busy()\n ? (('@ai-management:assist-popup.generating' | translate | async) ?? '')\n : (('@ai-management:assist-popup.generate' | translate | async) ?? '')\n \" (onClick)=\"onSend()\"></ax-button>\n </div>\n </div>\n</div>", styles: [".axm-ai-assist-prompt-box-shell{pointer-events:none;box-sizing:border-box;inset:0;width:100%;max-height:100%;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-right:max(.75rem,env(safe-area-inset-right,0px));padding-bottom:max(.75rem,env(safe-area-inset-bottom,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-ai-assist-prompt-box-shell .ax-overlay-pane{pointer-events:auto;border-style:none;background-color:transparent;flex:0 0 auto;width:auto!important;max-width:calc(100vw - 1.5rem);min-width:min(480px,100vw - 1.5rem)}.axm-ai-assist-prompt-box{--axm-ai-assist-prompt-chrome-gradient: linear-gradient(125deg, rgb(var(--ax-sys-color-primary-200)) 0%, rgb(var(--ax-sys-color-primary-400)) 48%, rgb(var(--ax-sys-color-primary-300)) 100%);--axm-ai-assist-prompt-send-gradient: linear-gradient(90deg, rgb(var(--ax-sys-color-primary-500)), rgb(var(--ax-sys-color-primary-700)));box-sizing:border-box;margin:0;max-height:min(78vh,620px);overflow:hidden;padding:.65rem .7rem .7rem;border-radius:1.35rem;background:var(--axm-ai-assist-prompt-chrome-gradient);box-shadow:0 18px 50px -12px rgba(var(--ax-sys-color-on-surface),.12),0 8px 20px -8px rgba(var(--ax-sys-color-primary-400),.2)}.ax-dark .axm-ai-assist-prompt-box,.dark .axm-ai-assist-prompt-box{--axm-ai-assist-prompt-chrome-gradient: linear-gradient(125deg, rgb(var(--ax-sys-color-primary-600)) 0%, rgb(var(--ax-sys-color-primary-500)) 48%, rgb(var(--ax-sys-color-primary-400)) 100%);box-shadow:0 20px 55px -14px rgba(var(--ax-sys-color-dark),.48),0 8px 24px -8px rgba(var(--ax-sys-color-primary-400),.26)}.axm-ai-assist-prompt-box__brand-title{font-size:.72rem;line-height:1.25;font-weight:600;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-surface))}.ax-dark .axm-ai-assist-prompt-box__brand-title{color:rgb(var(--ax-sys-color-on-lightest-surface))}.axm-ai-assist-prompt-box__brand-mark{display:inline-flex;width:1.65rem;height:1.65rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:9999px;font-size:.75rem;line-height:1;color:rgb(var(--ax-sys-color-on-primary-surface));background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)));box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box__sheet{flex:1 1 auto;min-height:0;padding:.65rem .65rem .55rem;border-radius:1rem;background:rgb(var(--ax-sys-color-lightest-surface));border:1px solid rgba(var(--ax-sys-color-neutral-300),.35);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.95)}.ax-dark .axm-ai-assist-prompt-box__sheet{background:rgb(var(--ax-sys-color-neutral-800));border-color:rgba(var(--ax-sys-color-neutral-500),.4);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.06)}.axm-ai-assist-prompt-box__body{overflow-y:auto;min-height:0;flex:1 1 auto}.axm-ai-assist-prompt-box__prompt-input{display:block;width:100%;min-height:0;border:none!important;box-shadow:none!important;background:transparent!important}.axm-ai-assist-prompt-box__prompt-input:focus-within{outline:none!important;border:none!important;box-shadow:none!important}.axm-ai-assist-prompt-box__prompt-input:focus-within>*{border:none!important;box-shadow:none!important;outline:none!important}.axm-ai-assist-prompt-box__prompt-input textarea{min-height:4.5rem;max-height:min(30vh,240px);font-size:.8125rem;line-height:1.45;padding-block:.55rem;padding-inline:.65rem;border-radius:.65rem;border:none!important;box-shadow:none!important;background:transparent!important}.axm-ai-assist-prompt-box__prompt-input textarea:focus,.axm-ai-assist-prompt-box__prompt-input textarea:focus-visible,.axm-ai-assist-prompt-box__prompt-input textarea:active{outline:none!important;outline-offset:0!important;border:none!important;box-shadow:none!important}.ax-dark .axm-ai-assist-prompt-box__prompt-input textarea{color:rgb(var(--ax-sys-color-on-lightest-surface));background:rgb(var(--ax-sys-color-neutral-900))!important}.axm-ai-assist-prompt-box__footer{min-height:0}ax-button.axm-ai-assist-prompt-box__menu-trigger{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;border-radius:9999px!important;overflow:hidden;background:transparent!important;border-color:transparent!important}ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected),ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected){background:transparent!important;background-color:transparent!important;border-color:transparent!important}ax-button.axm-ai-assist-prompt-box__menu-trigger>button{width:2.25rem;height:2.25rem;min-width:2.25rem;min-height:2.25rem;padding:0!important;border-radius:9999px!important;border:none!important;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)))!important;box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-disabled>button,ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-loading>button,ax-button.axm-ai-assist-prompt-box__menu-trigger>button:disabled{opacity:.55;box-shadow:none}ax-button.axm-ai-assist-prompt-box__send-gradient{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;border-radius:9999px!important;overflow:hidden;background:transparent!important;border-color:transparent!important}ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected),ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected){background:transparent!important;background-color:transparent!important;border-color:transparent!important}ax-button.axm-ai-assist-prompt-box__send-gradient>button{min-height:2.25rem;padding-inline:1rem!important;font-size:.8rem;font-weight:600;letter-spacing:.01em;border-radius:9999px!important;border:none!important;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:var(--axm-ai-assist-prompt-send-gradient)!important;box-shadow:0 3px 12px rgba(var(--ax-sys-color-secondary-400),.35)}ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-disabled>button,ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-loading>button,ax-button.axm-ai-assist-prompt-box__send-gradient>button:disabled{opacity:.55;box-shadow:none}ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected)>button{filter:brightness(.94)}ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected)>button{filter:brightness(.88)}ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected)>button{filter:brightness(.96)}ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected)>button{filter:brightness(.9)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i4.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXTextAreaModule }, { kind: "component", type: i5.AXTextAreaComponent, selector: "ax-text-area", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "placeholder", "maxLength", "look", "rows", "allowResize", "showCounter", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2390
+ }
2391
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiAssistPromptBoxComponent, decorators: [{
2392
+ type: Component,
2393
+ args: [{ selector: 'axm-ai-assist-prompt-box', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2394
+ '(document:keydown.escape)': 'onDocumentEscape()',
2395
+ }, imports: [
2396
+ CommonModule,
2397
+ FormsModule,
2398
+ AXButtonModule,
2399
+ AXDecoratorModule,
2400
+ AXDropdownModule,
2401
+ AXDropdownButtonModule,
2402
+ AXTextAreaModule,
2403
+ AXTranslationModule,
2404
+ ], template: "<div class=\"axm-ai-assist-prompt-box ax-flex ax-flex-col ax-gap-2.5 ax-min-h-0 ax-w-full\"\n [style.max-width.px]=\"contentMaxWidthPx()\">\n <div\n class=\"axm-ai-assist-prompt-box__eyebrow ax-flex ax-items-center ax-justify-between ax-gap-3 ax-shrink-0 ax-px-0.5\">\n <div class=\"axm-ai-assist-prompt-box__brand ax-inline-flex ax-min-w-0 ax-items-center ax-gap-2\">\n <span class=\"axm-ai-assist-prompt-box__brand-mark\" aria-hidden=\"true\">\n <i class=\"fa-light fa-sparkles\" aria-hidden=\"true\"></i>\n </span>\n <span class=\"axm-ai-assist-prompt-box__brand-title ax-truncate\">{{ title() }}</span>\n </div>\n <ax-button class=\"ax-shrink-0 ax-xs\" look=\"blank\" color=\"default\" type=\"button\" [iconOnly]=\"true\"\n [disabled]=\"busy()\" [attr.aria-label]=\"('@general:actions.close.title' | translate | async) ?? ''\"\n (onClick)=\"onCancel()\">\n <ax-prefix>\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button>\n </div>\n\n <div class=\"axm-ai-assist-prompt-box__sheet ax-flex ax-min-h-0 ax-flex-col ax-gap-2\">\n @if (\n draftComposerImages().length > 0 ||\n draftComposerAudios().length > 0 ||\n draftComposerFiles().length > 0 ||\n isComposerSaving()\n ) {\n <div\n class=\"ax-shrink-0 ax-rounded-xl ax-border ax-border-default/45 dark:ax-border-darker ax-bg-lightest/90 ax-p-1.5 ax-flex ax-flex-col ax-gap-1.5\"\n [attr.aria-label]=\"('@ai-management:chat.composer-attachments-region' | translate | async) ?? ''\">\n <div class=\"ax-flex ax-flex-wrap ax-items-center ax-justify-between ax-gap-1.5 ax-text-[0.65rem] ax-text-muted\">\n <span>\n @if (isComposerSaving()) {\n {{ '@ai-management:chat.composer-uploading' | translate | async }}\n } @else {\n @if (draftComposerImages().length > 0) {\n <span>{{ draftComposerImages().length }}\n {{ '@ai-management:chat.composer-images-count' | translate | async }}</span>\n }\n @if (draftComposerImages().length > 0 && draftComposerAudios().length > 0) {\n <span class=\"ax-mx-1\">\u00B7</span>\n }\n @if (draftComposerAudios().length > 0) {\n <span>{{ draftComposerAudios().length }}\n {{ '@ai-management:chat.composer-audio-count' | translate | async }}</span>\n }\n @if (draftComposerFiles().length > 0) {\n @if (draftComposerImages().length > 0 || draftComposerAudios().length > 0) {\n <span class=\"ax-mx-1\">\u00B7</span>\n }\n <span>{{ draftComposerFiles().length }}\n {{ '@ai-management:chat.composer-documents-count' | translate | async }}</span>\n }\n }\n </span>\n </div>\n @if (draftComposerImages().length > 0) {\n <div class=\"ax-flex ax-flex-wrap ax-gap-1.5\">\n @for (slot of draftComposerImages(); track slot.clientId) {\n <div\n class=\"ax-relative ax-h-12 ax-w-12 ax-shrink-0 ax-overflow-hidden ax-rounded-md ax-border ax-border-default/60 dark:ax-border-darker ax-bg-lightest\">\n <img [src]=\"slot.previewUrl\" [alt]=\"slot.name ?? ''\" class=\"ax-h-full ax-w-full ax-object-cover\" />\n @if (!slot.fileId) {\n <span\n class=\"ax-absolute ax-inset-0 ax-flex ax-items-center ax-justify-center ax-bg-default/40 ax-text-[0.6rem] ax-font-medium ax-text-on-lightest\">\u2026</span>\n }\n <button type=\"button\"\n class=\"ax-absolute ax-end-0.5 ax-top-0.5 ax-flex ax-h-4 ax-w-4 ax-items-center ax-justify-center ax-rounded ax-bg-default/80 ax-text-[0.65rem] ax-leading-none ax-text-on-lightest hover:ax-bg-default focus-visible:ax-outline-none focus-visible:ax-ring-2 focus-visible:ax-ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"('@ai-management:chat.remove-draft-image' | translate | async) ?? ''\"\n (click)=\"removeDraftImage(slot.clientId)\">\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n @if (draftComposerAudios().length > 0) {\n <div class=\"ax-flex ax-flex-col ax-gap-1\">\n @for (slot of draftComposerAudios(); track slot.clientId) {\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1.5 ax-rounded ax-border ax-border-default/60 dark:ax-border-darker ax-bg-lightest ax-px-1.5 ax-py-1 ax-text-[0.65rem] ax-min-w-0\">\n <span class=\"ax-truncate ax-text-on-lightest\" [attr.title]=\"slot.name ?? ''\">\n {{ '@ai-management:chat.attached-audio-label' | translate | async }}:\n {{ slot.name?.trim() || ('@ai-management:chat.audio-untitled' | translate | async) }}\n </span>\n @if (!slot.fileId) {\n <span class=\"ax-text-muted ax-shrink-0\">\u2026</span>\n }\n <button type=\"button\"\n class=\"ax-shrink-0 ax-flex ax-h-5 ax-w-5 ax-items-center ax-justify-center ax-rounded ax-bg-default/80 ax-text-[0.75rem] ax-leading-none ax-text-on-lightest hover:ax-bg-default focus-visible:ax-outline-none focus-visible:ax-ring-2 focus-visible:ax-ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"('@ai-management:chat.remove-draft-audio' | translate | async) ?? ''\"\n (click)=\"removeDraftAudio(slot.clientId)\">\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n @if (draftComposerFiles().length > 0) {\n <div class=\"ax-flex ax-flex-col ax-gap-1\">\n @for (slot of draftComposerFiles(); track slot.clientId) {\n <div\n class=\"ax-flex ax-items-center ax-justify-between ax-gap-1.5 ax-rounded ax-border ax-border-default/60 dark:ax-border-darker ax-bg-lightest ax-px-1.5 ax-py-1 ax-text-[0.65rem] ax-min-w-0\">\n <span class=\"ax-truncate ax-text-on-lightest\" [attr.title]=\"slot.name ?? ''\">\n {{ '@ai-management:chat.attached-document-label' | translate | async }}:\n {{ slot.name?.trim() || ('@ai-management:chat.document-untitled' | translate | async) }}\n </span>\n @if (!slot.fileId) {\n <span class=\"ax-text-muted ax-shrink-0\">\u2026</span>\n }\n <button type=\"button\"\n class=\"ax-shrink-0 ax-flex ax-h-5 ax-w-5 ax-items-center ax-justify-center ax-rounded ax-bg-default/80 ax-text-[0.75rem] ax-leading-none ax-text-on-lightest hover:ax-bg-default focus-visible:ax-outline-none focus-visible:ax-ring-2 focus-visible:ax-ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"('@ai-management:chat.remove-draft-document' | translate | async) ?? ''\"\n (click)=\"removeDraftFile(slot.clientId)\">\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"axm-ai-assist-prompt-box__body ax-flex ax-min-h-0 ax-flex-col\">\n <ax-text-area class=\"axm-ai-assist-prompt-box__prompt-input ax-w-full ax-min-h-0\" [rows]=\"3\"\n [disabled]=\"busy()\" [ngModel]=\"promptDraft()\" (ngModelChange)=\"onPromptDraftChange($event)\"\n (keydown)=\"onPromptKeydown($event)\" [placeholder]=\"\n placeholder().trim().length > 0\n ? placeholder()\n : ((('@ai-management:assist-popup.placeholder' | translate | async) ?? ''))\n \"></ax-text-area>\n </div>\n\n <div\n class=\"axm-ai-assist-prompt-box__footer ax-flex ax-shrink-0 ax-items-center ax-justify-between ax-gap-2\">\n <ax-button class=\"axm-ai-assist-prompt-box__menu-trigger\" look=\"solid\" color=\"primary\" type=\"button\"\n [iconOnly]=\"true\" [disabled]=\"busy()\"\n [attr.aria-label]=\"('@ai-management:assist-popup.composer-menu-aria' | translate | async) ?? ''\">\n <ax-prefix>\n <i class=\"fa-light fa-plus ax-text-sm\" aria-hidden=\"true\"></i>\n </ax-prefix>\n <ax-dropdown-panel #composerMenu>\n <ax-button-item-list class=\"ax-min-w-56\">\n <ax-button-item [text]=\"('@ai-management:chat.upload-images' | translate | async) ?? ''\"\n [attr.aria-label]=\"('@ai-management:chat.upload-images-aria' | translate | async) ?? ''\"\n (onClick)=\"openImagePicker(); composerMenu.close()\">\n <ax-prefix>\n <i class=\"fa-light fa-image ax-size-4 ax-text-center\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item [text]=\"('@ai-management:chat.upload-audio' | translate | async) ?? ''\"\n [attr.aria-label]=\"('@ai-management:chat.upload-audio-aria' | translate | async) ?? ''\"\n (onClick)=\"openAudioPicker(); composerMenu.close()\">\n <ax-prefix>\n <i class=\"fa-light fa-microphone ax-size-4 ax-text-center\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item [text]=\"('@ai-management:chat.upload-documents' | translate | async) ?? ''\"\n [attr.aria-label]=\"('@ai-management:chat.upload-documents-aria' | translate | async) ?? ''\"\n (onClick)=\"openDocumentPicker(); composerMenu.close()\">\n <ax-prefix>\n <i class=\"fa-light fa-paperclip ax-size-4 ax-text-center\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n\n <ax-button class=\"axm-ai-assist-prompt-box__send axm-ai-assist-prompt-box__send-gradient\"\n color=\"primary\" type=\"button\" [disabled]=\"busy() || !canSend()\" [text]=\"\n busy()\n ? (('@ai-management:assist-popup.generating' | translate | async) ?? '')\n : (('@ai-management:assist-popup.generate' | translate | async) ?? '')\n \" (onClick)=\"onSend()\"></ax-button>\n </div>\n </div>\n</div>", styles: [".axm-ai-assist-prompt-box-shell{pointer-events:none;box-sizing:border-box;inset:0;width:100%;max-height:100%;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-right:max(.75rem,env(safe-area-inset-right,0px));padding-bottom:max(.75rem,env(safe-area-inset-bottom,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-ai-assist-prompt-box-shell .ax-overlay-pane{pointer-events:auto;border-style:none;background-color:transparent;flex:0 0 auto;width:auto!important;max-width:calc(100vw - 1.5rem);min-width:min(480px,100vw - 1.5rem)}.axm-ai-assist-prompt-box{--axm-ai-assist-prompt-chrome-gradient: linear-gradient(125deg, rgb(var(--ax-sys-color-primary-200)) 0%, rgb(var(--ax-sys-color-primary-400)) 48%, rgb(var(--ax-sys-color-primary-300)) 100%);--axm-ai-assist-prompt-send-gradient: linear-gradient(90deg, rgb(var(--ax-sys-color-primary-500)), rgb(var(--ax-sys-color-primary-700)));box-sizing:border-box;margin:0;max-height:min(78vh,620px);overflow:hidden;padding:.65rem .7rem .7rem;border-radius:1.35rem;background:var(--axm-ai-assist-prompt-chrome-gradient);box-shadow:0 18px 50px -12px rgba(var(--ax-sys-color-on-surface),.12),0 8px 20px -8px rgba(var(--ax-sys-color-primary-400),.2)}.ax-dark .axm-ai-assist-prompt-box,.dark .axm-ai-assist-prompt-box{--axm-ai-assist-prompt-chrome-gradient: linear-gradient(125deg, rgb(var(--ax-sys-color-primary-600)) 0%, rgb(var(--ax-sys-color-primary-500)) 48%, rgb(var(--ax-sys-color-primary-400)) 100%);box-shadow:0 20px 55px -14px rgba(var(--ax-sys-color-dark),.48),0 8px 24px -8px rgba(var(--ax-sys-color-primary-400),.26)}.axm-ai-assist-prompt-box__brand-title{font-size:.72rem;line-height:1.25;font-weight:600;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-surface))}.ax-dark .axm-ai-assist-prompt-box__brand-title{color:rgb(var(--ax-sys-color-on-lightest-surface))}.axm-ai-assist-prompt-box__brand-mark{display:inline-flex;width:1.65rem;height:1.65rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:9999px;font-size:.75rem;line-height:1;color:rgb(var(--ax-sys-color-on-primary-surface));background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)));box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box__sheet{flex:1 1 auto;min-height:0;padding:.65rem .65rem .55rem;border-radius:1rem;background:rgb(var(--ax-sys-color-lightest-surface));border:1px solid rgba(var(--ax-sys-color-neutral-300),.35);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.95)}.ax-dark .axm-ai-assist-prompt-box__sheet{background:rgb(var(--ax-sys-color-neutral-800));border-color:rgba(var(--ax-sys-color-neutral-500),.4);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.06)}.axm-ai-assist-prompt-box__body{overflow-y:auto;min-height:0;flex:1 1 auto}.axm-ai-assist-prompt-box__prompt-input{display:block;width:100%;min-height:0;border:none!important;box-shadow:none!important;background:transparent!important}.axm-ai-assist-prompt-box__prompt-input:focus-within{outline:none!important;border:none!important;box-shadow:none!important}.axm-ai-assist-prompt-box__prompt-input:focus-within>*{border:none!important;box-shadow:none!important;outline:none!important}.axm-ai-assist-prompt-box__prompt-input textarea{min-height:4.5rem;max-height:min(30vh,240px);font-size:.8125rem;line-height:1.45;padding-block:.55rem;padding-inline:.65rem;border-radius:.65rem;border:none!important;box-shadow:none!important;background:transparent!important}.axm-ai-assist-prompt-box__prompt-input textarea:focus,.axm-ai-assist-prompt-box__prompt-input textarea:focus-visible,.axm-ai-assist-prompt-box__prompt-input textarea:active{outline:none!important;outline-offset:0!important;border:none!important;box-shadow:none!important}.ax-dark .axm-ai-assist-prompt-box__prompt-input textarea{color:rgb(var(--ax-sys-color-on-lightest-surface));background:rgb(var(--ax-sys-color-neutral-900))!important}.axm-ai-assist-prompt-box__footer{min-height:0}ax-button.axm-ai-assist-prompt-box__menu-trigger{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;border-radius:9999px!important;overflow:hidden;background:transparent!important;border-color:transparent!important}ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected),ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected){background:transparent!important;background-color:transparent!important;border-color:transparent!important}ax-button.axm-ai-assist-prompt-box__menu-trigger>button{width:2.25rem;height:2.25rem;min-width:2.25rem;min-height:2.25rem;padding:0!important;border-radius:9999px!important;border:none!important;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)))!important;box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-disabled>button,ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-loading>button,ax-button.axm-ai-assist-prompt-box__menu-trigger>button:disabled{opacity:.55;box-shadow:none}ax-button.axm-ai-assist-prompt-box__send-gradient{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;border-radius:9999px!important;overflow:hidden;background:transparent!important;border-color:transparent!important}ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected),ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected){background:transparent!important;background-color:transparent!important;border-color:transparent!important}ax-button.axm-ai-assist-prompt-box__send-gradient>button{min-height:2.25rem;padding-inline:1rem!important;font-size:.8rem;font-weight:600;letter-spacing:.01em;border-radius:9999px!important;border:none!important;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:var(--axm-ai-assist-prompt-send-gradient)!important;box-shadow:0 3px 12px rgba(var(--ax-sys-color-secondary-400),.35)}ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-disabled>button,ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-loading>button,ax-button.axm-ai-assist-prompt-box__send-gradient>button:disabled{opacity:.55;box-shadow:none}ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected)>button{filter:brightness(.94)}ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected)>button{filter:brightness(.88)}ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected)>button{filter:brightness(.96)}ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.ax-state-disabled,.ax-state-loading,.ax-state-selected)>button{filter:brightness(.9)}\n"] }]
2405
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], initialPrompt: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialPrompt", required: false }] }], contentMaxWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentMaxWidthPx", required: false }] }], initialAssistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialAssistId", required: false }] }], initialDirectAgentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialDirectAgentId", required: false }] }], runPrompt: [{ type: i0.Input, args: [{ isSignal: true, alias: "runPrompt", required: true }] }], requestClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestClose", required: true }] }] } });
2406
+
2407
+ //#endregion
2408
+ //#region ---- Service ----
2409
+ /**
2410
+ * Opens the AI assist prompt box in a bottom overlay using {@link AXOverlayService} (`centered: false`, panel CSS).
2411
+ */
2412
+ class AXMAiAssistPromptBoxService {
2413
+ constructor() {
2414
+ //#region ---- Services & Dependencies ----
2415
+ this.overlayService = inject(AXOverlayService);
2416
+ //#endregion
2417
+ //#region ---- Private Properties ----
2418
+ this.overlayRef = null;
2419
+ this.pendingResolve = null;
2420
+ this.settled = false;
2421
+ }
2422
+ //#endregion
2423
+ //#region ---- Public Methods ----
2424
+ /**
2425
+ * Presents the assist prompt box and resolves when the user submits, cancels, or dismisses the overlay.
2426
+ */
2427
+ open(options, executeRun) {
2428
+ if (this.pendingResolve) {
2429
+ const superseded = this.pendingResolve;
2430
+ this.pendingResolve = null;
2431
+ superseded(null);
2432
+ }
2433
+ this.disposeOverlayOnly();
2434
+ return new Promise((resolve) => {
2435
+ this.pendingResolve = resolve;
2436
+ this.settled = false;
2437
+ const requestClose = (result) => {
2438
+ this.settle(result);
2439
+ this.overlayRef?.dispose();
2440
+ };
2441
+ void this.overlayService
2442
+ .create(AXMAiAssistPromptBoxComponent, {
2443
+ centered: false,
2444
+ width: 'auto',
2445
+ actionSheetStyle: false,
2446
+ panelClass: ['axm-ai-assist-prompt-box-shell'],
2447
+ backdrop: {
2448
+ enabled: false,
2449
+ background: false,
2450
+ closeOnClick: false,
2451
+ },
2452
+ closeOnEscape: true,
2453
+ closeOnOutsideClick: true,
2454
+ inputs: {
2455
+ title: options.title,
2456
+ placeholder: options.placeholder ?? '',
2457
+ initialPrompt: options.initialPrompt ?? '',
2458
+ initialAssistId: options.assistId,
2459
+ initialDirectAgentId: options.directAgentId,
2460
+ runPrompt: executeRun,
2461
+ requestClose,
2462
+ },
2463
+ onDispose: () => {
2464
+ this.overlayRef = null;
2465
+ if (!this.settled && this.pendingResolve) {
2466
+ this.settle(null);
2467
+ }
2468
+ },
2469
+ })
2470
+ .then((ref) => {
2471
+ this.overlayRef = ref;
2472
+ })
2473
+ .catch(() => {
2474
+ this.settle(null);
2475
+ });
2476
+ });
2477
+ }
2478
+ //#endregion
2479
+ //#region ---- Utility Methods ----
2480
+ settle(result) {
2481
+ if (this.settled) {
2482
+ return;
2483
+ }
2484
+ const done = this.pendingResolve;
2485
+ if (!done) {
2486
+ return;
2487
+ }
2488
+ this.settled = true;
2489
+ this.pendingResolve = null;
2490
+ done(result);
2491
+ }
2492
+ disposeOverlayOnly() {
2493
+ if (this.overlayRef) {
2494
+ this.overlayRef.dispose();
2495
+ this.overlayRef = null;
2496
+ }
2497
+ }
2498
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiAssistPromptBoxService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2499
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiAssistPromptBoxService, providedIn: 'root' }); }
2500
+ }
2501
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiAssistPromptBoxService, decorators: [{
2502
+ type: Injectable,
2503
+ args: [{ providedIn: 'root' }]
2504
+ }] });
2505
+
2506
+ //#region ---- Transcript ----
2507
+ /**
2508
+ * Text segments from the last assistant message (`type: 'text'` only).
2509
+ * Omits `think` and `node` segments so JSON parsing is not polluted by widget envelopes or reasoning blocks stored separately.
2510
+ */
2511
+ function extractLastAssistantTextSegments(messages) {
2512
+ for (let i = messages.length - 1; i >= 0; i--) {
2513
+ const m = messages[i];
2514
+ if (m.role !== 'assistant') {
2515
+ continue;
2516
+ }
2517
+ const parts = [];
2518
+ for (const r of m.responses) {
2519
+ if (r.type === 'text') {
2520
+ parts.push(r.content);
2521
+ }
2522
+ }
2523
+ return parts;
2524
+ }
2525
+ return [];
2526
+ }
2527
+ /**
2528
+ * Combined text for structured JSON extraction (text segments only).
2529
+ */
2530
+ function extractLastAssistantStructuredParts(messages) {
2531
+ const segments = extractLastAssistantTextSegments(messages);
2532
+ const combined = segments.join('\n\n').trim();
2533
+ return { combined, segments };
2534
+ }
2535
+ /**
2536
+ * Concatenated plain text from the last assistant message in the transcript (includes `node` payloads like {@link axpAiChatMessageGetText}).
2537
+ */
2538
+ function extractLastAssistantPlainText(messages) {
2539
+ for (let i = messages.length - 1; i >= 0; i--) {
2540
+ const m = messages[i];
2541
+ if (m.role === 'assistant') {
2542
+ return axpAiChatMessageGetText(m).trim();
2543
+ }
2544
+ }
2545
+ return '';
2546
+ }
2547
+ //#endregion
2548
+
2549
+ //#region ---- Retry prompt ----
2550
+ /**
2551
+ * User follow-up appended to the transcript when structured JSON parse/validation fails.
2552
+ *
2553
+ * @param validationDetail - Parse or schema validation error text.
2554
+ * @param schemaSummary - Optional expected shape (e.g. TypeScript-style) to improve retry quality.
2555
+ * @param failurePhase - Parse failures get stronger anti-truncation wording; validator failures focus on schema/rules.
2556
+ */
2557
+ function buildStructuredOutputRetryUserText(validationDetail, schemaSummary, failurePhase) {
2558
+ const detail = validationDetail.trim() || 'Unknown validation error.';
2559
+ const lines = [
2560
+ 'The previous response could not be parsed or validated:',
2561
+ detail,
2562
+ '',
2563
+ ];
2564
+ if (failurePhase === 'parse') {
2565
+ lines.push('Likely causes: incomplete/truncated JSON, extra prose around the value, or unclosed strings/brackets.', 'Reply with ONE complete JSON value only — fully closed strings, braces, and brackets. Do not stop until the JSON is valid.', '');
2566
+ }
2567
+ else if (failurePhase === 'validator') {
2568
+ lines.push('The JSON was parsed but did not match the required rules or shape. Fix the structure and values; keep the reply as a single JSON value only.', '');
2569
+ }
2570
+ const shape = schemaSummary?.trim();
2571
+ if (shape && shape.length > 0) {
2572
+ lines.push('Expected JSON shape (summary):', shape, '');
2573
+ }
2574
+ lines.push('Return ONLY valid JSON matching the requested structure.', 'Do not include markdown fences or explanations.');
2575
+ return lines.join('\n');
2576
+ }
2577
+ //#endregion
2578
+
2579
+ //#region ---- Parse structured assistant text ----
2580
+ /**
2581
+ * Parses assistant plain text as JSON, supporting optional ```json fences.
2582
+ */
2583
+ function tryParseStructuredAssistantText(text) {
2584
+ const t = text.trim();
2585
+ if (!t) {
2586
+ return undefined;
2587
+ }
2588
+ try {
2589
+ return JSON.parse(t);
2590
+ }
2591
+ catch {
2592
+ const fence = /^```(?:json)?\s*([\s\S]*?)```$/im.exec(t);
2593
+ if (fence?.[1]) {
2594
+ try {
2595
+ return JSON.parse(fence[1].trim());
2596
+ }
2597
+ catch {
2598
+ return undefined;
2599
+ }
2600
+ }
2601
+ return undefined;
2602
+ }
2603
+ }
2604
+ //#endregion
2605
+
2606
+ //#region ---- Imports ----
2607
+ //#endregion
2608
+ //#region ---- Balanced JSON extraction ----
2609
+ function tryParseBalancedJsonObjectAt(s, start) {
2610
+ if (s[start] !== '{') {
2611
+ return null;
2612
+ }
2613
+ let depth = 0;
2614
+ let inString = false;
2615
+ let escape = false;
2616
+ for (let i = start; i < s.length; i++) {
2617
+ const c = s[i];
2618
+ if (inString) {
2619
+ if (escape) {
2620
+ escape = false;
2621
+ continue;
2622
+ }
2623
+ if (c === '\\') {
2624
+ escape = true;
2625
+ continue;
2626
+ }
2627
+ if (c === '"') {
2628
+ inString = false;
2629
+ }
2630
+ continue;
2631
+ }
2632
+ if (c === '"') {
2633
+ inString = true;
2634
+ continue;
2635
+ }
2636
+ if (c === '{') {
2637
+ depth++;
2638
+ }
2639
+ else if (c === '}') {
2640
+ depth--;
2641
+ if (depth === 0) {
2642
+ const slice = s.slice(start, i + 1);
2643
+ try {
2644
+ return { value: JSON.parse(slice), end: i + 1 };
2645
+ }
2646
+ catch {
2647
+ return null;
2648
+ }
2649
+ }
2650
+ }
2651
+ }
2652
+ return null;
2653
+ }
2654
+ function tryParseBalancedJsonArrayAt(s, start) {
2655
+ if (s[start] !== '[') {
2656
+ return null;
2657
+ }
2658
+ let depth = 0;
2659
+ let inString = false;
2660
+ let escape = false;
2661
+ for (let i = start; i < s.length; i++) {
2662
+ const c = s[i];
2663
+ if (inString) {
2664
+ if (escape) {
2665
+ escape = false;
2666
+ continue;
2667
+ }
2668
+ if (c === '\\') {
2669
+ escape = true;
2670
+ continue;
2671
+ }
2672
+ if (c === '"') {
2673
+ inString = false;
2674
+ }
2675
+ continue;
2676
+ }
2677
+ if (c === '"') {
2678
+ inString = true;
2679
+ continue;
2680
+ }
2681
+ if (c === '[') {
2682
+ depth++;
2683
+ }
2684
+ else if (c === ']') {
2685
+ depth--;
2686
+ if (depth === 0) {
2687
+ const slice = s.slice(start, i + 1);
2688
+ try {
2689
+ return { value: JSON.parse(slice), end: i + 1 };
2690
+ }
2691
+ catch {
2692
+ return null;
2693
+ }
2694
+ }
2695
+ }
2696
+ }
2697
+ return null;
2698
+ }
2699
+ /**
2700
+ * Finds first top-level JSON object or array and returns balanced slice text.
2701
+ */
2702
+ function extractFirstBalancedJsonSlice(s) {
2703
+ const iObj = s.indexOf('{');
2704
+ const iArr = s.indexOf('[');
2705
+ let start = -1;
2706
+ let kind = null;
2707
+ if (iObj >= 0 && iArr >= 0) {
2708
+ if (iObj <= iArr) {
2709
+ start = iObj;
2710
+ kind = 'obj';
2711
+ }
2712
+ else {
2713
+ start = iArr;
2714
+ kind = 'arr';
2715
+ }
2716
+ }
2717
+ else if (iObj >= 0) {
2718
+ start = iObj;
2719
+ kind = 'obj';
2720
+ }
2721
+ else if (iArr >= 0) {
2722
+ start = iArr;
2723
+ kind = 'arr';
2724
+ }
2725
+ if (start < 0 || !kind) {
2726
+ return undefined;
2727
+ }
2728
+ const parsed = kind === 'obj' ? tryParseBalancedJsonObjectAt(s, start) : tryParseBalancedJsonArrayAt(s, start);
2729
+ if (!parsed) {
2730
+ return undefined;
2731
+ }
2732
+ return s.slice(start, parsed.end);
2733
+ }
2734
+ //#endregion
2735
+ //#region ---- Lightweight repair ----
2736
+ /**
2737
+ * Removes assistant reasoning tags when they appear inside the text channel (they break JSON extraction).
2738
+ */
2739
+ function stripAssistantThinkingXml(raw) {
2740
+ return raw
2741
+ .replace(/<(?:redacted_thinking|think)\b[^>]*>[\s\S]*?<\/(?:redacted_thinking|think)>/gi, '')
2742
+ .replace(/&lt;\/?(?:redacted_thinking|think)&gt;/gi, '')
2743
+ .trim();
2744
+ }
2745
+ function stripOuterMarkdownFence(s) {
2746
+ const t = s.trim();
2747
+ const fence = /^```(?:json)?\s*([\s\S]*?)```$/im.exec(t);
2748
+ if (fence?.[1]) {
2749
+ return fence[1].trim();
2750
+ }
2751
+ return t;
2752
+ }
2753
+ /** Removes trailing commas before `}` or `]` outside of strings (best-effort for LLM JSON). */
2754
+ function removeTrailingCommasBeforeBrackets(jsonLike) {
2755
+ return jsonLike.replace(/,(\s*[}\]])/g, '$1');
2756
+ }
2757
+ function tryParseJsonLenient(slice) {
2758
+ const t = slice.trim();
2759
+ if (!t) {
2760
+ return undefined;
2761
+ }
2762
+ try {
2763
+ return JSON.parse(t);
2764
+ }
2765
+ catch {
2766
+ try {
2767
+ return JSON.parse(removeTrailingCommasBeforeBrackets(t));
2768
+ }
2769
+ catch {
2770
+ return undefined;
2771
+ }
2772
+ }
2773
+ }
2774
+ /**
2775
+ * Best-effort parse when the model stopped mid-JSON (truncated completion): closes `{` `[` using a delimiter stack
2776
+ * with string awareness. Unsafe inside unclosed strings; last resort after normal repair.
2777
+ */
2778
+ function tryRepairTruncatedJsonWithDelimiterStack(raw) {
2779
+ const s = raw.trim();
2780
+ if (!s.length) {
2781
+ return undefined;
2782
+ }
2783
+ const stack = [];
2784
+ let inStr = false;
2785
+ let esc = false;
2786
+ for (let i = 0; i < s.length; i++) {
2787
+ const c = s[i];
2788
+ if (inStr) {
2789
+ if (esc) {
2790
+ esc = false;
2791
+ continue;
2792
+ }
2793
+ if (c === '\\') {
2794
+ esc = true;
2795
+ continue;
2796
+ }
2797
+ if (c === '"') {
2798
+ inStr = false;
2799
+ }
2800
+ continue;
2801
+ }
2802
+ if (c === '"') {
2803
+ inStr = true;
2804
+ continue;
2805
+ }
2806
+ if (c === '{') {
2807
+ stack.push('{');
2808
+ }
2809
+ else if (c === '[') {
2810
+ stack.push('[');
2811
+ }
2812
+ else if (c === '}') {
2813
+ if (stack.length > 0 && stack[stack.length - 1] === '{') {
2814
+ stack.pop();
2815
+ }
2816
+ }
2817
+ else if (c === ']') {
2818
+ if (stack.length > 0 && stack[stack.length - 1] === '[') {
2819
+ stack.pop();
2820
+ }
2821
+ }
2822
+ }
2823
+ let suffix = '';
2824
+ if (inStr) {
2825
+ suffix = '"';
2826
+ }
2827
+ for (let k = stack.length - 1; k >= 0; k--) {
2828
+ suffix += stack[k] === '{' ? '}' : ']';
2829
+ }
2830
+ if (!suffix.length) {
2831
+ return undefined;
2832
+ }
2833
+ try {
2834
+ return JSON.parse(s + suffix);
2835
+ }
2836
+ catch {
2837
+ return undefined;
2838
+ }
2839
+ }
2840
+ /**
2841
+ * Parses assistant text after cheap local repairs (fences, trailing commas, first JSON value slice).
2842
+ * Does not call the model.
2843
+ */
2844
+ function parseStructuredAssistantWithLocalRepair(raw) {
2845
+ const cleaned = stripAssistantThinkingXml(raw);
2846
+ const direct = tryParseStructuredAssistantText(cleaned);
2847
+ if (direct !== undefined) {
2848
+ return direct;
2849
+ }
2850
+ const stripped = stripOuterMarkdownFence(cleaned);
2851
+ let v = tryParseJsonLenient(stripped);
2852
+ if (v !== undefined) {
2853
+ return v;
2854
+ }
2855
+ const slice = extractFirstBalancedJsonSlice(cleaned) ?? extractFirstBalancedJsonSlice(stripped);
2856
+ if (slice !== undefined) {
2857
+ v = tryParseJsonLenient(slice);
2858
+ if (v !== undefined) {
2859
+ return v;
2860
+ }
2861
+ v = tryRepairTruncatedJsonWithDelimiterStack(slice);
2862
+ if (v !== undefined) {
2863
+ return v;
2864
+ }
2865
+ }
2866
+ v = tryRepairTruncatedJsonWithDelimiterStack(cleaned) ?? tryRepairTruncatedJsonWithDelimiterStack(stripped);
2867
+ if (v !== undefined) {
2868
+ return v;
2869
+ }
2870
+ return undefined;
2871
+ }
2872
+ /**
2873
+ * Tries combined assistant text, then each text segment from last to first (models often put JSON only in the last paragraph).
2874
+ */
2875
+ function parseStructuredAssistantWithSegmentFallback(combined, segments) {
2876
+ let v = parseStructuredAssistantWithLocalRepair(combined);
2877
+ if (v !== undefined) {
2878
+ return v;
2879
+ }
2880
+ const seen = new Set();
2881
+ const mark = stripAssistantThinkingXml(combined).trim();
2882
+ if (mark.length > 0) {
2883
+ seen.add(mark);
2884
+ }
2885
+ for (let i = segments.length - 1; i >= 0; i--) {
2886
+ const seg = stripAssistantThinkingXml(segments[i] ?? '').trim();
2887
+ if (!seg.length || seen.has(seg)) {
2888
+ continue;
2889
+ }
2890
+ seen.add(seg);
2891
+ v = parseStructuredAssistantWithLocalRepair(seg);
2892
+ if (v !== undefined) {
2893
+ return v;
2894
+ }
2895
+ }
2896
+ return undefined;
2897
+ }
2898
+ //#endregion
2899
+
2900
+ //#region ---- Imports ----
2901
+ function hasAnyStructuredContent(combined, segments) {
2902
+ if (combined.trim().length > 0) {
2903
+ return true;
2904
+ }
2905
+ if (!segments?.length) {
2906
+ return false;
2907
+ }
2908
+ return segments.some((s) => (s ?? '').trim().length > 0);
2909
+ }
2910
+ /**
2911
+ * Parses JSON from assistant text (including lightweight local repair), then optionally runs a custom validator.
2912
+ *
2913
+ * @param textSegmentsFallback - When provided, each segment is tried after combined text (last segment first); helps when prose and JSON sit in separate assistant text blocks.
2914
+ */
2915
+ async function validateStructuredAssistantResponse(assistantPlainText, structuredValidator, textSegmentsFallback) {
2916
+ if (!hasAnyStructuredContent(assistantPlainText, textSegmentsFallback)) {
2917
+ return {
2918
+ ok: false,
2919
+ errorMessage: 'Assistant returned empty output.',
2920
+ failurePhase: 'parse',
2921
+ };
2922
+ }
2923
+ const parsed = parseStructuredAssistantWithSegmentFallback(assistantPlainText, textSegmentsFallback ?? []);
2924
+ if (parsed === undefined) {
2925
+ return {
2926
+ ok: false,
2927
+ errorMessage: 'Could not parse assistant output as JSON (expected a JSON object or array; optional markdown fence; segment fallback, local repair, and truncation repair also failed).',
2928
+ failurePhase: 'parse',
2929
+ };
2930
+ }
2931
+ if (!structuredValidator) {
2932
+ return { ok: true, value: parsed };
2933
+ }
2934
+ try {
2935
+ const value = await structuredValidator(parsed);
2936
+ return { ok: true, value };
2937
+ }
2938
+ catch (err) {
2939
+ const msg = err instanceof Error ? err.message : String(err);
2940
+ return {
2941
+ ok: false,
2942
+ errorMessage: msg.trim().length > 0 ? msg : 'Structured validation failed.',
2943
+ failurePhase: 'validator',
2944
+ };
2945
+ }
2946
+ }
2947
+ //#endregion
2948
+
2949
+ //#region ---- Imports ----
2950
+ //#endregion
2951
+ //#region ---- Usage aggregation ----
2952
+ function mergeEngineUsageTotals(acc, next) {
2953
+ if (!acc && !next) {
2954
+ return undefined;
2955
+ }
2956
+ const promptTokens = (acc?.promptTokens ?? 0) + (next?.promptTokens ?? 0);
2957
+ const completionTokens = (acc?.completionTokens ?? 0) + (next?.completionTokens ?? 0);
2958
+ const totalTokens = (acc?.totalTokens ?? 0) + (next?.totalTokens ?? 0);
2959
+ const cachedPromptTokens = (acc?.cachedPromptTokens ?? 0) + (next?.cachedPromptTokens ?? 0);
2960
+ return {
2961
+ promptTokens,
2962
+ completionTokens,
2963
+ totalTokens,
2964
+ ...(cachedPromptTokens > 0 ? { cachedPromptTokens } : {}),
2965
+ };
2966
+ }
2967
+ function engineTotalsToSnapshot(totals) {
2968
+ if (!totals) {
2969
+ return undefined;
2970
+ }
2971
+ return {
2972
+ promptTokens: totals.promptTokens,
2973
+ completionTokens: totals.completionTokens,
2974
+ totalTokens: totals.totalTokens,
2975
+ ...(totals.cachedPromptTokens != null && totals.cachedPromptTokens > 0
2976
+ ? { cachedPromptTokens: totals.cachedPromptTokens }
2977
+ : {}),
2978
+ };
2979
+ }
2980
+ //#endregion
2981
+ //#region ---- Error snapshot ----
2982
+ const STRUCTURED_OUTPUT_ERROR_TEXT_MAX = 8000;
2983
+ function truncateForStructuredOutputError(text) {
2984
+ if (text.length <= STRUCTURED_OUTPUT_ERROR_TEXT_MAX) {
2985
+ return text;
2986
+ }
2987
+ return `${text.slice(0, STRUCTURED_OUTPUT_ERROR_TEXT_MAX)}…`;
2988
+ }
2989
+ /**
2990
+ * Runs the engine, validates JSON (+ optional custom validator), and appends user retry messages on failure.
2991
+ */
2992
+ async function runStructuredOutputPipeline(params) {
2993
+ const maxAttempts = params.retryOnInvalidStructure
2994
+ ? 1 + Math.max(0, params.maxStructuredRetries)
2995
+ : 1;
2996
+ let messages = params.initialMessages;
2997
+ let mergedUsage;
2998
+ let lastProvider;
2999
+ let prevFailureStructuredFingerprint;
3000
+ let prevFailurePhase;
3001
+ const perAttemptUsage = [];
3002
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
3003
+ const result = await params.executeRun(messages);
3004
+ mergedUsage = mergeEngineUsageTotals(mergedUsage, result.usageTotals);
3005
+ if (result.lastProviderResult !== undefined) {
3006
+ lastProvider = result.lastProviderResult;
3007
+ }
3008
+ messages = result.messages;
3009
+ const displayText = extractLastAssistantPlainText(messages);
3010
+ const structuredParts = extractLastAssistantStructuredParts(messages);
3011
+ const structuredFingerprint = stripAssistantThinkingXml(structuredParts.combined).trim();
3012
+ const attemptUsageSnapshot = engineTotalsToSnapshot(result.usageTotals);
3013
+ perAttemptUsage.push({
3014
+ attemptIndex: attempt,
3015
+ usage: attemptUsageSnapshot,
3016
+ hasLastProviderResult: result.lastProviderResult !== undefined,
3017
+ });
3018
+ if (attempt > 1 &&
3019
+ prevFailureStructuredFingerprint !== undefined &&
3020
+ structuredFingerprint === prevFailureStructuredFingerprint &&
3021
+ prevFailurePhase === 'validator') {
3022
+ throw new AXPAiStructuredOutputError({
3023
+ message: 'Assistant returned the same output as the previous attempt while schema validation still failed; stopped to avoid excess token usage.',
3024
+ attempts: attempt,
3025
+ lastAssistantText: truncateForStructuredOutputError(displayText),
3026
+ validationMessage: 'The model repeated identical assistant text after a successful JSON parse; no further retries will be requested for this run.',
3027
+ code: 'duplicate_assistant_output',
3028
+ });
3029
+ }
3030
+ const validation = await validateStructuredAssistantResponse(structuredParts.combined, params.structuredValidator, structuredParts.segments);
3031
+ if (validation.ok) {
3032
+ const structuredRunRaw = {
3033
+ kind: 'structured-output',
3034
+ attempts: perAttemptUsage,
3035
+ totalUsage: engineTotalsToSnapshot(mergedUsage),
3036
+ finalAttempt: attempt,
3037
+ lastProviderResult: lastProvider,
3038
+ };
3039
+ return {
3040
+ text: displayText,
3041
+ structured: validation.value,
3042
+ structuredRunRaw,
3043
+ };
3044
+ }
3045
+ prevFailureStructuredFingerprint = structuredFingerprint;
3046
+ prevFailurePhase = validation.failurePhase;
3047
+ const canRetry = params.retryOnInvalidStructure && attempt < maxAttempts;
3048
+ if (!canRetry) {
3049
+ throw new AXPAiStructuredOutputError({
3050
+ message: `Structured output validation failed after ${attempt} attempt(s).`,
3051
+ attempts: attempt,
3052
+ lastAssistantText: truncateForStructuredOutputError(displayText),
3053
+ validationMessage: validation.errorMessage,
3054
+ code: 'validation_exhausted',
3055
+ });
3056
+ }
3057
+ messages = [
3058
+ ...result.messages,
3059
+ axpAiChatTextMessage('user', buildStructuredOutputRetryUserText(validation.errorMessage, params.structuredOutputSchemaSummary, validation.failurePhase)),
3060
+ ];
3061
+ }
3062
+ throw new AXPAiStructuredOutputError({
3063
+ message: 'Structured output validation failed (unexpected end of retry loop).',
3064
+ attempts: maxAttempts,
3065
+ lastAssistantText: '',
3066
+ validationMessage: 'Unexpected pipeline state.',
3067
+ code: 'validation_exhausted',
3068
+ });
3069
+ }
3070
+ //#endregion
3071
+
3072
+ //#region ---- Imports ----
3073
+ //#endregion
3074
+ //#region ---- Assist prompt run loading dialog ----
3075
+ const AI_ASSIST_RUN_LOADING_DIALOG_CLOSE_DELAY_MS = 200;
3076
+ //#endregion
3077
+ //#region ---- Assist run helpers ----
3078
+ function mergePlatformRuntimeContext(base, notes) {
3079
+ if (!notes || Object.keys(notes).length === 0) {
3080
+ return base;
3081
+ }
3082
+ return { ...base, ...notes };
3083
+ }
3084
+ function buildUserPromptBody(input) {
3085
+ const parts = [];
3086
+ const prompt = input.prompt?.trim() ?? '';
3087
+ if (prompt.length > 0) {
3088
+ parts.push(prompt);
3089
+ }
3090
+ const hints = input.context?.hints?.filter((h) => (h ?? '').toString().trim().length > 0) ?? [];
3091
+ if (hints.length > 0) {
3092
+ parts.push('', 'Hints:', ...hints.map((h) => `- ${String(h).trim()}`));
3093
+ }
3094
+ const structured = input.context?.structuredContext;
3095
+ if (structured !== undefined && structured !== null) {
3096
+ let serialized;
3097
+ try {
3098
+ serialized = typeof structured === 'string' ? structured : JSON.stringify(structured, null, 2);
3099
+ }
3100
+ catch {
3101
+ serialized = String(structured);
3102
+ }
3103
+ parts.push('', 'Context (structured):', serialized);
3104
+ }
3105
+ if (input.expectStructuredOutput) {
3106
+ const extra = input.structuredOutputInstruction?.trim();
3107
+ parts.push('', 'Structured output requirements:', '- Reply with exactly one JSON value (a single object or array). It must be complete and valid: close every string, bracket, and brace.', '- Do not truncate — finish the entire structure in one message.', '- No markdown code fences, no text or commentary before or after the JSON.', ...(extra && extra.length > 0 ? ['', 'Additional output rules from the task:', extra] : []));
3108
+ const schemaSummary = input.structuredOutputSchemaSummary?.trim();
3109
+ if (schemaSummary && schemaSummary.length > 0) {
3110
+ parts.push('', 'Expected JSON shape (summary):', schemaSummary);
3111
+ }
3112
+ }
3113
+ return parts.join('\n').trim();
3114
+ }
3115
+ function buildChatMessages(input) {
3116
+ const messages = [];
3117
+ const systemInstruction = input.context?.systemInstruction?.trim();
3118
+ if (systemInstruction) {
3119
+ messages.push(axpAiChatTextMessage('system', systemInstruction));
3120
+ }
3121
+ const body = buildUserPromptBody(input);
3122
+ const media = (input.userMediaAttachments ?? []).filter((a) => a.fileId?.trim() && a.mimeType?.trim());
3123
+ if (media.length > 0) {
3124
+ const responses = [];
3125
+ for (const a of media) {
3126
+ const fileId = a.fileId.trim();
3127
+ const mimeType = a.mimeType.trim();
3128
+ const name = a.name?.trim();
3129
+ responses.push({
3130
+ type: 'file',
3131
+ content: { fileId, mimeType, ...(name ? { name } : {}) },
3132
+ });
3133
+ }
3134
+ const textBody = body.trim().length > 0 ? body : '(empty prompt)';
3135
+ responses.push({ type: 'text', content: textBody });
3136
+ messages.push(axpAiChatUserMessage(responses));
3137
+ }
3138
+ else {
3139
+ messages.push(axpAiChatTextMessage('user', body.trim().length > 0 ? body : '(empty prompt)'));
3140
+ }
3141
+ return messages;
3142
+ }
3143
+ //#endregion
3144
+ /**
3145
+ * Frontend facade for AI: assist catalog, tenant defaults, engine runs, structured assist runs, and prompt UI.
3146
+ */
3147
+ class AXPAiManagerService extends AXPAiAssistService {
3148
+ constructor() {
3149
+ super(...arguments);
3150
+ //#region ---- Services & Dependencies ----
3151
+ this.aiEngine = inject(AXPAiEngine);
3152
+ this.entityService = inject(AXPEntityService);
3153
+ this.settings = inject(AXPSettingsService);
3154
+ this.runtimeContextBuilder = inject(AXPAiPlatformRuntimeContextBuilder);
3155
+ this.assistPromptBox = inject(AXMAiAssistPromptBoxService);
3156
+ this.localeId = inject(LOCALE_ID);
3157
+ this.loadingDialog = inject(AXLoadingDialogService);
3158
+ this.assistData = this.entityService
3159
+ .withEntity(RootConfig.module.name, RootConfig.entities.assist.name)
3160
+ .data();
3161
+ this.modelEntityData = this.entityService
3162
+ .withEntity(RootConfig.module.name, RootConfig.entities.model.name)
3163
+ .data();
3164
+ this.agentEntityData = this.entityService
3165
+ .withEntity(RootConfig.module.name, RootConfig.entities.agent.name)
3166
+ .data();
3167
+ }
3168
+ //#endregion
3169
+ //#region ---- Assist catalog (frontend) ----
3170
+ /**
3171
+ * Loads the effective assist from `DefaultAssistId` (tenant setting), or the assist named `platform-assistant`.
3172
+ */
3173
+ async getEffectiveAssist() {
3174
+ const raw = await this.settings.get(AXPAiManagementSettings.DefaultAssistId);
3175
+ const assistId = typeof raw === 'string'
3176
+ ? raw.trim()
3177
+ : raw?.value != null
3178
+ ? String(raw.value).trim()
3179
+ : '';
3180
+ if (assistId) {
3181
+ const byId = await this.assistData.byKey(assistId);
3182
+ if (byId) {
3183
+ return byId;
3184
+ }
3185
+ throw new Error(`AI assist with id "${assistId}" was not found. Open AI Management → AI Settings and pick a valid default assist.`);
3186
+ }
3187
+ const queryResult = await this.assistData.query({
3188
+ skip: 0,
3189
+ take: 1,
3190
+ filter: {
3191
+ field: 'name',
3192
+ operator: { type: 'equal' },
3193
+ value: 'platform-assistant',
3194
+ },
3195
+ });
3196
+ const items = (queryResult?.items ?? []);
3197
+ const record = items[0];
3198
+ if (!record) {
3199
+ throw new Error('No default assist is configured. Create an assist named "platform-assistant" or select one under AI Settings.');
3200
+ }
3201
+ return record;
3202
+ }
3203
+ /**
3204
+ * Resolves the assist row for chat: explicit primary key, otherwise the effective default from settings.
3205
+ */
3206
+ async getAssistForChat(assistId) {
3207
+ const id = assistId?.trim();
3208
+ if (id) {
3209
+ const row = await this.assistData.byKey(id);
3210
+ if (!row) {
3211
+ throw new Error(`Assist "${id}" was not found. Open AI Management → Assists or clear the assist id in the chat URL.`);
3212
+ }
3213
+ return row;
3214
+ }
3215
+ return this.getEffectiveAssist();
3216
+ }
3217
+ //#endregion
3218
+ //#region ---- Engine delegation ----
3219
+ /**
3220
+ * Low-level engine run (chat streaming and tool orchestration).
3221
+ */
3222
+ runEngine(options) {
3223
+ return this.aiEngine.run(options);
3224
+ }
3225
+ //#endregion
3226
+ //#region ---- Assist API (run / show) ----
3227
+ /**
3228
+ * Normalizes AiModel.maxOutputTokens from the catalog.
3229
+ */
3230
+ normalizeMaxOutputTokens(value) {
3231
+ if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
3232
+ return undefined;
3233
+ }
3234
+ return Math.floor(value);
3235
+ }
3236
+ /**
3237
+ * Reads {@link AXMAiModelMaxTokensRow.maxOutputTokens} for the model bound to the assist or direct agent.
3238
+ */
3239
+ async resolveCatalogMaxOutputTokens(assistId, directAgentId) {
3240
+ try {
3241
+ if (directAgentId) {
3242
+ const agent = await this.agentEntityData.byKey(directAgentId);
3243
+ const modelEntityId = agent?.modelEntityId?.trim();
3244
+ if (!modelEntityId) {
3245
+ return undefined;
3246
+ }
3247
+ const model = await this.modelEntityData.byKey(modelEntityId);
3248
+ return this.normalizeMaxOutputTokens(model?.maxOutputTokens);
3249
+ }
3250
+ const assist = await this.getAssistForChat(assistId);
3251
+ const modelEntityId = assist.modelId?.trim();
3252
+ if (!modelEntityId) {
3253
+ return undefined;
3254
+ }
3255
+ const model = await this.modelEntityData.byKey(modelEntityId);
3256
+ return this.normalizeMaxOutputTokens(model?.maxOutputTokens);
3257
+ }
3258
+ catch {
3259
+ return undefined;
3260
+ }
3261
+ }
3262
+ /** @inheritdoc */
3263
+ async run(input) {
3264
+ const baseCtx = await this.runtimeContextBuilder.build();
3265
+ const platformRuntimeContext = mergePlatformRuntimeContext(baseCtx, input.platformRuntimeNotes ?? null);
3266
+ const directAgentId = input.directAgentId?.trim();
3267
+ let assistId = input.assistId?.trim();
3268
+ if (!directAgentId && !assistId) {
3269
+ const assist = await this.getEffectiveAssist();
3270
+ assistId = assist.id;
3271
+ }
3272
+ const messages = buildChatMessages(input);
3273
+ const catalogMax = await this.resolveCatalogMaxOutputTokens(assistId, directAgentId);
3274
+ const effectiveMaxTokens = input.maxTokens ?? catalogMax ?? AXPAiAssistDefaultStructuredMaxTokens;
3275
+ const runOptions = {
3276
+ platformRuntimeContext,
3277
+ ...(directAgentId ? { directAgentId } : { assistId: assistId }),
3278
+ ...(input.maxSteps !== undefined ? { maxSteps: input.maxSteps } : {}),
3279
+ ...(input.temperature !== undefined ? { temperature: input.temperature } : {}),
3280
+ maxTokens: effectiveMaxTokens,
3281
+ };
3282
+ if (!input.expectStructuredOutput) {
3283
+ const result = await this.runEngine({ ...runOptions, messages });
3284
+ const text = extractLastAssistantPlainText(result.messages);
3285
+ return {
3286
+ text,
3287
+ raw: { usageTotals: result.usageTotals, lastProviderResult: result.lastProviderResult },
3288
+ };
3289
+ }
3290
+ const retryOnInvalidStructure = input.retryOnInvalidStructure !== false;
3291
+ const maxStructuredRetries = input.maxStructuredRetries ?? AXPAiAssistDefaultMaxStructuredRetries;
3292
+ const structuredMaxTokens = input.structuredOutputMaxTokens ?? effectiveMaxTokens;
3293
+ const pipelineResult = await runStructuredOutputPipeline({
3294
+ initialMessages: messages,
3295
+ executeRun: (nextMessages) => this.runEngine({ ...runOptions, maxTokens: structuredMaxTokens, messages: nextMessages }),
3296
+ maxStructuredRetries,
3297
+ retryOnInvalidStructure,
3298
+ structuredValidator: input.structuredValidator,
3299
+ structuredOutputSchemaSummary: input.structuredOutputSchemaSummary,
3300
+ });
3301
+ return {
3302
+ text: pipelineResult.text,
3303
+ structured: pipelineResult.structured,
3304
+ raw: pipelineResult.structuredRunRaw,
3305
+ };
3306
+ }
3307
+ /** @inheritdoc */
3308
+ async show(options) {
3309
+ const runLoadingSpec = options.runLoadingDialog;
3310
+ const data = await this.assistPromptBox.open(options, async (payload) => {
3311
+ let progressDialog;
3312
+ if (runLoadingSpec) {
3313
+ progressDialog = this.loadingDialog.show({
3314
+ title: runLoadingSpec.title,
3315
+ mode: 'indeterminate',
3316
+ progressColor: 'primary',
3317
+ text: runLoadingSpec.text,
3318
+ });
3319
+ }
3320
+ try {
3321
+ return await this.run({
3322
+ prompt: payload.prompt,
3323
+ userMediaAttachments: payload.userMediaAttachments.length > 0 ? payload.userMediaAttachments : undefined,
3324
+ context: options.context,
3325
+ assistId: payload.assistId,
3326
+ directAgentId: payload.directAgentId,
3327
+ maxSteps: options.maxSteps,
3328
+ temperature: options.temperature,
3329
+ maxTokens: options.maxTokens,
3330
+ expectStructuredOutput: options.expectStructuredOutput,
3331
+ structuredOutputInstruction: options.structuredOutputInstruction,
3332
+ platformRuntimeNotes: options.platformRuntimeNotes,
3333
+ maxStructuredRetries: options.maxStructuredRetries,
3334
+ structuredValidator: options.structuredValidator,
3335
+ retryOnInvalidStructure: options.retryOnInvalidStructure,
3336
+ structuredOutputSchemaSummary: options.structuredOutputSchemaSummary,
3337
+ structuredOutputMaxTokens: options.structuredOutputMaxTokens,
3338
+ });
3339
+ }
3340
+ catch (err) {
3341
+ if (progressDialog !== undefined) {
3342
+ try {
3343
+ progressDialog.setProgressColor('danger');
3344
+ progressDialog.setProgressText(err instanceof Error ? err.message : String(err));
3345
+ }
3346
+ catch {
3347
+ // Ignore dialog update failures.
3348
+ }
3349
+ }
3350
+ throw err;
3351
+ }
3352
+ finally {
3353
+ if (progressDialog !== undefined) {
3354
+ const dlg = progressDialog;
3355
+ setTimeout(() => dlg.close(), AI_ASSIST_RUN_LOADING_DIALOG_CLOSE_DELAY_MS);
3356
+ }
3357
+ }
3358
+ });
3359
+ return data ?? null;
3360
+ }
3361
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiManagerService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
3362
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiManagerService, providedIn: 'root' }); }
3363
+ }
3364
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiManagerService, decorators: [{
3365
+ type: Injectable,
3366
+ args: [{ providedIn: 'root' }]
3367
+ }] });
3368
+
3369
+ //#region ---- Imports ----
3370
+ //#endregion
3371
+ //#region ---- Config ----
3372
+ const AXMAgentRegistryToolConfiguratorWidget = {
3373
+ name: 'agent-registry-tool-configurator',
3374
+ title: 'Agent registry tool (command / query)',
3375
+ icon: 'fa-light fa-screwdriver-wrench',
3376
+ description: 'Select a command or query definition from the platform registry and optionally set default argument values (persisted with the agent).',
3377
+ categories: AXP_WIDGETS_EDITOR_CATEGORY,
3378
+ groups: [AXPWidgetGroupEnum.UtilityWidget],
3379
+ type: 'editor',
3380
+ defaultFilterWidgetName: 'string-filter',
3381
+ properties: [
3382
+ AXP_NAME_PROPERTY,
3383
+ AXP_DATA_PATH_PROPERTY,
3384
+ {
3385
+ name: 'label',
3386
+ title: 'Label',
3387
+ visible: true,
3388
+ group: { name: 'general', title: 'General', order: 1 },
3389
+ schema: {
3390
+ dataType: 'string',
3391
+ defaultValue: '',
3392
+ interface: {
3393
+ path: 'label',
3394
+ type: 'text-box',
3395
+ options: {
3396
+ placeholder: 'Field label',
3397
+ },
3398
+ },
3399
+ },
3400
+ },
3401
+ {
3402
+ name: 'registryKind',
3403
+ title: 'Registry kind',
3404
+ visible: true,
3405
+ group: { name: 'behavior', title: 'Behavior', order: 2 },
3406
+ schema: {
3407
+ dataType: 'string',
3408
+ defaultValue: 'command',
3409
+ interface: {
3410
+ path: 'options.registryKind',
3411
+ type: 'select-editor',
3412
+ options: {
3413
+ items: [
3414
+ { id: 'command', title: 'Command' },
3415
+ { id: 'query', title: 'Query' },
3416
+ ],
3417
+ valueField: 'id',
3418
+ textField: 'title',
3419
+ },
3420
+ },
3421
+ },
3422
+ },
3423
+ {
3424
+ name: 'readonly',
3425
+ title: 'Readonly',
3426
+ visible: true,
3427
+ group: { name: 'behavior', title: 'Behavior', order: 2 },
3428
+ schema: {
3429
+ dataType: 'string',
3430
+ interface: {
3431
+ path: 'options.readonly',
3432
+ type: 'text-box',
3433
+ options: {
3434
+ placeholder: 'true / false / expression',
3435
+ },
3436
+ },
3437
+ },
3438
+ },
3439
+ {
3440
+ name: 'dataSource',
3441
+ title: 'Data source override',
3442
+ visible: true,
3443
+ group: { name: 'data', title: 'Data', order: 3 },
3444
+ schema: {
3445
+ dataType: 'string',
3446
+ interface: {
3447
+ path: 'options.dataSource',
3448
+ type: 'text-box',
3449
+ options: {
3450
+ placeholder: 'Optional; defaults by registry kind',
3451
+ },
3452
+ },
3453
+ },
3454
+ },
3455
+ ],
3456
+ components: {
3457
+ edit: {
3458
+ component: () => import('./acorex-modules-ai-management-agent-registry-tool-configurator-widget-edit.component-C-XsPEIg.mjs').then((c) => c.AXMAgentRegistryToolConfiguratorWidgetEditComponent),
3459
+ },
3460
+ designer: {
3461
+ component: () => import('./acorex-modules-ai-management-agent-registry-tool-configurator-widget-edit.component-C-XsPEIg.mjs').then((c) => c.AXMAgentRegistryToolConfiguratorWidgetEditComponent),
3462
+ },
3463
+ column: {
3464
+ component: () => import('./acorex-modules-ai-management-agent-registry-tool-configurator-widget-column.component-D0ruV6aJ.mjs').then((c) => c.AXMAgentRegistryToolConfiguratorWidgetColumnComponent),
3465
+ },
3466
+ },
3467
+ };
3468
+ //#endregion
3469
+
3470
+ //#region ---- Imports ----
3471
+ //#endregion
3472
+ //#region ---- Config ----
3473
+ const AXMAssistDelegatedAgentConfiguratorWidget = {
3474
+ name: 'assist-delegated-agent-configurator',
3475
+ title: 'Assist Delegated Agent Configurator',
3476
+ icon: 'fa-light fa-user-robot',
3477
+ description: 'Select a delegated agent and configure injected delegated parameters.',
3478
+ categories: AXP_WIDGETS_EDITOR_CATEGORY,
3479
+ groups: [AXPWidgetGroupEnum.UtilityWidget],
3480
+ type: 'editor',
3481
+ defaultFilterWidgetName: 'string-filter',
3482
+ properties: [
3483
+ AXP_NAME_PROPERTY,
3484
+ AXP_DATA_PATH_PROPERTY,
3485
+ {
3486
+ name: 'label',
3487
+ title: 'Label',
3488
+ visible: true,
3489
+ group: { name: 'general', title: 'General', order: 1 },
3490
+ schema: {
3491
+ dataType: 'string',
3492
+ defaultValue: '@ai-management:assists.entities.assist.fields.delegated-agent.title',
3493
+ interface: {
3494
+ path: 'label',
3495
+ type: 'text-box',
3496
+ options: {
3497
+ placeholder: 'Field label',
3498
+ },
3499
+ },
3500
+ },
3501
+ },
3502
+ {
3503
+ name: 'readonly',
3504
+ title: 'Readonly',
3505
+ visible: true,
3506
+ group: { name: 'behavior', title: 'Behavior', order: 2 },
3507
+ schema: {
3508
+ dataType: 'string',
3509
+ interface: {
3510
+ path: 'options.readonly',
3511
+ type: 'text-box',
3512
+ options: {
3513
+ placeholder: 'true / false / expression',
3514
+ },
3515
+ },
3516
+ },
3517
+ },
3518
+ {
3519
+ name: 'dataSource',
3520
+ title: 'Data Source',
3521
+ visible: true,
3522
+ group: { name: 'data', title: 'Data', order: 3 },
3523
+ schema: {
3524
+ dataType: 'string',
3525
+ defaultValue: AI_AGENT_CATALOG_DATASOURCE_NAME,
3526
+ interface: {
3527
+ path: 'options.dataSource',
3528
+ type: 'text-box',
3529
+ },
3530
+ },
3531
+ },
3532
+ ],
3533
+ components: {
3534
+ edit: {
3535
+ component: () => import('./acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-u1hZ4P5s.mjs').then((c) => c.AXMAssistDelegatedAgentConfiguratorWidgetEditComponent),
3536
+ },
3537
+ designer: {
3538
+ component: () => import('./acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-u1hZ4P5s.mjs').then((c) => c.AXMAssistDelegatedAgentConfiguratorWidgetEditComponent),
3539
+ },
3540
+ column: {
3541
+ component: () => import('./acorex-modules-ai-management-assist-delegated-agent-configurator-widget-column.component-DSC48iD0.mjs').then((c) => c.AXMAssistDelegatedAgentConfiguratorWidgetColumnComponent),
3542
+ },
3543
+ },
3544
+ };
3545
+ //#endregion
3546
+
3547
+ //#endregion
3548
+ //#region ---- AI Management Widgets Provider ----
3549
+ const AI_MANAGEMENT_WIDGETS = [
3550
+ AXMAssistDelegatedAgentConfiguratorWidget,
3551
+ AXMAgentRegistryToolConfiguratorWidget,
3552
+ ];
3553
+ class AXMAiManagementWidgetsProvider {
3554
+ getWidgets() {
3555
+ return AI_MANAGEMENT_WIDGETS;
3556
+ }
3557
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementWidgetsProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3558
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementWidgetsProvider }); }
3559
+ }
3560
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementWidgetsProvider, decorators: [{
3561
+ type: Injectable
3562
+ }] });
3563
+
3564
+ //#region ---- Imports ----
3565
+ //#endregion
3566
+ //#region ---- Routes ----
3567
+ function routesFactory() {
3568
+ return [];
3569
+ }
3570
+ //#endregion
3571
+ //#region ---- Module ----
3572
+ class AXMAiManagementModule {
3573
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3574
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementModule, imports: [i1$1.AXPComponentSlotModule, AXPWidgetsModule] }); }
3575
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementModule, providers: [
3576
+ {
3577
+ provide: ROUTES,
3578
+ multi: true,
3579
+ useFactory: routesFactory,
3580
+ },
3581
+ {
3582
+ provide: AXP_ENTITY_DEFINITION_LOADER,
3583
+ useClass: AXMAiManagementEntityProvider,
3584
+ multi: true,
3585
+ },
3586
+ {
3587
+ provide: AXP_MODULE_MANIFEST_PROVIDER,
3588
+ useValue: AiManagementManifest,
3589
+ multi: true,
3590
+ },
3591
+ {
3592
+ provide: AXP_MENU_PROVIDER,
3593
+ useClass: AXMAiManagementMenuProvider,
3594
+ multi: true,
3595
+ },
3596
+ {
3597
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
3598
+ useClass: AXMAiManagementSettingProvider,
3599
+ multi: true,
3600
+ },
3601
+ {
3602
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
3603
+ useClass: AXMAiModelCatalogDataSourceDefinition,
3604
+ multi: true,
3605
+ },
3606
+ {
3607
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
3608
+ useClass: AXMAiAgentCatalogDataSourceDefinition,
3609
+ multi: true,
3610
+ },
3611
+ {
3612
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
3613
+ useClass: AXMAiCommandRegistryCatalogDataSourceDefinition,
3614
+ multi: true,
3615
+ },
3616
+ {
3617
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
3618
+ useClass: AXMAiQueryRegistryCatalogDataSourceDefinition,
3619
+ multi: true,
3620
+ },
3621
+ {
3622
+ provide: AXP_WIDGET_DEFINITION_PROVIDER,
3623
+ useClass: AXMAiManagementWidgetsProvider,
3624
+ multi: true,
3625
+ },
3626
+ {
3627
+ provide: AXP_TAG_PROVIDER,
3628
+ useClass: AXMAiModelPurposeTagProvider,
3629
+ multi: true,
3630
+ },
3631
+ {
3632
+ provide: AXPAiAssistService,
3633
+ useExisting: AXPAiManagerService,
3634
+ },
3635
+ ], imports: [AXPComponentSlotModule.forChild({}),
3636
+ AXPWidgetsModule] }); }
3637
+ }
3638
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMAiManagementModule, decorators: [{
3639
+ type: NgModule,
3640
+ args: [{
3641
+ imports: [
3642
+ AXPComponentSlotModule.forChild({}),
3643
+ AXPWidgetsModule,
3644
+ ],
3645
+ providers: [
3646
+ {
3647
+ provide: ROUTES,
3648
+ multi: true,
3649
+ useFactory: routesFactory,
3650
+ },
3651
+ {
3652
+ provide: AXP_ENTITY_DEFINITION_LOADER,
3653
+ useClass: AXMAiManagementEntityProvider,
3654
+ multi: true,
3655
+ },
3656
+ {
3657
+ provide: AXP_MODULE_MANIFEST_PROVIDER,
3658
+ useValue: AiManagementManifest,
3659
+ multi: true,
3660
+ },
3661
+ {
3662
+ provide: AXP_MENU_PROVIDER,
3663
+ useClass: AXMAiManagementMenuProvider,
3664
+ multi: true,
3665
+ },
3666
+ {
3667
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
3668
+ useClass: AXMAiManagementSettingProvider,
3669
+ multi: true,
3670
+ },
3671
+ {
3672
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
3673
+ useClass: AXMAiModelCatalogDataSourceDefinition,
3674
+ multi: true,
3675
+ },
3676
+ {
3677
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
3678
+ useClass: AXMAiAgentCatalogDataSourceDefinition,
3679
+ multi: true,
3680
+ },
3681
+ {
3682
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
3683
+ useClass: AXMAiCommandRegistryCatalogDataSourceDefinition,
3684
+ multi: true,
3685
+ },
3686
+ {
3687
+ provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
3688
+ useClass: AXMAiQueryRegistryCatalogDataSourceDefinition,
3689
+ multi: true,
3690
+ },
3691
+ {
3692
+ provide: AXP_WIDGET_DEFINITION_PROVIDER,
3693
+ useClass: AXMAiManagementWidgetsProvider,
3694
+ multi: true,
3695
+ },
3696
+ {
3697
+ provide: AXP_TAG_PROVIDER,
3698
+ useClass: AXMAiModelPurposeTagProvider,
3699
+ multi: true,
3700
+ },
3701
+ {
3702
+ provide: AXPAiAssistService,
3703
+ useExisting: AXPAiManagerService,
3704
+ },
3705
+ ],
3706
+ }]
3707
+ }] });
3708
+
3709
+ //#region ---- Delegated agent prompt preview ----
3710
+ function normalizeDelegatedAgentToolArgs(argumentsValue) {
3711
+ if (argumentsValue == null) {
3712
+ return null;
3713
+ }
3714
+ if (typeof argumentsValue === 'object' && !Array.isArray(argumentsValue)) {
3715
+ return { ...argumentsValue };
3716
+ }
3717
+ if (typeof argumentsValue === 'string') {
3718
+ const t = argumentsValue.trim();
3719
+ if (!t) {
3720
+ return null;
3721
+ }
3722
+ try {
3723
+ const p = JSON.parse(t);
3724
+ if (p != null && typeof p === 'object' && !Array.isArray(p)) {
3725
+ return p;
3726
+ }
3727
+ }
3728
+ catch {
3729
+ return null;
3730
+ }
3731
+ }
3732
+ return null;
3733
+ }
3734
+ function formatArgsFallback(argumentsValue) {
3735
+ if (argumentsValue == null) {
3736
+ return '';
3737
+ }
3738
+ if (typeof argumentsValue === 'string') {
3739
+ return argumentsValue;
3740
+ }
3741
+ try {
3742
+ return JSON.stringify(argumentsValue, null, 2);
3743
+ }
3744
+ catch {
3745
+ return String(argumentsValue);
3746
+ }
3747
+ }
3748
+ /**
3749
+ * Human-readable specialist prompt from delegated-agent tool arguments (conversation / mini-chat UI).
3750
+ */
3751
+ function axpAiDelegatedAgentPromptPreview(argumentsValue) {
3752
+ const obj = normalizeDelegatedAgentToolArgs(argumentsValue);
3753
+ if (!obj) {
3754
+ return formatArgsFallback(argumentsValue);
3755
+ }
3756
+ const preferKeys = ['query', 'task', 'prompt', 'message', 'userMessage', 'instruction', 'goal'];
3757
+ for (const k of preferKeys) {
3758
+ const v = obj[k];
3759
+ if (typeof v === 'string' && v.trim()) {
3760
+ return v.trim();
3761
+ }
3762
+ }
3763
+ const keys = Object.keys(obj);
3764
+ if (keys.length === 1) {
3765
+ const only = obj[keys[0]];
3766
+ if (typeof only === 'string' && only.trim()) {
3767
+ return only.trim();
3768
+ }
3769
+ }
3770
+ try {
3771
+ return JSON.stringify(obj, null, 2);
3772
+ }
3773
+ catch {
3774
+ return formatArgsFallback(argumentsValue);
3775
+ }
3776
+ }
3777
+ //#endregion
3778
+
3779
+ //#region ---- AI tool command args ----
3780
+ /**
3781
+ * Recursively parses string values that look like JSON objects or arrays, then
3782
+ * normalizes nested values the same way.
3783
+ *
3784
+ * LLM tool calls often stringify nested payloads (e.g. `__context__` for
3785
+ * `Entity:Create`). Use this before passing args to the command or query service
3786
+ * from AI paths only — not inside generic command infrastructure.
3787
+ *
3788
+ * @param toolName When set, command-specific AI defaults from command definitions are merged (e.g. `Entity:Create` redirect).
3789
+ */
3790
+ function normalizeAiToolCommandArgs(value, toolName) {
3791
+ const normalized = normalizeLikelyJsonStringValuesRecursive(value);
3792
+ return applyAiToolInputDefaultsByCommandName(toolName, normalized);
3793
+ }
3794
+ function normalizeLikelyJsonStringValuesRecursive(value) {
3795
+ if (value === null || value === undefined) {
3796
+ return value;
3797
+ }
3798
+ if (typeof value === 'string') {
3799
+ const trimmed = value.trim();
3800
+ if ((trimmed.startsWith('{') && trimmed.endsWith('}')) ||
3801
+ (trimmed.startsWith('[') && trimmed.endsWith(']'))) {
3802
+ try {
3803
+ const parsed = JSON.parse(trimmed);
3804
+ return normalizeLikelyJsonStringValuesRecursive(parsed);
3805
+ }
3806
+ catch {
3807
+ return value;
3808
+ }
3809
+ }
3810
+ return value;
3811
+ }
3812
+ if (Array.isArray(value)) {
3813
+ return value.map((item) => normalizeLikelyJsonStringValuesRecursive(item));
3814
+ }
3815
+ if (typeof value === 'object') {
3816
+ const obj = value;
3817
+ const out = {};
3818
+ for (const key of Object.keys(obj)) {
3819
+ out[key] = normalizeLikelyJsonStringValuesRecursive(obj[key]);
3820
+ }
3821
+ return out;
3822
+ }
3823
+ return value;
3824
+ }
3825
+ function applyAiToolInputDefaultsByCommandName(toolName, payload) {
3826
+ if (toolName !== 'Entity:Create') {
3827
+ return payload;
3828
+ }
3829
+ return mergeEntityCreateAiToolDefaults(payload);
3830
+ }
3831
+ /** Applies `axpCreateEntityAiToolInputDefaults` so AI flows do not trigger post-create navigation. */
3832
+ function mergeEntityCreateAiToolDefaults(payload) {
3833
+ if (payload == null || typeof payload !== 'object' || Array.isArray(payload)) {
3834
+ return payload;
3835
+ }
3836
+ const p = payload;
3837
+ const ctx = p['__context__'] ?? {};
3838
+ const opts = ctx['options'] ?? {};
3839
+ const proc = opts['process'] ?? {};
3840
+ const defProcess = axpCreateEntityAiToolInputDefaults.__context__.options.process;
3841
+ p['__context__'] = {
3842
+ ...ctx,
3843
+ options: {
3844
+ ...opts,
3845
+ process: {
3846
+ ...proc,
3847
+ ...defProcess,
3848
+ },
3849
+ },
3850
+ };
3851
+ return p;
3852
+ }
3853
+ //#endregion
3854
+
3855
+ //#region ---- Imports ----
3856
+ //#endregion
3857
+ /** Maximum length for assist initial transcript text after HTML strip (characters). */
3858
+ const ASSIST_INITIAL_MESSAGES_MAX_LENGTH = 16_000;
3859
+ //#region ---- HTML / rich text to plain ----
3860
+ /**
3861
+ * Strips HTML tags and decodes a few common entities for safe plain-text transcript lines.
3862
+ * Used for Assist `initialMessages` (may be stored as rich text HTML).
3863
+ */
3864
+ function axpAiStripAssistInitialHtmlToPlain(raw) {
3865
+ let s = raw
3866
+ .replace(/<\/p>\s*(?:<br\s*\/?>\s*)*<p[^>]*>/gi, '\n\n')
3867
+ .replace(/<\/p>\s*<p[^>]*>/gi, '\n\n')
3868
+ .replace(/<br\s*\/?>/gi, '\n');
3869
+ s = s.replace(/<\/(div|h[1-6]|li|tr)>/gi, '\n');
3870
+ s = s.replace(/<[^>]+>/g, '');
3871
+ s = s
3872
+ .replace(/&nbsp;/gi, ' ')
3873
+ .replace(/&amp;/g, '&')
3874
+ .replace(/&lt;/g, '<')
3875
+ .replace(/&gt;/g, '>')
3876
+ .replace(/&quot;/g, '"')
3877
+ .replace(/&#39;/g, "'");
3878
+ s = s.replace(/\r\n/g, '\n').trim();
3879
+ if (s.length > ASSIST_INITIAL_MESSAGES_MAX_LENGTH) {
3880
+ s = s.slice(0, ASSIST_INITIAL_MESSAGES_MAX_LENGTH).trimEnd() + '…';
3881
+ }
3882
+ return s;
3883
+ }
3884
+ //#endregion
3885
+ //#region ---- Transcript messages ----
3886
+ /**
3887
+ * Converts assist `initialMessages` (HTML or plain) into one or more `assistant` transcript lines.
3888
+ * Non-empty paragraphs (split by blank lines) become separate messages; single block stays one message.
3889
+ */
3890
+ function axpAiAssistInitialMessagesToTranscript(raw) {
3891
+ const trimmed = raw?.trim() ?? '';
3892
+ if (!trimmed) {
3893
+ return [];
3894
+ }
3895
+ const plain = axpAiStripAssistInitialHtmlToPlain(trimmed);
3896
+ if (!plain) {
3897
+ return [];
3898
+ }
3899
+ const blocks = plain
3900
+ .split(/\n{2,}/)
3901
+ .map((b) => b.replace(/\n+/g, ' ').trim())
3902
+ .filter((b) => b.length > 0);
3903
+ if (blocks.length === 0) {
3904
+ return [];
3905
+ }
3906
+ return blocks.map((text) => axpAiChatTextMessage('assistant', text));
3907
+ }
3908
+ //#endregion
3909
+
3910
+ /**
3911
+ * Build-time only. Do not import from Angular modules.
3912
+ */
3913
+ /** Generates an image from a text prompt; model resolution: explicit input, then delegated specialist `options.model`, then mock catalog default (OpenAI gpt-image-1). */
3914
+ const AIMANAGEMENT_CHAT_GENERATE_IMAGE_COMMAND_KEY = 'AiManagement:ChatGenerateImage';
3915
+ const aiManagementChatGenerateImageCommandDefinition = defineCommand({
3916
+ key: AIMANAGEMENT_CHAT_GENERATE_IMAGE_COMMAND_KEY,
3917
+ title: 'Generate image (chat)',
3918
+ description: 'Generates an image from a text description. Pass catalog image model id, or use options.model on the image-generation delegated specialist; if both are unset, the mock uses the catalog default image model (OpenAI gpt-image-1). Routing follows the model row (transport and provider).',
3919
+ executionMode: 'both',
3920
+ inputs: [
3921
+ {
3922
+ name: 'model',
3923
+ title: 'Model',
3924
+ description: 'Optional AiModel catalog row id (image purpose). When omitted, uses delegatedAgents[].options.model for the active delegated specialist (agentId in run context), then the mock default image model if still unset.',
3925
+ interface: { name: 'text-editor' },
3926
+ },
3927
+ {
3928
+ name: 'prompt',
3929
+ title: 'Prompt',
3930
+ description: 'Detailed description of the image to generate.',
3931
+ interface: { name: 'text-editor' },
3932
+ validations: [{ rule: 'required' }],
3933
+ },
3934
+ {
3935
+ name: 'size',
3936
+ title: 'Size',
3937
+ description: 'Optional size hint (e.g. 1024x1024). May be ignored.',
3938
+ interface: { name: 'text-editor' },
3939
+ },
3940
+ {
3941
+ name: 'style',
3942
+ title: 'Style',
3943
+ description: 'Optional style hint merged into the prompt by the backend.',
3944
+ interface: { name: 'text-editor' },
3945
+ },
3946
+ ],
3947
+ outputs: [
3948
+ {
3949
+ name: 'fileId',
3950
+ title: 'File id',
3951
+ description: 'Persisted file id when storage succeeds.',
3952
+ interface: { name: 'text-editor' },
3953
+ },
3954
+ {
3955
+ name: 'prompt',
3956
+ title: 'Prompt',
3957
+ description: 'Original prompt text.',
3958
+ interface: { name: 'text-editor' },
3959
+ },
3960
+ {
3961
+ name: 'imageUrl',
3962
+ title: 'Image URL',
3963
+ description: 'Short https or data URL fallback when persistence fails.',
3964
+ interface: { name: 'text-editor' },
3965
+ },
3966
+ ],
3967
+ outcomes: {
3968
+ mode: 'static',
3969
+ values: ['success'],
3970
+ },
3971
+ capabilities: ['ai'],
3972
+ ai: {
3973
+ tags: ['ai-tool', 'ai-chat', 'image'],
3974
+ },
3975
+ categories: [AXP_COMMAND_DEFINITION_CATEGORY_AI_TOOLS],
3976
+ });
3977
+
3978
+ /**
3979
+ * Build-time only. Do not import from Angular modules.
3980
+ */
3981
+ /** Transcribes audio from a stored file; default speech model comes from the delegated specialist row (`delegatedAgents[].options.model`). */
3982
+ const AIMANAGEMENT_CHAT_TRANSCRIBE_SPEECH_COMMAND_KEY = 'AiManagement:ChatTranscribeSpeech';
3983
+ const aiManagementChatTranscribeSpeechCommandDefinition = defineCommand({
3984
+ key: AIMANAGEMENT_CHAT_TRANSCRIBE_SPEECH_COMMAND_KEY,
3985
+ title: 'Transcribe speech (chat)',
3986
+ description: 'Transcribes audio from a platform file id. Pass catalog speech model id or rely on options.model for the speech-to-text delegated specialist on this assist; routing uses the model row (transport and provider).',
3987
+ executionMode: 'both',
3988
+ inputs: [
3989
+ {
3990
+ name: 'model',
3991
+ title: 'Model',
3992
+ description: 'Optional AiModel catalog row id (speech purpose). When omitted, uses delegatedAgents[].options.model for the active delegated specialist (agentId in run context).',
3993
+ interface: { name: 'text-editor' },
3994
+ },
3995
+ {
3996
+ name: 'fileId',
3997
+ title: 'File id',
3998
+ description: 'Platform file storage id for the audio attachment.',
3999
+ interface: { name: 'text-editor' },
4000
+ validations: [{ rule: 'required' }],
4001
+ },
4002
+ {
4003
+ name: 'language',
4004
+ title: 'Language',
4005
+ description: 'Optional BCP-47 language hint (e.g. en) when supported by the provider.',
4006
+ interface: { name: 'text-editor' },
4007
+ },
4008
+ ],
4009
+ outputs: [
4010
+ {
4011
+ name: 'text',
4012
+ title: 'Text',
4013
+ description: 'Transcribed plain text.',
4014
+ interface: { name: 'text-editor' },
4015
+ },
4016
+ ],
4017
+ outcomes: {
4018
+ mode: 'static',
4019
+ values: ['success'],
4020
+ },
4021
+ capabilities: ['ai'],
4022
+ ai: {
4023
+ tags: ['ai-tool', 'ai-chat', 'speech'],
4024
+ },
4025
+ categories: [AXP_COMMAND_DEFINITION_CATEGORY_AI_TOOLS],
4026
+ });
4027
+
4028
+ /**
4029
+ * Build-time only. Do not import from Angular modules.
4030
+ */
4031
+ /** Synthesizes speech audio from text; default TTS model comes from the delegated specialist row (`delegatedAgents[].options.model`). */
4032
+ const AIMANAGEMENT_CHAT_SYNTHESIZE_SPEECH_COMMAND_KEY = 'AiManagement:ChatSynthesizeSpeech';
4033
+ const aiManagementChatSynthesizeSpeechCommandDefinition = defineCommand({
4034
+ key: AIMANAGEMENT_CHAT_SYNTHESIZE_SPEECH_COMMAND_KEY,
4035
+ title: 'Synthesize speech (chat)',
4036
+ description: 'Converts text to spoken audio and stores it in platform file storage. Pass catalog TTS model id or rely on options.model for the text-to-speech delegated specialist on this assist; routing uses the model row (transport and provider).',
4037
+ executionMode: 'both',
4038
+ inputs: [
4039
+ {
4040
+ name: 'model',
4041
+ title: 'Model',
4042
+ description: 'Optional AiModel catalog row id (tts purpose). When omitted, uses delegatedAgents[].options.model for the active delegated specialist (agentId in run context).',
4043
+ interface: { name: 'text-editor' },
4044
+ },
4045
+ {
4046
+ name: 'text',
4047
+ title: 'Text',
4048
+ description: 'Plain text to speak (provider input length limits apply, e.g. OpenAI 4096 characters).',
4049
+ interface: { name: 'text-editor' },
4050
+ validations: [{ rule: 'required' }],
4051
+ },
4052
+ {
4053
+ name: 'voice',
4054
+ title: 'Voice',
4055
+ description: 'Optional OpenAI voice id: alloy, echo, fable, onyx, nova, shimmer. When omitted, uses delegatedAgents[].options.voice or alloy.',
4056
+ interface: { name: 'text-editor' },
4057
+ },
4058
+ {
4059
+ name: 'responseFormat',
4060
+ title: 'Response format',
4061
+ description: 'Optional audio format for OpenAI (mp3, opus, aac, flac, wav, pcm). Default mp3.',
4062
+ interface: { name: 'text-editor' },
4063
+ },
4064
+ ],
4065
+ outputs: [
4066
+ {
4067
+ name: 'fileId',
4068
+ title: 'File id',
4069
+ description: 'Persisted audio file id when storage succeeds.',
4070
+ interface: { name: 'text-editor' },
4071
+ },
4072
+ {
4073
+ name: 'text',
4074
+ title: 'Text',
4075
+ description: 'Source text that was synthesized.',
4076
+ interface: { name: 'text-editor' },
4077
+ },
4078
+ {
4079
+ name: 'mimeType',
4080
+ title: 'MIME type',
4081
+ description: 'Audio MIME type of the stored file.',
4082
+ interface: { name: 'text-editor' },
4083
+ },
4084
+ ],
4085
+ outcomes: {
4086
+ mode: 'static',
4087
+ values: ['success'],
4088
+ },
4089
+ capabilities: ['ai'],
4090
+ ai: {
4091
+ tags: ['ai-tool', 'ai-chat', 'tts'],
4092
+ },
4093
+ categories: [AXP_COMMAND_DEFINITION_CATEGORY_AI_TOOLS],
4094
+ });
4095
+
4096
+ /**
4097
+ * Build-time only. Do not import from Angular modules.
4098
+ */
4099
+ const AIMANAGEMENT_EXTRACT_DOCUMENT_TEXT_COMMAND_KEY = 'AiManagement:ExtractDocumentText';
4100
+ const aiManagementExtractDocumentTextCommandDefinition = defineCommand({
4101
+ key: AIMANAGEMENT_EXTRACT_DOCUMENT_TEXT_COMMAND_KEY,
4102
+ title: 'Extract text from document image',
4103
+ description: 'Transcribes visible text from an image stored in platform file storage (scans, photos of documents, forms, including medical paperwork). Uses the active chat model’s vision capability. Output is informational transcription only—not clinical interpretation.',
4104
+ executionMode: 'both',
4105
+ inputs: [
4106
+ {
4107
+ name: 'fileId',
4108
+ title: 'File id',
4109
+ description: 'Platform file storage id for the image (same as chat image attachments). Supported formats follow the active vision model (e.g. PNG, JPEG, WEBP).',
4110
+ interface: { name: 'text-editor' },
4111
+ validations: [{ rule: 'required' }],
4112
+ },
4113
+ {
4114
+ name: 'instruction',
4115
+ title: 'Instruction',
4116
+ description: 'Optional extra instructions (e.g. language, focus on lab values only, preserve table layout).',
4117
+ interface: { name: 'text-editor' },
4118
+ },
4119
+ ],
4120
+ outputs: [
4121
+ {
4122
+ name: 'text',
4123
+ title: 'Extracted text',
4124
+ description: 'Transcribed text with structure preserved where possible.',
4125
+ interface: { name: 'text-editor' },
4126
+ },
4127
+ ],
4128
+ outcomes: {
4129
+ mode: 'static',
4130
+ values: ['success'],
4131
+ },
4132
+ capabilities: ['ai'],
4133
+ ai: {
4134
+ shortDescription: 'OCR-style transcription from an image file id using the chat vision model; preserves layout; no medical diagnosis.',
4135
+ tags: ['ai-tool', 'ai-chat', 'ocr', 'vision', 'document', 'multimodal'],
4136
+ },
4137
+ categories: [AXP_COMMAND_DEFINITION_CATEGORY_AI_TOOLS],
4138
+ });
4139
+
4140
+ /**
4141
+ * Build-time only. Do not import from Angular modules.
4142
+ */
4143
+ const AIMANAGEMENT_STRUCTURED_TEXT_COMPLETION_COMMAND_KEY = 'AiManagement:StructuredTextCompletion';
4144
+ const aiManagementStructuredTextCompletionCommandDefinition = defineCommand({
4145
+ key: AIMANAGEMENT_STRUCTURED_TEXT_COMPLETION_COMMAND_KEY,
4146
+ title: 'Structured text completion',
4147
+ description: 'Single-turn chat completion without tools (e.g. map OCR text to JSON). Uses the resolved assist model.',
4148
+ executionMode: 'both',
4149
+ inputs: [],
4150
+ outputs: [
4151
+ {
4152
+ name: 'text',
4153
+ title: 'Assistant text',
4154
+ description: 'Plain text from the model.',
4155
+ interface: { name: 'large-text-editor' },
4156
+ },
4157
+ ],
4158
+ outcomes: {
4159
+ mode: 'static',
4160
+ values: ['success'],
4161
+ },
4162
+ capabilities: ['ai'],
4163
+ ai: {
4164
+ shortDescription: 'Tool-free structured completion for metadata mapping and similar tasks.',
4165
+ tags: ['ai-tool', 'ai-chat', 'completion'],
4166
+ },
4167
+ categories: [AXP_COMMAND_DEFINITION_CATEGORY_AI_TOOLS],
4168
+ });
4169
+
4170
+ //#region ---- AI chat registry command keys (re-exports) ----
4171
+ //#endregion
4172
+
4173
+ //#region ---- Imports ----
4174
+ /**
4175
+ * Per chat run: stores which assist and chat transport are active.
4176
+ * Injected commands (e.g. image generation) read this instead of receiving assist/transport inside tool args.
4177
+ */
4178
+ class AXPAiChatToolRunContextService {
4179
+ constructor() {
4180
+ this.runContext = signal(null, ...(ngDevMode ? [{ debugName: "runContext" }] : /* istanbul ignore next */ []));
4181
+ }
4182
+ setContext(ctx) {
4183
+ this.runContext.set(ctx);
4184
+ }
4185
+ getContext() {
4186
+ return this.runContext();
4187
+ }
4188
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiChatToolRunContextService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4189
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiChatToolRunContextService, providedIn: 'root' }); }
4190
+ }
4191
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiChatToolRunContextService, decorators: [{
4192
+ type: Injectable,
4193
+ args: [{ providedIn: 'root' }]
4194
+ }] });
4195
+
4196
+ //#region ---- Imports ----
4197
+ //#endregion
4198
+ //#region ---- LLM JSON Schema overrides ----
4199
+ /**
4200
+ * Registry rows map inputs to string-typed JSON schemas. Override parameters for AI chat tools
4201
+ * so models receive accurate types (arrays, booleans, nested objects).
4202
+ */
4203
+ function getAiChatCommandLlmParametersOverride(commandName) {
4204
+ switch (commandName) {
4205
+ case AIMANAGEMENT_CHAT_GENERATE_IMAGE_COMMAND_KEY:
4206
+ return {
4207
+ type: 'object',
4208
+ properties: {
4209
+ model: {
4210
+ type: 'string',
4211
+ description: 'Optional catalog AiModel row id for image generation. Omit to use options.model on the image delegated specialist row.',
4212
+ },
4213
+ prompt: {
4214
+ type: 'string',
4215
+ description: 'Detailed text description of the image to generate.',
4216
+ },
4217
+ size: {
4218
+ type: 'string',
4219
+ description: 'Optional size hint for backends that support it (e.g. 1024x1024). May be ignored.',
4220
+ },
4221
+ style: {
4222
+ type: 'string',
4223
+ description: 'Optional style hint (e.g. photorealistic, flat vector). May be merged into the prompt by the backend.',
4224
+ },
4225
+ },
4226
+ required: ['prompt'],
4227
+ };
4228
+ case AIMANAGEMENT_CHAT_TRANSCRIBE_SPEECH_COMMAND_KEY:
4229
+ return {
4230
+ type: 'object',
4231
+ properties: {
4232
+ model: {
4233
+ type: 'string',
4234
+ description: 'Optional catalog AiModel row id for speech-to-text. Omit to use options.model on the speech delegated specialist row.',
4235
+ },
4236
+ fileId: {
4237
+ type: 'string',
4238
+ description: 'Platform file storage id for the audio file to transcribe.',
4239
+ },
4240
+ language: {
4241
+ type: 'string',
4242
+ description: 'Optional language hint (e.g. en) when supported by the provider.',
4243
+ },
4244
+ },
4245
+ required: ['fileId'],
4246
+ };
4247
+ case AIMANAGEMENT_CHAT_SYNTHESIZE_SPEECH_COMMAND_KEY:
4248
+ return {
4249
+ type: 'object',
4250
+ properties: {
4251
+ model: {
4252
+ type: 'string',
4253
+ description: 'Optional catalog AiModel row id for text-to-speech (purpose tts). Omit to use options.model on the TTS delegated specialist row.',
4254
+ },
4255
+ text: {
4256
+ type: 'string',
4257
+ description: 'Plain text to convert to speech.',
4258
+ },
4259
+ voice: {
4260
+ type: 'string',
4261
+ description: 'Optional OpenAI voice (alloy, echo, fable, onyx, nova, shimmer). Omit to use options.voice or alloy.',
4262
+ },
4263
+ responseFormat: {
4264
+ type: 'string',
4265
+ description: 'Optional audio format: mp3, opus, aac, flac, wav, pcm. Default mp3.',
4266
+ },
4267
+ },
4268
+ required: ['text'],
4269
+ };
4270
+ default:
4271
+ return null;
4272
+ }
4273
+ }
4274
+ //#endregion
4275
+
4276
+ //#region ---- Imports ----
4277
+ //#endregion
4278
+ /**
4279
+ * Lists chat-purpose AI models (catalog), without using {@link AXPAiEngine}.
4280
+ */
4281
+ class AXPAiAssistChatModelCatalogService {
4282
+ constructor() {
4283
+ //#region ---- Services & Dependencies ----
4284
+ this.entityService = inject(AXPEntityService);
4285
+ this.localeId = inject(LOCALE_ID);
4286
+ this.modelData = this.entityService
4287
+ .withEntity(RootConfig.module.name, RootConfig.entities.model.name)
4288
+ .data();
4289
+ this.openAiEndpointData = this.entityService
4290
+ .withEntity(RootConfig.module.name, RootConfig.entities.openAiEndpoint.name)
4291
+ .data();
4292
+ }
4293
+ //#endregion
4294
+ //#region ---- Public API ----
4295
+ /**
4296
+ * All active chat-purpose models in the catalog (assist / agent policy is applied at engine runtime).
4297
+ */
4298
+ async listModels(_request) {
4299
+ const queryResult = await this.modelData.query({
4300
+ skip: 0,
4301
+ take: 500,
4302
+ });
4303
+ const items = (queryResult?.items ?? []);
4304
+ let rows = items.filter((x) => isChatPurposeModelRow(x));
4305
+ rows = await this.filterModelsActiveForChat(rows);
4306
+ return rows.map((x) => ({
4307
+ id: x.id,
4308
+ name: x.name?.trim() ?? '',
4309
+ title: resolveMultiLanguageString((x.title ?? x.name ?? x.id), this.localeId).trim() || x.id,
4310
+ modelPurposes: normalizeModelPurposes(x),
4311
+ chatTransport: x.chatTransport,
4312
+ maxContextTokens: typeof x.maxContextTokens === 'number' && x.maxContextTokens > 0
4313
+ ? x.maxContextTokens
4314
+ : undefined,
4315
+ inputPricePerMillion: typeof x.inputPricePerMillion === 'number' && x.inputPricePerMillion > 0
4316
+ ? x.inputPricePerMillion
4317
+ : undefined,
4318
+ outputPricePerMillion: typeof x.outputPricePerMillion === 'number' && x.outputPricePerMillion > 0
4319
+ ? x.outputPricePerMillion
4320
+ : undefined,
4321
+ cachedInputPricePerMillion: typeof x.cachedInputPricePerMillion === 'number' && x.cachedInputPricePerMillion > 0
4322
+ ? x.cachedInputPricePerMillion
4323
+ : undefined,
4324
+ }));
4325
+ }
4326
+ //#endregion
4327
+ //#region ---- Model filtering ----
4328
+ /**
4329
+ * Chat pickers only use models that are enabled and backed by an enabled OpenAI endpoint when applicable.
4330
+ */
4331
+ async filterModelsActiveForChat(rows) {
4332
+ const endpointIds = [
4333
+ ...new Set(rows
4334
+ .filter((r) => String(r.chatTransport ?? '').toLowerCase() === 'openai' && r.openAiEndpointId?.trim())
4335
+ .map((r) => r.openAiEndpointId.trim())),
4336
+ ];
4337
+ const endpointDisabled = new Map();
4338
+ for (const id of endpointIds) {
4339
+ const ep = await this.openAiEndpointData.byKey(id);
4340
+ endpointDisabled.set(id, ep?.isDisabled === true);
4341
+ }
4342
+ return rows.filter((x) => {
4343
+ if (x.isDisabled === true) {
4344
+ return false;
4345
+ }
4346
+ if (x.openAiEndpointIsDisabled === true) {
4347
+ return false;
4348
+ }
4349
+ const transport = String(x.chatTransport ?? '').toLowerCase();
4350
+ if (transport === 'openai' && x.openAiEndpointId?.trim()) {
4351
+ if (endpointDisabled.get(x.openAiEndpointId.trim()) === true) {
4352
+ return false;
4353
+ }
4354
+ }
4355
+ return true;
4356
+ });
4357
+ }
4358
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiAssistChatModelCatalogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4359
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiAssistChatModelCatalogService, providedIn: 'root' }); }
4360
+ }
4361
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiAssistChatModelCatalogService, decorators: [{
4362
+ type: Injectable,
4363
+ args: [{ providedIn: 'root' }]
4364
+ }] });
4365
+
4366
+ //#region ---- Imports ----
4367
+ //#endregion
4368
+ //#region ---- Service ----
4369
+ class AXPAiDefaultModelPickerService {
4370
+ constructor() {
4371
+ //#region ---- Services & Dependencies ----
4372
+ this.settings = inject(AXPSettingsService);
4373
+ }
4374
+ //#endregion
4375
+ //#region ---- Public API ----
4376
+ /**
4377
+ * Reads the tenant setting for the given catalog purpose (catalog `AiModel` row id, or empty).
4378
+ */
4379
+ async getTenantDefaultModelIdForPurpose(purpose) {
4380
+ const key = settingKeyForPurpose(purpose);
4381
+ const raw = await this.settings.get(key);
4382
+ const id = typeof raw === 'string' ? raw.trim() : '';
4383
+ return id || undefined;
4384
+ }
4385
+ /**
4386
+ * Picks a model from chat/vision catalog candidates:
4387
+ * tenant default when it matches an entry and supports the purpose; otherwise first candidate
4388
+ * that supports the purpose; otherwise the first candidate.
4389
+ */
4390
+ pickFromChatCatalogForPurpose(models, purpose, tenantPreferredId) {
4391
+ if (!models.length) {
4392
+ return undefined;
4393
+ }
4394
+ const preferred = tenantPreferredId?.trim();
4395
+ if (preferred) {
4396
+ const match = models.find((m) => m.id === preferred);
4397
+ if (match && modelItemSupportsChatCatalogPurpose(match, purpose)) {
4398
+ return match;
4399
+ }
4400
+ }
4401
+ const byPurpose = models.find((m) => modelItemSupportsChatCatalogPurpose(m, purpose));
4402
+ if (byPurpose) {
4403
+ return byPurpose;
4404
+ }
4405
+ return models[0];
4406
+ }
4407
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiDefaultModelPickerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4408
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiDefaultModelPickerService, providedIn: 'root' }); }
4409
+ }
4410
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAiDefaultModelPickerService, decorators: [{
4411
+ type: Injectable,
4412
+ args: [{ providedIn: 'root' }]
4413
+ }] });
4414
+ //#endregion
4415
+ //#region ---- Helpers ----
4416
+ function settingKeyForPurpose(purpose) {
4417
+ switch (purpose) {
4418
+ case 'chat':
4419
+ return AXPAiManagementSettings.DefaultModelChat;
4420
+ case 'vision':
4421
+ return AXPAiManagementSettings.DefaultModelVision;
4422
+ case 'image':
4423
+ return AXPAiManagementSettings.DefaultModelImage;
4424
+ case 'speech':
4425
+ return AXPAiManagementSettings.DefaultModelSpeech;
4426
+ case 'tts':
4427
+ return AXPAiManagementSettings.DefaultModelTts;
4428
+ }
4429
+ }
4430
+ function modelItemSupportsChatCatalogPurpose(m, purpose) {
4431
+ const p = m.modelPurposes?.length ? m.modelPurposes : [];
4432
+ if (purpose === 'vision') {
4433
+ return p.includes('vision');
4434
+ }
4435
+ return p.includes('chat');
4436
+ }
4437
+
4438
+ /**
4439
+ * Generated bundle index. Do not edit.
4440
+ */
4441
+
4442
+ export { AIMANAGEMENT_CHAT_GENERATE_IMAGE_COMMAND_KEY, AIMANAGEMENT_CHAT_SYNTHESIZE_SPEECH_COMMAND_KEY, AIMANAGEMENT_CHAT_TRANSCRIBE_SPEECH_COMMAND_KEY, AIMANAGEMENT_EXTRACT_DOCUMENT_TEXT_COMMAND_KEY, AIMANAGEMENT_STRUCTURED_TEXT_COMPLETION_COMMAND_KEY, AI_AGENT_CATALOG_DATASOURCE_NAME, AI_CHAT_ATTACHMENT_CATEGORY, AI_CHAT_ATTACHMENT_REF_TYPE, AI_CHAT_GENERATED_IMAGE_REF_TYPE, AI_CHAT_GENERATED_SPEECH_REF_TYPE, AI_COMMAND_REGISTRY_CATALOG_DATASOURCE_NAME, AI_GENERATED_IMAGE_MAX_REMOTE_URL_IN_TOOL, AI_MODEL_CATALOG_DATASOURCE_NAME, AI_MODEL_IMAGE_CATALOG_DATASOURCE_NAME, AI_MODEL_SPEECH_CATALOG_DATASOURCE_NAME, AI_MODEL_TTS_CATALOG_DATASOURCE_NAME, AI_QUERY_REGISTRY_CATALOG_DATASOURCE_NAME, AXMAiAgentCatalogDataSourceDefinition, AXMAiAssistPromptBoxComponent, AXMAiAssistPromptBoxService, AXMAiCommandRegistryCatalogDataSourceDefinition, AXMAiManagementEntityProvider, AXMAiManagementMenuProvider, AXMAiManagementModule, AXMAiModelCatalogDataSourceDefinition, AXMAiQueryRegistryCatalogDataSourceDefinition, AXPAI_DELEGATED_AGENT_DEFAULT_MAX_STEPS, AXPAI_DOCUMENT_VISION_DEFAULT_USER_INSTRUCTION, AXPAI_DOCUMENT_VISION_EXTRACTION_SYSTEM, AXPAI_ENGINE_DEFAULT_MAX_STEPS, AXPAI_SUPERVISOR_AGENT_TOOL_PREFIX, AXPAiAssistChatModelCatalogService, AXPAiAssistDefaultMaxStructuredRetries, AXPAiAssistDefaultStructuredMaxTokens, AXPAiAssistService, AXPAiChatToolRunContextService, AXPAiDefaultModelPickerService, AXPAiEngine, AXPAiManagementMenuKeys, AXPAiManagementSettings, AXPAiManagerService, AXPAiPlatformRuntimeContextBuilder, AXPAiStructuredOutputError, AiManagementManifest, RootConfig, axpAiAssistInitialMessagesToTranscript, axpAiChatAgentResultMessage, axpAiChatDelegatedReflectionAssistantMessage, axpAiChatMessageGetText, axpAiChatMessageIsDelegatedReflectionExcluded, axpAiChatMessagesFromProviderAssistant, axpAiChatTextMessage, axpAiChatToolOrAgentResultBodyJson, axpAiChatToolResultBodyJson, axpAiChatToolResultMessage, axpAiChatUserMessage, axpAiCoercePlanningAssistantTextToThink, axpAiCollectDelegatedAgentOutcomeResponses, axpAiDelegatedAgentOutcomeResponsesPlainText, axpAiDelegatedAgentPromptPreview, axpAiDelegatedSubTranscriptAppendFileArtifactFromToolResults, axpAiExtractLastStoredFileArtifactFromChatMessages, axpAiExtractStoredFileArtifactFromUnknown, axpAiMergePlainAssistantTextTurn, axpAiNormalizeHandlerResultToToolBody, axpAiParseDelegatedAgentResultSegmentsFromUnknown, axpAiParseSupervisorAgentToolName, axpAiPruneAssistantPiecesToFirstToolOnly, axpAiStripAssistInitialHtmlToPlain, axpAiSupervisorAgentToolName, axpAiToolCallFromAssistantToolMessage, blobOrFileFromImageResult, getAiChatCommandLlmParametersOverride, isChatPurposeModelRow, isImagePurposeModelRow, isSpeechPurposeModelRow, isTtsPurposeModelRow, modelRowHasPurpose, normalizeAiToolCommandArgs, normalizeModelPurposes, persistAiChatAttachmentImage, persistAiGeneratedImage, persistAiGeneratedSpeech };
2
4443
  //# sourceMappingURL=acorex-modules-ai-management.mjs.map