@memberjunction/ng-core-entity-forms 6.1.4 → 6.2.0-edge.1

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 (327) hide show
  1. package/README.md +22 -0
  2. package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.d.ts +1 -1
  3. package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.js +2 -2
  4. package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.js.map +1 -1
  5. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
  6. package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts +90 -16
  7. package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
  8. package/dist/lib/custom/AIAgents/add-action-dialog.component.js +218 -70
  9. package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
  10. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts +80 -16
  11. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts.map +1 -1
  12. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js +146 -46
  13. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js.map +1 -1
  14. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +329 -27
  15. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
  16. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +794 -262
  17. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  18. package/dist/lib/custom/AIAgents/ai-agent-management.service.d.ts +76 -0
  19. package/dist/lib/custom/AIAgents/ai-agent-management.service.d.ts.map +1 -1
  20. package/dist/lib/custom/AIAgents/ai-agent-management.service.js +77 -33
  21. package/dist/lib/custom/AIAgents/ai-agent-management.service.js.map +1 -1
  22. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts +69 -15
  23. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts.map +1 -1
  24. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js +182 -74
  25. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js.map +1 -1
  26. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts +105 -25
  27. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts.map +1 -1
  28. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +272 -112
  29. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
  30. package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts +32 -6
  31. package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts.map +1 -1
  32. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +71 -19
  33. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
  34. package/dist/lib/custom/AIAgents/new-agent-dialog.service.d.ts +10 -0
  35. package/dist/lib/custom/AIAgents/new-agent-dialog.service.d.ts.map +1 -1
  36. package/dist/lib/custom/AIAgents/new-agent-dialog.service.js +27 -7
  37. package/dist/lib/custom/AIAgents/new-agent-dialog.service.js.map +1 -1
  38. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts +65 -15
  39. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts.map +1 -1
  40. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +152 -52
  41. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
  42. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts +81 -15
  43. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts.map +1 -1
  44. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js +145 -45
  45. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js.map +1 -1
  46. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +71 -17
  47. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
  48. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +175 -67
  49. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
  50. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts +173 -27
  51. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts.map +1 -1
  52. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +385 -93
  53. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
  54. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.d.ts +64 -4
  55. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.d.ts.map +1 -1
  56. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +129 -29
  57. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js.map +1 -1
  58. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts +260 -27
  59. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts.map +1 -1
  60. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +686 -238
  61. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
  62. package/dist/lib/custom/AIPrompts/ai-prompt-management.service.d.ts +10 -0
  63. package/dist/lib/custom/AIPrompts/ai-prompt-management.service.d.ts.map +1 -1
  64. package/dist/lib/custom/AIPrompts/ai-prompt-management.service.js +17 -9
  65. package/dist/lib/custom/AIPrompts/ai-prompt-management.service.js.map +1 -1
  66. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts +74 -16
  67. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts.map +1 -1
  68. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js +174 -58
  69. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js.map +1 -1
  70. package/dist/lib/custom/Actions/action-execution-log-form.component.d.ts +108 -14
  71. package/dist/lib/custom/Actions/action-execution-log-form.component.d.ts.map +1 -1
  72. package/dist/lib/custom/Actions/action-execution-log-form.component.js +258 -70
  73. package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
  74. package/dist/lib/custom/Actions/action-form.component.d.ts +198 -14
  75. package/dist/lib/custom/Actions/action-form.component.d.ts.map +1 -1
  76. package/dist/lib/custom/Actions/action-form.component.js +387 -107
  77. package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
  78. package/dist/lib/custom/BridgeProviders/bridge-provider-features.d.ts +12 -6
  79. package/dist/lib/custom/BridgeProviders/bridge-provider-features.d.ts.map +1 -1
  80. package/dist/lib/custom/BridgeProviders/bridge-provider-features.js +41 -29
  81. package/dist/lib/custom/BridgeProviders/bridge-provider-features.js.map +1 -1
  82. package/dist/lib/custom/BridgeProviders/bridge-provider-form.component.js +14 -14
  83. package/dist/lib/custom/BridgeProviders/bridge-provider-form.component.js.map +1 -1
  84. package/dist/lib/custom/Companies/company-overview.panel.d.ts +1 -1
  85. package/dist/lib/custom/Companies/company-overview.panel.js +2 -2
  86. package/dist/lib/custom/Companies/company-overview.panel.js.map +1 -1
  87. package/dist/lib/custom/Conversations/conversation-overview.panel.d.ts +1 -1
  88. package/dist/lib/custom/Conversations/conversation-overview.panel.js +2 -2
  89. package/dist/lib/custom/Conversations/conversation-overview.panel.js.map +1 -1
  90. package/dist/lib/custom/Employees/employee-overview.panel.d.ts +1 -1
  91. package/dist/lib/custom/Employees/employee-overview.panel.js +2 -2
  92. package/dist/lib/custom/Employees/employee-overview.panel.js.map +1 -1
  93. package/dist/lib/custom/Entities/entity-form.component.d.ts +209 -28
  94. package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
  95. package/dist/lib/custom/Entities/entity-form.component.js +494 -138
  96. package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
  97. package/dist/lib/custom/EntityActions/entityaction.form.component.d.ts +5 -1
  98. package/dist/lib/custom/EntityActions/entityaction.form.component.d.ts.map +1 -1
  99. package/dist/lib/custom/EntityActions/entityaction.form.component.js +10 -2
  100. package/dist/lib/custom/EntityActions/entityaction.form.component.js.map +1 -1
  101. package/dist/lib/custom/Files/file-form.component.d.ts +1 -1
  102. package/dist/lib/custom/Files/file-form.component.js +2 -2
  103. package/dist/lib/custom/Files/file-form.component.js.map +1 -1
  104. package/dist/lib/custom/Lists/list-form.component.d.ts +300 -36
  105. package/dist/lib/custom/Lists/list-form.component.d.ts.map +1 -1
  106. package/dist/lib/custom/Lists/list-form.component.js +664 -208
  107. package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
  108. package/dist/lib/custom/MLModels/ml-model-form.component.d.ts +27 -0
  109. package/dist/lib/custom/MLModels/ml-model-form.component.d.ts.map +1 -0
  110. package/dist/lib/custom/MLModels/ml-model-form.component.js +193 -0
  111. package/dist/lib/custom/MLModels/ml-model-form.component.js.map +1 -0
  112. package/dist/lib/custom/MLModels/ml-model-view-models.d.ts +75 -0
  113. package/dist/lib/custom/MLModels/ml-model-view-models.d.ts.map +1 -0
  114. package/dist/lib/custom/MLModels/ml-model-view-models.js +244 -0
  115. package/dist/lib/custom/MLModels/ml-model-view-models.js.map +1 -0
  116. package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts +173 -0
  117. package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts.map +1 -0
  118. package/dist/lib/custom/MLModels/ps-model-detail.component.js +883 -0
  119. package/dist/lib/custom/MLModels/ps-model-detail.component.js.map +1 -0
  120. package/dist/lib/custom/Queries/query-form.component.d.ts +201 -26
  121. package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
  122. package/dist/lib/custom/Queries/query-form.component.js +429 -109
  123. package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
  124. package/dist/lib/custom/Queries/query-run-dialog.component.d.ts +107 -14
  125. package/dist/lib/custom/Queries/query-run-dialog.component.d.ts.map +1 -1
  126. package/dist/lib/custom/Queries/query-run-dialog.component.js +249 -79
  127. package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
  128. package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts +133 -7
  129. package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts.map +1 -1
  130. package/dist/lib/custom/RecordProcesses/record-process-form.component.js +1268 -19
  131. package/dist/lib/custom/RecordProcesses/record-process-form.component.js.map +1 -1
  132. package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts +1 -1
  133. package/dist/lib/custom/SearchScopes/searchscope-form.component.js +4 -4
  134. package/dist/lib/custom/SearchScopes/searchscope-form.component.js.map +1 -1
  135. package/dist/lib/custom/SessionBridges/session-bridge-form.component.js.map +1 -1
  136. package/dist/lib/custom/Templates/template-param-dialog.component.d.ts +77 -13
  137. package/dist/lib/custom/Templates/template-param-dialog.component.d.ts.map +1 -1
  138. package/dist/lib/custom/Templates/template-param-dialog.component.js +196 -78
  139. package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
  140. package/dist/lib/custom/Templates/template-params-grid.component.d.ts +49 -7
  141. package/dist/lib/custom/Templates/template-params-grid.component.d.ts.map +1 -1
  142. package/dist/lib/custom/Templates/template-params-grid.component.js +132 -44
  143. package/dist/lib/custom/Templates/template-params-grid.component.js.map +1 -1
  144. package/dist/lib/custom/Templates/templates-form.component.d.ts +142 -17
  145. package/dist/lib/custom/Templates/templates-form.component.d.ts.map +1 -1
  146. package/dist/lib/custom/Templates/templates-form.component.js +333 -113
  147. package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
  148. package/dist/lib/custom/Tests/entity-link-pill.component.d.ts +24 -4
  149. package/dist/lib/custom/Tests/entity-link-pill.component.d.ts.map +1 -1
  150. package/dist/lib/custom/Tests/entity-link-pill.component.js +64 -20
  151. package/dist/lib/custom/Tests/entity-link-pill.component.js.map +1 -1
  152. package/dist/lib/custom/Tests/test-form.component.d.ts +217 -27
  153. package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
  154. package/dist/lib/custom/Tests/test-form.component.js +549 -169
  155. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  156. package/dist/lib/custom/Tests/test-run-checks.d.ts +2 -0
  157. package/dist/lib/custom/Tests/test-run-checks.d.ts.map +1 -1
  158. package/dist/lib/custom/Tests/test-run-checks.js +5 -1
  159. package/dist/lib/custom/Tests/test-run-checks.js.map +1 -1
  160. package/dist/lib/custom/Tests/test-run-feedback-form.component.d.ts +2 -0
  161. package/dist/lib/custom/Tests/test-run-feedback-form.component.d.ts.map +1 -1
  162. package/dist/lib/custom/Tests/test-run-feedback-form.component.js +5 -1
  163. package/dist/lib/custom/Tests/test-run-feedback-form.component.js.map +1 -1
  164. package/dist/lib/custom/Tests/test-run-form.component.d.ts +146 -18
  165. package/dist/lib/custom/Tests/test-run-form.component.d.ts.map +1 -1
  166. package/dist/lib/custom/Tests/test-run-form.component.js +362 -106
  167. package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
  168. package/dist/lib/custom/Tests/test-suite-form.component.d.ts +390 -47
  169. package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
  170. package/dist/lib/custom/Tests/test-suite-form.component.js +1015 -343
  171. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  172. package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts +214 -26
  173. package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts.map +1 -1
  174. package/dist/lib/custom/Tests/test-suite-run-form.component.js +535 -159
  175. package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
  176. package/dist/lib/custom/Users/user-overview.panel.d.ts +1 -1
  177. package/dist/lib/custom/Users/user-overview.panel.js +2 -2
  178. package/dist/lib/custom/Users/user-overview.panel.js.map +1 -1
  179. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts +208 -29
  180. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts.map +1 -1
  181. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +446 -138
  182. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
  183. package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.d.ts +6 -0
  184. package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.d.ts.map +1 -1
  185. package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js +16 -4
  186. package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js.map +1 -1
  187. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts +50 -6
  188. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts.map +1 -1
  189. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js +84 -12
  190. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js.map +1 -1
  191. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts +89 -5
  192. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts.map +1 -1
  193. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +216 -70
  194. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -1
  195. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.d.ts +62 -3
  196. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.d.ts.map +1 -1
  197. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js +140 -42
  198. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js.map +1 -1
  199. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts +81 -10
  200. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts.map +1 -1
  201. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +165 -37
  202. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
  203. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +121 -14
  204. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
  205. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +287 -79
  206. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
  207. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts +101 -15
  208. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts.map +1 -1
  209. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js +281 -97
  210. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js.map +1 -1
  211. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts +43 -25
  212. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts.map +1 -1
  213. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js +100 -64
  214. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js.map +1 -1
  215. package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts +14 -2
  216. package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts.map +1 -1
  217. package/dist/lib/custom/ai-agent-run/flow/constellation.component.js +71 -53
  218. package/dist/lib/custom/ai-agent-run/flow/constellation.component.js.map +1 -1
  219. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts +14 -2
  220. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts.map +1 -1
  221. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js +70 -52
  222. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js.map +1 -1
  223. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts +8 -0
  224. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts.map +1 -1
  225. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js +22 -6
  226. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js.map +1 -1
  227. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts +24 -2
  228. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts.map +1 -1
  229. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js +91 -59
  230. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js.map +1 -1
  231. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts +10 -2
  232. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts.map +1 -1
  233. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js +33 -17
  234. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js.map +1 -1
  235. package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.d.ts +2 -0
  236. package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.d.ts.map +1 -1
  237. package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.js +34 -30
  238. package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.js.map +1 -1
  239. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts +14 -2
  240. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts.map +1 -1
  241. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js +69 -51
  242. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js.map +1 -1
  243. package/dist/lib/custom/custom-forms.module.d.ts +32 -30
  244. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  245. package/dist/lib/custom/custom-forms.module.js +21 -4
  246. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  247. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +38 -12
  248. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
  249. package/dist/lib/custom/shared/entity-selector-dialog.component.js +103 -51
  250. package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
  251. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.d.ts.map +1 -1
  252. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +62 -26
  253. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
  254. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
  255. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +59 -51
  256. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
  257. package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js +76 -74
  258. package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js.map +1 -1
  259. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.d.ts.map +1 -1
  260. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js +33 -15
  261. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js.map +1 -1
  262. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  263. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +100 -82
  264. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  265. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js +24 -20
  266. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js.map +1 -1
  267. package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.d.ts +10 -0
  268. package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.d.ts.map +1 -0
  269. package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.js +122 -0
  270. package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.js.map +1 -0
  271. package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.d.ts +10 -0
  272. package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.d.ts.map +1 -0
  273. package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.js +125 -0
  274. package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.js.map +1 -0
  275. package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.d.ts.map +1 -1
  276. package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js +23 -5
  277. package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js.map +1 -1
  278. package/dist/lib/generated/Entities/MJProcessRunDetail/mjprocessrundetail.form.component.d.ts.map +1 -1
  279. package/dist/lib/generated/Entities/MJProcessRunDetail/mjprocessrundetail.form.component.js +25 -6
  280. package/dist/lib/generated/Entities/MJProcessRunDetail/mjprocessrundetail.form.component.js.map +1 -1
  281. package/dist/lib/generated/Entities/MJProject/mjproject.form.component.js +27 -25
  282. package/dist/lib/generated/Entities/MJProject/mjproject.form.component.js.map +1 -1
  283. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.d.ts.map +1 -1
  284. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js +11 -15
  285. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js.map +1 -1
  286. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.d.ts.map +1 -1
  287. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js +43 -7
  288. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js.map +1 -1
  289. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  290. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +155 -119
  291. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  292. package/dist/lib/generated/Entities/MJWebSearchProvider/mjwebsearchprovider.form.component.d.ts +10 -0
  293. package/dist/lib/generated/Entities/MJWebSearchProvider/mjwebsearchprovider.form.component.d.ts.map +1 -0
  294. package/dist/lib/generated/Entities/MJWebSearchProvider/mjwebsearchprovider.form.component.js +78 -0
  295. package/dist/lib/generated/Entities/MJWebSearchProvider/mjwebsearchprovider.form.component.js.map +1 -0
  296. package/dist/lib/generated/generated-forms.module.d.ts +240 -237
  297. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  298. package/dist/lib/generated/generated-forms.module.js +11 -2
  299. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  300. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts +5 -1
  301. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts.map +1 -1
  302. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js +11 -3
  303. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js.map +1 -1
  304. package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.d.ts +2 -0
  305. package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.d.ts.map +1 -1
  306. package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.js +16 -12
  307. package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.js.map +1 -1
  308. package/dist/lib/panels/content-sources/website-crawler-settings.panel.d.ts +1 -1
  309. package/dist/lib/panels/content-sources/website-crawler-settings.panel.js +2 -2
  310. package/dist/lib/panels/content-sources/website-crawler-settings.panel.js.map +1 -1
  311. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +122 -1
  312. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -1
  313. package/dist/lib/panels/model-predictions/model-prediction.logic.js +236 -11
  314. package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -1
  315. package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts +72 -13
  316. package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts.map +1 -1
  317. package/dist/lib/panels/model-predictions/model-prediction.panel.js +577 -78
  318. package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -1
  319. package/dist/lib/shared/components/template-editor.component.d.ts +133 -14
  320. package/dist/lib/shared/components/template-editor.component.d.ts.map +1 -1
  321. package/dist/lib/shared/components/template-editor.component.js +322 -124
  322. package/dist/lib/shared/components/template-editor.component.js.map +1 -1
  323. package/dist/public-api.d.ts +4 -0
  324. package/dist/public-api.d.ts.map +1 -1
  325. package/dist/public-api.js +4 -0
  326. package/dist/public-api.js.map +1 -1
  327. package/package.json +43 -41
@@ -7,6 +7,7 @@
7
7
  * or domain-specific — it operates purely on numbers, strings, and the model's
8
8
  * generic `ProblemType` / `FeatureImportance` JSON.
9
9
  */
10
+ import { OutcomeBand, OutcomeConfig } from '@memberjunction/predictive-studio-core';
10
11
  /**
11
12
  * The neutral tercile a numeric prediction falls into. No moral direction is
12
13
  * implied — `low`/`mid`/`high` describe position on the value axis only.
@@ -21,7 +22,7 @@ export interface PredictionDriver {
21
22
  /** Importance magnitude (absolute value of the raw contribution). */
22
23
  importance: number;
23
24
  /** Importance as a 0–100 share of the strongest driver, for the bar width. */
24
- relativePct: number;
25
+ RelativePct: number;
25
26
  }
26
27
  /** How a prediction's primary value should be rendered. */
27
28
  export type PredictionValueKind = 'probability' | 'numeric' | 'class';
@@ -30,6 +31,8 @@ export declare const MAX_DRIVERS = 5;
30
31
  /**
31
32
  * Coerce a dynamic field value into a finite number, or null when it isn't one.
32
33
  */
34
+ export declare function ToNumber(value: unknown): number | null;
35
+ /** @deprecated Use {@link ToNumber}. */
33
36
  export declare function toNumber(value: unknown): number | null;
34
37
  /**
35
38
  * Decide how to render a value given the model's problem type and the value.
@@ -37,13 +40,19 @@ export declare function toNumber(value: unknown): number | null;
37
40
  * - classification + value in [0,1] → 'probability' (a confidence/score we can gauge)
38
41
  * - everything else (a class label, a missing value) → 'class'
39
42
  */
43
+ export declare function ValueKind(problemType: ModelProblemType, numeric: number | null): PredictionValueKind;
44
+ /** @deprecated Use {@link ValueKind}. */
40
45
  export declare function valueKind(problemType: ModelProblemType, numeric: number | null): PredictionValueKind;
41
46
  /**
42
47
  * Neutral tercile for a 0–1 value. Position on the value axis only — no
43
48
  * assumption that high is good or bad. Values are clamped to [0,1].
44
49
  */
50
+ export declare function BandFor(value: number): PredictionBand;
51
+ /** @deprecated Use {@link BandFor}. */
45
52
  export declare function bandFor(value: number): PredictionBand;
46
53
  /** Round a 0–1 probability to an integer 0–100 gauge fill, clamped. */
54
+ export declare function GaugePct(value: number): number;
55
+ /** @deprecated Use {@link GaugePct}. */
47
56
  export declare function gaugePct(value: number): number;
48
57
  /**
49
58
  * Format the primary value for display:
@@ -52,18 +61,130 @@ export declare function gaugePct(value: number): number;
52
61
  * - class label → the label string
53
62
  * - missing/empty → "—" (em dash)
54
63
  */
64
+ export declare function FormatValue(rawValue: unknown, numeric: number | null, kind: PredictionValueKind): string;
65
+ /** @deprecated Use {@link FormatValue}. */
55
66
  export declare function formatValue(rawValue: unknown, numeric: number | null, kind: PredictionValueKind): string;
56
67
  /**
57
68
  * Pick the human label for a prediction: prefer the model's target variable,
58
69
  * then the bound column name, then a generic fallback.
59
70
  */
71
+ export declare function ResolveLabel(targetVariable: string | null, targetColumn: string | null): string;
72
+ /** @deprecated Use {@link ResolveLabel}. */
60
73
  export declare function resolveLabel(targetVariable: string | null, targetColumn: string | null): string;
61
74
  /**
62
75
  * Parse a model's `FeatureImportance` JSON (`Record<string, number>`) into the
63
76
  * top-N sorted drivers with relative bar widths. Returns [] on null / invalid /
64
77
  * empty input — the caller omits the drivers section cleanly when empty.
65
78
  */
79
+ export declare function ParseDrivers(featureImportanceJson: string | null): PredictionDriver[];
80
+ /** @deprecated Use {@link ParseDrivers}. */
66
81
  export declare function parseDrivers(featureImportanceJson: string | null): PredictionDriver[];
67
82
  /** Format a last-scored timestamp to a short date, or null when absent/invalid. */
83
+ export declare function FormatLastScored(lastScoredAt: Date | string | null): string | null;
84
+ /** @deprecated Use {@link FormatLastScored}. */
68
85
  export declare function formatLastScored(lastScoredAt: Date | string | null): string | null;
86
+ /**
87
+ * A resolved historical prediction row from `MJ: Process Run Details` for an entity record.
88
+ */
89
+ export interface PredictionHistoryItem {
90
+ /** The MJ: Process Run Details primary key ID */
91
+ id: string;
92
+ /** The parent Process Run ID */
93
+ ProcessRunId: string;
94
+ /** Model ID if resolved from payload or model lookup */
95
+ modelId: string | null;
96
+ /** Resolved model name (e.g. "Member Churn Risk" or "LatePaymentOutcome") */
97
+ ModelName: string;
98
+ /** Resolved pipeline & version string (e.g. "Pipeline v1") */
99
+ Provenance: string;
100
+ /** Target variable / label */
101
+ target: string;
102
+ /** Problem type: classification or regression */
103
+ problemType: ModelProblemType;
104
+ /** Primary numeric value / score */
105
+ NumericValue: number | null;
106
+ /** Class label if classification */
107
+ PredictedClass: string | null;
108
+ /** Formatted display value (e.g. "88%", "Late", "1,240.5") */
109
+ DisplayValue: string;
110
+ /** True if 0–1 probability we can gauge/badge */
111
+ IsProbability: boolean;
112
+ /** Neutral band: 'low' | 'mid' | 'high' */
113
+ Band: PredictionBand | null;
114
+ /** Resolved semantic status band from outcomeConfig */
115
+ StatusBand: OutcomeBand | null;
116
+ /** Human-readable status label (e.g. "Low Risk", "High") */
117
+ StatusLabel: string | null;
118
+ /** Semantic badge color ('green' | 'amber' | 'red' | 'blue' | 'gray') */
119
+ BadgeColor: 'green' | 'amber' | 'red' | 'blue' | 'gray';
120
+ /** Icon class if specified in band/style */
121
+ BadgeIcon: string | null;
122
+ /** Execution status: 'Succeeded' | 'Failed' | 'Pending' | 'Skipped' */
123
+ status: string;
124
+ /** When processing completed */
125
+ CompletedAt: Date | null;
126
+ /** Formatted date/time for history display */
127
+ FormattedTime: string;
128
+ /** Drivers if available in payload */
129
+ Drivers: PredictionDriver[];
130
+ /** Error message if Failed */
131
+ ErrorMessage: string | null;
132
+ /** Full raw payload object for JSON inspection */
133
+ RawPayload: Record<string, unknown> | null;
134
+ }
135
+ /** Summary descriptor of a model represented in prediction history. */
136
+ export interface ModelHistorySummary {
137
+ modelId: string;
138
+ ModelName: string;
139
+ count: number;
140
+ }
141
+ /** Input contract for parsing a Process Run Detail record. */
142
+ export interface RawProcessRunDetail {
143
+ ID: string;
144
+ ProcessRunID: string;
145
+ Status: string;
146
+ CompletedAt: Date | string | null;
147
+ ResultPayload: string | null;
148
+ ErrorMessage: string | null;
149
+ }
150
+ /** Model metadata lookup contract for decorating history items. */
151
+ export interface HistoryModelMetadata {
152
+ Name?: string;
153
+ Pipeline?: string;
154
+ Version?: number;
155
+ ProblemType?: string;
156
+ TargetVariable?: string;
157
+ Lineage?: string | null;
158
+ outcomeConfig?: OutcomeConfig | null;
159
+ }
160
+ /**
161
+ * Format a history completion timestamp with date and time.
162
+ */
163
+ export declare function FormatHistoryTimestamp(date: Date | string | null): string;
164
+ /** @deprecated Use {@link FormatHistoryTimestamp}. */
165
+ export declare function formatHistoryTimestamp(date: Date | string | null): string;
166
+ /**
167
+ * Parse an array of drivers from payload driver shapes (array of { feature, value } or map).
168
+ */
169
+ export declare function ParsePayloadDrivers(rawDrivers: unknown): PredictionDriver[];
170
+ /** @deprecated Use {@link ParsePayloadDrivers}. */
171
+ export declare function parsePayloadDrivers(rawDrivers: unknown): PredictionDriver[];
172
+ /**
173
+ * Parse a raw `MJ: Process Run Details` row into a decorated {@link PredictionHistoryItem}.
174
+ */
175
+ export declare function ParseHistoryItem(detail: RawProcessRunDetail, modelLookup?: Map<string, HistoryModelMetadata>): PredictionHistoryItem;
176
+ /** @deprecated Use {@link ParseHistoryItem}. */
177
+ export declare function parseHistoryItem(detail: RawProcessRunDetail, modelLookup?: Map<string, HistoryModelMetadata>): PredictionHistoryItem;
178
+ /**
179
+ * Filter prediction history by a selected model ID (or return all when null / 'ALL').
180
+ */
181
+ export declare function FilterHistoryByModel(history: PredictionHistoryItem[], selectedModelId: string | null): PredictionHistoryItem[];
182
+ /** @deprecated Use {@link FilterHistoryByModel}. */
183
+ export declare function filterHistoryByModel(history: PredictionHistoryItem[], selectedModelId: string | null): PredictionHistoryItem[];
184
+ /**
185
+ * Aggregate unique models from prediction history for multi-model tabs / filters.
186
+ */
187
+ export declare function GetDistinctModelsFromHistory(history: PredictionHistoryItem[]): ModelHistorySummary[];
188
+ /** @deprecated Use {@link GetDistinctModelsFromHistory}. */
189
+ export declare function getDistinctModelsFromHistory(history: PredictionHistoryItem[]): ModelHistorySummary[];
69
190
  //# sourceMappingURL=model-prediction.logic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-prediction.logic.d.ts","sourceRoot":"","sources":["../../../../src/lib/panels/model-predictions/model-prediction.logic.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpD,sDAAsD;AACtD,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,YAAY,CAAC;AAE/D,4DAA4D;AAC5D,MAAM,WAAW,gBAAgB;IAC7B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,2DAA2D;AAC3D,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC;AAEtE,mEAAmE;AACnE,eAAO,MAAM,WAAW,IAAI,CAAC;AAE7B;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAStD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,mBAAmB,CASpG;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAKrD;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAWxG;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAM/F;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,GAAG,gBAAgB,EAAE,CAwBrF;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CASlF"}
1
+ {"version":3,"file":"model-prediction.logic.d.ts","sourceRoot":"","sources":["../../../../src/lib/panels/model-predictions/model-prediction.logic.ts"],"names":[],"mappings":"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"}
@@ -7,12 +7,13 @@
7
7
  * or domain-specific — it operates purely on numbers, strings, and the model's
8
8
  * generic `ProblemType` / `FeatureImportance` JSON.
9
9
  */
10
+ import { resolveOutcomeConfig, resolveOutcomeStyle, resolveScoreBand, } from '@memberjunction/predictive-studio-core';
10
11
  /** Maximum number of feature-importance drivers shown per card. */
11
12
  export const MAX_DRIVERS = 5;
12
13
  /**
13
14
  * Coerce a dynamic field value into a finite number, or null when it isn't one.
14
15
  */
15
- export function toNumber(value) {
16
+ export function ToNumber(value) {
16
17
  if (typeof value === 'number') {
17
18
  return Number.isFinite(value) ? value : null;
18
19
  }
@@ -22,13 +23,17 @@ export function toNumber(value) {
22
23
  }
23
24
  return null;
24
25
  }
26
+ /** @deprecated Use {@link ToNumber}. */
27
+ export function toNumber(value) {
28
+ return ToNumber(value);
29
+ }
25
30
  /**
26
31
  * Decide how to render a value given the model's problem type and the value.
27
32
  * - regression + numeric → 'numeric'
28
33
  * - classification + value in [0,1] → 'probability' (a confidence/score we can gauge)
29
34
  * - everything else (a class label, a missing value) → 'class'
30
35
  */
31
- export function valueKind(problemType, numeric) {
36
+ export function ValueKind(problemType, numeric) {
32
37
  const isRegression = problemType === 'regression';
33
38
  if (isRegression && numeric != null) {
34
39
  return 'numeric';
@@ -38,11 +43,15 @@ export function valueKind(problemType, numeric) {
38
43
  }
39
44
  return 'class';
40
45
  }
46
+ /** @deprecated Use {@link ValueKind}. */
47
+ export function valueKind(problemType, numeric) {
48
+ return ValueKind(problemType, numeric);
49
+ }
41
50
  /**
42
51
  * Neutral tercile for a 0–1 value. Position on the value axis only — no
43
52
  * assumption that high is good or bad. Values are clamped to [0,1].
44
53
  */
45
- export function bandFor(value) {
54
+ export function BandFor(value) {
46
55
  const v = Math.max(0, Math.min(1, value));
47
56
  if (v < 1 / 3)
48
57
  return 'low';
@@ -50,10 +59,18 @@ export function bandFor(value) {
50
59
  return 'mid';
51
60
  return 'high';
52
61
  }
62
+ /** @deprecated Use {@link BandFor}. */
63
+ export function bandFor(value) {
64
+ return BandFor(value);
65
+ }
53
66
  /** Round a 0–1 probability to an integer 0–100 gauge fill, clamped. */
54
- export function gaugePct(value) {
67
+ export function GaugePct(value) {
55
68
  return Math.round(Math.max(0, Math.min(1, value)) * 100);
56
69
  }
70
+ /** @deprecated Use {@link GaugePct}. */
71
+ export function gaugePct(value) {
72
+ return GaugePct(value);
73
+ }
57
74
  /**
58
75
  * Format the primary value for display:
59
76
  * - probability → "72%"
@@ -61,9 +78,9 @@ export function gaugePct(value) {
61
78
  * - class label → the label string
62
79
  * - missing/empty → "—" (em dash)
63
80
  */
64
- export function formatValue(rawValue, numeric, kind) {
81
+ export function FormatValue(rawValue, numeric, kind) {
65
82
  if (kind === 'probability' && numeric != null) {
66
- return `${gaugePct(numeric)}%`;
83
+ return `${GaugePct(numeric)}%`;
67
84
  }
68
85
  if (kind === 'numeric' && numeric != null) {
69
86
  return numeric.toLocaleString(undefined, { maximumFractionDigits: 4 });
@@ -73,11 +90,15 @@ export function formatValue(rawValue, numeric, kind) {
73
90
  }
74
91
  return String(rawValue);
75
92
  }
93
+ /** @deprecated Use {@link FormatValue}. */
94
+ export function formatValue(rawValue, numeric, kind) {
95
+ return FormatValue(rawValue, numeric, kind);
96
+ }
76
97
  /**
77
98
  * Pick the human label for a prediction: prefer the model's target variable,
78
99
  * then the bound column name, then a generic fallback.
79
100
  */
80
- export function resolveLabel(targetVariable, targetColumn) {
101
+ export function ResolveLabel(targetVariable, targetColumn) {
81
102
  const target = targetVariable?.trim();
82
103
  if (target)
83
104
  return target;
@@ -86,12 +107,16 @@ export function resolveLabel(targetVariable, targetColumn) {
86
107
  return col;
87
108
  return 'Prediction';
88
109
  }
110
+ /** @deprecated Use {@link ResolveLabel}. */
111
+ export function resolveLabel(targetVariable, targetColumn) {
112
+ return ResolveLabel(targetVariable, targetColumn);
113
+ }
89
114
  /**
90
115
  * Parse a model's `FeatureImportance` JSON (`Record<string, number>`) into the
91
116
  * top-N sorted drivers with relative bar widths. Returns [] on null / invalid /
92
117
  * empty input — the caller omits the drivers section cleanly when empty.
93
118
  */
94
- export function parseDrivers(featureImportanceJson) {
119
+ export function ParseDrivers(featureImportanceJson) {
95
120
  if (!featureImportanceJson) {
96
121
  return [];
97
122
  }
@@ -106,18 +131,22 @@ export function parseDrivers(featureImportanceJson) {
106
131
  return [];
107
132
  }
108
133
  const entries = Object.entries(parsed)
109
- .map(([name, raw]) => ({ name, importance: Math.abs(toNumber(raw) ?? 0) }))
134
+ .map(([name, raw]) => ({ name, importance: Math.abs(ToNumber(raw) ?? 0) }))
110
135
  .filter(d => d.importance > 0)
111
136
  .sort((a, b) => b.importance - a.importance)
112
137
  .slice(0, MAX_DRIVERS);
113
138
  const max = entries.length > 0 ? entries[0].importance : 0;
114
139
  return entries.map(d => ({
115
140
  ...d,
116
- relativePct: max > 0 ? Math.round((d.importance / max) * 100) : 0,
141
+ RelativePct: max > 0 ? Math.round((d.importance / max) * 100) : 0,
117
142
  }));
118
143
  }
144
+ /** @deprecated Use {@link ParseDrivers}. */
145
+ export function parseDrivers(featureImportanceJson) {
146
+ return ParseDrivers(featureImportanceJson);
147
+ }
119
148
  /** Format a last-scored timestamp to a short date, or null when absent/invalid. */
120
- export function formatLastScored(lastScoredAt) {
149
+ export function FormatLastScored(lastScoredAt) {
121
150
  if (!lastScoredAt) {
122
151
  return null;
123
152
  }
@@ -127,4 +156,200 @@ export function formatLastScored(lastScoredAt) {
127
156
  }
128
157
  return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
129
158
  }
159
+ /** @deprecated Use {@link FormatLastScored}. */
160
+ export function formatLastScored(lastScoredAt) {
161
+ return FormatLastScored(lastScoredAt);
162
+ }
163
+ /**
164
+ * Format a history completion timestamp with date and time.
165
+ */
166
+ export function FormatHistoryTimestamp(date) {
167
+ if (!date)
168
+ return '—';
169
+ const d = date instanceof Date ? date : new Date(date);
170
+ if (isNaN(d.getTime()))
171
+ return '—';
172
+ return d.toLocaleString(undefined, {
173
+ month: 'short',
174
+ day: 'numeric',
175
+ year: 'numeric',
176
+ hour: 'numeric',
177
+ minute: '2-digit',
178
+ });
179
+ }
180
+ /** @deprecated Use {@link FormatHistoryTimestamp}. */
181
+ export function formatHistoryTimestamp(date) {
182
+ return FormatHistoryTimestamp(date);
183
+ }
184
+ /**
185
+ * Parse an array of drivers from payload driver shapes (array of { feature, value } or map).
186
+ */
187
+ export function ParsePayloadDrivers(rawDrivers) {
188
+ if (!rawDrivers)
189
+ return [];
190
+ if (Array.isArray(rawDrivers)) {
191
+ const entries = rawDrivers
192
+ .map((item) => {
193
+ if (!item || typeof item !== 'object')
194
+ return null;
195
+ const rec = item;
196
+ const name = typeof rec['feature'] === 'string' ? rec['feature'] : (typeof rec['name'] === 'string' ? rec['name'] : '');
197
+ const val = ToNumber(rec['value'] ?? rec['importance']);
198
+ if (!name || val == null)
199
+ return null;
200
+ return { name, importance: Math.abs(val) };
201
+ })
202
+ .filter((d) => d != null && d.importance > 0)
203
+ .sort((a, b) => b.importance - a.importance)
204
+ .slice(0, MAX_DRIVERS);
205
+ const max = entries.length > 0 ? entries[0].importance : 0;
206
+ return entries.map(d => ({
207
+ ...d,
208
+ RelativePct: max > 0 ? Math.round((d.importance / max) * 100) : 0,
209
+ }));
210
+ }
211
+ if (typeof rawDrivers === 'object') {
212
+ return ParseDrivers(JSON.stringify(rawDrivers));
213
+ }
214
+ return [];
215
+ }
216
+ /** @deprecated Use {@link ParsePayloadDrivers}. */
217
+ export function parsePayloadDrivers(rawDrivers) {
218
+ return ParsePayloadDrivers(rawDrivers);
219
+ }
220
+ /**
221
+ * Parse a raw `MJ: Process Run Details` row into a decorated {@link PredictionHistoryItem}.
222
+ */
223
+ export function ParseHistoryItem(detail, modelLookup) {
224
+ let rawPayload = null;
225
+ let payloadSection = null;
226
+ if (detail.ResultPayload) {
227
+ try {
228
+ const parsed = JSON.parse(detail.ResultPayload);
229
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
230
+ rawPayload = parsed;
231
+ const outputObj = rawPayload['output'];
232
+ if (outputObj && typeof outputObj === 'object' && !Array.isArray(outputObj)) {
233
+ payloadSection = outputObj;
234
+ }
235
+ else {
236
+ payloadSection = rawPayload;
237
+ }
238
+ }
239
+ }
240
+ catch {
241
+ rawPayload = null;
242
+ payloadSection = null;
243
+ }
244
+ }
245
+ const payloadModelId = typeof payloadSection?.['modelId'] === 'string' ? payloadSection['modelId'] : null;
246
+ const modelMeta = payloadModelId && modelLookup ? modelLookup.get(payloadModelId) : undefined;
247
+ const rawScore = payloadSection?.['score'] ?? payloadSection?.['value'] ?? null;
248
+ const numericScore = ToNumber(rawScore);
249
+ const predictedClass = typeof payloadSection?.['class'] === 'string' ? payloadSection['class'] : null;
250
+ const probTypeStr = (typeof payloadSection?.['problemType'] === 'string' ? payloadSection['problemType'] : modelMeta?.ProblemType) ?? '';
251
+ const problemType = probTypeStr.toLowerCase() === 'regression' ? 'regression' : 'classification';
252
+ const kind = ValueKind(problemType, numericScore);
253
+ const displayValue = predictedClass ?? FormatValue(rawScore, numericScore, kind);
254
+ const targetVar = (typeof payloadSection?.['target'] === 'string' ? payloadSection['target'] : modelMeta?.TargetVariable) ?? '';
255
+ const label = ResolveLabel(targetVar, null);
256
+ const modelName = modelMeta?.Name ?? label;
257
+ const provenance = modelMeta?.Pipeline && modelMeta?.Version
258
+ ? `${modelMeta.Pipeline} v${modelMeta.Version}`
259
+ : (modelMeta?.Name ?? 'Predictive Model');
260
+ const completedAt = detail.CompletedAt ? (detail.CompletedAt instanceof Date ? detail.CompletedAt : new Date(detail.CompletedAt)) : null;
261
+ const drivers = ParsePayloadDrivers(payloadSection?.['drivers']);
262
+ const rawOutcomeConfig = (payloadSection?.['outcomeConfig'] ?? modelMeta?.outcomeConfig);
263
+ const outcomeConfig = rawOutcomeConfig
264
+ ? resolveOutcomeConfig({ outcomeConfig: rawOutcomeConfig })
265
+ : resolveOutcomeConfig({
266
+ Lineage: modelMeta?.Lineage ?? null,
267
+ TargetVariable: targetVar || modelMeta?.TargetVariable || null,
268
+ ProblemType: probTypeStr || modelMeta?.ProblemType || null,
269
+ });
270
+ let statusBand = null;
271
+ let badgeColor = 'gray';
272
+ let badgeIcon = null;
273
+ let statusLabel = null;
274
+ if (numericScore != null) {
275
+ statusBand = resolveScoreBand(numericScore, outcomeConfig);
276
+ if (statusBand) {
277
+ badgeColor = statusBand.BadgeColor;
278
+ badgeIcon = statusBand.Icon ?? null;
279
+ statusLabel = statusBand.Label;
280
+ }
281
+ }
282
+ else if (predictedClass) {
283
+ const style = resolveOutcomeStyle(predictedClass, outcomeConfig);
284
+ badgeColor = style.BadgeColor;
285
+ badgeIcon = style.Icon ?? null;
286
+ statusLabel = style.DisplayLabel ?? predictedClass;
287
+ }
288
+ return {
289
+ id: detail.ID,
290
+ ProcessRunId: detail.ProcessRunID,
291
+ modelId: payloadModelId,
292
+ ModelName: modelName,
293
+ Provenance: provenance,
294
+ target: targetVar || label,
295
+ problemType,
296
+ NumericValue: numericScore,
297
+ PredictedClass: predictedClass,
298
+ DisplayValue: displayValue,
299
+ IsProbability: kind === 'probability',
300
+ Band: kind === 'probability' && numericScore != null ? BandFor(numericScore) : null,
301
+ StatusBand: statusBand,
302
+ StatusLabel: statusLabel,
303
+ BadgeColor: badgeColor,
304
+ BadgeIcon: badgeIcon,
305
+ status: detail.Status || 'Succeeded',
306
+ CompletedAt: completedAt,
307
+ FormattedTime: FormatHistoryTimestamp(completedAt),
308
+ Drivers: drivers,
309
+ ErrorMessage: detail.ErrorMessage,
310
+ RawPayload: rawPayload,
311
+ };
312
+ }
313
+ /** @deprecated Use {@link ParseHistoryItem}. */
314
+ export function parseHistoryItem(detail, modelLookup) {
315
+ return ParseHistoryItem(detail, modelLookup);
316
+ }
317
+ /**
318
+ * Filter prediction history by a selected model ID (or return all when null / 'ALL').
319
+ */
320
+ export function FilterHistoryByModel(history, selectedModelId) {
321
+ if (!selectedModelId || selectedModelId === 'ALL') {
322
+ return history;
323
+ }
324
+ return history.filter(item => item.modelId === selectedModelId);
325
+ }
326
+ /** @deprecated Use {@link FilterHistoryByModel}. */
327
+ export function filterHistoryByModel(history, selectedModelId) {
328
+ return FilterHistoryByModel(history, selectedModelId);
329
+ }
330
+ /**
331
+ * Aggregate unique models from prediction history for multi-model tabs / filters.
332
+ */
333
+ export function GetDistinctModelsFromHistory(history) {
334
+ const counts = new Map();
335
+ for (const item of history) {
336
+ const id = item.modelId ?? 'UNKNOWN';
337
+ const existing = counts.get(id);
338
+ if (existing) {
339
+ existing.count += 1;
340
+ }
341
+ else {
342
+ counts.set(id, { ModelName: item.ModelName, count: 1 });
343
+ }
344
+ }
345
+ return Array.from(counts.entries()).map(([modelId, data]) => ({
346
+ modelId,
347
+ ModelName: data.ModelName,
348
+ count: data.count,
349
+ }));
350
+ }
351
+ /** @deprecated Use {@link GetDistinctModelsFromHistory}. */
352
+ export function getDistinctModelsFromHistory(history) {
353
+ return GetDistinctModelsFromHistory(history);
354
+ }
130
355
  //# sourceMappingURL=model-prediction.logic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-prediction.logic.js","sourceRoot":"","sources":["../../../../src/lib/panels/model-predictions/model-prediction.logic.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure, framework-free logic for the entity-agnostic Model Predictions panel.\n *\n * Extracted from the Angular component so the band computation, value\n * formatting, and feature-importance parsing can be unit-tested without\n * standing up Angular or a real entity record. NONE of this is entity-specific\n * or domain-specific — it operates purely on numbers, strings, and the model's\n * generic `ProblemType` / `FeatureImportance` JSON.\n */\n\n/**\n * The neutral tercile a numeric prediction falls into. No moral direction is\n * implied — `low`/`mid`/`high` describe position on the value axis only.\n */\nexport type PredictionBand = 'low' | 'mid' | 'high';\n\n/** Generic problem types a trained model can have. */\nexport type ModelProblemType = 'classification' | 'regression';\n\n/** One normalized feature-importance driver for display. */\nexport interface PredictionDriver {\n /** Raw feature name as the model stored it. */\n name: string;\n /** Importance magnitude (absolute value of the raw contribution). */\n importance: number;\n /** Importance as a 0–100 share of the strongest driver, for the bar width. */\n relativePct: number;\n}\n\n/** How a prediction's primary value should be rendered. */\nexport type PredictionValueKind = 'probability' | 'numeric' | 'class';\n\n/** Maximum number of feature-importance drivers shown per card. */\nexport const MAX_DRIVERS = 5;\n\n/**\n * Coerce a dynamic field value into a finite number, or null when it isn't one.\n */\nexport function toNumber(value: unknown): number | null {\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : null;\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n }\n return null;\n}\n\n/**\n * Decide how to render a value given the model's problem type and the value.\n * - regression + numeric → 'numeric'\n * - classification + value in [0,1] → 'probability' (a confidence/score we can gauge)\n * - everything else (a class label, a missing value) → 'class'\n */\nexport function valueKind(problemType: ModelProblemType, numeric: number | null): PredictionValueKind {\n const isRegression = problemType === 'regression';\n if (isRegression && numeric != null) {\n return 'numeric';\n }\n if (!isRegression && numeric != null && numeric >= 0 && numeric <= 1) {\n return 'probability';\n }\n return 'class';\n}\n\n/**\n * Neutral tercile for a 0–1 value. Position on the value axis only — no\n * assumption that high is good or bad. Values are clamped to [0,1].\n */\nexport function bandFor(value: number): PredictionBand {\n const v = Math.max(0, Math.min(1, value));\n if (v < 1 / 3) return 'low';\n if (v < 2 / 3) return 'mid';\n return 'high';\n}\n\n/** Round a 0–1 probability to an integer 0–100 gauge fill, clamped. */\nexport function gaugePct(value: number): number {\n return Math.round(Math.max(0, Math.min(1, value)) * 100);\n}\n\n/**\n * Format the primary value for display:\n * - probability → \"72%\"\n * - numeric (regression) → grouped number, up to 4 decimals\n * - class label → the label string\n * - missing/empty → \"—\" (em dash)\n */\nexport function formatValue(rawValue: unknown, numeric: number | null, kind: PredictionValueKind): string {\n if (kind === 'probability' && numeric != null) {\n return `${gaugePct(numeric)}%`;\n }\n if (kind === 'numeric' && numeric != null) {\n return numeric.toLocaleString(undefined, { maximumFractionDigits: 4 });\n }\n if (rawValue == null || rawValue === '') {\n return '—';\n }\n return String(rawValue);\n}\n\n/**\n * Pick the human label for a prediction: prefer the model's target variable,\n * then the bound column name, then a generic fallback.\n */\nexport function resolveLabel(targetVariable: string | null, targetColumn: string | null): string {\n const target = targetVariable?.trim();\n if (target) return target;\n const col = targetColumn?.trim();\n if (col) return col;\n return 'Prediction';\n}\n\n/**\n * Parse a model's `FeatureImportance` JSON (`Record<string, number>`) into the\n * top-N sorted drivers with relative bar widths. Returns [] on null / invalid /\n * empty input — the caller omits the drivers section cleanly when empty.\n */\nexport function parseDrivers(featureImportanceJson: string | null): PredictionDriver[] {\n if (!featureImportanceJson) {\n return [];\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(featureImportanceJson);\n } catch {\n return [];\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return [];\n }\n const entries = Object.entries(parsed as Record<string, unknown>)\n .map(([name, raw]) => ({ name, importance: Math.abs(toNumber(raw) ?? 0) }))\n .filter(d => d.importance > 0)\n .sort((a, b) => b.importance - a.importance)\n .slice(0, MAX_DRIVERS);\n\n const max = entries.length > 0 ? entries[0].importance : 0;\n return entries.map(d => ({\n ...d,\n relativePct: max > 0 ? Math.round((d.importance / max) * 100) : 0,\n }));\n}\n\n/** Format a last-scored timestamp to a short date, or null when absent/invalid. */\nexport function formatLastScored(lastScoredAt: Date | string | null): string | null {\n if (!lastScoredAt) {\n return null;\n }\n const d = lastScoredAt instanceof Date ? lastScoredAt : new Date(lastScoredAt);\n if (isNaN(d.getTime())) {\n return null;\n }\n return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n"]}
1
+ {"version":3,"file":"model-prediction.logic.js","sourceRoot":"","sources":["../../../../src/lib/panels/model-predictions/model-prediction.logic.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure, framework-free logic for the entity-agnostic Model Predictions panel.\n *\n * Extracted from the Angular component so the band computation, value\n * formatting, and feature-importance parsing can be unit-tested without\n * standing up Angular or a real entity record. NONE of this is entity-specific\n * or domain-specific — it operates purely on numbers, strings, and the model's\n * generic `ProblemType` / `FeatureImportance` JSON.\n */\n\nimport {\n OutcomeBand,\n OutcomeConfig,\n formatPredictionScore,\n resolveOutcomeConfig,\n resolveOutcomeStyle,\n resolveScoreBand,\n} from '@memberjunction/predictive-studio-core';\n\n/**\n * The neutral tercile a numeric prediction falls into. No moral direction is\n * implied — `low`/`mid`/`high` describe position on the value axis only.\n */\nexport type PredictionBand = 'low' | 'mid' | 'high';\n\n/** Generic problem types a trained model can have. */\nexport type ModelProblemType = 'classification' | 'regression';\n\n/** One normalized feature-importance driver for display. */\nexport interface PredictionDriver {\n /** Raw feature name as the model stored it. */\n name: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n /** Importance magnitude (absolute value of the raw contribution). */\n importance: number; // case-violation-ok-legacy-back-compat: renaming it broke a use the checker could not see from the declaration — the compile proved it\n /** Importance as a 0–100 share of the strongest driver, for the bar width. */\n RelativePct: number;\n}\n\n/** How a prediction's primary value should be rendered. */\nexport type PredictionValueKind = 'probability' | 'numeric' | 'class';\n\n/** Maximum number of feature-importance drivers shown per card. */\nexport const MAX_DRIVERS = 5;\n\n/**\n * Coerce a dynamic field value into a finite number, or null when it isn't one.\n */\nexport function ToNumber(value: unknown): number | null {\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : null;\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n }\n return null;\n}\n\n/** @deprecated Use {@link ToNumber}. */\nexport function toNumber(value: unknown): number | null {\n return ToNumber(value);\n}\n\n/**\n * Decide how to render a value given the model's problem type and the value.\n * - regression + numeric → 'numeric'\n * - classification + value in [0,1] → 'probability' (a confidence/score we can gauge)\n * - everything else (a class label, a missing value) → 'class'\n */\nexport function ValueKind(problemType: ModelProblemType, numeric: number | null): PredictionValueKind {\n const isRegression = problemType === 'regression';\n if (isRegression && numeric != null) {\n return 'numeric';\n }\n if (!isRegression && numeric != null && numeric >= 0 && numeric <= 1) {\n return 'probability';\n }\n return 'class';\n}\n\n/** @deprecated Use {@link ValueKind}. */\nexport function valueKind(problemType: ModelProblemType, numeric: number | null): PredictionValueKind {\n return ValueKind(problemType, numeric);\n}\n\n/**\n * Neutral tercile for a 0–1 value. Position on the value axis only — no\n * assumption that high is good or bad. Values are clamped to [0,1].\n */\nexport function BandFor(value: number): PredictionBand {\n const v = Math.max(0, Math.min(1, value));\n if (v < 1 / 3) return 'low';\n if (v < 2 / 3) return 'mid';\n return 'high';\n}\n\n/** @deprecated Use {@link BandFor}. */\nexport function bandFor(value: number): PredictionBand {\n return BandFor(value);\n}\n\n/** Round a 0–1 probability to an integer 0–100 gauge fill, clamped. */\nexport function GaugePct(value: number): number {\n return Math.round(Math.max(0, Math.min(1, value)) * 100);\n}\n\n/** @deprecated Use {@link GaugePct}. */\nexport function gaugePct(value: number): number {\n return GaugePct(value);\n}\n\n/**\n * Format the primary value for display:\n * - probability → \"72%\"\n * - numeric (regression) → grouped number, up to 4 decimals\n * - class label → the label string\n * - missing/empty → \"—\" (em dash)\n */\nexport function FormatValue(rawValue: unknown, numeric: number | null, kind: PredictionValueKind): string {\n if (kind === 'probability' && numeric != null) {\n return `${GaugePct(numeric)}%`;\n }\n if (kind === 'numeric' && numeric != null) {\n return numeric.toLocaleString(undefined, { maximumFractionDigits: 4 });\n }\n if (rawValue == null || rawValue === '') {\n return '—';\n }\n return String(rawValue);\n}\n\n/** @deprecated Use {@link FormatValue}. */\nexport function formatValue(rawValue: unknown, numeric: number | null, kind: PredictionValueKind): string {\n return FormatValue(rawValue, numeric, kind);\n}\n\n/**\n * Pick the human label for a prediction: prefer the model's target variable,\n * then the bound column name, then a generic fallback.\n */\nexport function ResolveLabel(targetVariable: string | null, targetColumn: string | null): string {\n const target = targetVariable?.trim();\n if (target) return target;\n const col = targetColumn?.trim();\n if (col) return col;\n return 'Prediction';\n}\n\n/** @deprecated Use {@link ResolveLabel}. */\nexport function resolveLabel(targetVariable: string | null, targetColumn: string | null): string {\n return ResolveLabel(targetVariable, targetColumn);\n}\n\n/**\n * Parse a model's `FeatureImportance` JSON (`Record<string, number>`) into the\n * top-N sorted drivers with relative bar widths. Returns [] on null / invalid /\n * empty input — the caller omits the drivers section cleanly when empty.\n */\nexport function ParseDrivers(featureImportanceJson: string | null): PredictionDriver[] {\n if (!featureImportanceJson) {\n return [];\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(featureImportanceJson);\n } catch {\n return [];\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return [];\n }\n const entries = Object.entries(parsed as Record<string, unknown>)\n .map(([name, raw]) => ({ name, importance: Math.abs(ToNumber(raw) ?? 0) }))\n .filter(d => d.importance > 0)\n .sort((a, b) => b.importance - a.importance)\n .slice(0, MAX_DRIVERS);\n\n const max = entries.length > 0 ? entries[0].importance : 0;\n return entries.map(d => ({\n ...d,\n RelativePct: max > 0 ? Math.round((d.importance / max) * 100) : 0,\n }));\n}\n\n/** @deprecated Use {@link ParseDrivers}. */\nexport function parseDrivers(featureImportanceJson: string | null): PredictionDriver[] {\n return ParseDrivers(featureImportanceJson);\n}\n\n/** Format a last-scored timestamp to a short date, or null when absent/invalid. */\nexport function FormatLastScored(lastScoredAt: Date | string | null): string | null {\n if (!lastScoredAt) {\n return null;\n }\n const d = lastScoredAt instanceof Date ? lastScoredAt : new Date(lastScoredAt);\n if (isNaN(d.getTime())) {\n return null;\n }\n return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n\n/** @deprecated Use {@link FormatLastScored}. */\nexport function formatLastScored(lastScoredAt: Date | string | null): string | null {\n return FormatLastScored(lastScoredAt);\n}\n\n/**\n * A resolved historical prediction row from `MJ: Process Run Details` for an entity record.\n */\nexport interface PredictionHistoryItem {\n /** The MJ: Process Run Details primary key ID */\n id: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n /** The parent Process Run ID */\n ProcessRunId: string;\n /** Model ID if resolved from payload or model lookup */\n modelId: string | null; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n /** Resolved model name (e.g. \"Member Churn Risk\" or \"LatePaymentOutcome\") */\n ModelName: string;\n /** Resolved pipeline & version string (e.g. \"Pipeline v1\") */\n Provenance: string;\n /** Target variable / label */\n target: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n /** Problem type: classification or regression */\n problemType: ModelProblemType; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n /** Primary numeric value / score */\n NumericValue: number | null;\n /** Class label if classification */\n PredictedClass: string | null;\n /** Formatted display value (e.g. \"88%\", \"Late\", \"1,240.5\") */\n DisplayValue: string;\n /** True if 0–1 probability we can gauge/badge */\n IsProbability: boolean;\n /** Neutral band: 'low' | 'mid' | 'high' */\n Band: PredictionBand | null;\n /** Resolved semantic status band from outcomeConfig */\n StatusBand: OutcomeBand | null;\n /** Human-readable status label (e.g. \"Low Risk\", \"High\") */\n StatusLabel: string | null;\n /** Semantic badge color ('green' | 'amber' | 'red' | 'blue' | 'gray') */\n BadgeColor: 'green' | 'amber' | 'red' | 'blue' | 'gray';\n /** Icon class if specified in band/style */\n BadgeIcon: string | null;\n /** Execution status: 'Succeeded' | 'Failed' | 'Pending' | 'Skipped' */\n status: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n /** When processing completed */\n CompletedAt: Date | null;\n /** Formatted date/time for history display */\n FormattedTime: string;\n /** Drivers if available in payload */\n Drivers: PredictionDriver[];\n /** Error message if Failed */\n ErrorMessage: string | null;\n /** Full raw payload object for JSON inspection */\n RawPayload: Record<string, unknown> | null;\n}\n\n/** Summary descriptor of a model represented in prediction history. */\nexport interface ModelHistorySummary {\n modelId: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n ModelName: string;\n count: number; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined\n}\n\n/** Input contract for parsing a Process Run Detail record. */\nexport interface RawProcessRunDetail {\n ID: string;\n ProcessRunID: string;\n Status: string;\n CompletedAt: Date | string | null;\n ResultPayload: string | null;\n ErrorMessage: string | null;\n}\n\n/** Model metadata lookup contract for decorating history items. */\nexport interface HistoryModelMetadata {\n Name?: string;\n Pipeline?: string;\n Version?: number;\n ProblemType?: string;\n TargetVariable?: string;\n Lineage?: string | null;\n outcomeConfig?: OutcomeConfig | null; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined\n}\n\n/**\n * Format a history completion timestamp with date and time.\n */\nexport function FormatHistoryTimestamp(date: Date | string | null): string {\n if (!date) return '—';\n const d = date instanceof Date ? date : new Date(date);\n if (isNaN(d.getTime())) return '—';\n return d.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n });\n}\n\n/** @deprecated Use {@link FormatHistoryTimestamp}. */\nexport function formatHistoryTimestamp(date: Date | string | null): string {\n return FormatHistoryTimestamp(date);\n}\n\n/**\n * Parse an array of drivers from payload driver shapes (array of { feature, value } or map).\n */\nexport function ParsePayloadDrivers(rawDrivers: unknown): PredictionDriver[] {\n if (!rawDrivers) return [];\n if (Array.isArray(rawDrivers)) {\n const entries = rawDrivers\n .map((item: unknown) => {\n if (!item || typeof item !== 'object') return null;\n const rec = item as Record<string, unknown>;\n const name = typeof rec['feature'] === 'string' ? rec['feature'] : (typeof rec['name'] === 'string' ? rec['name'] : '');\n const val = ToNumber(rec['value'] ?? rec['importance']);\n if (!name || val == null) return null;\n return { name, importance: Math.abs(val) };\n })\n .filter((d): d is { name: string; importance: number } => d != null && d.importance > 0)\n .sort((a, b) => b.importance - a.importance)\n .slice(0, MAX_DRIVERS);\n\n const max = entries.length > 0 ? entries[0].importance : 0;\n return entries.map(d => ({\n ...d,\n RelativePct: max > 0 ? Math.round((d.importance / max) * 100) : 0,\n }));\n }\n if (typeof rawDrivers === 'object') {\n return ParseDrivers(JSON.stringify(rawDrivers));\n }\n return [];\n}\n\n/** @deprecated Use {@link ParsePayloadDrivers}. */\nexport function parsePayloadDrivers(rawDrivers: unknown): PredictionDriver[] {\n return ParsePayloadDrivers(rawDrivers);\n}\n\n/**\n * Parse a raw `MJ: Process Run Details` row into a decorated {@link PredictionHistoryItem}.\n */\nexport function ParseHistoryItem(\n detail: RawProcessRunDetail,\n modelLookup?: Map<string, HistoryModelMetadata>,\n): PredictionHistoryItem {\n let rawPayload: Record<string, unknown> | null = null;\n let payloadSection: Record<string, unknown> | null = null;\n\n if (detail.ResultPayload) {\n try {\n const parsed = JSON.parse(detail.ResultPayload);\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n rawPayload = parsed as Record<string, unknown>;\n const outputObj = rawPayload['output'];\n if (outputObj && typeof outputObj === 'object' && !Array.isArray(outputObj)) {\n payloadSection = outputObj as Record<string, unknown>;\n } else {\n payloadSection = rawPayload;\n }\n }\n } catch {\n rawPayload = null;\n payloadSection = null;\n }\n }\n\n const payloadModelId = typeof payloadSection?.['modelId'] === 'string' ? payloadSection['modelId'] : null;\n const modelMeta = payloadModelId && modelLookup ? modelLookup.get(payloadModelId) : undefined;\n\n const rawScore = payloadSection?.['score'] ?? payloadSection?.['value'] ?? null;\n const numericScore = ToNumber(rawScore);\n const predictedClass = typeof payloadSection?.['class'] === 'string' ? payloadSection['class'] : null;\n\n const probTypeStr = (typeof payloadSection?.['problemType'] === 'string' ? payloadSection['problemType'] : modelMeta?.ProblemType) ?? '';\n const problemType: ModelProblemType = probTypeStr.toLowerCase() === 'regression' ? 'regression' : 'classification';\n\n const kind = ValueKind(problemType, numericScore);\n const displayValue = predictedClass ?? FormatValue(rawScore, numericScore, kind);\n\n const targetVar = (typeof payloadSection?.['target'] === 'string' ? payloadSection['target'] : modelMeta?.TargetVariable) ?? '';\n const label = ResolveLabel(targetVar, null);\n\n const modelName = modelMeta?.Name ?? label;\n const provenance = modelMeta?.Pipeline && modelMeta?.Version\n ? `${modelMeta.Pipeline} v${modelMeta.Version}`\n : (modelMeta?.Name ?? 'Predictive Model');\n\n const completedAt = detail.CompletedAt ? (detail.CompletedAt instanceof Date ? detail.CompletedAt : new Date(detail.CompletedAt)) : null;\n const drivers = ParsePayloadDrivers(payloadSection?.['drivers']);\n\n const rawOutcomeConfig = (payloadSection?.['outcomeConfig'] ?? modelMeta?.outcomeConfig) as OutcomeConfig | undefined;\n const outcomeConfig = rawOutcomeConfig\n ? resolveOutcomeConfig({ outcomeConfig: rawOutcomeConfig })\n : resolveOutcomeConfig({\n Lineage: modelMeta?.Lineage ?? null,\n TargetVariable: targetVar || modelMeta?.TargetVariable || null,\n ProblemType: probTypeStr || modelMeta?.ProblemType || null,\n });\n\n let statusBand: OutcomeBand | null = null;\n let badgeColor: 'green' | 'amber' | 'red' | 'blue' | 'gray' = 'gray';\n let badgeIcon: string | null = null;\n let statusLabel: string | null = null;\n\n if (numericScore != null) {\n statusBand = resolveScoreBand(numericScore, outcomeConfig);\n if (statusBand) {\n badgeColor = statusBand.BadgeColor;\n badgeIcon = statusBand.Icon ?? null;\n statusLabel = statusBand.Label;\n }\n } else if (predictedClass) {\n const style = resolveOutcomeStyle(predictedClass, outcomeConfig);\n badgeColor = style.BadgeColor;\n badgeIcon = style.Icon ?? null;\n statusLabel = style.DisplayLabel ?? predictedClass;\n }\n\n return {\n id: detail.ID,\n ProcessRunId: detail.ProcessRunID,\n modelId: payloadModelId,\n ModelName: modelName,\n Provenance: provenance,\n target: targetVar || label,\n problemType,\n NumericValue: numericScore,\n PredictedClass: predictedClass,\n DisplayValue: displayValue,\n IsProbability: kind === 'probability',\n Band: kind === 'probability' && numericScore != null ? BandFor(numericScore) : null,\n StatusBand: statusBand,\n StatusLabel: statusLabel,\n BadgeColor: badgeColor,\n BadgeIcon: badgeIcon,\n status: detail.Status || 'Succeeded',\n CompletedAt: completedAt,\n FormattedTime: FormatHistoryTimestamp(completedAt),\n Drivers: drivers,\n ErrorMessage: detail.ErrorMessage,\n RawPayload: rawPayload,\n };\n}\n\n/** @deprecated Use {@link ParseHistoryItem}. */\nexport function parseHistoryItem(\n detail: RawProcessRunDetail,\n modelLookup?: Map<string, HistoryModelMetadata>,\n): PredictionHistoryItem {\n return ParseHistoryItem(detail, modelLookup);\n}\n\n/**\n * Filter prediction history by a selected model ID (or return all when null / 'ALL').\n */\nexport function FilterHistoryByModel(\n history: PredictionHistoryItem[],\n selectedModelId: string | null,\n): PredictionHistoryItem[] {\n if (!selectedModelId || selectedModelId === 'ALL') {\n return history;\n }\n return history.filter(item => item.modelId === selectedModelId);\n}\n\n/** @deprecated Use {@link FilterHistoryByModel}. */\nexport function filterHistoryByModel(\n history: PredictionHistoryItem[],\n selectedModelId: string | null,\n): PredictionHistoryItem[] {\n return FilterHistoryByModel(history, selectedModelId);\n}\n\n/**\n * Aggregate unique models from prediction history for multi-model tabs / filters.\n */\nexport function GetDistinctModelsFromHistory(history: PredictionHistoryItem[]): ModelHistorySummary[] {\n const counts = new Map<string, { ModelName: string; count: number }>();\n for (const item of history) {\n const id = item.modelId ?? 'UNKNOWN';\n const existing = counts.get(id);\n if (existing) {\n existing.count += 1;\n } else {\n counts.set(id, { ModelName: item.ModelName, count: 1 });\n }\n }\n return Array.from(counts.entries()).map(([modelId, data]) => ({\n modelId,\n ModelName: data.ModelName,\n count: data.count,\n }));\n}\n\n/** @deprecated Use {@link GetDistinctModelsFromHistory}. */\nexport function getDistinctModelsFromHistory(history: PredictionHistoryItem[]): ModelHistorySummary[] {\n return GetDistinctModelsFromHistory(history);\n}\n"]}