@memberjunction/ng-dashboards 5.38.0 → 5.40.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 (321) hide show
  1. package/README.md +14 -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 +217 -860
  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 +1717 -7802
  29. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  30. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts +56 -0
  31. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts.map +1 -0
  32. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js +423 -0
  33. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js.map +1 -0
  34. package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts +70 -0
  35. package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts.map +1 -0
  36. package/dist/AI/components/autotagging/components/classify-item-grid.component.js +308 -0
  37. package/dist/AI/components/autotagging/components/classify-item-grid.component.js.map +1 -0
  38. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts +29 -0
  39. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts.map +1 -0
  40. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js +186 -0
  41. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js.map +1 -0
  42. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts +69 -0
  43. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts.map +1 -0
  44. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js +278 -0
  45. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js.map +1 -0
  46. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts +73 -0
  47. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts.map +1 -0
  48. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js +393 -0
  49. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js.map +1 -0
  50. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts +122 -0
  51. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts.map +1 -0
  52. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js +908 -0
  53. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js.map +1 -0
  54. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts +87 -0
  55. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts.map +1 -0
  56. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js +475 -0
  57. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js.map +1 -0
  58. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts +29 -0
  59. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts.map +1 -0
  60. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js +208 -0
  61. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js.map +1 -0
  62. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts +21 -0
  63. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts.map +1 -0
  64. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js +70 -0
  65. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js.map +1 -0
  66. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +333 -0
  67. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -0
  68. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +2125 -0
  69. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -0
  70. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts +61 -0
  71. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts.map +1 -0
  72. package/dist/AI/components/autotagging/shared/classify.dryrun.js +78 -0
  73. package/dist/AI/components/autotagging/shared/classify.dryrun.js.map +1 -0
  74. package/dist/AI/components/autotagging/shared/classify.format.d.ts +58 -0
  75. package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -0
  76. package/dist/AI/components/autotagging/shared/classify.format.js +260 -0
  77. package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -0
  78. package/dist/AI/components/autotagging/shared/classify.types.d.ts +319 -0
  79. package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -0
  80. package/dist/AI/components/autotagging/shared/classify.types.js +6 -0
  81. package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -0
  82. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts +103 -0
  83. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts.map +1 -0
  84. package/dist/AI/components/autotagging/tabs/health-tab.component.js +571 -0
  85. package/dist/AI/components/autotagging/tabs/health-tab.component.js.map +1 -0
  86. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +77 -0
  87. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -0
  88. package/dist/AI/components/autotagging/tabs/history-tab.component.js +519 -0
  89. package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -0
  90. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts +107 -0
  91. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts.map +1 -0
  92. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js +719 -0
  93. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js.map +1 -0
  94. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +131 -0
  95. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -0
  96. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +813 -0
  97. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -0
  98. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +177 -0
  99. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -0
  100. package/dist/AI/components/autotagging/tabs/sources-tab.component.js +1465 -0
  101. package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -0
  102. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +78 -0
  103. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -0
  104. package/dist/AI/components/autotagging/tabs/tags-tab.component.js +492 -0
  105. package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -0
  106. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts +397 -0
  107. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts.map +1 -0
  108. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js +3490 -0
  109. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js.map +1 -0
  110. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +56 -0
  111. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -0
  112. package/dist/AI/components/autotagging/tabs/types-tab.component.js +271 -0
  113. package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -0
  114. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +3 -0
  115. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  116. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +306 -290
  117. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  118. package/dist/AI/components/execution-monitoring.component.js +1 -1
  119. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  120. package/dist/AI/components/models/model-management.component.js +209 -208
  121. package/dist/AI/components/models/model-management.component.js.map +1 -1
  122. package/dist/AI/components/prompts/prompt-management.component.js +130 -128
  123. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  124. package/dist/AI/components/requests/agent-requests-resource.component.js +61 -61
  125. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
  126. package/dist/AI/components/system/system-configuration.component.js +17 -17
  127. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  128. package/dist/AI/components/tags/tags-resource.component.d.ts +1 -0
  129. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  130. package/dist/AI/components/tags/tags-resource.component.js +578 -538
  131. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  132. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +3 -0
  133. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  134. package/dist/AI/components/vectors/vector-management-resource.component.js +331 -303
  135. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  136. package/dist/AI/services/ai-instrumentation.service.d.ts +5 -0
  137. package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
  138. package/dist/AI/services/ai-instrumentation.service.js +14 -2
  139. package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
  140. package/dist/AI/services/cache-metrics.d.ts +50 -0
  141. package/dist/AI/services/cache-metrics.d.ts.map +1 -0
  142. package/dist/AI/services/cache-metrics.js +43 -0
  143. package/dist/AI/services/cache-metrics.js.map +1 -0
  144. package/dist/APIKeys/api-applications-panel.component.js +2 -2
  145. package/dist/APIKeys/api-key-create-dialog.component.js +2 -2
  146. package/dist/APIKeys/api-key-edit-panel.component.js +2 -2
  147. package/dist/APIKeys/api-keys-resource.component.js +132 -131
  148. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  149. package/dist/Actions/components/actions-overview.component.js +141 -141
  150. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  151. package/dist/Actions/components/execution-monitoring.component.js +15 -15
  152. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  153. package/dist/Actions/components/explorer/action-explorer.component.d.ts +0 -5
  154. package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
  155. package/dist/Actions/components/explorer/action-explorer.component.js +139 -212
  156. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  157. package/dist/Admin/admin-data-schema.component.js +2 -2
  158. package/dist/Admin/admin-data-schema.component.js.map +1 -1
  159. package/dist/Admin/admin-dev-tools-resource.component.js +2 -2
  160. package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
  161. package/dist/Admin/admin-identity-access.component.js +2 -2
  162. package/dist/Admin/admin-identity-access.component.js.map +1 -1
  163. package/dist/Admin/admin-monitoring.component.js +2 -2
  164. package/dist/Admin/admin-monitoring.component.js.map +1 -1
  165. package/dist/ApplicationRoles/application-roles-resource.component.js +54 -49
  166. package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
  167. package/dist/Communication/communication-logs-resource.component.d.ts +6 -0
  168. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  169. package/dist/Communication/communication-logs-resource.component.js +72 -50
  170. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  171. package/dist/Communication/communication-monitor-resource.component.js +103 -102
  172. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  173. package/dist/Communication/communication-providers-resource.component.js +52 -51
  174. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  175. package/dist/Communication/communication-runs-resource.component.js +39 -38
  176. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  177. package/dist/Communication/communication-templates-resource.component.d.ts +6 -0
  178. package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
  179. package/dist/Communication/communication-templates-resource.component.js +92 -89
  180. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  181. package/dist/Credentials/components/credentials-audit-resource.component.js +136 -135
  182. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  183. package/dist/Credentials/components/credentials-categories-resource.component.js +155 -152
  184. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  185. package/dist/Credentials/components/credentials-list-resource.component.js +119 -118
  186. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  187. package/dist/Credentials/components/credentials-overview-resource.component.js +129 -128
  188. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  189. package/dist/Credentials/components/credentials-types-resource.component.js +107 -106
  190. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  191. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +31 -340
  192. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  193. package/dist/DataExplorer/data-explorer-dashboard.component.js +468 -1958
  194. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  195. package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
  196. package/dist/DataExplorer/data-explorer-resource.component.js +10 -0
  197. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
  198. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +1 -1
  199. package/dist/DatabaseDesigner/components/entity-list.component.js +115 -114
  200. package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
  201. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +5 -6
  202. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
  203. package/dist/DatabaseDesigner/database-designer-dashboards.module.js +4 -5
  204. package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
  205. package/dist/DevTools/app-state-inspector.component.js +18 -17
  206. package/dist/DevTools/app-state-inspector.component.js.map +1 -1
  207. package/dist/DevTools/class-registry.component.js +88 -85
  208. package/dist/DevTools/class-registry.component.js.map +1 -1
  209. package/dist/DevTools/event-monitor.component.js +155 -150
  210. package/dist/DevTools/event-monitor.component.js.map +1 -1
  211. package/dist/DevTools/graphql-console.component.js +245 -243
  212. package/dist/DevTools/graphql-console.component.js.map +1 -1
  213. package/dist/DevTools/layout-inspector.component.js +18 -17
  214. package/dist/DevTools/layout-inspector.component.js.map +1 -1
  215. package/dist/EntityAdmin/entity-admin-dashboard.component.js +20 -19
  216. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  217. package/dist/Home/home-dashboard.component.js +2 -2
  218. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  219. package/dist/Integration/components/activity/activity.component.js +236 -229
  220. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  221. package/dist/Integration/components/connections/connections.component.js +390 -389
  222. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  223. package/dist/Integration/components/overview/overview.component.js +2 -2
  224. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
  225. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +14 -11
  226. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  227. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +27 -2
  228. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  229. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +244 -119
  230. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  231. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +293 -291
  232. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  233. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +62 -61
  234. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
  235. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts +65 -0
  236. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts.map +1 -0
  237. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js +176 -0
  238. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js.map +1 -0
  239. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts +81 -0
  240. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts.map +1 -0
  241. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js +308 -0
  242. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js.map +1 -0
  243. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts +85 -0
  244. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts.map +1 -0
  245. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js +362 -0
  246. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js.map +1 -0
  247. package/dist/KnowledgeHub/index.d.ts +3 -0
  248. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  249. package/dist/KnowledgeHub/index.js +3 -0
  250. package/dist/KnowledgeHub/index.js.map +1 -1
  251. package/dist/Lists/components/lists-browse-resource.component.d.ts +6 -2
  252. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  253. package/dist/Lists/components/lists-browse-resource.component.js +525 -566
  254. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  255. package/dist/Lists/components/lists-categories-resource.component.js +135 -134
  256. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  257. package/dist/Lists/components/lists-my-lists-resource.component.js +199 -198
  258. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  259. package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
  260. package/dist/MCP/mcp-dashboard.component.js +443 -438
  261. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  262. package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
  263. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  264. package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
  265. package/dist/Scheduling/components/scheduling-activity.component.js +146 -147
  266. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
  267. package/dist/Scheduling/components/scheduling-jobs.component.js +76 -75
  268. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  269. package/dist/Scheduling/components/scheduling-overview.component.js +97 -96
  270. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  271. package/dist/Scheduling/scheduling-dashboard.component.js +24 -22
  272. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  273. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +2 -0
  274. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
  275. package/dist/Scheduling/services/scheduling-instrumentation.service.js +1 -0
  276. package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
  277. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
  278. package/dist/Testing/components/testing-explorer.component.d.ts +14 -4
  279. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  280. package/dist/Testing/components/testing-explorer.component.js +436 -427
  281. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  282. package/dist/Testing/components/testing-runs-resource.component.js +1 -1
  283. package/dist/Testing/components/testing-runs.component.js +116 -115
  284. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  285. package/dist/Testing/testing-dashboard.component.js +6 -7
  286. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  287. package/dist/VersionHistory/components/labels-resource.component.js +173 -172
  288. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  289. package/dist/VersionHistory/components/restore-resource.component.d.ts +6 -0
  290. package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
  291. package/dist/VersionHistory/components/restore-resource.component.js +116 -92
  292. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  293. package/dist/ai-dashboards.module.d.ts +57 -35
  294. package/dist/ai-dashboards.module.d.ts.map +1 -1
  295. package/dist/ai-dashboards.module.js +80 -1
  296. package/dist/ai-dashboards.module.js.map +1 -1
  297. package/dist/communication-dashboards.module.d.ts +1 -1
  298. package/dist/communication-dashboards.module.d.ts.map +1 -1
  299. package/dist/communication-dashboards.module.js +7 -1
  300. package/dist/communication-dashboards.module.js.map +1 -1
  301. package/dist/data-explorer-dashboards.module.d.ts +12 -14
  302. package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
  303. package/dist/data-explorer-dashboards.module.js +5 -14
  304. package/dist/data-explorer-dashboards.module.js.map +1 -1
  305. package/dist/public-api.d.ts +3 -0
  306. package/dist/public-api.d.ts.map +1 -1
  307. package/dist/public-api.js +3 -0
  308. package/dist/public-api.js.map +1 -1
  309. package/dist/testing-dashboards.module.d.ts +4 -5
  310. package/dist/testing-dashboards.module.d.ts.map +1 -1
  311. package/dist/testing-dashboards.module.js +7 -5
  312. package/dist/testing-dashboards.module.js.map +1 -1
  313. package/package.json +57 -54
  314. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts +0 -79
  315. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts.map +0 -1
  316. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +0 -195
  317. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +0 -1
  318. package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +0 -226
  319. package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +0 -1
  320. package/dist/DataExplorer/components/view-selector/view-selector.component.js +0 -861
  321. package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +0 -1
@@ -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":"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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 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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"}