@memberjunction/ng-dashboards 5.37.0 → 5.39.0

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 (328) hide show
  1. package/README.md +46 -7
  2. package/dist/AI/components/agents/agent-configuration.component.js +199 -198
  3. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  4. package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -1
  5. package/dist/AI/components/analytics/ai-analytics-resource.component.js +20 -17
  6. package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -1
  7. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +15 -0
  8. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -1
  9. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +166 -58
  10. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -1
  11. package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -1
  12. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +2 -1
  13. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -1
  14. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +1 -0
  15. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -1
  16. package/dist/AI/components/analytics/model-performance/model-performance.component.js +55 -36
  17. package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -1
  18. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts +9 -1
  19. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -1
  20. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +158 -117
  21. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -1
  22. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts +1 -0
  23. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -1
  24. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +22 -8
  25. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -1
  26. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +89 -842
  27. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  28. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +1353 -7683
  29. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  30. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts +87 -0
  31. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts.map +1 -0
  32. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js +475 -0
  33. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js.map +1 -0
  34. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts +29 -0
  35. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts.map +1 -0
  36. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js +208 -0
  37. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js.map +1 -0
  38. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts +21 -0
  39. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts.map +1 -0
  40. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js +70 -0
  41. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js.map +1 -0
  42. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +235 -0
  43. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -0
  44. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +1735 -0
  45. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -0
  46. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts +61 -0
  47. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts.map +1 -0
  48. package/dist/AI/components/autotagging/shared/classify.dryrun.js +78 -0
  49. package/dist/AI/components/autotagging/shared/classify.dryrun.js.map +1 -0
  50. package/dist/AI/components/autotagging/shared/classify.format.d.ts +43 -0
  51. package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -0
  52. package/dist/AI/components/autotagging/shared/classify.format.js +209 -0
  53. package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -0
  54. package/dist/AI/components/autotagging/shared/classify.types.d.ts +276 -0
  55. package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -0
  56. package/dist/AI/components/autotagging/shared/classify.types.js +6 -0
  57. package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -0
  58. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts +103 -0
  59. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts.map +1 -0
  60. package/dist/AI/components/autotagging/tabs/health-tab.component.js +571 -0
  61. package/dist/AI/components/autotagging/tabs/health-tab.component.js.map +1 -0
  62. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +40 -0
  63. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -0
  64. package/dist/AI/components/autotagging/tabs/history-tab.component.js +402 -0
  65. package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -0
  66. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts +107 -0
  67. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts.map +1 -0
  68. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js +719 -0
  69. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js.map +1 -0
  70. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +122 -0
  71. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -0
  72. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +752 -0
  73. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -0
  74. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +166 -0
  75. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -0
  76. package/dist/AI/components/autotagging/tabs/sources-tab.component.js +1384 -0
  77. package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -0
  78. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +70 -0
  79. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -0
  80. package/dist/AI/components/autotagging/tabs/tags-tab.component.js +448 -0
  81. package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -0
  82. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts +397 -0
  83. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts.map +1 -0
  84. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js +3490 -0
  85. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js.map +1 -0
  86. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +47 -0
  87. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -0
  88. package/dist/AI/components/autotagging/tabs/types-tab.component.js +220 -0
  89. package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -0
  90. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +293 -289
  91. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  92. package/dist/AI/components/models/model-management.component.js +209 -208
  93. package/dist/AI/components/models/model-management.component.js.map +1 -1
  94. package/dist/AI/components/prompts/prompt-management.component.js +130 -128
  95. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  96. package/dist/AI/components/requests/agent-requests-resource.component.js +61 -61
  97. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
  98. package/dist/AI/components/system/system-configuration.component.js +17 -17
  99. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  100. package/dist/AI/components/tags/tags-resource.component.js +550 -532
  101. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  102. package/dist/AI/components/vectors/vector-management-resource.component.js +1 -1
  103. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  104. package/dist/AI/services/ai-instrumentation.service.d.ts +5 -0
  105. package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
  106. package/dist/AI/services/ai-instrumentation.service.js +14 -2
  107. package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
  108. package/dist/AI/services/cache-metrics.d.ts +50 -0
  109. package/dist/AI/services/cache-metrics.d.ts.map +1 -0
  110. package/dist/AI/services/cache-metrics.js +43 -0
  111. package/dist/AI/services/cache-metrics.js.map +1 -0
  112. package/dist/APIKeys/api-key-edit-panel.component.js +2 -2
  113. package/dist/APIKeys/api-keys-resource.component.js +132 -131
  114. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  115. package/dist/Actions/components/actions-overview.component.js +141 -141
  116. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  117. package/dist/Actions/components/execution-monitoring.component.js +15 -15
  118. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  119. package/dist/Actions/components/explorer/action-explorer.component.d.ts +0 -5
  120. package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
  121. package/dist/Actions/components/explorer/action-explorer.component.js +139 -212
  122. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  123. package/dist/Admin/admin-data-schema.component.js +2 -2
  124. package/dist/Admin/admin-data-schema.component.js.map +1 -1
  125. package/dist/Admin/admin-dev-tools-resource.component.js +2 -2
  126. package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
  127. package/dist/Admin/admin-identity-access.component.js +2 -2
  128. package/dist/Admin/admin-identity-access.component.js.map +1 -1
  129. package/dist/Admin/admin-monitoring.component.js +2 -2
  130. package/dist/Admin/admin-monitoring.component.js.map +1 -1
  131. package/dist/ApplicationRoles/application-roles-resource.component.js +54 -49
  132. package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
  133. package/dist/Communication/communication-logs-resource.component.d.ts +6 -0
  134. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  135. package/dist/Communication/communication-logs-resource.component.js +72 -50
  136. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  137. package/dist/Communication/communication-monitor-resource.component.js +103 -102
  138. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  139. package/dist/Communication/communication-providers-resource.component.js +52 -51
  140. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  141. package/dist/Communication/communication-runs-resource.component.js +39 -38
  142. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  143. package/dist/Communication/communication-templates-resource.component.d.ts +6 -0
  144. package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
  145. package/dist/Communication/communication-templates-resource.component.js +92 -89
  146. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  147. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +73 -1
  148. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  149. package/dist/ComponentStudio/component-studio-dashboard.component.js +512 -127
  150. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  151. package/dist/ComponentStudio/component-studio-resource.component.d.ts +22 -0
  152. package/dist/ComponentStudio/component-studio-resource.component.d.ts.map +1 -0
  153. package/dist/ComponentStudio/component-studio-resource.component.js +55 -0
  154. package/dist/ComponentStudio/component-studio-resource.component.js.map +1 -0
  155. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +104 -45
  156. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
  157. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +234 -331
  158. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
  159. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.d.ts +54 -0
  160. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.d.ts.map +1 -0
  161. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.js +339 -0
  162. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.js.map +1 -0
  163. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.d.ts +65 -0
  164. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.d.ts.map +1 -0
  165. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.js +492 -0
  166. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.js.map +1 -0
  167. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.d.ts +88 -0
  168. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.d.ts.map +1 -0
  169. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.js +457 -0
  170. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.js.map +1 -0
  171. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts +106 -0
  172. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts.map +1 -0
  173. package/dist/ComponentStudio/components/form-override-dialog.component.js +478 -0
  174. package/dist/ComponentStudio/components/form-override-dialog.component.js.map +1 -0
  175. package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts +54 -0
  176. package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts.map +1 -1
  177. package/dist/ComponentStudio/components/workspace/component-preview.component.js +361 -50
  178. package/dist/ComponentStudio/components/workspace/component-preview.component.js.map +1 -1
  179. package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts +10 -0
  180. package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts.map +1 -1
  181. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +114 -45
  182. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
  183. package/dist/ComponentStudio/services/canvas-to-code.d.ts +32 -0
  184. package/dist/ComponentStudio/services/canvas-to-code.d.ts.map +1 -0
  185. package/dist/ComponentStudio/services/canvas-to-code.js +347 -0
  186. package/dist/ComponentStudio/services/canvas-to-code.js.map +1 -0
  187. package/dist/ComponentStudio/services/code-to-canvas.d.ts +32 -0
  188. package/dist/ComponentStudio/services/code-to-canvas.d.ts.map +1 -0
  189. package/dist/ComponentStudio/services/code-to-canvas.js +92 -0
  190. package/dist/ComponentStudio/services/code-to-canvas.js.map +1 -0
  191. package/dist/ComponentStudio/services/component-studio-state.service.d.ts +29 -0
  192. package/dist/ComponentStudio/services/component-studio-state.service.d.ts.map +1 -1
  193. package/dist/ComponentStudio/services/component-studio-state.service.js +76 -0
  194. package/dist/ComponentStudio/services/component-studio-state.service.js.map +1 -1
  195. package/dist/ComponentStudio/services/entity-form-override.service.d.ts +86 -0
  196. package/dist/ComponentStudio/services/entity-form-override.service.d.ts.map +1 -0
  197. package/dist/ComponentStudio/services/entity-form-override.service.js +246 -0
  198. package/dist/ComponentStudio/services/entity-form-override.service.js.map +1 -0
  199. package/dist/ComponentStudio/services/field-binding-scanner.d.ts +29 -0
  200. package/dist/ComponentStudio/services/field-binding-scanner.d.ts.map +1 -0
  201. package/dist/ComponentStudio/services/field-binding-scanner.js +110 -0
  202. package/dist/ComponentStudio/services/field-binding-scanner.js.map +1 -0
  203. package/dist/ComponentStudio/services/form-canvas-model.d.ts +56 -0
  204. package/dist/ComponentStudio/services/form-canvas-model.d.ts.map +1 -0
  205. package/dist/ComponentStudio/services/form-canvas-model.js +35 -0
  206. package/dist/ComponentStudio/services/form-canvas-model.js.map +1 -0
  207. package/dist/ComponentStudio/services/form-host-props-fixture.d.ts +10 -0
  208. package/dist/ComponentStudio/services/form-host-props-fixture.d.ts.map +1 -0
  209. package/dist/ComponentStudio/services/form-host-props-fixture.js +10 -0
  210. package/dist/ComponentStudio/services/form-host-props-fixture.js.map +1 -0
  211. package/dist/Credentials/components/credentials-audit-resource.component.js +136 -135
  212. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  213. package/dist/Credentials/components/credentials-categories-resource.component.js +155 -152
  214. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  215. package/dist/Credentials/components/credentials-list-resource.component.js +119 -118
  216. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  217. package/dist/Credentials/components/credentials-overview-resource.component.js +129 -128
  218. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  219. package/dist/Credentials/components/credentials-types-resource.component.js +107 -106
  220. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  221. package/dist/DataExplorer/data-explorer-dashboard.component.js +2 -2
  222. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  223. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +1 -1
  224. package/dist/DatabaseDesigner/components/entity-list.component.js +115 -114
  225. package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
  226. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +5 -6
  227. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
  228. package/dist/DatabaseDesigner/database-designer-dashboards.module.js +4 -5
  229. package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
  230. package/dist/DevTools/app-state-inspector.component.js +18 -17
  231. package/dist/DevTools/app-state-inspector.component.js.map +1 -1
  232. package/dist/DevTools/class-registry.component.js +88 -85
  233. package/dist/DevTools/class-registry.component.js.map +1 -1
  234. package/dist/DevTools/event-monitor.component.js +155 -150
  235. package/dist/DevTools/event-monitor.component.js.map +1 -1
  236. package/dist/DevTools/graphql-console.component.js +245 -243
  237. package/dist/DevTools/graphql-console.component.js.map +1 -1
  238. package/dist/DevTools/layout-inspector.component.js +18 -17
  239. package/dist/DevTools/layout-inspector.component.js.map +1 -1
  240. package/dist/EntityAdmin/entity-admin-dashboard.component.js +20 -19
  241. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  242. package/dist/FormBuilder/form-builder-resource.component.d.ts +964 -0
  243. package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -0
  244. package/dist/FormBuilder/form-builder-resource.component.js +4487 -0
  245. package/dist/FormBuilder/form-builder-resource.component.js.map +1 -0
  246. package/dist/FormBuilder/form-builder-version-rail.helpers.d.ts +55 -0
  247. package/dist/FormBuilder/form-builder-version-rail.helpers.d.ts.map +1 -0
  248. package/dist/FormBuilder/form-builder-version-rail.helpers.js +73 -0
  249. package/dist/FormBuilder/form-builder-version-rail.helpers.js.map +1 -0
  250. package/dist/Home/home-application.d.ts +21 -1
  251. package/dist/Home/home-application.d.ts.map +1 -1
  252. package/dist/Home/home-application.js +60 -8
  253. package/dist/Home/home-application.js.map +1 -1
  254. package/dist/Home/home-dashboard.component.js +2 -2
  255. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  256. package/dist/Integration/components/activity/activity.component.js +236 -229
  257. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  258. package/dist/Integration/components/connections/connections.component.js +390 -389
  259. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  260. package/dist/Integration/components/overview/overview.component.js +2 -2
  261. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +2 -2
  262. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  263. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +45 -44
  264. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  265. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +293 -291
  266. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  267. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +62 -61
  268. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
  269. package/dist/Lists/components/lists-browse-resource.component.d.ts +6 -2
  270. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  271. package/dist/Lists/components/lists-browse-resource.component.js +525 -566
  272. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  273. package/dist/Lists/components/lists-categories-resource.component.js +135 -134
  274. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  275. package/dist/Lists/components/lists-my-lists-resource.component.js +199 -198
  276. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  277. package/dist/MCP/mcp-dashboard.component.js +443 -438
  278. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  279. package/dist/QueryBrowser/query-browser-resource.component.d.ts +14 -14
  280. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  281. package/dist/QueryBrowser/query-browser-resource.component.js +11 -10
  282. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  283. package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
  284. package/dist/Scheduling/components/scheduling-activity.component.js +146 -147
  285. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
  286. package/dist/Scheduling/components/scheduling-jobs.component.js +76 -75
  287. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  288. package/dist/Scheduling/components/scheduling-overview.component.js +97 -96
  289. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  290. package/dist/Scheduling/scheduling-dashboard.component.js +24 -22
  291. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  292. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +2 -0
  293. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
  294. package/dist/Scheduling/services/scheduling-instrumentation.service.js +1 -0
  295. package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
  296. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
  297. package/dist/Testing/components/testing-explorer.component.d.ts +14 -4
  298. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  299. package/dist/Testing/components/testing-explorer.component.js +436 -427
  300. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  301. package/dist/Testing/components/testing-runs-resource.component.js +1 -1
  302. package/dist/Testing/components/testing-runs.component.js +116 -115
  303. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  304. package/dist/Testing/testing-dashboard.component.js +6 -7
  305. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  306. package/dist/VersionHistory/components/labels-resource.component.js +173 -172
  307. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  308. package/dist/VersionHistory/components/restore-resource.component.d.ts +6 -0
  309. package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
  310. package/dist/VersionHistory/components/restore-resource.component.js +116 -92
  311. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  312. package/dist/ai-dashboards.module.d.ts +47 -35
  313. package/dist/ai-dashboards.module.d.ts.map +1 -1
  314. package/dist/ai-dashboards.module.js +40 -1
  315. package/dist/ai-dashboards.module.js.map +1 -1
  316. package/dist/communication-dashboards.module.d.ts +1 -1
  317. package/dist/communication-dashboards.module.d.ts.map +1 -1
  318. package/dist/communication-dashboards.module.js +7 -1
  319. package/dist/communication-dashboards.module.js.map +1 -1
  320. package/dist/component-studio-dashboards.module.d.ts +34 -22
  321. package/dist/component-studio-dashboards.module.d.ts.map +1 -1
  322. package/dist/component-studio-dashboards.module.js +65 -9
  323. package/dist/component-studio-dashboards.module.js.map +1 -1
  324. package/dist/testing-dashboards.module.d.ts +4 -5
  325. package/dist/testing-dashboards.module.d.ts.map +1 -1
  326. package/dist/testing-dashboards.module.js +7 -5
  327. package/dist/testing-dashboards.module.js.map +1 -1
  328. package/package.json +55 -53
@@ -19,13 +19,13 @@ function AnalyticsModelPerformanceComponent_Conditional_0_Template(rf, ctx) { if
19
19
  i0.ɵɵelement(1, "mj-loading", 2);
20
20
  i0.ɵɵelementEnd();
21
21
  } }
22
- function AnalyticsModelPerformanceComponent_Conditional_1_Conditional_24_Template(rf, ctx) { if (rf & 1) {
23
- i0.ɵɵelementStart(0, "tr")(1, "td", 9);
22
+ function AnalyticsModelPerformanceComponent_Conditional_1_Conditional_26_Template(rf, ctx) { if (rf & 1) {
23
+ i0.ɵɵelementStart(0, "tr")(1, "td", 11);
24
24
  i0.ɵɵtext(2, "No model data for selected period");
25
25
  i0.ɵɵelementEnd()();
26
26
  } }
27
- function AnalyticsModelPerformanceComponent_Conditional_1_For_26_Conditional_7_Template(rf, ctx) { if (rf & 1) {
28
- i0.ɵɵelementStart(0, "div", 13);
27
+ function AnalyticsModelPerformanceComponent_Conditional_1_For_28_Conditional_7_Template(rf, ctx) { if (rf & 1) {
28
+ i0.ɵɵelementStart(0, "div", 15);
29
29
  i0.ɵɵtext(1);
30
30
  i0.ɵɵelementEnd();
31
31
  } if (rf & 2) {
@@ -33,40 +33,44 @@ function AnalyticsModelPerformanceComponent_Conditional_1_For_26_Conditional_7_T
33
33
  i0.ɵɵadvance();
34
34
  i0.ɵɵtextInterpolate(row_r1.ApiId);
35
35
  } }
36
- function AnalyticsModelPerformanceComponent_Conditional_1_For_26_Template(rf, ctx) { if (rf & 1) {
37
- i0.ɵɵelementStart(0, "tr")(1, "td")(2, "span", 10);
36
+ function AnalyticsModelPerformanceComponent_Conditional_1_For_28_Template(rf, ctx) { if (rf & 1) {
37
+ i0.ɵɵelementStart(0, "tr")(1, "td")(2, "span", 12);
38
38
  i0.ɵɵtext(3);
39
39
  i0.ɵɵelementEnd()();
40
- i0.ɵɵelementStart(4, "td", 11)(5, "div", 12);
40
+ i0.ɵɵelementStart(4, "td", 13)(5, "div", 14);
41
41
  i0.ɵɵtext(6);
42
42
  i0.ɵɵelementEnd();
43
- i0.ɵɵconditionalCreate(7, AnalyticsModelPerformanceComponent_Conditional_1_For_26_Conditional_7_Template, 2, 1, "div", 13);
43
+ i0.ɵɵconditionalCreate(7, AnalyticsModelPerformanceComponent_Conditional_1_For_28_Conditional_7_Template, 2, 1, "div", 15);
44
44
  i0.ɵɵelementEnd();
45
- i0.ɵɵelementStart(8, "td", 14);
45
+ i0.ɵɵelementStart(8, "td", 16);
46
46
  i0.ɵɵtext(9);
47
47
  i0.ɵɵelementEnd();
48
- i0.ɵɵelementStart(10, "td", 15);
48
+ i0.ɵɵelementStart(10, "td", 17);
49
49
  i0.ɵɵtext(11);
50
50
  i0.ɵɵpipe(12, "number");
51
51
  i0.ɵɵelementEnd();
52
- i0.ɵɵelementStart(13, "td", 15)(14, "span");
52
+ i0.ɵɵelementStart(13, "td", 17)(14, "span");
53
53
  i0.ɵɵtext(15);
54
54
  i0.ɵɵelementEnd()();
55
- i0.ɵɵelementStart(16, "td", 15);
55
+ i0.ɵɵelementStart(16, "td", 17);
56
56
  i0.ɵɵtext(17);
57
57
  i0.ɵɵelementEnd();
58
- i0.ɵɵelementStart(18, "td", 15)(19, "div", 16)(20, "span", 17);
58
+ i0.ɵɵelementStart(18, "td", 17)(19, "div", 18)(20, "span", 19);
59
59
  i0.ɵɵtext(21);
60
60
  i0.ɵɵpipe(22, "number");
61
61
  i0.ɵɵelementEnd();
62
- i0.ɵɵelementStart(23, "div", 18);
63
- i0.ɵɵelement(24, "div", 19);
62
+ i0.ɵɵelementStart(23, "div", 20);
63
+ i0.ɵɵelement(24, "div", 21);
64
64
  i0.ɵɵelementEnd()()();
65
- i0.ɵɵelementStart(25, "td", 15);
65
+ i0.ɵɵelementStart(25, "td", 17);
66
66
  i0.ɵɵtext(26);
67
+ i0.ɵɵpipe(27, "number");
67
68
  i0.ɵɵelementEnd();
68
- i0.ɵɵelementStart(27, "td", 20);
69
- i0.ɵɵtext(28);
69
+ i0.ɵɵelementStart(28, "td", 17);
70
+ i0.ɵɵtext(29);
71
+ i0.ɵɵelementEnd();
72
+ i0.ɵɵelementStart(30, "td", 22);
73
+ i0.ɵɵtext(31);
70
74
  i0.ɵɵelementEnd()();
71
75
  } if (rf & 2) {
72
76
  const row_r1 = ctx.$implicit;
@@ -82,7 +86,7 @@ function AnalyticsModelPerformanceComponent_Conditional_1_For_26_Template(rf, ct
82
86
  i0.ɵɵadvance(2);
83
87
  i0.ɵɵtextInterpolate(row_r1.Vendor);
84
88
  i0.ɵɵadvance(2);
85
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(12, 16, row_r1.Runs));
89
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(12, 17, row_r1.Runs));
86
90
  i0.ɵɵadvance(3);
87
91
  i0.ɵɵstyleProp("color", row_r1.AvgLatencyColor);
88
92
  i0.ɵɵadvance();
@@ -90,10 +94,12 @@ function AnalyticsModelPerformanceComponent_Conditional_1_For_26_Template(rf, ct
90
94
  i0.ɵɵadvance(2);
91
95
  i0.ɵɵtextInterpolate(ctx_r1.FormatLatency(row_r1.P95LatencyMs));
92
96
  i0.ɵɵadvance(4);
93
- i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(22, 18, row_r1.SuccessRate, "1.1-1"), "%");
97
+ i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(22, 19, row_r1.SuccessRate, "1.1-1"), "%");
94
98
  i0.ɵɵadvance(3);
95
99
  i0.ɵɵstyleProp("width", row_r1.SuccessRate, "%");
96
100
  i0.ɵɵadvance(2);
101
+ i0.ɵɵtextInterpolate(row_r1.CacheHitRate > 0 ? i0.ɵɵpipeBind2(27, 22, row_r1.CacheHitRate * 100, "1.0-0") + "%" : "\u2014");
102
+ i0.ɵɵadvance(3);
97
103
  i0.ɵɵtextInterpolate(ctx_r1.FormatCurrency(row_r1.CostPer1KTokens, 4));
98
104
  i0.ɵɵadvance(2);
99
105
  i0.ɵɵtextInterpolate(ctx_r1.FormatCurrency(row_r1.TotalCost));
@@ -120,27 +126,30 @@ function AnalyticsModelPerformanceComponent_Conditional_1_Template(rf, ctx) { if
120
126
  i0.ɵɵelementStart(17, "th", 8);
121
127
  i0.ɵɵtext(18, "Success Rate");
122
128
  i0.ɵɵelementEnd();
123
- i0.ɵɵelementStart(19, "th", 8);
124
- i0.ɵɵtext(20, "$/1K Tokens");
129
+ i0.ɵɵelementStart(19, "th", 9);
130
+ i0.ɵɵtext(20, "Cache Hit");
131
+ i0.ɵɵelementEnd();
132
+ i0.ɵɵelementStart(21, "th", 10);
133
+ i0.ɵɵtext(22, "$/1K Tokens");
125
134
  i0.ɵɵelementEnd();
126
- i0.ɵɵelementStart(21, "th", 8);
127
- i0.ɵɵtext(22, "Total Cost");
135
+ i0.ɵɵelementStart(23, "th", 8);
136
+ i0.ɵɵtext(24, "Total Cost");
128
137
  i0.ɵɵelementEnd()()();
129
- i0.ɵɵelementStart(23, "tbody");
130
- i0.ɵɵconditionalCreate(24, AnalyticsModelPerformanceComponent_Conditional_1_Conditional_24_Template, 3, 0, "tr");
131
- i0.ɵɵrepeaterCreate(25, AnalyticsModelPerformanceComponent_Conditional_1_For_26_Template, 29, 21, "tr", null, _forTrack0);
138
+ i0.ɵɵelementStart(25, "tbody");
139
+ i0.ɵɵconditionalCreate(26, AnalyticsModelPerformanceComponent_Conditional_1_Conditional_26_Template, 3, 0, "tr");
140
+ i0.ɵɵrepeaterCreate(27, AnalyticsModelPerformanceComponent_Conditional_1_For_28_Template, 32, 25, "tr", null, _forTrack0);
132
141
  i0.ɵɵelementEnd()()()();
133
142
  } if (rf & 2) {
134
143
  const ctx_r1 = i0.ɵɵnextContext();
135
- i0.ɵɵadvance(24);
136
- i0.ɵɵconditional(ctx_r1.Rows.length === 0 ? 24 : -1);
144
+ i0.ɵɵadvance(26);
145
+ i0.ɵɵconditional(ctx_r1.Rows.length === 0 ? 26 : -1);
137
146
  i0.ɵɵadvance();
138
147
  i0.ɵɵrepeater(ctx_r1.Rows);
139
148
  } }
140
149
  const FIELDS = [
141
150
  'ID', 'RunAt', 'CompletedAt', 'ExecutionTimeMS', 'Success',
142
151
  'Cost', 'TotalCost', 'TokensUsed', 'TokensPrompt', 'TokensCompletion',
143
- 'ModelID', 'Model', 'VendorID', 'Vendor'
152
+ 'TokensCacheRead', 'TokensCacheWrite', 'ModelID', 'Model', 'VendorID', 'Vendor'
144
153
  ];
145
154
  export class AnalyticsModelPerformanceComponent extends BaseAngularComponent {
146
155
  _timeRange = '7d';
@@ -266,9 +275,16 @@ export class AnalyticsModelPerformanceComponent extends BaseAngularComponent {
266
275
  ? latencies.reduce((s, l) => s + l, 0) / latencies.length
267
276
  : 0;
268
277
  const p95Latency = this.computePercentile(latencies, 0.95);
269
- const totalTokens = runs.reduce((s, r) => s + (r.TokensUsed ?? 0), 0);
278
+ // Effective rate uses TOTAL tokens the model processed, including cache reads/writes — so a
279
+ // model that caches heavily shows its true (lower) cost per token rather than dividing the
280
+ // discounted cost by only the uncached tokens.
281
+ const cacheRead = runs.reduce((s, r) => s + (r.TokensCacheRead ?? 0), 0);
282
+ const cacheWrite = runs.reduce((s, r) => s + (r.TokensCacheWrite ?? 0), 0);
283
+ const totalTokens = runs.reduce((s, r) => s + (r.TokensUsed ?? 0), 0) + cacheRead + cacheWrite;
270
284
  const totalCost = runs.reduce((s, r) => s + (r.Cost ?? r.TotalCost ?? 0), 0);
271
285
  const costPer1K = totalTokens > 0 ? (totalCost / totalTokens) * 1000 : 0;
286
+ const inputForHit = runs.reduce((s, r) => s + (r.TokensPrompt ?? 0), 0) + cacheRead + cacheWrite;
287
+ const cacheHitRate = inputForHit > 0 ? cacheRead / inputForHit : 0;
272
288
  const firstName = runs.find(r => r.Model != null);
273
289
  const firstVendor = runs.find(r => r.Vendor != null);
274
290
  // Look up model API name from engine
@@ -293,6 +309,7 @@ export class AnalyticsModelPerformanceComponent extends BaseAngularComponent {
293
309
  P95LatencyMs: p95Latency,
294
310
  SuccessRate: successRate,
295
311
  CostPer1KTokens: costPer1K,
312
+ CacheHitRate: cacheHitRate,
296
313
  TotalCost: totalCost
297
314
  };
298
315
  }
@@ -348,8 +365,8 @@ export class AnalyticsModelPerformanceComponent extends BaseAngularComponent {
348
365
  return `RunAt >= '${start.toISOString()}'`;
349
366
  }
350
367
  static ɵfac = /*@__PURE__*/ (() => { let ɵAnalyticsModelPerformanceComponent_BaseFactory; return function AnalyticsModelPerformanceComponent_Factory(__ngFactoryType__) { return (ɵAnalyticsModelPerformanceComponent_BaseFactory || (ɵAnalyticsModelPerformanceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(AnalyticsModelPerformanceComponent)))(__ngFactoryType__ || AnalyticsModelPerformanceComponent); }; })();
351
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AnalyticsModelPerformanceComponent, selectors: [["app-analytics-model-performance"]], inputs: { TimeRange: "TimeRange", SortBy: "SortBy", SelectedVendor: "SelectedVendor" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "loading-container"], [1, "leaderboard-panel"], ["text", "Loading model performance..."], [1, "table-wrapper"], [1, "leaderboard-table"], [1, "col-rank"], [1, "col-model"], [1, "col-vendor"], [1, "col-numeric"], ["colspan", "9", 1, "empty-row"], [1, "rank-badge"], [1, "cell-model"], [1, "model-name"], [1, "model-api-id"], [1, "cell-vendor"], [1, "cell-numeric"], [1, "success-rate-cell"], [1, "success-rate-value"], [1, "success-bar-bg"], [1, "success-bar-fill"], [1, "cell-numeric", "cell-cost"]], template: function AnalyticsModelPerformanceComponent_Template(rf, ctx) { if (rf & 1) {
352
- i0.ɵɵconditionalCreate(0, AnalyticsModelPerformanceComponent_Conditional_0_Template, 2, 0, "div", 0)(1, AnalyticsModelPerformanceComponent_Conditional_1_Template, 27, 1, "div", 1);
368
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AnalyticsModelPerformanceComponent, selectors: [["app-analytics-model-performance"]], inputs: { TimeRange: "TimeRange", SortBy: "SortBy", SelectedVendor: "SelectedVendor" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "loading-container"], [1, "leaderboard-panel"], ["text", "Loading model performance..."], [1, "table-wrapper"], [1, "leaderboard-table"], [1, "col-rank"], [1, "col-model"], [1, "col-vendor"], [1, "col-numeric"], ["title", "Share of input tokens served from the provider's prompt cache", 1, "col-numeric"], ["title", "Cost per 1K tokens processed, including cached tokens (effective rate)", 1, "col-numeric"], ["colspan", "10", 1, "empty-row"], [1, "rank-badge"], [1, "cell-model"], [1, "model-name"], [1, "model-api-id"], [1, "cell-vendor"], [1, "cell-numeric"], [1, "success-rate-cell"], [1, "success-rate-value"], [1, "success-bar-bg"], [1, "success-bar-fill"], [1, "cell-numeric", "cell-cost"]], template: function AnalyticsModelPerformanceComponent_Template(rf, ctx) { if (rf & 1) {
369
+ i0.ɵɵconditionalCreate(0, AnalyticsModelPerformanceComponent_Conditional_0_Template, 2, 0, "div", 0)(1, AnalyticsModelPerformanceComponent_Conditional_1_Template, 29, 1, "div", 1);
353
370
  } if (rf & 2) {
354
371
  i0.ɵɵconditional(ctx.IsLoading ? 0 : 1);
355
372
  } }, dependencies: [i1.LoadingComponent, i2.DecimalPipe], styles: ["[_nghost-%COMP%] { display: block; }\n\n .loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n }\n\n \n\n .leaderboard-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n }\n\n .table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n }\n\n .leaderboard-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n\n .leaderboard-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .leaderboard-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 14px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n\n .leaderboard-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n background: var(--mj-bg-surface-card);\n position: sticky;\n top: 0;\n white-space: nowrap;\n }\n\n .col-rank[_ngcontent-%COMP%] { width: 60px; text-align: center; }\n .col-model[_ngcontent-%COMP%] { min-width: 180px; }\n .col-vendor[_ngcontent-%COMP%] { min-width: 100px; }\n .col-numeric[_ngcontent-%COMP%] { text-align: right; white-space: nowrap; }\n\n .leaderboard-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n transition: background 0.15s;\n }\n\n .leaderboard-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n }\n\n .empty-row[_ngcontent-%COMP%] {\n text-align: center;\n color: var(--mj-text-disabled);\n padding: 32px;\n }\n\n \n\n .rank-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n font-size: 12px;\n font-weight: 700;\n }\n\n .rank-gold[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, color-mix(in srgb, var(--mj-status-warning) 35%, var(--mj-bg-surface)), color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface)));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n }\n\n .rank-silver[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-text-muted) 18%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-text-muted) 20%, transparent);\n }\n\n .rank-bronze[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 18%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n }\n\n .rank-neutral[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n \n\n .cell-model[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n }\n\n .model-name[_ngcontent-%COMP%] {\n font-weight: 600;\n }\n\n .model-api-id[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n font-family: monospace;\n }\n\n .cell-vendor[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n }\n\n .cell-numeric[_ngcontent-%COMP%] {\n text-align: right;\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n }\n\n .cell-cost[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n \n\n .success-rate-cell[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 3px;\n }\n\n .success-rate-value[_ngcontent-%COMP%] {\n font-weight: 600;\n }\n\n .success-bar-bg[_ngcontent-%COMP%] {\n width: 60px;\n height: 4px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 2px;\n overflow: hidden;\n }\n\n .success-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 2px;\n transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n \n\n @media (max-width: 1200px) {\n .leaderboard-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .leaderboard-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 10px;\n }\n }"] });
@@ -375,13 +392,14 @@ export class AnalyticsModelPerformanceComponent extends BaseAngularComponent {
375
392
  <th class="col-numeric">Avg Latency</th>
376
393
  <th class="col-numeric">P95 Latency</th>
377
394
  <th class="col-numeric">Success Rate</th>
378
- <th class="col-numeric">$/1K Tokens</th>
395
+ <th class="col-numeric" title="Share of input tokens served from the provider's prompt cache">Cache Hit</th>
396
+ <th class="col-numeric" title="Cost per 1K tokens processed, including cached tokens (effective rate)">$/1K Tokens</th>
379
397
  <th class="col-numeric">Total Cost</th>
380
398
  </tr>
381
399
  </thead>
382
400
  <tbody>
383
401
  @if (Rows.length === 0) {
384
- <tr><td colspan="9" class="empty-row">No model data for selected period</td></tr>
402
+ <tr><td colspan="10" class="empty-row">No model data for selected period</td></tr>
385
403
  }
386
404
  @for (row of Rows; track row.ModelName) {
387
405
  <tr>
@@ -412,6 +430,7 @@ export class AnalyticsModelPerformanceComponent extends BaseAngularComponent {
412
430
  </div>
413
431
  </div>
414
432
  </td>
433
+ <td class="cell-numeric">{{ row.CacheHitRate > 0 ? ((row.CacheHitRate * 100 | number:'1.0-0') + '%') : '—' }}</td>
415
434
  <td class="cell-numeric">{{ FormatCurrency(row.CostPer1KTokens, 4) }}</td>
416
435
  <td class="cell-numeric cell-cost">{{ FormatCurrency(row.TotalCost) }}</td>
417
436
  </tr>
@@ -429,6 +448,6 @@ export class AnalyticsModelPerformanceComponent extends BaseAngularComponent {
429
448
  }], SelectedVendor: [{
430
449
  type: Input
431
450
  }] }); })();
432
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AnalyticsModelPerformanceComponent, { className: "AnalyticsModelPerformanceComponent", filePath: "src/AI/components/analytics/model-performance/model-performance.component.ts", lineNumber: 300 }); })();
451
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AnalyticsModelPerformanceComponent, { className: "AnalyticsModelPerformanceComponent", filePath: "src/AI/components/analytics/model-performance/model-performance.component.ts", lineNumber: 305 }); })();
433
452
  export function LoadAnalyticsModelPerformance() { }
434
453
  //# sourceMappingURL=model-performance.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-performance.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/analytics/model-performance/model-performance.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Model Performance Leaderboard.\n *\n * Ranks AI models by configurable metrics (Cost Efficiency, Speed, Reliability, Usage Volume).\n * Data is loaded from MJ: AI Prompt Runs and augmented with model metadata from AIEngineBase.\n */\n\nimport {\n Component, Input,\n OnInit, OnDestroy,\n ChangeDetectorRef, inject\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { RunView } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\n\n// ── Interfaces ──\n\ninterface PromptRunRecord {\n ID: string;\n RunAt: string;\n CompletedAt: string | null;\n ExecutionTimeMS: number | null;\n Success: boolean;\n Cost: number | null;\n TotalCost: number | null;\n TokensUsed: number | null;\n TokensPrompt: number | null;\n TokensCompletion: number | null;\n ModelID: string | null;\n Model: string | null;\n VendorID: string | null;\n Vendor: string | null;\n}\n\ninterface ModelLeaderboardRow {\n Rank: number;\n RankClass: string;\n ModelName: string;\n ApiId: string;\n Vendor: string;\n VendorID: string;\n Runs: number;\n AvgLatencyMs: number;\n AvgLatencyColor: string;\n P95LatencyMs: number;\n SuccessRate: number;\n CostPer1KTokens: number;\n TotalCost: number;\n}\n\ntype SortByOption = 'cost-efficiency' | 'speed' | 'reliability' | 'usage-volume';\n\nconst FIELDS = [\n 'ID', 'RunAt', 'CompletedAt', 'ExecutionTimeMS', 'Success',\n 'Cost', 'TotalCost', 'TokensUsed', 'TokensPrompt', 'TokensCompletion',\n 'ModelID', 'Model', 'VendorID', 'Vendor'\n];\n\n@Component({\n standalone: false,\n selector: 'app-analytics-model-performance',\n template: `\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading model performance...\"></mj-loading>\n </div>\n } @else {\n <!-- Leaderboard Table -->\n <div class=\"leaderboard-panel\">\n <div class=\"table-wrapper\">\n <table class=\"leaderboard-table\">\n <thead>\n <tr>\n <th class=\"col-rank\">Rank</th>\n <th class=\"col-model\">Model</th>\n <th class=\"col-vendor\">Vendor</th>\n <th class=\"col-numeric\">Runs</th>\n <th class=\"col-numeric\">Avg Latency</th>\n <th class=\"col-numeric\">P95 Latency</th>\n <th class=\"col-numeric\">Success Rate</th>\n <th class=\"col-numeric\">$/1K Tokens</th>\n <th class=\"col-numeric\">Total Cost</th>\n </tr>\n </thead>\n <tbody>\n @if (Rows.length === 0) {\n <tr><td colspan=\"9\" class=\"empty-row\">No model data for selected period</td></tr>\n }\n @for (row of Rows; track row.ModelName) {\n <tr>\n <td>\n <span class=\"rank-badge\" [class]=\"row.RankClass\">\n {{ row.Rank }}\n </span>\n </td>\n <td class=\"cell-model\">\n <div class=\"model-name\">{{ row.ModelName }}</div>\n @if (row.ApiId && row.ApiId !== row.ModelName) {\n <div class=\"model-api-id\">{{ row.ApiId }}</div>\n }\n </td>\n <td class=\"cell-vendor\">{{ row.Vendor }}</td>\n <td class=\"cell-numeric\">{{ row.Runs | number }}</td>\n <td class=\"cell-numeric\">\n <span [style.color]=\"row.AvgLatencyColor\">\n {{ FormatLatency(row.AvgLatencyMs) }}\n </span>\n </td>\n <td class=\"cell-numeric\">{{ FormatLatency(row.P95LatencyMs) }}</td>\n <td class=\"cell-numeric\">\n <div class=\"success-rate-cell\">\n <span class=\"success-rate-value\">{{ row.SuccessRate | number:'1.1-1' }}%</span>\n <div class=\"success-bar-bg\">\n <div class=\"success-bar-fill\" [style.width.%]=\"row.SuccessRate\"></div>\n </div>\n </div>\n </td>\n <td class=\"cell-numeric\">{{ FormatCurrency(row.CostPer1KTokens, 4) }}</td>\n <td class=\"cell-numeric cell-cost\">{{ FormatCurrency(row.TotalCost) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n `,\n styles: [`\n :host { display: block; }\n\n .loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n }\n\n /* ── Leaderboard ── */\n .leaderboard-panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n }\n\n .table-wrapper {\n overflow-x: auto;\n }\n\n .leaderboard-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n\n .leaderboard-table th,\n .leaderboard-table td {\n padding: 12px 14px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n\n .leaderboard-table th {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n background: var(--mj-bg-surface-card);\n position: sticky;\n top: 0;\n white-space: nowrap;\n }\n\n .col-rank { width: 60px; text-align: center; }\n .col-model { min-width: 180px; }\n .col-vendor { min-width: 100px; }\n .col-numeric { text-align: right; white-space: nowrap; }\n\n .leaderboard-table tbody tr {\n transition: background 0.15s;\n }\n\n .leaderboard-table tbody tr:hover {\n background: var(--mj-bg-surface-hover);\n }\n\n .empty-row {\n text-align: center;\n color: var(--mj-text-disabled);\n padding: 32px;\n }\n\n /* ── Rank Badge ── */\n .rank-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n font-size: 12px;\n font-weight: 700;\n }\n\n .rank-gold {\n background: linear-gradient(135deg, color-mix(in srgb, var(--mj-status-warning) 35%, var(--mj-bg-surface)), color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface)));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n }\n\n .rank-silver {\n background: color-mix(in srgb, var(--mj-text-muted) 18%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-text-muted) 20%, transparent);\n }\n\n .rank-bronze {\n background: color-mix(in srgb, var(--mj-status-warning) 18%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n }\n\n .rank-neutral {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n /* ── Model Cell ── */\n .cell-model {\n font-weight: 500;\n color: var(--mj-text-primary);\n }\n\n .model-name {\n font-weight: 600;\n }\n\n .model-api-id {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n font-family: monospace;\n }\n\n .cell-vendor {\n color: var(--mj-text-secondary);\n }\n\n .cell-numeric {\n text-align: right;\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n }\n\n .cell-cost {\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n /* ── Success Rate Mini Bar ── */\n .success-rate-cell {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 3px;\n }\n\n .success-rate-value {\n font-weight: 600;\n }\n\n .success-bar-bg {\n width: 60px;\n height: 4px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 2px;\n overflow: hidden;\n }\n\n .success-bar-fill {\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 2px;\n transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* ── Responsive ── */\n @media (max-width: 1200px) {\n .leaderboard-table th,\n .leaderboard-table td {\n padding: 10px 10px;\n }\n }\n\n `]\n})\nexport class AnalyticsModelPerformanceComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n private _timeRange = '7d';\n @Input()\n set TimeRange(value: string) {\n const prev = this._timeRange;\n this._timeRange = value;\n if (prev !== value && this.initialized) this.LoadData();\n }\n get TimeRange(): string { return this._timeRange; }\n\n private _sortBy: SortByOption = 'cost-efficiency';\n @Input()\n set SortBy(value: SortByOption | string) {\n const prev = this._sortBy;\n this._sortBy = (value || 'cost-efficiency') as SortByOption;\n if (prev !== this._sortBy && this.initialized) {\n this.buildRows();\n this.cdr.markForCheck();\n }\n }\n get SortBy(): SortByOption { return this._sortBy; }\n\n private _selectedVendor = '';\n @Input()\n set SelectedVendor(value: string) {\n const prev = this._selectedVendor;\n this._selectedVendor = value ?? '';\n if (prev !== this._selectedVendor && this.initialized) {\n this.buildRows();\n this.cdr.markForCheck();\n }\n }\n get SelectedVendor(): string { return this._selectedVendor; }\n\n private cdr = inject(ChangeDetectorRef);\n private destroy$ = new Subject<void>();\n private initialized = false;\n\n public IsLoading = false;\n public Rows: ModelLeaderboardRow[] = [];\n\n private allRuns: PromptRunRecord[] = [];\n\n async ngOnInit(): Promise<void> {\n // AIEngineBase is deferred at startup — make sure it's loaded before\n // we read .Vendors / .Models from it.\n await AIEngineBase.Instance.EnsureLoaded();\n this.initialized = true;\n this.LoadData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n public FormatLatency(ms: number): string {\n if (ms < 1000) return Math.round(ms) + 'ms';\n return (ms / 1000).toFixed(2) + 's';\n }\n\n public FormatCurrency(value: number, decimals = 2): string {\n if (value === 0) return '$0.00';\n if (value < 0.01 && decimals < 4) decimals = 4;\n return '$' + value.toFixed(decimals);\n }\n\n // ── Data Loading ──\n\n private async LoadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const dateFilter = this.buildDateFilter();\n\n const result = await rv.RunView<PromptRunRecord>({\n EntityName: 'MJ: AI Prompt Runs',\n ExtraFilter: dateFilter,\n Fields: FIELDS,\n OrderBy: 'RunAt DESC',\n ResultType: 'simple'\n });\n\n this.allRuns = (result?.Results ?? []) as PromptRunRecord[];\n this.buildRows();\n } catch (e) {\n console.error('Model Performance load error:', e);\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n // ── Row Building ──\n\n private buildRows(): void {\n // Filter by vendor if needed\n let runs = this.allRuns;\n if (this.SelectedVendor) {\n runs = runs.filter(r => r.VendorID === this.SelectedVendor);\n }\n\n // Group by model\n const groups = new Map<string, PromptRunRecord[]>();\n for (const run of runs) {\n const key = run.ModelID ?? 'unknown';\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(run);\n }\n\n // Compute metrics per model\n const modelRows: ModelLeaderboardRow[] = [];\n for (const [modelId, modelRuns] of groups) {\n const row = this.computeModelMetrics(modelId, modelRuns);\n modelRows.push(row);\n }\n\n // Sort by chosen metric\n this.sortRows(modelRows);\n\n // Assign ranks\n modelRows.forEach((row, i) => {\n row.Rank = i + 1;\n row.RankClass = this.getRankClass(i + 1);\n });\n\n this.Rows = modelRows;\n }\n\n private computeModelMetrics(modelId: string, runs: PromptRunRecord[]): ModelLeaderboardRow {\n const totalRuns = runs.length;\n const successCount = runs.filter(r => r.Success).length;\n const successRate = totalRuns > 0 ? (successCount / totalRuns) * 100 : 0;\n\n const latencies = runs\n .filter(r => r.ExecutionTimeMS != null && r.ExecutionTimeMS > 0)\n .map(r => r.ExecutionTimeMS!);\n\n const avgLatency = latencies.length > 0\n ? latencies.reduce((s, l) => s + l, 0) / latencies.length\n : 0;\n\n const p95Latency = this.computePercentile(latencies, 0.95);\n\n const totalTokens = runs.reduce((s, r) => s + (r.TokensUsed ?? 0), 0);\n const totalCost = runs.reduce((s, r) => s + (r.Cost ?? r.TotalCost ?? 0), 0);\n const costPer1K = totalTokens > 0 ? (totalCost / totalTokens) * 1000 : 0;\n\n const firstName = runs.find(r => r.Model != null);\n const firstVendor = runs.find(r => r.Vendor != null);\n\n // Look up model API name from engine\n let apiId = '';\n try {\n const model = AIEngineBase.Instance.Models.find(m => UUIDsEqual(m.ID, modelId));\n apiId = model?.APIName ?? '';\n } catch {\n // engine might not be ready\n }\n\n return {\n Rank: 0,\n RankClass: 'rank-neutral',\n ModelName: firstName?.Model ?? 'Unknown',\n ApiId: apiId,\n Vendor: firstVendor?.Vendor ?? 'Unknown',\n VendorID: firstVendor?.VendorID ?? '',\n Runs: totalRuns,\n AvgLatencyMs: avgLatency,\n AvgLatencyColor: this.getLatencyColor(avgLatency),\n P95LatencyMs: p95Latency,\n SuccessRate: successRate,\n CostPer1KTokens: costPer1K,\n TotalCost: totalCost\n };\n }\n\n private sortRows(rows: ModelLeaderboardRow[]): void {\n switch (this.SortBy) {\n case 'cost-efficiency':\n rows.sort((a, b) => a.CostPer1KTokens - b.CostPer1KTokens);\n break;\n case 'speed':\n rows.sort((a, b) => a.AvgLatencyMs - b.AvgLatencyMs);\n break;\n case 'reliability':\n rows.sort((a, b) => b.SuccessRate - a.SuccessRate);\n break;\n case 'usage-volume':\n rows.sort((a, b) => b.Runs - a.Runs);\n break;\n }\n }\n\n // ── Helpers ──\n\n private computePercentile(sortedValues: number[], percentile: number): number {\n if (sortedValues.length === 0) return 0;\n const sorted = [...sortedValues].sort((a, b) => a - b);\n const idx = Math.ceil(sorted.length * percentile) - 1;\n return sorted[Math.max(0, idx)];\n }\n\n private getRankClass(rank: number): string {\n if (rank === 1) return 'rank-badge rank-gold';\n if (rank === 2) return 'rank-badge rank-silver';\n if (rank === 3) return 'rank-badge rank-bronze';\n return 'rank-badge rank-neutral';\n }\n\n private getLatencyColor(ms: number): string {\n if (ms < 1000) return 'var(--mj-status-success)';\n if (ms < 3000) return 'var(--mj-status-warning)';\n return 'var(--mj-status-error)';\n }\n\n private buildDateFilter(): string {\n const now = new Date();\n const msMap: Record<string, number> = {\n '24h': 86400000,\n '7d': 604800000,\n '30d': 2592000000\n };\n const ms = msMap[this.TimeRange] ?? 604800000;\n const start = new Date(now.getTime() - ms);\n return `RunAt >= '${start.toISOString()}'`;\n }\n}\n\nexport function LoadAnalyticsModelPerformance() { /* tree-shaking prevention */ }\n"]}
1
+ {"version":3,"file":"model-performance.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/analytics/model-performance/model-performance.component.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACH,SAAS,EAAE,KAAK,EAEhB,iBAAiB,EAAE,MAAM,EAC5B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;;;;;;IAqDlD,8BAA+B;IAC3B,gCAA6D;IACjE,iBAAM;;;IAsBkB,AAAJ,0BAAI,aAAmC;IAAA,iDAAiC;IAAK,AAAL,iBAAK,EAAK;;;IAYtE,+BAA0B;IAAA,YAAe;IAAA,iBAAM;;;IAArB,cAAe;IAAf,kCAAe;;;IAP7C,AADJ,AADJ,0BAAI,SACI,eACiD;IAC7C,YACJ;IACJ,AADI,iBAAO,EACN;IAED,AADJ,8BAAuB,cACK;IAAA,YAAmB;IAAA,iBAAM;IACjD,0HAAgD;IAGpD,iBAAK;IACL,8BAAwB;IAAA,YAAgB;IAAA,iBAAK;IAC7C,+BAAyB;IAAA,aAAuB;;IAAA,iBAAK;IAEjD,AADJ,+BAAyB,YACqB;IACtC,aACJ;IACJ,AADI,iBAAO,EACN;IACL,+BAAyB;IAAA,aAAqC;IAAA,iBAAK;IAG3D,AADJ,AADJ,+BAAyB,eACU,gBACM;IAAA,aAAuC;;IAAA,iBAAO;IAC/E,gCAA4B;IACxB,2BAAsE;IAGlF,AADI,AADI,iBAAM,EACJ,EACL;IACL,+BAAyB;IAAA,aAAoF;;IAAA,iBAAK;IAClH,+BAAyB;IAAA,aAA4C;IAAA,iBAAK;IAC1E,+BAAmC;IAAA,aAAmC;IAC1E,AAD0E,iBAAK,EAC1E;;;;IA7B4B,eAAuB;IAAvB,+BAAuB;IAC5C,cACJ;IADI,4CACJ;IAGwB,eAAmB;IAAnB,sCAAmB;IAC3C,cAEC;IAFD,4EAEC;IAEmB,eAAgB;IAAhB,mCAAgB;IACf,eAAuB;IAAvB,yDAAuB;IAEtC,eAAmC;IAAnC,+CAAmC;IACrC,cACJ;IADI,0EACJ;IAEqB,eAAqC;IAArC,+DAAqC;IAGrB,eAAuC;IAAvC,mFAAuC;IAEtC,eAAiC;IAAjC,gDAAiC;IAIlD,eAAoF;IAApF,2HAAoF;IACpF,eAA4C;IAA5C,sEAA4C;IAClC,eAAmC;IAAnC,6DAAmC;;;IA/C1E,AADJ,AADJ,AADJ,AADJ,AADJ,8BAA+B,aACA,eACU,YACtB,SACC,YACqB;IAAA,oBAAI;IAAA,iBAAK;IAC9B,6BAAsB;IAAA,qBAAK;IAAA,iBAAK;IAChC,6BAAuB;IAAA,uBAAM;IAAA,iBAAK;IAClC,8BAAwB;IAAA,qBAAI;IAAA,iBAAK;IACjC,8BAAwB;IAAA,4BAAW;IAAA,iBAAK;IACxC,8BAAwB;IAAA,4BAAW;IAAA,iBAAK;IACxC,8BAAwB;IAAA,6BAAY;IAAA,iBAAK;IACzC,8BAA8F;IAAA,0BAAS;IAAA,iBAAK;IAC5G,+BAAuG;IAAA,4BAAW;IAAA,iBAAK;IACvH,8BAAwB;IAAA,2BAAU;IAE1C,AADI,AADsC,iBAAK,EACtC,EACD;IACR,8BAAO;IACH,gHAAyB;IAGzB,yHAiCC;IAIjB,AADI,AADI,AADI,iBAAQ,EACJ,EACN,EACJ;;;IAxCU,gBAEC;IAFD,oDAEC;IACD,cAiCC;IAjCD,0BAiCC;;AAtE7B,MAAM,MAAM,GAAG;IACX,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS;IAC1D,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB;IACrE,iBAAiB,EAAE,kBAAkB,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ;CAClF,CAAC;AAkPF,MAAM,OAAO,kCAAmC,SAAQ,oBAAoB;IAChE,UAAU,GAAG,IAAI,CAAC;IAC1B,IACI,SAAS,CAAC,KAAa;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,WAAW;YAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC5D,CAAC;IACD,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE3C,OAAO,GAAiB,iBAAiB,CAAC;IAClD,IACI,MAAM,CAAC,KAA4B;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,CAAC,KAAK,IAAI,iBAAiB,CAAiB,CAAC;QAC5D,IAAI,IAAI,KAAK,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IACD,IAAI,MAAM,KAAmB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE3C,eAAe,GAAG,EAAE,CAAC;IAC7B,IACI,cAAc,CAAC,KAAa;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC;QAClC,IAAI,CAAC,eAAe,GAAG,KAAK,IAAI,EAAE,CAAC;QACnC,IAAI,IAAI,KAAK,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACpD,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IACD,IAAI,cAAc,KAAa,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IAErD,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAChC,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAC/B,WAAW,GAAG,KAAK,CAAC;IAErB,SAAS,GAAG,KAAK,CAAC;IAClB,IAAI,GAA0B,EAAE,CAAC;IAEhC,OAAO,GAAsB,EAAE,CAAC;IAExC,KAAK,CAAC,QAAQ;QACV,qEAAqE;QACrE,sCAAsC;QACtC,MAAM,YAAY,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC3C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,WAAW;QACP,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAEM,aAAa,CAAC,EAAU;QAC3B,IAAI,EAAE,GAAG,IAAI;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QAC5C,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IACxC,CAAC;IAEM,cAAc,CAAC,KAAa,EAAE,QAAQ,GAAG,CAAC;QAC7C,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAChC,IAAI,KAAK,GAAG,IAAI,IAAI,QAAQ,GAAG,CAAC;YAAE,QAAQ,GAAG,CAAC,CAAC;QAC/C,OAAO,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,qBAAqB;IAEb,KAAK,CAAC,QAAQ;QAClB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YAE1C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAkB;gBAC7C,UAAU,EAAE,oBAAoB;gBAChC,WAAW,EAAE,UAAU;gBACvB,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,YAAY;gBACrB,UAAU,EAAE,QAAQ;aACvB,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,GAAG,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAsB,CAAC;YAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;QACrB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,qBAAqB;IAEb,SAAS;QACb,6BAA6B;QAC7B,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QACxB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,cAAc,CAAC,CAAC;QAChE,CAAC;QAED,iBAAiB;QACjB,MAAM,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;QACpD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC1C,MAAM,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;QAED,4BAA4B;QAC5B,MAAM,SAAS,GAA0B,EAAE,CAAC;QAC5C,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,MAAM,EAAE,CAAC;YACxC,MAAM,GAAG,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACzD,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAEzB,eAAe;QACf,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACzB,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YACjB,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IAC1B,CAAC;IAEO,mBAAmB,CAAC,OAAe,EAAE,IAAuB;QAChE,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QACxD,MAAM,WAAW,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzE,MAAM,SAAS,GAAG,IAAI;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,IAAI,IAAI,IAAI,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC;aAC/D,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAgB,CAAC,CAAC;QAElC,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC;YACnC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM;YACzD,CAAC,CAAC,CAAC,CAAC;QAER,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAE3D,4FAA4F;QAC5F,2FAA2F;QAC3F,+CAA+C;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzE,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3E,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,GAAG,UAAU,CAAC;QAC/F,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7E,MAAM,SAAS,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzE,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,GAAG,UAAU,CAAC;QACjG,MAAM,YAAY,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;QAClD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;QAErD,qCAAqC;QACrC,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,CAAC;YACD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;YAChF,KAAK,GAAG,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACL,4BAA4B;QAChC,CAAC;QAED,OAAO;YACH,IAAI,EAAE,CAAC;YACP,SAAS,EAAE,cAAc;YACzB,SAAS,EAAE,SAAS,EAAE,KAAK,IAAI,SAAS;YACxC,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,WAAW,EAAE,MAAM,IAAI,SAAS;YACxC,QAAQ,EAAE,WAAW,EAAE,QAAQ,IAAI,EAAE;YACrC,IAAI,EAAE,SAAS;YACf,YAAY,EAAE,UAAU;YACxB,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC;YACjD,YAAY,EAAE,UAAU;YACxB,WAAW,EAAE,WAAW;YACxB,eAAe,EAAE,SAAS;YAC1B,YAAY,EAAE,YAAY;YAC1B,SAAS,EAAE,SAAS;SACvB,CAAC;IACN,CAAC;IAEO,QAAQ,CAAC,IAA2B;QACxC,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YAClB,KAAK,iBAAiB;gBAClB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC;gBAC3D,MAAM;YACV,KAAK,OAAO;gBACR,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC;gBACrD,MAAM;YACV,KAAK,aAAa;gBACd,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;gBACnD,MAAM;YACV,KAAK,cAAc;gBACf,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;gBACrC,MAAM;QACd,CAAC;IACL,CAAC;IAED,gBAAgB;IAER,iBAAiB,CAAC,YAAsB,EAAE,UAAkB;QAChE,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACtD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC;IAEO,YAAY,CAAC,IAAY;QAC7B,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,sBAAsB,CAAC;QAC9C,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,wBAAwB,CAAC;QAChD,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,wBAAwB,CAAC;QAChD,OAAO,yBAAyB,CAAC;IACrC,CAAC;IAEO,eAAe,CAAC,EAAU;QAC9B,IAAI,EAAE,GAAG,IAAI;YAAE,OAAO,0BAA0B,CAAC;QACjD,IAAI,EAAE,GAAG,IAAI;YAAE,OAAO,0BAA0B,CAAC;QACjD,OAAO,wBAAwB,CAAC;IACpC,CAAC;IAEO,eAAe;QACnB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAA2B;YAClC,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,UAAU;SACpB,CAAC;QACF,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,OAAO,aAAa,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;IAC/C,CAAC;qTA7OQ,kCAAkC,yBAAlC,kCAAkC;6DAAlC,kCAAkC;YAxOrC,AAJF,oGAAiB,+EAIR;;YAJT,uCAiEC;;;iFA2KI,kCAAkC;cAhP9C,SAAS;6BACM,KAAK,YACP,iCAAiC,YACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmET;;kBA4KA,KAAK;;kBASL,KAAK;;kBAYL,KAAK;;kFAvBG,kCAAkC;AAgP/C,MAAM,UAAU,6BAA6B,KAAmC,CAAC","sourcesContent":["/**\n * @fileoverview Model Performance Leaderboard.\n *\n * Ranks AI models by configurable metrics (Cost Efficiency, Speed, Reliability, Usage Volume).\n * Data is loaded from MJ: AI Prompt Runs and augmented with model metadata from AIEngineBase.\n */\n\nimport {\n Component, Input,\n OnInit, OnDestroy,\n ChangeDetectorRef, inject\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { RunView } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\n\n// ── Interfaces ──\n\ninterface PromptRunRecord {\n ID: string;\n RunAt: string;\n CompletedAt: string | null;\n ExecutionTimeMS: number | null;\n Success: boolean;\n Cost: number | null;\n TotalCost: number | null;\n TokensUsed: number | null;\n TokensPrompt: number | null;\n TokensCompletion: number | null;\n TokensCacheRead: number | null;\n TokensCacheWrite: number | null;\n ModelID: string | null;\n Model: string | null;\n VendorID: string | null;\n Vendor: string | null;\n}\n\ninterface ModelLeaderboardRow {\n Rank: number;\n RankClass: string;\n ModelName: string;\n ApiId: string;\n Vendor: string;\n VendorID: string;\n Runs: number;\n AvgLatencyMs: number;\n AvgLatencyColor: string;\n P95LatencyMs: number;\n SuccessRate: number;\n CostPer1KTokens: number;\n CacheHitRate: number;\n TotalCost: number;\n}\n\ntype SortByOption = 'cost-efficiency' | 'speed' | 'reliability' | 'usage-volume';\n\nconst FIELDS = [\n 'ID', 'RunAt', 'CompletedAt', 'ExecutionTimeMS', 'Success',\n 'Cost', 'TotalCost', 'TokensUsed', 'TokensPrompt', 'TokensCompletion',\n 'TokensCacheRead', 'TokensCacheWrite', 'ModelID', 'Model', 'VendorID', 'Vendor'\n];\n\n@Component({\n standalone: false,\n selector: 'app-analytics-model-performance',\n template: `\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading model performance...\"></mj-loading>\n </div>\n } @else {\n <!-- Leaderboard Table -->\n <div class=\"leaderboard-panel\">\n <div class=\"table-wrapper\">\n <table class=\"leaderboard-table\">\n <thead>\n <tr>\n <th class=\"col-rank\">Rank</th>\n <th class=\"col-model\">Model</th>\n <th class=\"col-vendor\">Vendor</th>\n <th class=\"col-numeric\">Runs</th>\n <th class=\"col-numeric\">Avg Latency</th>\n <th class=\"col-numeric\">P95 Latency</th>\n <th class=\"col-numeric\">Success Rate</th>\n <th class=\"col-numeric\" title=\"Share of input tokens served from the provider's prompt cache\">Cache Hit</th>\n <th class=\"col-numeric\" title=\"Cost per 1K tokens processed, including cached tokens (effective rate)\">$/1K Tokens</th>\n <th class=\"col-numeric\">Total Cost</th>\n </tr>\n </thead>\n <tbody>\n @if (Rows.length === 0) {\n <tr><td colspan=\"10\" class=\"empty-row\">No model data for selected period</td></tr>\n }\n @for (row of Rows; track row.ModelName) {\n <tr>\n <td>\n <span class=\"rank-badge\" [class]=\"row.RankClass\">\n {{ row.Rank }}\n </span>\n </td>\n <td class=\"cell-model\">\n <div class=\"model-name\">{{ row.ModelName }}</div>\n @if (row.ApiId && row.ApiId !== row.ModelName) {\n <div class=\"model-api-id\">{{ row.ApiId }}</div>\n }\n </td>\n <td class=\"cell-vendor\">{{ row.Vendor }}</td>\n <td class=\"cell-numeric\">{{ row.Runs | number }}</td>\n <td class=\"cell-numeric\">\n <span [style.color]=\"row.AvgLatencyColor\">\n {{ FormatLatency(row.AvgLatencyMs) }}\n </span>\n </td>\n <td class=\"cell-numeric\">{{ FormatLatency(row.P95LatencyMs) }}</td>\n <td class=\"cell-numeric\">\n <div class=\"success-rate-cell\">\n <span class=\"success-rate-value\">{{ row.SuccessRate | number:'1.1-1' }}%</span>\n <div class=\"success-bar-bg\">\n <div class=\"success-bar-fill\" [style.width.%]=\"row.SuccessRate\"></div>\n </div>\n </div>\n </td>\n <td class=\"cell-numeric\">{{ row.CacheHitRate > 0 ? ((row.CacheHitRate * 100 | number:'1.0-0') + '%') : '—' }}</td>\n <td class=\"cell-numeric\">{{ FormatCurrency(row.CostPer1KTokens, 4) }}</td>\n <td class=\"cell-numeric cell-cost\">{{ FormatCurrency(row.TotalCost) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n `,\n styles: [`\n :host { display: block; }\n\n .loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n }\n\n /* ── Leaderboard ── */\n .leaderboard-panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n }\n\n .table-wrapper {\n overflow-x: auto;\n }\n\n .leaderboard-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n\n .leaderboard-table th,\n .leaderboard-table td {\n padding: 12px 14px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n\n .leaderboard-table th {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.4px;\n background: var(--mj-bg-surface-card);\n position: sticky;\n top: 0;\n white-space: nowrap;\n }\n\n .col-rank { width: 60px; text-align: center; }\n .col-model { min-width: 180px; }\n .col-vendor { min-width: 100px; }\n .col-numeric { text-align: right; white-space: nowrap; }\n\n .leaderboard-table tbody tr {\n transition: background 0.15s;\n }\n\n .leaderboard-table tbody tr:hover {\n background: var(--mj-bg-surface-hover);\n }\n\n .empty-row {\n text-align: center;\n color: var(--mj-text-disabled);\n padding: 32px;\n }\n\n /* ── Rank Badge ── */\n .rank-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n font-size: 12px;\n font-weight: 700;\n }\n\n .rank-gold {\n background: linear-gradient(135deg, color-mix(in srgb, var(--mj-status-warning) 35%, var(--mj-bg-surface)), color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface)));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n }\n\n .rank-silver {\n background: color-mix(in srgb, var(--mj-text-muted) 18%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-text-muted) 20%, transparent);\n }\n\n .rank-bronze {\n background: color-mix(in srgb, var(--mj-status-warning) 18%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n }\n\n .rank-neutral {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n /* ── Model Cell ── */\n .cell-model {\n font-weight: 500;\n color: var(--mj-text-primary);\n }\n\n .model-name {\n font-weight: 600;\n }\n\n .model-api-id {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n font-family: monospace;\n }\n\n .cell-vendor {\n color: var(--mj-text-secondary);\n }\n\n .cell-numeric {\n text-align: right;\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n }\n\n .cell-cost {\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n /* ── Success Rate Mini Bar ── */\n .success-rate-cell {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 3px;\n }\n\n .success-rate-value {\n font-weight: 600;\n }\n\n .success-bar-bg {\n width: 60px;\n height: 4px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 2px;\n overflow: hidden;\n }\n\n .success-bar-fill {\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 2px;\n transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* ── Responsive ── */\n @media (max-width: 1200px) {\n .leaderboard-table th,\n .leaderboard-table td {\n padding: 10px 10px;\n }\n }\n\n `]\n})\nexport class AnalyticsModelPerformanceComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n private _timeRange = '7d';\n @Input()\n set TimeRange(value: string) {\n const prev = this._timeRange;\n this._timeRange = value;\n if (prev !== value && this.initialized) this.LoadData();\n }\n get TimeRange(): string { return this._timeRange; }\n\n private _sortBy: SortByOption = 'cost-efficiency';\n @Input()\n set SortBy(value: SortByOption | string) {\n const prev = this._sortBy;\n this._sortBy = (value || 'cost-efficiency') as SortByOption;\n if (prev !== this._sortBy && this.initialized) {\n this.buildRows();\n this.cdr.markForCheck();\n }\n }\n get SortBy(): SortByOption { return this._sortBy; }\n\n private _selectedVendor = '';\n @Input()\n set SelectedVendor(value: string) {\n const prev = this._selectedVendor;\n this._selectedVendor = value ?? '';\n if (prev !== this._selectedVendor && this.initialized) {\n this.buildRows();\n this.cdr.markForCheck();\n }\n }\n get SelectedVendor(): string { return this._selectedVendor; }\n\n private cdr = inject(ChangeDetectorRef);\n private destroy$ = new Subject<void>();\n private initialized = false;\n\n public IsLoading = false;\n public Rows: ModelLeaderboardRow[] = [];\n\n private allRuns: PromptRunRecord[] = [];\n\n async ngOnInit(): Promise<void> {\n // AIEngineBase is deferred at startup — make sure it's loaded before\n // we read .Vendors / .Models from it.\n await AIEngineBase.Instance.EnsureLoaded();\n this.initialized = true;\n this.LoadData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n public FormatLatency(ms: number): string {\n if (ms < 1000) return Math.round(ms) + 'ms';\n return (ms / 1000).toFixed(2) + 's';\n }\n\n public FormatCurrency(value: number, decimals = 2): string {\n if (value === 0) return '$0.00';\n if (value < 0.01 && decimals < 4) decimals = 4;\n return '$' + value.toFixed(decimals);\n }\n\n // ── Data Loading ──\n\n private async LoadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const dateFilter = this.buildDateFilter();\n\n const result = await rv.RunView<PromptRunRecord>({\n EntityName: 'MJ: AI Prompt Runs',\n ExtraFilter: dateFilter,\n Fields: FIELDS,\n OrderBy: 'RunAt DESC',\n ResultType: 'simple'\n });\n\n this.allRuns = (result?.Results ?? []) as PromptRunRecord[];\n this.buildRows();\n } catch (e) {\n console.error('Model Performance load error:', e);\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n // ── Row Building ──\n\n private buildRows(): void {\n // Filter by vendor if needed\n let runs = this.allRuns;\n if (this.SelectedVendor) {\n runs = runs.filter(r => r.VendorID === this.SelectedVendor);\n }\n\n // Group by model\n const groups = new Map<string, PromptRunRecord[]>();\n for (const run of runs) {\n const key = run.ModelID ?? 'unknown';\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(run);\n }\n\n // Compute metrics per model\n const modelRows: ModelLeaderboardRow[] = [];\n for (const [modelId, modelRuns] of groups) {\n const row = this.computeModelMetrics(modelId, modelRuns);\n modelRows.push(row);\n }\n\n // Sort by chosen metric\n this.sortRows(modelRows);\n\n // Assign ranks\n modelRows.forEach((row, i) => {\n row.Rank = i + 1;\n row.RankClass = this.getRankClass(i + 1);\n });\n\n this.Rows = modelRows;\n }\n\n private computeModelMetrics(modelId: string, runs: PromptRunRecord[]): ModelLeaderboardRow {\n const totalRuns = runs.length;\n const successCount = runs.filter(r => r.Success).length;\n const successRate = totalRuns > 0 ? (successCount / totalRuns) * 100 : 0;\n\n const latencies = runs\n .filter(r => r.ExecutionTimeMS != null && r.ExecutionTimeMS > 0)\n .map(r => r.ExecutionTimeMS!);\n\n const avgLatency = latencies.length > 0\n ? latencies.reduce((s, l) => s + l, 0) / latencies.length\n : 0;\n\n const p95Latency = this.computePercentile(latencies, 0.95);\n\n // Effective rate uses TOTAL tokens the model processed, including cache reads/writes — so a\n // model that caches heavily shows its true (lower) cost per token rather than dividing the\n // discounted cost by only the uncached tokens.\n const cacheRead = runs.reduce((s, r) => s + (r.TokensCacheRead ?? 0), 0);\n const cacheWrite = runs.reduce((s, r) => s + (r.TokensCacheWrite ?? 0), 0);\n const totalTokens = runs.reduce((s, r) => s + (r.TokensUsed ?? 0), 0) + cacheRead + cacheWrite;\n const totalCost = runs.reduce((s, r) => s + (r.Cost ?? r.TotalCost ?? 0), 0);\n const costPer1K = totalTokens > 0 ? (totalCost / totalTokens) * 1000 : 0;\n\n const inputForHit = runs.reduce((s, r) => s + (r.TokensPrompt ?? 0), 0) + cacheRead + cacheWrite;\n const cacheHitRate = inputForHit > 0 ? cacheRead / inputForHit : 0;\n\n const firstName = runs.find(r => r.Model != null);\n const firstVendor = runs.find(r => r.Vendor != null);\n\n // Look up model API name from engine\n let apiId = '';\n try {\n const model = AIEngineBase.Instance.Models.find(m => UUIDsEqual(m.ID, modelId));\n apiId = model?.APIName ?? '';\n } catch {\n // engine might not be ready\n }\n\n return {\n Rank: 0,\n RankClass: 'rank-neutral',\n ModelName: firstName?.Model ?? 'Unknown',\n ApiId: apiId,\n Vendor: firstVendor?.Vendor ?? 'Unknown',\n VendorID: firstVendor?.VendorID ?? '',\n Runs: totalRuns,\n AvgLatencyMs: avgLatency,\n AvgLatencyColor: this.getLatencyColor(avgLatency),\n P95LatencyMs: p95Latency,\n SuccessRate: successRate,\n CostPer1KTokens: costPer1K,\n CacheHitRate: cacheHitRate,\n TotalCost: totalCost\n };\n }\n\n private sortRows(rows: ModelLeaderboardRow[]): void {\n switch (this.SortBy) {\n case 'cost-efficiency':\n rows.sort((a, b) => a.CostPer1KTokens - b.CostPer1KTokens);\n break;\n case 'speed':\n rows.sort((a, b) => a.AvgLatencyMs - b.AvgLatencyMs);\n break;\n case 'reliability':\n rows.sort((a, b) => b.SuccessRate - a.SuccessRate);\n break;\n case 'usage-volume':\n rows.sort((a, b) => b.Runs - a.Runs);\n break;\n }\n }\n\n // ── Helpers ──\n\n private computePercentile(sortedValues: number[], percentile: number): number {\n if (sortedValues.length === 0) return 0;\n const sorted = [...sortedValues].sort((a, b) => a - b);\n const idx = Math.ceil(sorted.length * percentile) - 1;\n return sorted[Math.max(0, idx)];\n }\n\n private getRankClass(rank: number): string {\n if (rank === 1) return 'rank-badge rank-gold';\n if (rank === 2) return 'rank-badge rank-silver';\n if (rank === 3) return 'rank-badge rank-bronze';\n return 'rank-badge rank-neutral';\n }\n\n private getLatencyColor(ms: number): string {\n if (ms < 1000) return 'var(--mj-status-success)';\n if (ms < 3000) return 'var(--mj-status-warning)';\n return 'var(--mj-status-error)';\n }\n\n private buildDateFilter(): string {\n const now = new Date();\n const msMap: Record<string, number> = {\n '24h': 86400000,\n '7d': 604800000,\n '30d': 2592000000\n };\n const ms = msMap[this.TimeRange] ?? 604800000;\n const start = new Date(now.getTime() - ms);\n return `RunAt >= '${start.toISOString()}'`;\n }\n}\n\nexport function LoadAnalyticsModelPerformance() { /* tree-shaking prevention */ }\n"]}
@@ -20,6 +20,8 @@ interface PromptRunRecord {
20
20
  TokensUsed: number | null;
21
21
  TokensPrompt: number | null;
22
22
  TokensCompletion: number | null;
23
+ TokensCacheRead: number | null;
24
+ TokensCacheWrite: number | null;
23
25
  ExecutionTimeMS: number | null;
24
26
  ModelID: string | null;
25
27
  Model: string | null;
@@ -37,6 +39,7 @@ interface PromptRunStats {
37
39
  SuccessRate: number;
38
40
  P95LatencySeconds: number;
39
41
  TotalCost: number;
42
+ CacheHitRate: number;
40
43
  }
41
44
  interface ChartBucket {
42
45
  label: string;
@@ -54,7 +57,7 @@ interface BreakdownItem {
54
57
  interface StatusBreakdownItem extends BreakdownItem {
55
58
  cssClass: string;
56
59
  }
57
- type ChartMetric = 'volume' | 'cost' | 'tokens';
60
+ type ChartMetric = 'volume' | 'cost' | 'tokens' | 'cacheHit';
58
61
  type SortField = 'RunAt' | 'Prompt' | 'Model' | 'Status' | 'ExecutionTimeMS' | 'TokensUsed' | 'Cost';
59
62
  type SortDirection = 'asc' | 'desc';
60
63
  export declare class AnalyticsPromptRunsComponent extends BaseAngularComponent implements OnInit, OnDestroy {
@@ -111,6 +114,11 @@ export declare class AnalyticsPromptRunsComponent extends BaseAngularComponent i
111
114
  GetStatusClass(status: string): string;
112
115
  LoadData(): Promise<void>;
113
116
  private applyFilters;
117
+ /**
118
+ * Total tokens the model processed for a run, INCLUDING cached input. TokensUsed excludes the
119
+ * cache buckets by design, so a heavily-cached run looks tiny; this is the true throughput.
120
+ */
121
+ TrueTotalTokens(run: PromptRunRecord): number;
114
122
  private computeStats;
115
123
  private computeChartBuckets;
116
124
  private getChartMetricValue;
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-run-analysis.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/analytics/prompt-runs/prompt-run-analysis.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompt-run-analysis.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/analytics/prompt-runs/prompt-run-analysis.component.ts"],"names":[],"mappings":"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"}