@memberjunction/ng-core-entity-forms 6.1.0-edge.0 → 6.1.0-edge.2

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 (182) hide show
  1. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.d.ts +19 -2
  2. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.d.ts.map +1 -1
  3. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js +50 -9
  4. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js.map +1 -1
  5. package/dist/lib/custom/AIAgents/agent-form-tabs.d.ts +59 -0
  6. package/dist/lib/custom/AIAgents/agent-form-tabs.d.ts.map +1 -0
  7. package/dist/lib/custom/AIAgents/agent-form-tabs.js +53 -0
  8. package/dist/lib/custom/AIAgents/agent-form-tabs.js.map +1 -0
  9. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +54 -0
  10. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
  11. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +1300 -1143
  12. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  13. package/dist/lib/custom/EntityActions/entityaction.form.component.js +9 -9
  14. package/dist/lib/custom/EntityActions/entityaction.form.component.js.map +1 -1
  15. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts +25 -1
  16. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts.map +1 -1
  17. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +228 -170
  18. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
  19. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts +60 -2
  20. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts.map +1 -1
  21. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +372 -188
  22. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -1
  23. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.d.ts +9 -0
  24. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.d.ts.map +1 -1
  25. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js +86 -51
  26. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js.map +1 -1
  27. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts +73 -4
  28. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts.map +1 -1
  29. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +133 -7
  30. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
  31. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +49 -1
  32. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
  33. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +383 -264
  34. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
  35. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts +10 -1
  36. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts.map +1 -1
  37. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js +25 -3
  38. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js.map +1 -1
  39. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts +21 -1
  40. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts.map +1 -1
  41. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js +11 -0
  42. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js.map +1 -1
  43. package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.d.ts +28 -0
  44. package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.d.ts.map +1 -0
  45. package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.js +120 -0
  46. package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.js.map +1 -0
  47. package/dist/lib/custom/ai-agent-run/run-tree-timeline-projection.d.ts +90 -0
  48. package/dist/lib/custom/ai-agent-run/run-tree-timeline-projection.d.ts.map +1 -0
  49. package/dist/lib/custom/ai-agent-run/run-tree-timeline-projection.js +326 -0
  50. package/dist/lib/custom/ai-agent-run/run-tree-timeline-projection.js.map +1 -0
  51. package/dist/lib/custom/custom-forms.module.d.ts +14 -13
  52. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  53. package/dist/lib/custom/custom-forms.module.js +8 -1
  54. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  55. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  56. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +59 -41
  57. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  58. package/dist/lib/generated/Entities/MJAIAgentCredential/mjaiagentcredential.form.component.d.ts +10 -0
  59. package/dist/lib/generated/Entities/MJAIAgentCredential/mjaiagentcredential.form.component.d.ts.map +1 -0
  60. package/dist/lib/generated/Entities/MJAIAgentCredential/mjaiagentcredential.form.component.js +78 -0
  61. package/dist/lib/generated/Entities/MJAIAgentCredential/mjaiagentcredential.form.component.js.map +1 -0
  62. package/dist/lib/generated/Entities/MJAIAgentHarness/mjaiagentharness.form.component.d.ts +10 -0
  63. package/dist/lib/generated/Entities/{MJReportSnapshot/mjreportsnapshot.form.component.d.ts.map → MJAIAgentHarness/mjaiagentharness.form.component.d.ts.map} +1 -1
  64. package/dist/lib/generated/Entities/MJAIAgentHarness/mjaiagentharness.form.component.js +90 -0
  65. package/dist/lib/generated/Entities/MJAIAgentHarness/mjaiagentharness.form.component.js.map +1 -0
  66. package/dist/lib/generated/Entities/MJAIAgentRequest/mjaiagentrequest.form.component.js +8 -6
  67. package/dist/lib/generated/Entities/MJAIAgentRequest/mjaiagentrequest.form.component.js.map +1 -1
  68. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.d.ts.map +1 -1
  69. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +105 -83
  70. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
  71. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.d.ts.map +1 -1
  72. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js +184 -164
  73. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js.map +1 -1
  74. package/dist/lib/generated/Entities/MJAIModelType/mjaimodeltype.form.component.js +25 -23
  75. package/dist/lib/generated/Entities/MJAIModelType/mjaimodeltype.form.component.js.map +1 -1
  76. package/dist/lib/generated/Entities/MJAIModelVendor/mjaimodelvendor.form.component.js +15 -13
  77. package/dist/lib/generated/Entities/MJAIModelVendor/mjaimodelvendor.form.component.js.map +1 -1
  78. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.d.ts.map +1 -1
  79. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +43 -25
  80. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
  81. package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.d.ts.map +1 -1
  82. package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js +31 -13
  83. package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js.map +1 -1
  84. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js +31 -31
  85. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js.map +1 -1
  86. package/dist/lib/generated/Entities/MJActionExecutionLog/mjactionexecutionlog.form.component.js +11 -11
  87. package/dist/lib/generated/Entities/MJActionExecutionLog/mjactionexecutionlog.form.component.js.map +1 -1
  88. package/dist/lib/generated/Entities/MJActionParam/mjactionparam.form.component.d.ts.map +1 -1
  89. package/dist/lib/generated/Entities/MJActionParam/mjactionparam.form.component.js +5 -23
  90. package/dist/lib/generated/Entities/MJActionParam/mjactionparam.form.component.js.map +1 -1
  91. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js +2 -2
  92. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js.map +1 -1
  93. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.d.ts.map +1 -1
  94. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +31 -49
  95. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
  96. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.d.ts.map +1 -1
  97. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js +38 -56
  98. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js.map +1 -1
  99. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.d.ts.map +1 -1
  100. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js +31 -13
  101. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js.map +1 -1
  102. package/dist/lib/generated/Entities/MJDataContext/mjdatacontext.form.component.d.ts.map +1 -1
  103. package/dist/lib/generated/Entities/MJDataContext/mjdatacontext.form.component.js +7 -25
  104. package/dist/lib/generated/Entities/MJDataContext/mjdatacontext.form.component.js.map +1 -1
  105. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +3 -3
  106. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  107. package/dist/lib/generated/Entities/MJEntityAction/mjentityaction.form.component.js +38 -36
  108. package/dist/lib/generated/Entities/MJEntityAction/mjentityaction.form.component.js.map +1 -1
  109. package/dist/lib/generated/Entities/MJEntityActionParam/mjentityactionparam.form.component.d.ts.map +1 -1
  110. package/dist/lib/generated/Entities/MJEntityActionParam/mjentityactionparam.form.component.js +7 -13
  111. package/dist/lib/generated/Entities/MJEntityActionParam/mjentityactionparam.form.component.js.map +1 -1
  112. package/dist/lib/generated/Entities/MJEntityRelationship/mjentityrelationship.form.component.js +12 -10
  113. package/dist/lib/generated/Entities/MJEntityRelationship/mjentityrelationship.form.component.js.map +1 -1
  114. package/dist/lib/generated/Entities/MJEnvironment/mjenvironment.form.component.d.ts.map +1 -1
  115. package/dist/lib/generated/Entities/MJEnvironment/mjenvironment.form.component.js +15 -33
  116. package/dist/lib/generated/Entities/MJEnvironment/mjenvironment.form.component.js.map +1 -1
  117. package/dist/lib/generated/Entities/MJOutputDeliveryType/mjoutputdeliverytype.form.component.d.ts.map +1 -1
  118. package/dist/lib/generated/Entities/MJOutputDeliveryType/mjoutputdeliverytype.form.component.js +6 -25
  119. package/dist/lib/generated/Entities/MJOutputDeliveryType/mjoutputdeliverytype.form.component.js.map +1 -1
  120. package/dist/lib/generated/Entities/MJOutputFormatType/mjoutputformattype.form.component.d.ts.map +1 -1
  121. package/dist/lib/generated/Entities/MJOutputFormatType/mjoutputformattype.form.component.js +6 -25
  122. package/dist/lib/generated/Entities/MJOutputFormatType/mjoutputformattype.form.component.js.map +1 -1
  123. package/dist/lib/generated/Entities/MJScheduledJob/mjscheduledjob.form.component.d.ts.map +1 -1
  124. package/dist/lib/generated/Entities/MJScheduledJob/mjscheduledjob.form.component.js +45 -25
  125. package/dist/lib/generated/Entities/MJScheduledJob/mjscheduledjob.form.component.js.map +1 -1
  126. package/dist/lib/generated/Entities/MJTask/mjtask.form.component.d.ts.map +1 -1
  127. package/dist/lib/generated/Entities/MJTask/mjtask.form.component.js +68 -24
  128. package/dist/lib/generated/Entities/MJTask/mjtask.form.component.js.map +1 -1
  129. package/dist/lib/generated/Entities/MJTaskDependency/mjtaskdependency.form.component.d.ts.map +1 -1
  130. package/dist/lib/generated/Entities/MJTaskDependency/mjtaskdependency.form.component.js +20 -6
  131. package/dist/lib/generated/Entities/MJTaskDependency/mjtaskdependency.form.component.js.map +1 -1
  132. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  133. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +372 -462
  134. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  135. package/dist/lib/generated/generated-forms.module.d.ts +375 -389
  136. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  137. package/dist/lib/generated/generated-forms.module.js +158 -215
  138. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  139. package/package.json +43 -42
  140. package/dist/lib/generated/Entities/MJOutputTriggerType/mjoutputtriggertype.form.component.d.ts +0 -10
  141. package/dist/lib/generated/Entities/MJOutputTriggerType/mjoutputtriggertype.form.component.d.ts.map +0 -1
  142. package/dist/lib/generated/Entities/MJOutputTriggerType/mjoutputtriggertype.form.component.js +0 -83
  143. package/dist/lib/generated/Entities/MJOutputTriggerType/mjoutputtriggertype.form.component.js.map +0 -1
  144. package/dist/lib/generated/Entities/MJReport/mjreport.form.component.d.ts +0 -10
  145. package/dist/lib/generated/Entities/MJReport/mjreport.form.component.d.ts.map +0 -1
  146. package/dist/lib/generated/Entities/MJReport/mjreport.form.component.js +0 -161
  147. package/dist/lib/generated/Entities/MJReport/mjreport.form.component.js.map +0 -1
  148. package/dist/lib/generated/Entities/MJReportCategory/mjreportcategory.form.component.d.ts +0 -10
  149. package/dist/lib/generated/Entities/MJReportCategory/mjreportcategory.form.component.d.ts.map +0 -1
  150. package/dist/lib/generated/Entities/MJReportCategory/mjreportcategory.form.component.js +0 -113
  151. package/dist/lib/generated/Entities/MJReportCategory/mjreportcategory.form.component.js.map +0 -1
  152. package/dist/lib/generated/Entities/MJReportSnapshot/mjreportsnapshot.form.component.d.ts +0 -10
  153. package/dist/lib/generated/Entities/MJReportSnapshot/mjreportsnapshot.form.component.js +0 -72
  154. package/dist/lib/generated/Entities/MJReportSnapshot/mjreportsnapshot.form.component.js.map +0 -1
  155. package/dist/lib/generated/Entities/MJReportUserState/mjreportuserstate.form.component.d.ts +0 -10
  156. package/dist/lib/generated/Entities/MJReportUserState/mjreportuserstate.form.component.d.ts.map +0 -1
  157. package/dist/lib/generated/Entities/MJReportUserState/mjreportuserstate.form.component.js +0 -72
  158. package/dist/lib/generated/Entities/MJReportUserState/mjreportuserstate.form.component.js.map +0 -1
  159. package/dist/lib/generated/Entities/MJReportVersion/mjreportversion.form.component.d.ts +0 -10
  160. package/dist/lib/generated/Entities/MJReportVersion/mjreportversion.form.component.d.ts.map +0 -1
  161. package/dist/lib/generated/Entities/MJReportVersion/mjreportversion.form.component.js +0 -78
  162. package/dist/lib/generated/Entities/MJReportVersion/mjreportversion.form.component.js.map +0 -1
  163. package/dist/lib/generated/Entities/MJScheduledAction/mjscheduledaction.form.component.d.ts +0 -10
  164. package/dist/lib/generated/Entities/MJScheduledAction/mjscheduledaction.form.component.d.ts.map +0 -1
  165. package/dist/lib/generated/Entities/MJScheduledAction/mjscheduledaction.form.component.js +0 -135
  166. package/dist/lib/generated/Entities/MJScheduledAction/mjscheduledaction.form.component.js.map +0 -1
  167. package/dist/lib/generated/Entities/MJScheduledActionParam/mjscheduledactionparam.form.component.d.ts +0 -10
  168. package/dist/lib/generated/Entities/MJScheduledActionParam/mjscheduledactionparam.form.component.d.ts.map +0 -1
  169. package/dist/lib/generated/Entities/MJScheduledActionParam/mjscheduledactionparam.form.component.js +0 -76
  170. package/dist/lib/generated/Entities/MJScheduledActionParam/mjscheduledactionparam.form.component.js.map +0 -1
  171. package/dist/lib/generated/Entities/MJWorkflow/mjworkflow.form.component.d.ts +0 -10
  172. package/dist/lib/generated/Entities/MJWorkflow/mjworkflow.form.component.d.ts.map +0 -1
  173. package/dist/lib/generated/Entities/MJWorkflow/mjworkflow.form.component.js +0 -121
  174. package/dist/lib/generated/Entities/MJWorkflow/mjworkflow.form.component.js.map +0 -1
  175. package/dist/lib/generated/Entities/MJWorkflowEngine/mjworkflowengine.form.component.d.ts +0 -10
  176. package/dist/lib/generated/Entities/MJWorkflowEngine/mjworkflowengine.form.component.d.ts.map +0 -1
  177. package/dist/lib/generated/Entities/MJWorkflowEngine/mjworkflowengine.form.component.js +0 -87
  178. package/dist/lib/generated/Entities/MJWorkflowEngine/mjworkflowengine.form.component.js.map +0 -1
  179. package/dist/lib/generated/Entities/MJWorkflowRun/mjworkflowrun.form.component.d.ts +0 -10
  180. package/dist/lib/generated/Entities/MJWorkflowRun/mjworkflowrun.form.component.d.ts.map +0 -1
  181. package/dist/lib/generated/Entities/MJWorkflowRun/mjworkflowrun.form.component.js +0 -80
  182. package/dist/lib/generated/Entities/MJWorkflowRun/mjworkflowrun.form.component.js.map +0 -1
@@ -2,6 +2,7 @@ import { Component, Input, ViewChild, ChangeDetectionStrategy } from '@angular/c
2
2
  import { Subject } from 'rxjs';
3
3
  import { RunView } from '@memberjunction/core';
4
4
  import { UUIDsEqual, NormalizeUUID } from '@memberjunction/global';
5
+ import { WalkAgentRunTree } from '@memberjunction/ai-core-plus';
5
6
  import * as d3 from 'd3';
6
7
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
7
8
  import * as i0 from "@angular/core";
@@ -56,7 +57,21 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_27_Template(rf,
56
57
  i0.ɵɵadvance();
57
58
  i0.ɵɵtextInterpolate1("", ctx_r1.actionMetrics.statusBreakdown.failed, " failed");
58
59
  } }
59
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_40_Template(rf, ctx) { if (rf & 1) {
60
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_36_Template(rf, ctx) { if (rf & 1) {
61
+ i0.ɵɵelementStart(0, "div", 31)(1, "span");
62
+ i0.ɵɵtext(2);
63
+ i0.ɵɵelementEnd();
64
+ i0.ɵɵelementStart(3, "span");
65
+ i0.ɵɵtext(4);
66
+ i0.ɵɵelementEnd()();
67
+ } if (rf & 2) {
68
+ const ctx_r1 = i0.ɵɵnextContext(2);
69
+ i0.ɵɵadvance(2);
70
+ i0.ɵɵtextInterpolate1("", ctx_r1.formatCost(ctx_r1.promptMetrics.costBreakdown.totalCost), " this run");
71
+ i0.ɵɵadvance(2);
72
+ i0.ɵɵtextInterpolate3("+ ", ctx_r1.formatCost(ctx_r1.DispatchedCost.Cost), " across ", ctx_r1.DispatchedCost.NodeCount, " workflow step", ctx_r1.DispatchedCost.NodeCount === 1 ? "" : "s");
73
+ } }
74
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_41_Template(rf, ctx) { if (rf & 1) {
60
75
  i0.ɵɵelementStart(0, "span");
61
76
  i0.ɵɵtext(1);
62
77
  i0.ɵɵpipe(2, "number");
@@ -66,7 +81,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_40_Template(rf,
66
81
  i0.ɵɵadvance();
67
82
  i0.ɵɵtextInterpolate1("incl. ", i0.ɵɵpipeBind1(2, 1, ctx_r1.promptMetrics.tokenUsage.totalCacheRead + ctx_r1.promptMetrics.tokenUsage.totalCacheWrite), " cached");
68
83
  } }
69
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_41_Template(rf, ctx) { if (rf & 1) {
84
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_42_Template(rf, ctx) { if (rf & 1) {
70
85
  i0.ɵɵelementStart(0, "span");
71
86
  i0.ɵɵtext(1);
72
87
  i0.ɵɵelementEnd();
@@ -75,7 +90,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_41_Template(rf,
75
90
  i0.ɵɵadvance();
76
91
  i0.ɵɵtextInterpolate2("input ", ctx_r1.formatCost(ctx_r1.inputCost), " \u00B7 output ", ctx_r1.formatCost(ctx_r1.outputCost));
77
92
  } }
78
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_42_Template(rf, ctx) { if (rf & 1) {
93
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_43_Template(rf, ctx) { if (rf & 1) {
79
94
  i0.ɵɵelementStart(0, "span", 25);
80
95
  i0.ɵɵtext(1);
81
96
  i0.ɵɵpipe(2, "number");
@@ -85,7 +100,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_42_Template(rf,
85
100
  i0.ɵɵadvance();
86
101
  i0.ɵɵtextInterpolate2("saved ", ctx_r1.formatCost(ctx_r1.cacheSavings), " (", i0.ɵɵpipeBind2(2, 2, ctx_r1.cacheSavingsPct, "1.0-0"), "%) via cache");
87
102
  } }
88
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_55_Template(rf, ctx) { if (rf & 1) {
103
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_56_Template(rf, ctx) { if (rf & 1) {
89
104
  i0.ɵɵelementStart(0, "span");
90
105
  i0.ɵɵtext(1);
91
106
  i0.ɵɵpipe(2, "number");
@@ -95,7 +110,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_55_Template(rf,
95
110
  i0.ɵɵadvance();
96
111
  i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind1(2, 1, ctx_r1.promptMetrics.tokenUsage.totalCacheWrite), " written");
97
112
  } }
98
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_56_Template(rf, ctx) { if (rf & 1) {
113
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_57_Template(rf, ctx) { if (rf & 1) {
99
114
  i0.ɵɵelementStart(0, "span");
100
115
  i0.ɵɵtext(1);
101
116
  i0.ɵɵpipe(2, "number");
@@ -105,14 +120,14 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_56_Template(rf,
105
120
  i0.ɵɵadvance();
106
121
  i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(2, 1, ctx_r1.cacheHitRatePct, "1.0-0"), "% hit rate");
107
122
  } }
108
- function AIAgentRunAnalyticsComponent_Conditional_3_ng_template_69_Template(rf, ctx) { if (rf & 1) {
123
+ function AIAgentRunAnalyticsComponent_Conditional_3_ng_template_70_Template(rf, ctx) { if (rf & 1) {
109
124
  i0.ɵɵelement(0, "i", 21);
110
125
  i0.ɵɵtext(1, " Prompt Analytics ");
111
126
  } }
112
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_71_Template(rf, ctx) { if (rf & 1) {
127
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_72_Template(rf, ctx) { if (rf & 1) {
113
128
  const _r4 = i0.ɵɵgetCurrentView();
114
129
  i0.ɵɵelementStart(0, "div", 37)(1, "button", 42);
115
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_71_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleViewMode()); });
130
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_72_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleViewMode()); });
116
131
  i0.ɵɵelement(2, "i", 43);
117
132
  i0.ɵɵtext(3);
118
133
  i0.ɵɵelementEnd()();
@@ -123,10 +138,10 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_71_Template(rf,
123
138
  i0.ɵɵadvance();
124
139
  i0.ɵɵtextInterpolate1(" ", ctx_r1.viewMode === "grid" ? "Expand All" : "Collapse All", " ");
125
140
  } }
126
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_72_Template(rf, ctx) { if (rf & 1) {
141
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template(rf, ctx) { if (rf & 1) {
127
142
  i0.ɵɵelement(0, "mj-empty-state", 38);
128
143
  } }
129
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
144
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
130
145
  i0.ɵɵelementStart(0, "div", 75);
131
146
  i0.ɵɵelement(1, "span", 76);
132
147
  i0.ɵɵelementStart(2, "span", 77);
@@ -140,9 +155,9 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Conditional_1
140
155
  i0.ɵɵadvance(2);
141
156
  i0.ɵɵtextInterpolate3("", item_r6.key, ": ", item_r6.value.count, " (", (item_r6.value.count / ctx_r1.promptMetrics.totalCount * 100).toFixed(1), "%)");
142
157
  } }
143
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Conditional_12_Template(rf, ctx) { if (rf & 1) {
158
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Conditional_12_Template(rf, ctx) { if (rf & 1) {
144
159
  i0.ɵɵelementStart(0, "div", 69);
145
- i0.ɵɵrepeaterCreate(1, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Conditional_12_For_2_Template, 4, 5, "div", 75, i0.ɵɵcomponentInstance().trackByKey, true);
160
+ i0.ɵɵrepeaterCreate(1, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Conditional_12_For_2_Template, 4, 5, "div", 75, i0.ɵɵcomponentInstance().trackByKey, true);
146
161
  i0.ɵɵpipe(3, "keyvalue");
147
162
  i0.ɵɵelementEnd();
148
163
  } if (rf & 2) {
@@ -150,10 +165,10 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Conditional_1
150
165
  i0.ɵɵadvance();
151
166
  i0.ɵɵrepeater(i0.ɵɵpipeBind1(3, 0, ctx_r1.promptMetrics.byModel));
152
167
  } }
153
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template(rf, ctx) { if (rf & 1) {
168
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template(rf, ctx) { if (rf & 1) {
154
169
  const _r5 = i0.ɵɵgetCurrentView();
155
170
  i0.ɵɵelementStart(0, "div", 39)(1, "div", 45)(2, "div", 46);
156
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("modelDistribution")); });
171
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("modelDistribution")); });
157
172
  i0.ɵɵelementStart(3, "h3");
158
173
  i0.ɵɵelement(4, "i", 67);
159
174
  i0.ɵɵtext(5, " Prompts by Model");
@@ -163,10 +178,10 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template(rf,
163
178
  i0.ɵɵelementEnd()();
164
179
  i0.ɵɵelementStart(8, "div", 50)(9, "div", 51);
165
180
  i0.ɵɵelement(10, "div", 68, 2);
166
- i0.ɵɵconditionalCreate(12, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Conditional_12_Template, 4, 2, "div", 69);
181
+ i0.ɵɵconditionalCreate(12, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Conditional_12_Template, 4, 2, "div", 69);
167
182
  i0.ɵɵelementEnd()()();
168
183
  i0.ɵɵelementStart(13, "div", 45)(14, "div", 46);
169
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template_div_click_14_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("executionTime")); });
184
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template_div_click_14_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("executionTime")); });
170
185
  i0.ɵɵelementStart(15, "h3");
171
186
  i0.ɵɵelement(16, "i", 35);
172
187
  i0.ɵɵtext(17, " Average Execution Time by Vendor");
@@ -178,7 +193,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template(rf,
178
193
  i0.ɵɵelement(22, "div", 70, 3);
179
194
  i0.ɵɵelementEnd()()();
180
195
  i0.ɵɵelementStart(24, "div", 45)(25, "div", 46);
181
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template_div_click_25_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("costByVendor")); });
196
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template_div_click_25_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("costByVendor")); });
182
197
  i0.ɵɵelementStart(26, "h3");
183
198
  i0.ɵɵelement(27, "i", 30);
184
199
  i0.ɵɵtext(28, " Cost Distribution by Vendor");
@@ -192,7 +207,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template(rf,
192
207
  i0.ɵɵtext(36);
193
208
  i0.ɵɵelementEnd()()()();
194
209
  i0.ɵɵelementStart(37, "div", 45)(38, "div", 46);
195
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template_div_click_38_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("tokenUsage")); });
210
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template_div_click_38_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("tokenUsage")); });
196
211
  i0.ɵɵelementStart(39, "h3");
197
212
  i0.ɵɵelement(40, "i", 73);
198
213
  i0.ɵɵtext(41, " Token Usage by Model");
@@ -234,10 +249,10 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template(rf,
234
249
  i0.ɵɵadvance();
235
250
  i0.ɵɵproperty("ngClass", ctx_r1.expandedCharts["tokenUsage"] ? "fa-compress" : "fa-expand");
236
251
  } }
237
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template(rf, ctx) { if (rf & 1) {
252
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_75_Template(rf, ctx) { if (rf & 1) {
238
253
  const _r7 = i0.ɵɵgetCurrentView();
239
254
  i0.ɵɵelementStart(0, "div", 40)(1, "div", 45)(2, "div", 46);
240
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptTime")); });
255
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_75_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptTime")); });
241
256
  i0.ɵɵelementStart(3, "h3");
242
257
  i0.ɵɵelement(4, "i", 78);
243
258
  i0.ɵɵtext(5, " Average Execution Time by Prompt");
@@ -249,7 +264,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template(rf,
249
264
  i0.ɵɵelement(10, "div", 79, 6);
250
265
  i0.ɵɵelementEnd()()();
251
266
  i0.ɵɵelementStart(12, "div", 45)(13, "div", 46);
252
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template_div_click_13_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptToken")); });
267
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_75_Template_div_click_13_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptToken")); });
253
268
  i0.ɵɵelementStart(14, "h3");
254
269
  i0.ɵɵelement(15, "i", 80);
255
270
  i0.ɵɵtext(16, " Token Usage by Prompt");
@@ -261,7 +276,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template(rf,
261
276
  i0.ɵɵelement(21, "div", 81, 7);
262
277
  i0.ɵɵelementEnd()()();
263
278
  i0.ɵɵelementStart(23, "div", 45)(24, "div", 46);
264
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template_div_click_24_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptCost")); });
279
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_75_Template_div_click_24_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptCost")); });
265
280
  i0.ɵɵelementStart(25, "h3");
266
281
  i0.ɵɵelement(26, "i", 67);
267
282
  i0.ɵɵtext(27, " Cost Distribution by Prompt");
@@ -273,7 +288,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template(rf,
273
288
  i0.ɵɵelement(32, "div", 82, 8);
274
289
  i0.ɵɵelementEnd()()();
275
290
  i0.ɵɵelementStart(34, "div", 45)(35, "div", 46);
276
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template_div_click_35_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptCount")); });
291
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_75_Template_div_click_35_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptCount")); });
277
292
  i0.ɵɵelementStart(36, "h3");
278
293
  i0.ɵɵelement(37, "i", 83);
279
294
  i0.ɵɵtext(38, " Prompt Execution Count");
@@ -311,7 +326,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template(rf,
311
326
  i0.ɵɵadvance();
312
327
  i0.ɵɵproperty("ngClass", ctx_r1.expandedCharts["promptCount"] ? "fa-compress" : "fa-expand");
313
328
  } }
314
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_79_For_16_Template(rf, ctx) { if (rf & 1) {
329
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_80_For_16_Template(rf, ctx) { if (rf & 1) {
315
330
  i0.ɵɵelementStart(0, "tr")(1, "td");
316
331
  i0.ɵɵtext(2);
317
332
  i0.ɵɵelementEnd();
@@ -341,7 +356,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_79_For_16_Templa
341
356
  i0.ɵɵadvance(3);
342
357
  i0.ɵɵtextInterpolate1(" ", ctx_r1.calculatePromptSuccessRate(prompt_r8.key), "% ");
343
358
  } }
344
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_79_Template(rf, ctx) { if (rf & 1) {
359
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_80_Template(rf, ctx) { if (rf & 1) {
345
360
  i0.ɵɵelementStart(0, "div", 44)(1, "table")(2, "thead")(3, "tr")(4, "th");
346
361
  i0.ɵɵtext(5, "Prompt Name");
347
362
  i0.ɵɵelementEnd();
@@ -358,7 +373,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_79_Template(rf,
358
373
  i0.ɵɵtext(13, "Success Rate");
359
374
  i0.ɵɵelementEnd()()();
360
375
  i0.ɵɵelementStart(14, "tbody");
361
- i0.ɵɵrepeaterCreate(15, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_79_For_16_Template, 12, 5, "tr", null, i0.ɵɵcomponentInstance().trackByKey, true);
376
+ i0.ɵɵrepeaterCreate(15, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_80_For_16_Template, 12, 5, "tr", null, i0.ɵɵcomponentInstance().trackByKey, true);
362
377
  i0.ɵɵpipe(17, "keyvalue");
363
378
  i0.ɵɵelementEnd()()();
364
379
  } if (rf & 2) {
@@ -366,11 +381,11 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_79_Template(rf,
366
381
  i0.ɵɵadvance(15);
367
382
  i0.ɵɵrepeater(i0.ɵɵpipeBind1(17, 0, ctx_r1.promptMetrics.byPrompt));
368
383
  } }
369
- function AIAgentRunAnalyticsComponent_Conditional_3_ng_template_81_Template(rf, ctx) { if (rf & 1) {
384
+ function AIAgentRunAnalyticsComponent_Conditional_3_ng_template_82_Template(rf, ctx) { if (rf & 1) {
370
385
  i0.ɵɵelement(0, "i", 28);
371
386
  i0.ɵɵtext(1, " Action Analytics ");
372
387
  } }
373
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_110_For_16_Template(rf, ctx) { if (rf & 1) {
388
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_111_For_16_Template(rf, ctx) { if (rf & 1) {
374
389
  i0.ɵɵelementStart(0, "tr")(1, "td");
375
390
  i0.ɵɵtext(2);
376
391
  i0.ɵɵelementEnd();
@@ -402,7 +417,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_110_For_16_Templ
402
417
  i0.ɵɵadvance(2);
403
418
  i0.ɵɵtextInterpolate(ctx_r1.getActionType(action_r9.key));
404
419
  } }
405
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_110_Template(rf, ctx) { if (rf & 1) {
420
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_111_Template(rf, ctx) { if (rf & 1) {
406
421
  i0.ɵɵelementStart(0, "div", 44)(1, "table")(2, "thead")(3, "tr")(4, "th");
407
422
  i0.ɵɵtext(5, "Action Name");
408
423
  i0.ɵɵelementEnd();
@@ -419,7 +434,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_110_Template(rf,
419
434
  i0.ɵɵtext(13, "Type");
420
435
  i0.ɵɵelementEnd()()();
421
436
  i0.ɵɵelementStart(14, "tbody");
422
- i0.ɵɵrepeaterCreate(15, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_110_For_16_Template, 12, 11, "tr", null, i0.ɵɵcomponentInstance().trackByKey, true);
437
+ i0.ɵɵrepeaterCreate(15, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_111_For_16_Template, 12, 11, "tr", null, i0.ɵɵcomponentInstance().trackByKey, true);
423
438
  i0.ɵɵpipe(17, "keyvalue");
424
439
  i0.ɵɵelementEnd()()();
425
440
  } if (rf & 2) {
@@ -427,7 +442,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_110_Template(rf,
427
442
  i0.ɵɵadvance(15);
428
443
  i0.ɵɵrepeater(i0.ɵɵpipeBind1(17, 0, ctx_r1.actionMetrics.byAction));
429
444
  } }
430
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_112_For_8_Template(rf, ctx) { if (rf & 1) {
445
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_113_For_8_Template(rf, ctx) { if (rf & 1) {
431
446
  i0.ɵɵelementStart(0, "div", 89)(1, "span", 90);
432
447
  i0.ɵɵtext(2);
433
448
  i0.ɵɵelementEnd();
@@ -441,7 +456,7 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_112_For_8_Templa
441
456
  i0.ɵɵadvance(2);
442
457
  i0.ɵɵtextInterpolate(error_r10.message);
443
458
  } }
444
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_112_Template(rf, ctx) { if (rf & 1) {
459
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_113_Template(rf, ctx) { if (rf & 1) {
445
460
  i0.ɵɵelementStart(0, "div", 56)(1, "h3");
446
461
  i0.ɵɵelement(2, "i", 86);
447
462
  i0.ɵɵtext(3, " Common Errors ");
@@ -450,21 +465,21 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_112_Template(rf,
450
465
  i0.ɵɵtext(5, " This section shows the most frequent error messages from failed actions, helping identify systemic issues that may need attention. ");
451
466
  i0.ɵɵelementEnd();
452
467
  i0.ɵɵelementStart(6, "div", 88);
453
- i0.ɵɵrepeaterCreate(7, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_112_For_8_Template, 5, 2, "div", 89, i0.ɵɵcomponentInstance().trackByErrorMessage, true);
468
+ i0.ɵɵrepeaterCreate(7, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_113_For_8_Template, 5, 2, "div", 89, i0.ɵɵcomponentInstance().trackByErrorMessage, true);
454
469
  i0.ɵɵelementEnd()();
455
470
  } if (rf & 2) {
456
471
  const ctx_r1 = i0.ɵɵnextContext(2);
457
472
  i0.ɵɵadvance(7);
458
473
  i0.ɵɵrepeater(ctx_r1.getTopErrors());
459
474
  } }
460
- function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_113_Template(rf, ctx) { if (rf & 1) {
475
+ function AIAgentRunAnalyticsComponent_Conditional_3_Conditional_114_Template(rf, ctx) { if (rf & 1) {
461
476
  i0.ɵɵelement(0, "mj-empty-state", 57);
462
477
  } }
463
- function AIAgentRunAnalyticsComponent_Conditional_3_ng_template_115_Template(rf, ctx) { if (rf & 1) {
478
+ function AIAgentRunAnalyticsComponent_Conditional_3_ng_template_116_Template(rf, ctx) { if (rf & 1) {
464
479
  i0.ɵɵelement(0, "i", 92);
465
480
  i0.ɵɵtext(1, " Model Performance Comparison ");
466
481
  } }
467
- function AIAgentRunAnalyticsComponent_Conditional_3_For_139_Template(rf, ctx) { if (rf & 1) {
482
+ function AIAgentRunAnalyticsComponent_Conditional_3_For_140_Template(rf, ctx) { if (rf & 1) {
468
483
  i0.ɵɵelementStart(0, "tr")(1, "td");
469
484
  i0.ɵɵtext(2);
470
485
  i0.ɵɵelementEnd();
@@ -511,11 +526,11 @@ function AIAgentRunAnalyticsComponent_Conditional_3_For_139_Template(rf, ctx) {
511
526
  i0.ɵɵadvance(3);
512
527
  i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(18, 11, model_r11.outputTokens, "1.0-0"));
513
528
  } }
514
- function AIAgentRunAnalyticsComponent_Conditional_3_ng_template_141_Template(rf, ctx) { if (rf & 1) {
529
+ function AIAgentRunAnalyticsComponent_Conditional_3_ng_template_142_Template(rf, ctx) { if (rf & 1) {
515
530
  i0.ɵɵelement(0, "i", 93);
516
531
  i0.ɵɵtext(1, " Execution Timeline Analysis ");
517
532
  } }
518
- function AIAgentRunAnalyticsComponent_Conditional_3_For_169_Template(rf, ctx) { if (rf & 1) {
533
+ function AIAgentRunAnalyticsComponent_Conditional_3_For_170_Template(rf, ctx) { if (rf & 1) {
519
534
  i0.ɵɵelementStart(0, "div", 65);
520
535
  i0.ɵɵelement(1, "i", 43);
521
536
  i0.ɵɵelementStart(2, "span", 94);
@@ -580,154 +595,155 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Template(rf, ctx) { if (rf &
580
595
  i0.ɵɵelementStart(34, "div", 23);
581
596
  i0.ɵɵtext(35);
582
597
  i0.ɵɵelementEnd();
583
- i0.ɵɵelementStart(36, "div", 31)(37, "span");
584
- i0.ɵɵtext(38);
585
- i0.ɵɵpipe(39, "number");
598
+ i0.ɵɵconditionalCreate(36, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_36_Template, 5, 4, "div", 31);
599
+ i0.ɵɵelementStart(37, "div", 31)(38, "span");
600
+ i0.ɵɵtext(39);
601
+ i0.ɵɵpipe(40, "number");
586
602
  i0.ɵɵelementEnd();
587
- i0.ɵɵconditionalCreate(40, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_40_Template, 3, 3, "span");
588
- i0.ɵɵconditionalCreate(41, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_41_Template, 2, 2, "span");
589
- i0.ɵɵconditionalCreate(42, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_42_Template, 3, 5, "span", 25);
603
+ i0.ɵɵconditionalCreate(41, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_41_Template, 3, 3, "span");
604
+ i0.ɵɵconditionalCreate(42, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_42_Template, 2, 2, "span");
605
+ i0.ɵɵconditionalCreate(43, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_43_Template, 3, 5, "span", 25);
590
606
  i0.ɵɵelementEnd()()();
591
- i0.ɵɵelementStart(43, "div", 19)(44, "div", 32);
592
- i0.ɵɵelement(45, "i", 33);
607
+ i0.ɵɵelementStart(44, "div", 19)(45, "div", 32);
608
+ i0.ɵɵelement(46, "i", 33);
593
609
  i0.ɵɵelementEnd();
594
- i0.ɵɵelementStart(46, "div", 22)(47, "h3");
595
- i0.ɵɵtext(48, "Prompt Cache");
610
+ i0.ɵɵelementStart(47, "div", 22)(48, "h3");
611
+ i0.ɵɵtext(49, "Prompt Cache");
596
612
  i0.ɵɵelementEnd();
597
- i0.ɵɵelementStart(49, "div", 23);
598
- i0.ɵɵtext(50);
599
- i0.ɵɵpipe(51, "number");
613
+ i0.ɵɵelementStart(50, "div", 23);
614
+ i0.ɵɵtext(51);
615
+ i0.ɵɵpipe(52, "number");
600
616
  i0.ɵɵelementEnd();
601
- i0.ɵɵelementStart(52, "div", 31)(53, "span");
602
- i0.ɵɵtext(54, "tokens read from cache");
617
+ i0.ɵɵelementStart(53, "div", 31)(54, "span");
618
+ i0.ɵɵtext(55, "tokens read from cache");
603
619
  i0.ɵɵelementEnd();
604
- i0.ɵɵconditionalCreate(55, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_55_Template, 3, 3, "span");
605
- i0.ɵɵconditionalCreate(56, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_56_Template, 3, 4, "span");
620
+ i0.ɵɵconditionalCreate(56, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_56_Template, 3, 3, "span");
621
+ i0.ɵɵconditionalCreate(57, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_57_Template, 3, 4, "span");
606
622
  i0.ɵɵelementEnd()()();
607
- i0.ɵɵelementStart(57, "div", 19)(58, "div", 34);
608
- i0.ɵɵelement(59, "i", 35);
623
+ i0.ɵɵelementStart(58, "div", 19)(59, "div", 34);
624
+ i0.ɵɵelement(60, "i", 35);
609
625
  i0.ɵɵelementEnd();
610
- i0.ɵɵelementStart(60, "div", 22)(61, "h3");
611
- i0.ɵɵtext(62, "Execution Time");
626
+ i0.ɵɵelementStart(61, "div", 22)(62, "h3");
627
+ i0.ɵɵtext(63, "Execution Time");
612
628
  i0.ɵɵelementEnd();
613
- i0.ɵɵelementStart(63, "div", 23);
614
- i0.ɵɵtext(64);
629
+ i0.ɵɵelementStart(64, "div", 23);
630
+ i0.ɵɵtext(65);
615
631
  i0.ɵɵelementEnd();
616
- i0.ɵɵelementStart(65, "div", 24)(66, "span");
617
- i0.ɵɵtext(67);
632
+ i0.ɵɵelementStart(66, "div", 24)(67, "span");
633
+ i0.ɵɵtext(68);
618
634
  i0.ɵɵelementEnd()()()()()();
619
- i0.ɵɵelementStart(68, "mj-accordion-panel", 16);
620
- i0.ɵɵtemplate(69, AIAgentRunAnalyticsComponent_Conditional_3_ng_template_69_Template, 2, 0, "ng-template", 17);
621
- i0.ɵɵelementStart(70, "div", 36);
622
- i0.ɵɵconditionalCreate(71, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_71_Template, 4, 2, "div", 37);
623
- i0.ɵɵconditionalCreate(72, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_72_Template, 1, 0, "mj-empty-state", 38);
624
- i0.ɵɵconditionalCreate(73, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template, 48, 18, "div", 39);
625
- i0.ɵɵconditionalCreate(74, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template, 45, 16, "div", 40);
626
- i0.ɵɵelementStart(75, "div", 41)(76, "button", 42);
627
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Template_button_click_76_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.promptDetailsExpanded = !ctx_r1.promptDetailsExpanded); });
628
- i0.ɵɵelement(77, "i", 43);
629
- i0.ɵɵtext(78, " Detailed Prompt Metrics ");
630
- i0.ɵɵelementEnd();
631
- i0.ɵɵconditionalCreate(79, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_79_Template, 18, 2, "div", 44);
635
+ i0.ɵɵelementStart(69, "mj-accordion-panel", 16);
636
+ i0.ɵɵtemplate(70, AIAgentRunAnalyticsComponent_Conditional_3_ng_template_70_Template, 2, 0, "ng-template", 17);
637
+ i0.ɵɵelementStart(71, "div", 36);
638
+ i0.ɵɵconditionalCreate(72, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_72_Template, 4, 2, "div", 37);
639
+ i0.ɵɵconditionalCreate(73, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_73_Template, 1, 0, "mj-empty-state", 38);
640
+ i0.ɵɵconditionalCreate(74, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_74_Template, 48, 18, "div", 39);
641
+ i0.ɵɵconditionalCreate(75, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_75_Template, 45, 16, "div", 40);
642
+ i0.ɵɵelementStart(76, "div", 41)(77, "button", 42);
643
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Template_button_click_77_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.promptDetailsExpanded = !ctx_r1.promptDetailsExpanded); });
644
+ i0.ɵɵelement(78, "i", 43);
645
+ i0.ɵɵtext(79, " Detailed Prompt Metrics ");
646
+ i0.ɵɵelementEnd();
647
+ i0.ɵɵconditionalCreate(80, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_80_Template, 18, 2, "div", 44);
632
648
  i0.ɵɵelementEnd()()();
633
- i0.ɵɵelementStart(80, "mj-accordion-panel", 16);
634
- i0.ɵɵtemplate(81, AIAgentRunAnalyticsComponent_Conditional_3_ng_template_81_Template, 2, 0, "ng-template", 17);
635
- i0.ɵɵelementStart(82, "div", 36)(83, "div", 39)(84, "div", 45)(85, "div", 46);
636
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Template_div_click_85_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("actionSuccess")); });
637
- i0.ɵɵelementStart(86, "h3");
638
- i0.ɵɵelement(87, "i", 47);
639
- i0.ɵɵtext(88, " Action Success Rate");
640
- i0.ɵɵelementEnd();
641
- i0.ɵɵelementStart(89, "button", 48);
642
- i0.ɵɵelement(90, "i", 49);
649
+ i0.ɵɵelementStart(81, "mj-accordion-panel", 16);
650
+ i0.ɵɵtemplate(82, AIAgentRunAnalyticsComponent_Conditional_3_ng_template_82_Template, 2, 0, "ng-template", 17);
651
+ i0.ɵɵelementStart(83, "div", 36)(84, "div", 39)(85, "div", 45)(86, "div", 46);
652
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Template_div_click_86_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("actionSuccess")); });
653
+ i0.ɵɵelementStart(87, "h3");
654
+ i0.ɵɵelement(88, "i", 47);
655
+ i0.ɵɵtext(89, " Action Success Rate");
656
+ i0.ɵɵelementEnd();
657
+ i0.ɵɵelementStart(90, "button", 48);
658
+ i0.ɵɵelement(91, "i", 49);
643
659
  i0.ɵɵelementEnd()();
644
- i0.ɵɵelementStart(91, "div", 50)(92, "div", 51);
645
- i0.ɵɵelement(93, "div", 52, 0);
660
+ i0.ɵɵelementStart(92, "div", 50)(93, "div", 51);
661
+ i0.ɵɵelement(94, "div", 52, 0);
646
662
  i0.ɵɵelementEnd()()();
647
- i0.ɵɵelementStart(95, "div", 45)(96, "div", 46);
648
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Template_div_click_96_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("stepType")); });
649
- i0.ɵɵelementStart(97, "h3");
650
- i0.ɵɵelement(98, "i", 53);
651
- i0.ɵɵtext(99, " Step Type Distribution");
652
- i0.ɵɵelementEnd();
653
- i0.ɵɵelementStart(100, "button", 48);
654
- i0.ɵɵelement(101, "i", 49);
663
+ i0.ɵɵelementStart(96, "div", 45)(97, "div", 46);
664
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Template_div_click_97_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("stepType")); });
665
+ i0.ɵɵelementStart(98, "h3");
666
+ i0.ɵɵelement(99, "i", 53);
667
+ i0.ɵɵtext(100, " Step Type Distribution");
668
+ i0.ɵɵelementEnd();
669
+ i0.ɵɵelementStart(101, "button", 48);
670
+ i0.ɵɵelement(102, "i", 49);
655
671
  i0.ɵɵelementEnd()();
656
- i0.ɵɵelementStart(102, "div", 50)(103, "div", 51);
657
- i0.ɵɵelement(104, "div", 54, 1);
672
+ i0.ɵɵelementStart(103, "div", 50)(104, "div", 51);
673
+ i0.ɵɵelement(105, "div", 54, 1);
658
674
  i0.ɵɵelementEnd()()()();
659
- i0.ɵɵelementStart(106, "div", 41)(107, "button", 42);
660
- i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Template_button_click_107_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.actionDetailsExpanded = !ctx_r1.actionDetailsExpanded); });
661
- i0.ɵɵelement(108, "i", 43);
662
- i0.ɵɵtext(109, " Detailed Action Metrics ");
675
+ i0.ɵɵelementStart(107, "div", 41)(108, "button", 42);
676
+ i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_Conditional_3_Template_button_click_108_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.actionDetailsExpanded = !ctx_r1.actionDetailsExpanded); });
677
+ i0.ɵɵelement(109, "i", 43);
678
+ i0.ɵɵtext(110, " Detailed Action Metrics ");
663
679
  i0.ɵɵelementEnd();
664
- i0.ɵɵconditionalCreate(110, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_110_Template, 18, 2, "div", 44);
680
+ i0.ɵɵconditionalCreate(111, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_111_Template, 18, 2, "div", 44);
665
681
  i0.ɵɵelementEnd();
666
- i0.ɵɵelementStart(111, "div", 55);
667
- i0.ɵɵconditionalCreate(112, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_112_Template, 9, 0, "div", 56);
668
- i0.ɵɵconditionalCreate(113, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_113_Template, 1, 0, "mj-empty-state", 57);
682
+ i0.ɵɵelementStart(112, "div", 55);
683
+ i0.ɵɵconditionalCreate(113, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_113_Template, 9, 0, "div", 56);
684
+ i0.ɵɵconditionalCreate(114, AIAgentRunAnalyticsComponent_Conditional_3_Conditional_114_Template, 1, 0, "mj-empty-state", 57);
669
685
  i0.ɵɵelementEnd()()();
670
- i0.ɵɵelementStart(114, "mj-accordion-panel", 16);
671
- i0.ɵɵtemplate(115, AIAgentRunAnalyticsComponent_Conditional_3_ng_template_115_Template, 2, 0, "ng-template", 17);
672
- i0.ɵɵelementStart(116, "div", 36)(117, "div", 58)(118, "table")(119, "thead")(120, "tr")(121, "th");
673
- i0.ɵɵtext(122, "Model");
686
+ i0.ɵɵelementStart(115, "mj-accordion-panel", 16);
687
+ i0.ɵɵtemplate(116, AIAgentRunAnalyticsComponent_Conditional_3_ng_template_116_Template, 2, 0, "ng-template", 17);
688
+ i0.ɵɵelementStart(117, "div", 36)(118, "div", 58)(119, "table")(120, "thead")(121, "tr")(122, "th");
689
+ i0.ɵɵtext(123, "Model");
674
690
  i0.ɵɵelementEnd();
675
- i0.ɵɵelementStart(123, "th");
676
- i0.ɵɵtext(124, "Vendor");
691
+ i0.ɵɵelementStart(124, "th");
692
+ i0.ɵɵtext(125, "Vendor");
677
693
  i0.ɵɵelementEnd();
678
- i0.ɵɵelementStart(125, "th");
679
- i0.ɵɵtext(126, "Prompts");
694
+ i0.ɵɵelementStart(126, "th");
695
+ i0.ɵɵtext(127, "Prompts");
680
696
  i0.ɵɵelementEnd();
681
- i0.ɵɵelementStart(127, "th");
682
- i0.ɵɵtext(128, "Avg Time");
697
+ i0.ɵɵelementStart(128, "th");
698
+ i0.ɵɵtext(129, "Avg Time");
683
699
  i0.ɵɵelementEnd();
684
- i0.ɵɵelementStart(129, "th");
685
- i0.ɵɵtext(130, "Total Cost");
700
+ i0.ɵɵelementStart(130, "th");
701
+ i0.ɵɵtext(131, "Total Cost");
686
702
  i0.ɵɵelementEnd();
687
- i0.ɵɵelementStart(131, "th");
688
- i0.ɵɵtext(132, "Avg Cost/Prompt");
703
+ i0.ɵɵelementStart(132, "th");
704
+ i0.ɵɵtext(133, "Avg Cost/Prompt");
689
705
  i0.ɵɵelementEnd();
690
- i0.ɵɵelementStart(133, "th");
691
- i0.ɵɵtext(134, "Input Tokens");
706
+ i0.ɵɵelementStart(134, "th");
707
+ i0.ɵɵtext(135, "Input Tokens");
692
708
  i0.ɵɵelementEnd();
693
- i0.ɵɵelementStart(135, "th");
694
- i0.ɵɵtext(136, "Output Tokens");
709
+ i0.ɵɵelementStart(136, "th");
710
+ i0.ɵɵtext(137, "Output Tokens");
695
711
  i0.ɵɵelementEnd()()();
696
- i0.ɵɵelementStart(137, "tbody");
697
- i0.ɵɵrepeaterCreate(138, AIAgentRunAnalyticsComponent_Conditional_3_For_139_Template, 19, 14, "tr", null, i0.ɵɵcomponentInstance().trackByModelName, true);
712
+ i0.ɵɵelementStart(138, "tbody");
713
+ i0.ɵɵrepeaterCreate(139, AIAgentRunAnalyticsComponent_Conditional_3_For_140_Template, 19, 14, "tr", null, i0.ɵɵcomponentInstance().trackByModelName, true);
698
714
  i0.ɵɵelementEnd()()()()();
699
- i0.ɵɵelementStart(140, "mj-accordion-panel", 16);
700
- i0.ɵɵtemplate(141, AIAgentRunAnalyticsComponent_Conditional_3_ng_template_141_Template, 2, 0, "ng-template", 17);
701
- i0.ɵɵelementStart(142, "div", 36)(143, "div", 59)(144, "div", 60)(145, "span", 61);
702
- i0.ɵɵtext(146, "Total Steps");
715
+ i0.ɵɵelementStart(141, "mj-accordion-panel", 16);
716
+ i0.ɵɵtemplate(142, AIAgentRunAnalyticsComponent_Conditional_3_ng_template_142_Template, 2, 0, "ng-template", 17);
717
+ i0.ɵɵelementStart(143, "div", 36)(144, "div", 59)(145, "div", 60)(146, "span", 61);
718
+ i0.ɵɵtext(147, "Total Steps");
703
719
  i0.ɵɵelementEnd();
704
- i0.ɵɵelementStart(147, "span", 62);
705
- i0.ɵɵtext(148);
720
+ i0.ɵɵelementStart(148, "span", 62);
721
+ i0.ɵɵtext(149);
706
722
  i0.ɵɵelementEnd()();
707
- i0.ɵɵelementStart(149, "div", 60)(150, "span", 61);
708
- i0.ɵɵtext(151, "Parallel Executions");
723
+ i0.ɵɵelementStart(150, "div", 60)(151, "span", 61);
724
+ i0.ɵɵtext(152, "Parallel Executions");
709
725
  i0.ɵɵelementEnd();
710
- i0.ɵɵelementStart(152, "span", 62);
711
- i0.ɵɵtext(153);
726
+ i0.ɵɵelementStart(153, "span", 62);
727
+ i0.ɵɵtext(154);
712
728
  i0.ɵɵelementEnd()();
713
- i0.ɵɵelementStart(154, "div", 60)(155, "span", 61);
714
- i0.ɵɵtext(156, "Max Nesting Depth");
729
+ i0.ɵɵelementStart(155, "div", 60)(156, "span", 61);
730
+ i0.ɵɵtext(157, "Max Nesting Depth");
715
731
  i0.ɵɵelementEnd();
716
- i0.ɵɵelementStart(157, "span", 62);
717
- i0.ɵɵtext(158);
732
+ i0.ɵɵelementStart(158, "span", 62);
733
+ i0.ɵɵtext(159);
718
734
  i0.ɵɵelementEnd()();
719
- i0.ɵɵelementStart(159, "div", 60)(160, "span", 61);
720
- i0.ɵɵtext(161, "Sub-Agent Runs");
735
+ i0.ɵɵelementStart(160, "div", 60)(161, "span", 61);
736
+ i0.ɵɵtext(162, "Sub-Agent Runs");
721
737
  i0.ɵɵelementEnd();
722
- i0.ɵɵelementStart(162, "span", 62);
723
- i0.ɵɵtext(163);
738
+ i0.ɵɵelementStart(163, "span", 62);
739
+ i0.ɵɵtext(164);
724
740
  i0.ɵɵelementEnd()()();
725
- i0.ɵɵelementStart(164, "div", 63)(165, "h3");
726
- i0.ɵɵtext(166, "Steps by Type");
741
+ i0.ɵɵelementStart(165, "div", 63)(166, "h3");
742
+ i0.ɵɵtext(167, "Steps by Type");
727
743
  i0.ɵɵelementEnd();
728
- i0.ɵɵelementStart(167, "div", 64);
729
- i0.ɵɵrepeaterCreate(168, AIAgentRunAnalyticsComponent_Conditional_3_For_169_Template, 8, 4, "div", 65, i0.ɵɵcomponentInstance().trackByKey, true);
730
- i0.ɵɵpipe(170, "keyvalue");
744
+ i0.ɵɵelementStart(168, "div", 64);
745
+ i0.ɵɵrepeaterCreate(169, AIAgentRunAnalyticsComponent_Conditional_3_For_170_Template, 8, 4, "div", 65, i0.ɵɵcomponentInstance().trackByKey, true);
746
+ i0.ɵɵpipe(171, "keyvalue");
731
747
  i0.ɵɵelementEnd()()()()();
732
748
  } if (rf & 2) {
733
749
  const ctx_r1 = i0.ɵɵnextContext();
@@ -746,21 +762,23 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Template(rf, ctx) { if (rf &
746
762
  i0.ɵɵadvance();
747
763
  i0.ɵɵconditional(ctx_r1.actionMetrics.statusBreakdown.failed > 0 ? 27 : -1);
748
764
  i0.ɵɵadvance(8);
749
- i0.ɵɵtextInterpolate(ctx_r1.formatCost(ctx_r1.promptMetrics.costBreakdown.totalCost));
765
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.formatCost(ctx_r1.promptMetrics.costBreakdown.totalCost + ctx_r1.DispatchedCost.Cost), " ");
766
+ i0.ɵɵadvance();
767
+ i0.ɵɵconditional(ctx_r1.HasDispatchedWork ? 36 : -1);
750
768
  i0.ɵɵadvance(3);
751
- i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind1(39, 43, ctx_r1.totalTokensProcessed), " tokens");
769
+ i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind1(40, 44, ctx_r1.totalTokensProcessed), " tokens");
752
770
  i0.ɵɵadvance(2);
753
- i0.ɵɵconditional(ctx_r1.promptMetrics.tokenUsage.totalCacheRead > 0 || ctx_r1.promptMetrics.tokenUsage.totalCacheWrite > 0 ? 40 : -1);
771
+ i0.ɵɵconditional(ctx_r1.promptMetrics.tokenUsage.totalCacheRead > 0 || ctx_r1.promptMetrics.tokenUsage.totalCacheWrite > 0 ? 41 : -1);
754
772
  i0.ɵɵadvance();
755
- i0.ɵɵconditional(ctx_r1.inputCost > 0 || ctx_r1.outputCost > 0 ? 41 : -1);
773
+ i0.ɵɵconditional(ctx_r1.inputCost > 0 || ctx_r1.outputCost > 0 ? 42 : -1);
756
774
  i0.ɵɵadvance();
757
- i0.ɵɵconditional(ctx_r1.cacheSavings > 0 ? 42 : -1);
775
+ i0.ɵɵconditional(ctx_r1.cacheSavings > 0 ? 43 : -1);
758
776
  i0.ɵɵadvance(8);
759
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(51, 45, ctx_r1.promptMetrics.tokenUsage.totalCacheRead));
777
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(52, 46, ctx_r1.promptMetrics.tokenUsage.totalCacheRead));
760
778
  i0.ɵɵadvance(5);
761
- i0.ɵɵconditional(ctx_r1.promptMetrics.tokenUsage.totalCacheWrite > 0 ? 55 : -1);
779
+ i0.ɵɵconditional(ctx_r1.promptMetrics.tokenUsage.totalCacheWrite > 0 ? 56 : -1);
762
780
  i0.ɵɵadvance();
763
- i0.ɵɵconditional(ctx_r1.promptMetrics.tokenUsage.totalCacheRead > 0 || ctx_r1.promptMetrics.tokenUsage.totalCacheWrite > 0 ? 56 : -1);
781
+ i0.ɵɵconditional(ctx_r1.promptMetrics.tokenUsage.totalCacheRead > 0 || ctx_r1.promptMetrics.tokenUsage.totalCacheWrite > 0 ? 57 : -1);
764
782
  i0.ɵɵadvance(8);
765
783
  i0.ɵɵtextInterpolate(ctx_r1.formatDuration(ctx_r1.promptMetrics.totalExecutionTime + ctx_r1.actionMetrics.totalExecutionTime));
766
784
  i0.ɵɵadvance(3);
@@ -768,17 +786,17 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Template(rf, ctx) { if (rf &
768
786
  i0.ɵɵadvance();
769
787
  i0.ɵɵproperty("Expanded", true);
770
788
  i0.ɵɵadvance(3);
771
- i0.ɵɵconditional(ctx_r1.promptMetrics.totalCount > 0 ? 71 : -1);
772
- i0.ɵɵadvance();
773
- i0.ɵɵconditional(ctx_r1.promptMetrics.totalCount === 0 ? 72 : -1);
789
+ i0.ɵɵconditional(ctx_r1.promptMetrics.totalCount > 0 ? 72 : -1);
774
790
  i0.ɵɵadvance();
775
- i0.ɵɵconditional(ctx_r1.promptMetrics.totalCount > 0 ? 73 : -1);
791
+ i0.ɵɵconditional(ctx_r1.promptMetrics.totalCount === 0 ? 73 : -1);
776
792
  i0.ɵɵadvance();
777
793
  i0.ɵɵconditional(ctx_r1.promptMetrics.totalCount > 0 ? 74 : -1);
794
+ i0.ɵɵadvance();
795
+ i0.ɵɵconditional(ctx_r1.promptMetrics.totalCount > 0 ? 75 : -1);
778
796
  i0.ɵɵadvance(3);
779
797
  i0.ɵɵproperty("ngClass", ctx_r1.promptDetailsExpanded ? "fa-chevron-up" : "fa-chevron-down");
780
798
  i0.ɵɵadvance(2);
781
- i0.ɵɵconditional(ctx_r1.promptDetailsExpanded ? 79 : -1);
799
+ i0.ɵɵconditional(ctx_r1.promptDetailsExpanded ? 80 : -1);
782
800
  i0.ɵɵadvance();
783
801
  i0.ɵɵproperty("Expanded", true);
784
802
  i0.ɵɵadvance(4);
@@ -796,11 +814,11 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Template(rf, ctx) { if (rf &
796
814
  i0.ɵɵadvance(7);
797
815
  i0.ɵɵproperty("ngClass", ctx_r1.actionDetailsExpanded ? "fa-chevron-up" : "fa-chevron-down");
798
816
  i0.ɵɵadvance(2);
799
- i0.ɵɵconditional(ctx_r1.actionDetailsExpanded ? 110 : -1);
817
+ i0.ɵɵconditional(ctx_r1.actionDetailsExpanded ? 111 : -1);
800
818
  i0.ɵɵadvance(2);
801
- i0.ɵɵconditional(ctx_r1.actionMetrics.errorAnalysis.size > 0 ? 112 : -1);
819
+ i0.ɵɵconditional(ctx_r1.actionMetrics.errorAnalysis.size > 0 ? 113 : -1);
802
820
  i0.ɵɵadvance();
803
- i0.ɵɵconditional(ctx_r1.actionMetrics.errorAnalysis.size === 0 ? 113 : -1);
821
+ i0.ɵɵconditional(ctx_r1.actionMetrics.errorAnalysis.size === 0 ? 114 : -1);
804
822
  i0.ɵɵadvance();
805
823
  i0.ɵɵproperty("Expanded", true);
806
824
  i0.ɵɵadvance(24);
@@ -816,9 +834,46 @@ function AIAgentRunAnalyticsComponent_Conditional_3_Template(rf, ctx) { if (rf &
816
834
  i0.ɵɵadvance(5);
817
835
  i0.ɵɵtextInterpolate(ctx_r1.subAgentRuns.length);
818
836
  i0.ɵɵadvance(5);
819
- i0.ɵɵrepeater(i0.ɵɵpipeBind1(170, 47, ctx_r1.timelineMetrics.stepsByType));
837
+ i0.ɵɵrepeater(i0.ɵɵpipeBind1(171, 48, ctx_r1.timelineMetrics.stepsByType));
820
838
  } }
821
839
  export class AIAgentRunAnalyticsComponent extends BaseAngularComponent {
840
+ /**
841
+ * The run's execution tree, loaded once by the form and shared with every tab.
842
+ *
843
+ * **This is what makes the totals honest.** Analytics derives cost from prompt runs reached
844
+ * through the run's own STEPS, which cannot see work the run dispatched: a task-graph's spend
845
+ * lives on Task rows and on prompt runs those tasks produced, so a workflow's cost was simply
846
+ * missing from every figure on this tab. Each tree node reports its OWN cost — never a rollup —
847
+ * so a total is an honest sum rather than a double-count.
848
+ */
849
+ set RunTree(value) {
850
+ this.runTree = value;
851
+ this.cdr.markForCheck();
852
+ }
853
+ /**
854
+ * What the dispatched work cost, from the tree — the part the step-based figures cannot see.
855
+ *
856
+ * Zero when there is no graph, so a run that dispatched nothing reads exactly as it did before.
857
+ */
858
+ get DispatchedCost() {
859
+ if (!this.runTree)
860
+ return { Cost: 0, Tokens: 0, NodeCount: 0 };
861
+ let cost = 0, tokens = 0, nodeCount = 0;
862
+ for (const node of WalkAgentRunTree(this.runTree)) {
863
+ // Only nodes the RUN's own step list cannot reach. Counting the run's steps here as well
864
+ // would double every figure this tab already shows correctly.
865
+ if (node.NodeType !== 'Task' && node.NodeType !== 'TaskGraph')
866
+ continue;
867
+ nodeCount++;
868
+ cost += node.Cost ?? 0;
869
+ tokens += node.Tokens ?? 0;
870
+ }
871
+ return { Cost: cost, Tokens: tokens, NodeCount: nodeCount };
872
+ }
873
+ /** True when this run dispatched a workflow, so the tab can show the extra figures at all. */
874
+ get HasDispatchedWork() {
875
+ return this.DispatchedCost.NodeCount > 0;
876
+ }
822
877
  /** Helper method to create tracked setTimeout calls */
823
878
  setTrackedTimeout(callback, delay = 0) {
824
879
  const timeoutId = setTimeout(() => {
@@ -843,6 +898,7 @@ export class AIAgentRunAnalyticsComponent extends BaseAngularComponent {
843
898
  super();
844
899
  this.cdr = cdr;
845
900
  this.costService = costService;
901
+ this.runTree = null;
846
902
  this.destroy$ = new Subject();
847
903
  /** Track active timeouts for cleanup */
848
904
  this.activeTimeouts = [];
@@ -2289,11 +2345,11 @@ export class AIAgentRunAnalyticsComponent extends BaseAngularComponent {
2289
2345
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.promptTokenDistributionChart = _t.first);
2290
2346
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.promptCostDistributionChart = _t.first);
2291
2347
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.promptCountByNameChart = _t.first);
2292
- } }, inputs: { agentRunId: "agentRunId" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 3, consts: [["actionSuccessRateChart", ""], ["stepTypeChart", ""], ["modelDistributionChart", ""], ["executionTimeChart", ""], ["costByVendorChart", ""], ["tokenUsageChart", ""], ["promptTimeDistributionChart", ""], ["promptTokenDistributionChart", ""], ["promptCostDistributionChart", ""], ["promptCountByNameChart", ""], [1, "analytics-container"], [1, "loading-state"], ["Variant", "error", "ActionText", "Retry", "ActionIcon", "fa-solid fa-arrows-rotate", 3, "Message"], [1, "analytics-content"], [1, "fas", "fa-spinner", "fa-spin", "fa-2x"], ["Variant", "error", "ActionText", "Retry", "ActionIcon", "fa-solid fa-arrows-rotate", 3, "Action", "Message"], [3, "Expanded"], ["mjAccordionTitle", ""], [1, "summary-cards"], [1, "summary-card"], [1, "card-icon", "prompts"], [1, "fas", "fa-microchip"], [1, "card-content"], [1, "metric-value"], [1, "metric-detail"], [1, "success"], [1, "failed"], [1, "card-icon", "actions"], [1, "fas", "fa-cog"], [1, "card-icon", "cost"], [1, "fas", "fa-dollar-sign"], [1, "metric-detail", "cache-detail"], [1, "card-icon", "cache"], [1, "fas", "fa-bolt"], [1, "card-icon", "time"], [1, "fas", "fa-clock"], [1, "analytics-panel"], [1, "view-mode-toggle"], ["Icon", "fa-solid fa-circle-info", "Title", "No prompt executions found in this agent run.", "Message", "This agent run may have only executed actions without any AI prompts."], [1, "charts-grid"], [1, "charts-grid", 2, "margin-top", "20px"], [1, "detailed-metrics"], ["mjButton", "", "variant", "flat", 3, "click"], [1, "fas", 3, "ngClass"], [1, "metrics-table"], [1, "chart-card"], [1, "chart-card-header", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "expand-btn"], ["aria-hidden", "true", 1, "fas", 3, "ngClass"], [1, "chart-card-body"], [1, "chart-container"], ["id", "actionSuccessRateChart"], [1, "fas", "fa-layer-group"], ["id", "stepTypeChart"], [1, "error-analysis-section"], [1, "error-analysis"], ["Variant", "success", "Message", "No action errors detected in this run. All actions completed successfully!"], [1, "model-comparison"], [1, "timeline-stats"], [1, "stat-item"], [1, "stat-label"], [1, "stat-value"], [1, "step-breakdown"], [1, "step-type-list"], [1, "step-type-item"], [1, "fas", "fa-tachometer-alt"], [1, "fas", "fa-chart-pie"], ["id", "modelDistributionChart"], [1, "chart-legend"], ["id", "executionTimeChart"], ["id", "costByVendorChart"], [1, "chart-total"], [1, "fas", "fa-coins"], ["id", "tokenUsageChart"], [1, "legend-item"], [1, "legend-color"], [1, "legend-label"], [1, "fas", "fa-hourglass-half"], ["id", "promptTimeDistributionChart"], [1, "fas", "fa-database"], ["id", "promptTokenDistributionChart"], ["id", "promptCostDistributionChart"], [1, "fas", "fa-list-ol"], ["id", "promptCountByNameChart"], [1, "success-rate"], [1, "fas", "fa-exclamation-triangle"], [1, "error-analysis-description"], [1, "error-list"], [1, "error-item"], [1, "error-count"], [1, "error-message"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-stream"], [1, "type-name"], [1, "type-count"], [1, "type-percentage"]], template: function AIAgentRunAnalyticsComponent_Template(rf, ctx) { if (rf & 1) {
2348
+ } }, inputs: { agentRunId: "agentRunId", RunTree: "RunTree" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 3, consts: [["actionSuccessRateChart", ""], ["stepTypeChart", ""], ["modelDistributionChart", ""], ["executionTimeChart", ""], ["costByVendorChart", ""], ["tokenUsageChart", ""], ["promptTimeDistributionChart", ""], ["promptTokenDistributionChart", ""], ["promptCostDistributionChart", ""], ["promptCountByNameChart", ""], [1, "analytics-container"], [1, "loading-state"], ["Variant", "error", "ActionText", "Retry", "ActionIcon", "fa-solid fa-arrows-rotate", 3, "Message"], [1, "analytics-content"], [1, "fas", "fa-spinner", "fa-spin", "fa-2x"], ["Variant", "error", "ActionText", "Retry", "ActionIcon", "fa-solid fa-arrows-rotate", 3, "Action", "Message"], [3, "Expanded"], ["mjAccordionTitle", ""], [1, "summary-cards"], [1, "summary-card"], [1, "card-icon", "prompts"], [1, "fas", "fa-microchip"], [1, "card-content"], [1, "metric-value"], [1, "metric-detail"], [1, "success"], [1, "failed"], [1, "card-icon", "actions"], [1, "fas", "fa-cog"], [1, "card-icon", "cost"], [1, "fas", "fa-dollar-sign"], [1, "metric-detail", "cache-detail"], [1, "card-icon", "cache"], [1, "fas", "fa-bolt"], [1, "card-icon", "time"], [1, "fas", "fa-clock"], [1, "analytics-panel"], [1, "view-mode-toggle"], ["Icon", "fa-solid fa-circle-info", "Title", "No prompt executions found in this agent run.", "Message", "This agent run may have only executed actions without any AI prompts."], [1, "charts-grid"], [1, "charts-grid", 2, "margin-top", "20px"], [1, "detailed-metrics"], ["mjButton", "", "variant", "flat", 3, "click"], [1, "fas", 3, "ngClass"], [1, "metrics-table"], [1, "chart-card"], [1, "chart-card-header", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "expand-btn"], ["aria-hidden", "true", 1, "fas", 3, "ngClass"], [1, "chart-card-body"], [1, "chart-container"], ["id", "actionSuccessRateChart"], [1, "fas", "fa-layer-group"], ["id", "stepTypeChart"], [1, "error-analysis-section"], [1, "error-analysis"], ["Variant", "success", "Message", "No action errors detected in this run. All actions completed successfully!"], [1, "model-comparison"], [1, "timeline-stats"], [1, "stat-item"], [1, "stat-label"], [1, "stat-value"], [1, "step-breakdown"], [1, "step-type-list"], [1, "step-type-item"], [1, "fas", "fa-tachometer-alt"], [1, "fas", "fa-chart-pie"], ["id", "modelDistributionChart"], [1, "chart-legend"], ["id", "executionTimeChart"], ["id", "costByVendorChart"], [1, "chart-total"], [1, "fas", "fa-coins"], ["id", "tokenUsageChart"], [1, "legend-item"], [1, "legend-color"], [1, "legend-label"], [1, "fas", "fa-hourglass-half"], ["id", "promptTimeDistributionChart"], [1, "fas", "fa-database"], ["id", "promptTokenDistributionChart"], ["id", "promptCostDistributionChart"], [1, "fas", "fa-list-ol"], ["id", "promptCountByNameChart"], [1, "success-rate"], [1, "fas", "fa-exclamation-triangle"], [1, "error-analysis-description"], [1, "error-list"], [1, "error-item"], [1, "error-count"], [1, "error-message"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-stream"], [1, "type-name"], [1, "type-count"], [1, "type-percentage"]], template: function AIAgentRunAnalyticsComponent_Template(rf, ctx) { if (rf & 1) {
2293
2349
  i0.ɵɵelementStart(0, "div", 10);
2294
2350
  i0.ɵɵconditionalCreate(1, AIAgentRunAnalyticsComponent_Conditional_1_Template, 4, 0, "div", 11);
2295
2351
  i0.ɵɵconditionalCreate(2, AIAgentRunAnalyticsComponent_Conditional_2_Template, 1, 1, "mj-empty-state", 12);
2296
- i0.ɵɵconditionalCreate(3, AIAgentRunAnalyticsComponent_Conditional_3_Template, 171, 49, "div", 13);
2352
+ i0.ɵɵconditionalCreate(3, AIAgentRunAnalyticsComponent_Conditional_3_Template, 172, 50, "div", 13);
2297
2353
  i0.ɵɵelementEnd();
2298
2354
  } if (rf & 2) {
2299
2355
  i0.ɵɵadvance();
@@ -2306,9 +2362,11 @@ export class AIAgentRunAnalyticsComponent extends BaseAngularComponent {
2306
2362
  }
2307
2363
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AIAgentRunAnalyticsComponent, [{
2308
2364
  type: Component,
2309
- args: [{ standalone: false, selector: 'mj-ai-agent-run-analytics', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"analytics-container\">\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-state\">\n <i class=\"fas fa-spinner fa-spin fa-2x\"></i>\n <p>Loading analytics data...</p>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <mj-empty-state\n Variant=\"error\"\n [Message]=\"error\"\n ActionText=\"Retry\"\n ActionIcon=\"fa-solid fa-arrows-rotate\"\n (Action)=\"loadData()\" />\n }\n\n <!-- Analytics Content -->\n @if (!isLoading && !error) {\n <div class=\"analytics-content\">\n <!-- Summary Cards -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-tachometer-alt\"></i> Overview\n </ng-template>\n <div class=\"summary-cards\">\n <div class=\"summary-card\">\n <div class=\"card-icon prompts\">\n <i class=\"fas fa-microchip\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Total Prompts</h3>\n <div class=\"metric-value\">{{ promptMetrics.totalCount }}</div>\n <div class=\"metric-detail\">\n <span class=\"success\">{{ promptMetrics.statusBreakdown.success }} successful</span>\n @if (promptMetrics.statusBreakdown.failed > 0) {\n <span class=\"failed\">{{ promptMetrics.statusBreakdown.failed }} failed</span>\n }\n </div>\n </div>\n </div>\n <div class=\"summary-card\">\n <div class=\"card-icon actions\">\n <i class=\"fas fa-cog\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Total Actions</h3>\n <div class=\"metric-value\">{{ actionMetrics.totalCount }}</div>\n <div class=\"metric-detail\">\n <span class=\"success\">{{ actionMetrics.statusBreakdown.success }} successful</span>\n @if (actionMetrics.statusBreakdown.failed > 0) {\n <span class=\"failed\">{{ actionMetrics.statusBreakdown.failed }} failed</span>\n }\n </div>\n </div>\n </div>\n <div class=\"summary-card\">\n <div class=\"card-icon cost\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Total Cost</h3>\n <div class=\"metric-value\">{{ formatCost(promptMetrics.costBreakdown.totalCost) }}</div>\n <div class=\"metric-detail cache-detail\">\n <span>{{ totalTokensProcessed | number }} tokens</span>\n @if (promptMetrics.tokenUsage.totalCacheRead > 0 || promptMetrics.tokenUsage.totalCacheWrite > 0) {\n <span>incl. {{ (promptMetrics.tokenUsage.totalCacheRead + promptMetrics.tokenUsage.totalCacheWrite) | number }} cached</span>\n }\n @if (inputCost > 0 || outputCost > 0) {\n <span>input {{ formatCost(inputCost) }} &middot; output {{ formatCost(outputCost) }}</span>\n }\n @if (cacheSavings > 0) {\n <span class=\"success\">saved {{ formatCost(cacheSavings) }} ({{ cacheSavingsPct | number:'1.0-0' }}%) via cache</span>\n }\n </div>\n </div>\n </div>\n <div class=\"summary-card\">\n <div class=\"card-icon cache\">\n <i class=\"fas fa-bolt\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Prompt Cache</h3>\n <div class=\"metric-value\">{{ promptMetrics.tokenUsage.totalCacheRead | number }}</div>\n <div class=\"metric-detail cache-detail\">\n <span>tokens read from cache</span>\n @if (promptMetrics.tokenUsage.totalCacheWrite > 0) {\n <span>{{ promptMetrics.tokenUsage.totalCacheWrite | number }} written</span>\n }\n @if (promptMetrics.tokenUsage.totalCacheRead > 0 || promptMetrics.tokenUsage.totalCacheWrite > 0) {\n <span>{{ cacheHitRatePct | number:'1.0-0' }}% hit rate</span>\n }\n </div>\n </div>\n </div>\n <div class=\"summary-card\">\n <div class=\"card-icon time\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Execution Time</h3>\n <div class=\"metric-value\">{{ formatDuration(promptMetrics.totalExecutionTime + actionMetrics.totalExecutionTime) }}</div>\n <div class=\"metric-detail\">\n <span>{{ timelineMetrics.totalSteps }} total steps</span>\n </div>\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Prompt Analytics -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-microchip\"></i> Prompt Analytics\n </ng-template>\n <div class=\"analytics-panel\">\n <!-- View Mode Toggle -->\n @if (promptMetrics.totalCount > 0) {\n <div class=\"view-mode-toggle\">\n <button mjButton\n variant=\"flat\"\n (click)=\"toggleViewMode()\">\n <i class=\"fas\" [ngClass]=\"viewMode === 'grid' ? 'fa-expand-arrows-alt' : 'fa-compress-arrows-alt'\"></i>\n {{ viewMode === 'grid' ? 'Expand All' : 'Collapse All' }}\n </button>\n </div>\n }\n <!-- No prompts message -->\n @if (promptMetrics.totalCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-info\"\n Title=\"No prompt executions found in this agent run.\"\n Message=\"This agent run may have only executed actions without any AI prompts.\" />\n }\n @if (promptMetrics.totalCount > 0) {\n <div class=\"charts-grid\">\n <!-- Model Distribution -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['modelDistribution']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('modelDistribution')\">\n <h3><i class=\"fas fa-chart-pie\"></i> Prompts by Model</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['modelDistribution'] ? 'Collapse Model Distribution chart' : 'Expand Model Distribution chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['modelDistribution'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"modelDistributionChart\" #modelDistributionChart></div>\n @if (promptMetrics.byModel.size > 0) {\n <div class=\"chart-legend\">\n @for (item of promptMetrics.byModel | keyvalue; track trackByKey($index, item)) {\n <div class=\"legend-item\">\n <span class=\"legend-color\" [style.backgroundColor]=\"getModelColor(item.key)\"></span>\n <span class=\"legend-label\">{{ item.key }}: {{ item.value.count }} ({{ (item.value.count / promptMetrics.totalCount * 100).toFixed(1) }}%)</span>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Execution Time by Vendor -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['executionTime']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('executionTime')\">\n <h3><i class=\"fas fa-clock\"></i> Average Execution Time by Vendor</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['executionTime'] ? 'Collapse Average Execution Time by Vendor chart' : 'Expand Average Execution Time by Vendor chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['executionTime'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"executionTimeChart\" #executionTimeChart></div>\n </div>\n </div>\n </div>\n <!-- Cost by Vendor -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['costByVendor']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('costByVendor')\">\n <h3><i class=\"fas fa-dollar-sign\"></i> Cost Distribution by Vendor</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['costByVendor'] ? 'Collapse Cost Distribution by Vendor chart' : 'Expand Cost Distribution by Vendor chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['costByVendor'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"costByVendorChart\" #costByVendorChart></div>\n <div class=\"chart-total\">Total: {{ formatCost(promptMetrics.costBreakdown.totalCost) }}</div>\n </div>\n </div>\n </div>\n <!-- Token Usage -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['tokenUsage']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('tokenUsage')\">\n <h3><i class=\"fas fa-coins\"></i> Token Usage by Model</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['tokenUsage'] ? 'Collapse Token Usage by Model chart' : 'Expand Token Usage by Model chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['tokenUsage'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"tokenUsageChart\" #tokenUsageChart></div>\n </div>\n </div>\n </div>\n </div>\n }\n <!-- Additional Prompt Analytics Charts -->\n @if (promptMetrics.totalCount > 0) {\n <div class=\"charts-grid\" style=\"margin-top: 20px;\">\n <!-- Prompt Execution Time Distribution -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['promptTime']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('promptTime')\">\n <h3><i class=\"fas fa-hourglass-half\"></i> Average Execution Time by Prompt</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['promptTime'] ? 'Collapse Average Execution Time by Prompt chart' : 'Expand Average Execution Time by Prompt chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptTime'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"promptTimeDistributionChart\" #promptTimeDistributionChart></div>\n </div>\n </div>\n </div>\n <!-- Prompt Token Usage -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['promptToken']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('promptToken')\">\n <h3><i class=\"fas fa-database\"></i> Token Usage by Prompt</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['promptToken'] ? 'Collapse Token Usage by Prompt chart' : 'Expand Token Usage by Prompt chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptToken'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"promptTokenDistributionChart\" #promptTokenDistributionChart></div>\n </div>\n </div>\n </div>\n <!-- Prompt Cost Distribution -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['promptCost']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('promptCost')\">\n <h3><i class=\"fas fa-chart-pie\"></i> Cost Distribution by Prompt</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['promptCost'] ? 'Collapse Cost Distribution by Prompt chart' : 'Expand Cost Distribution by Prompt chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptCost'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"promptCostDistributionChart\" #promptCostDistributionChart></div>\n </div>\n </div>\n </div>\n <!-- Prompt Count by Name -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['promptCount']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('promptCount')\">\n <h3><i class=\"fas fa-list-ol\"></i> Prompt Execution Count</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['promptCount'] ? 'Collapse Prompt Execution Count chart' : 'Expand Prompt Execution Count chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptCount'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"promptCountByNameChart\" #promptCountByNameChart></div>\n </div>\n </div>\n </div>\n </div>\n }\n <!-- Detailed Prompt Metrics -->\n <div class=\"detailed-metrics\">\n <button mjButton\n variant=\"flat\"\n (click)=\"promptDetailsExpanded = !promptDetailsExpanded\">\n <i class=\"fas\" [ngClass]=\"promptDetailsExpanded ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n Detailed Prompt Metrics\n </button>\n @if (promptDetailsExpanded) {\n <div class=\"metrics-table\">\n <table>\n <thead>\n <tr>\n <th>Prompt Name</th>\n <th>Count</th>\n <th>Avg Time</th>\n <th>Total Time</th>\n <th>Success Rate</th>\n </tr>\n </thead>\n <tbody>\n @for (prompt of promptMetrics.byPrompt | keyvalue; track trackByKey($index, prompt)) {\n <tr>\n <td>{{ prompt.key }}</td>\n <td>{{ prompt.value.count }}</td>\n <td>{{ formatDuration(prompt.value.avgTime) }}</td>\n <td>{{ formatDuration(prompt.value.totalTime) }}</td>\n <td>\n <span class=\"success-rate\">\n <!-- Calculate success rate for this prompt -->\n {{ calculatePromptSuccessRate(prompt.key) }}%\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Action Analytics -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-cog\"></i> Action Analytics\n </ng-template>\n <div class=\"analytics-panel\">\n <div class=\"charts-grid\">\n <!-- Action Success Rate -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['actionSuccess']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('actionSuccess')\">\n <h3><i class=\"fas fa-chart-bar\"></i> Action Success Rate</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['actionSuccess'] ? 'Collapse Action Success Rate chart' : 'Expand Action Success Rate chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['actionSuccess'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"actionSuccessRateChart\" #actionSuccessRateChart></div>\n </div>\n </div>\n </div>\n <!-- Step Type Distribution -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['stepType']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('stepType')\">\n <h3><i class=\"fas fa-layer-group\"></i> Step Type Distribution</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['stepType'] ? 'Collapse Step Type Distribution chart' : 'Expand Step Type Distribution chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['stepType'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"stepTypeChart\" #stepTypeChart></div>\n </div>\n </div>\n </div>\n </div>\n <!-- Detailed Action Metrics -->\n <div class=\"detailed-metrics\">\n <button mjButton\n variant=\"flat\"\n (click)=\"actionDetailsExpanded = !actionDetailsExpanded\">\n <i class=\"fas\" [ngClass]=\"actionDetailsExpanded ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n Detailed Action Metrics\n </button>\n @if (actionDetailsExpanded) {\n <div class=\"metrics-table\">\n <table>\n <thead>\n <tr>\n <th>Action Name</th>\n <th>Count</th>\n <th>Avg Time</th>\n <th>Success Rate</th>\n <th>Type</th>\n </tr>\n </thead>\n <tbody>\n @for (action of actionMetrics.byAction | keyvalue; track trackByKey($index, action)) {\n <tr>\n <td>{{ action.key }}</td>\n <td>{{ action.value.count }}</td>\n <td>{{ formatDuration(action.value.avgTime) }}</td>\n <td>\n <span class=\"success-rate\" [class.high]=\"action.value.successRate > 0.9\"\n [class.medium]=\"action.value.successRate > 0.7 && action.value.successRate <= 0.9\"\n [class.low]=\"action.value.successRate <= 0.7\">\n {{ (action.value.successRate * 100).toFixed(1) }}%\n </span>\n </td>\n <td>{{ getActionType(action.key) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n <!-- Error Analysis -->\n <div class=\"error-analysis-section\">\n @if (actionMetrics.errorAnalysis.size > 0) {\n <div class=\"error-analysis\">\n <h3>\n <i class=\"fas fa-exclamation-triangle\"></i>\n Common Errors\n </h3>\n <p class=\"error-analysis-description\">\n This section shows the most frequent error messages from failed actions, helping identify systemic issues that may need attention.\n </p>\n <div class=\"error-list\">\n @for (error of getTopErrors(); track trackByErrorMessage($index, error)) {\n <div class=\"error-item\">\n <span class=\"error-count\">{{ error.count }}x</span>\n <span class=\"error-message\">{{ error.message }}</span>\n </div>\n }\n </div>\n </div>\n }\n @if (actionMetrics.errorAnalysis.size === 0) {\n <mj-empty-state\n Variant=\"success\"\n Message=\"No action errors detected in this run. All actions completed successfully!\" />\n }\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Model Performance Comparison -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-chart-line\"></i> Model Performance Comparison\n </ng-template>\n <div class=\"analytics-panel\">\n <div class=\"model-comparison\">\n <table>\n <thead>\n <tr>\n <th>Model</th>\n <th>Vendor</th>\n <th>Prompts</th>\n <th>Avg Time</th>\n <th>Total Cost</th>\n <th>Avg Cost/Prompt</th>\n <th>Input Tokens</th>\n <th>Output Tokens</th>\n </tr>\n </thead>\n <tbody>\n @for (model of getModelPerformanceData(); track trackByModelName($index, model)) {\n <tr>\n <td>{{ model.name }}</td>\n <td>{{ model.vendor }}</td>\n <td>{{ model.count }}</td>\n <td>{{ formatDuration(model.avgTime) }}</td>\n <td>{{ formatCost(model.totalCost) }}</td>\n <td>{{ formatCost(model.avgCost) }}</td>\n <td>{{ model.inputTokens | number:'1.0-0' }}</td>\n <td>{{ model.outputTokens | number:'1.0-0' }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Timeline Analysis -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-stream\"></i> Execution Timeline Analysis\n </ng-template>\n <div class=\"analytics-panel\">\n <div class=\"timeline-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-label\">Total Steps</span>\n <span class=\"stat-value\">{{ timelineMetrics.totalSteps }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Parallel Executions</span>\n <span class=\"stat-value\">{{ timelineMetrics.parallelExecutions }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Max Nesting Depth</span>\n <span class=\"stat-value\">{{ timelineMetrics.deepestNesting }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Sub-Agent Runs</span>\n <span class=\"stat-value\">{{ subAgentRuns.length }}</span>\n </div>\n </div>\n <div class=\"step-breakdown\">\n <h3>Steps by Type</h3>\n <div class=\"step-type-list\">\n @for (type of timelineMetrics.stepsByType | keyvalue; track trackByKey($index, type)) {\n <div class=\"step-type-item\">\n <i class=\"fas\" [ngClass]=\"getStepTypeIcon(type.key)\"></i>\n <span class=\"type-name\">{{ type.key }}</span>\n <span class=\"type-count\">{{ type.value }}</span>\n <span class=\"type-percentage\">({{ (type.value / timelineMetrics.totalSteps * 100).toFixed(1) }}%)</span>\n </div>\n }\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n </div>\n }\n</div>", styles: [".analytics-container {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background-color: var(--mj-bg-surface-sunken);\n}\n\n/* Loading State */\n.loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 300px;\n color: var(--mj-text-muted);\n}\n\n.loading-state i {\n margin-bottom: 15px;\n}\n\n/* Summary Cards */\n.summary-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n margin-bottom: 30px;\n}\n\n.summary-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 20px;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.summary-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);\n}\n\n.card-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-right: 20px;\n font-size: 24px;\n color: var(--mj-text-inverse);\n}\n\n.card-icon.prompts {\n background: var(--mj-brand-primary);\n}\n\n.card-icon.actions {\n background: var(--mj-status-error);\n}\n\n.card-icon.cost {\n background: var(--mj-status-success);\n}\n\n.card-icon.time {\n background: var(--mj-status-warning);\n}\n\n.card-icon.cache {\n background: var(--mj-status-info);\n}\n\n.card-content h3 {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.metric-detail {\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.metric-detail .success {\n color: var(--mj-status-success);\n margin-right: 10px;\n}\n\n.metric-detail .failed {\n color: var(--mj-status-error);\n}\n\n/* Cache card stacks its facts (caption / written / hit rate) one per line. */\n.metric-detail.cache-detail span {\n display: block;\n}\n\n/* Analytics Panels */\n.analytics-panel {\n padding: 15px;\n}\n\n/* Accordion Panel Styling */\n.analytics-content mj-accordion-panel {\n display: block;\n margin-bottom: 12px;\n}\n\n/* Charts */\n.charts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 20px;\n margin-bottom: 20px;\n}\n\n/* Chart Cards */\n.chart-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n.chart-card.expanded {\n grid-column: 1 / -1;\n}\n\n.chart-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background-color: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n cursor: pointer;\n user-select: none;\n}\n\n.chart-card-header:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.chart-card-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.chart-card-header h3 i {\n font-size: 16px;\n color: var(--mj-text-muted);\n}\n\n.expand-btn {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.expand-btn:hover {\n color: var(--mj-text-secondary);\n}\n\n.chart-card-body {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n}\n\n.chart-card.expanded .chart-card-body {\n padding: 24px;\n}\n\n.chart-card.expanded .chart-container > div {\n min-height: 400px;\n}\n\n/* View Mode Toggle */\n.view-mode-toggle {\n display: flex;\n justify-content: flex-end;\n margin-bottom: 16px;\n}\n\n.view-mode-toggle button {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.chart-container {\n position: relative;\n}\n\n.chart-container h3 {\n margin: 0 0 10px 0;\n font-size: 15px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.chart-container > div {\n min-height: 220px;\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* Ensure SVG charts are centered */\n.chart-container svg {\n display: block;\n margin: 0 auto;\n}\n\n.chart-legend {\n margin-top: 10px;\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n font-size: 12px;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n}\n\n.legend-color {\n width: 16px;\n height: 16px;\n border-radius: 3px;\n}\n\n.chart-total {\n text-align: center;\n margin-top: 10px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n/* Detailed Metrics */\n.detailed-metrics {\n margin-top: 20px;\n border-top: 1px solid var(--mj-border-default);\n padding-top: 20px;\n}\n\n.detailed-metrics button {\n margin-bottom: 15px;\n}\n\n.detailed-metrics button i {\n margin-right: 8px;\n}\n\n.metrics-table {\n overflow-x: auto;\n}\n\n.metrics-table table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.metrics-table th {\n background-color: var(--mj-bg-surface-sunken);\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: var(--mj-text-secondary);\n border-bottom: 2px solid var(--mj-border-strong);\n}\n\n.metrics-table td {\n padding: 12px;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n.metrics-table tr:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.success-rate {\n font-weight: 500;\n}\n\n.success-rate.high {\n color: var(--mj-status-success);\n}\n\n.success-rate.medium {\n color: var(--mj-status-warning);\n}\n\n.success-rate.low {\n color: var(--mj-status-error);\n}\n\n/* Error Analysis */\n.error-analysis {\n margin-top: 30px;\n padding: 20px;\n background-color: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-radius: 8px;\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface));\n}\n\n.error-analysis h3 {\n margin: 0 0 15px 0;\n color: var(--mj-status-error);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-analysis-description {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin-bottom: 20px;\n line-height: 1.5;\n}\n\n.error-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.error-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 10px;\n background-color: var(--mj-bg-surface);\n border-radius: 4px;\n font-size: 14px;\n}\n\n.error-count {\n background-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.error-message {\n flex: 1;\n color: var(--mj-text-secondary);\n}\n\n/* Model Comparison Table */\n.model-comparison {\n overflow-x: auto;\n}\n\n.model-comparison table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.model-comparison th {\n background-color: var(--mj-bg-surface-sunken);\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: var(--mj-text-secondary);\n border-bottom: 2px solid var(--mj-border-strong);\n white-space: nowrap;\n}\n\n.model-comparison td {\n padding: 12px;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n.model-comparison tr:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n/* Timeline Analysis */\n.timeline-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 20px;\n margin-bottom: 30px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px;\n background-color: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.stat-label {\n font-size: 14px;\n color: var(--mj-text-muted);\n margin-bottom: 8px;\n}\n\n.stat-value {\n font-size: 32px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.step-breakdown h3 {\n margin: 0 0 15px 0;\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.step-type-list {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 12px;\n}\n\n.step-type-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px;\n background-color: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.step-type-item i {\n width: 30px;\n text-align: center;\n color: var(--mj-text-muted);\n}\n\n.type-name {\n flex: 1;\n font-weight: 500;\n}\n\n.type-count {\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.type-percentage {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-left: 5px;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .summary-cards {\n grid-template-columns: 1fr;\n }\n \n .charts-grid {\n grid-template-columns: 1fr;\n }\n \n .timeline-stats {\n grid-template-columns: repeat(2, 1fr);\n }\n}"] }]
2365
+ args: [{ standalone: false, selector: 'mj-ai-agent-run-analytics', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"analytics-container\">\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-state\">\n <i class=\"fas fa-spinner fa-spin fa-2x\"></i>\n <p>Loading analytics data...</p>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <mj-empty-state\n Variant=\"error\"\n [Message]=\"error\"\n ActionText=\"Retry\"\n ActionIcon=\"fa-solid fa-arrows-rotate\"\n (Action)=\"loadData()\" />\n }\n\n <!-- Analytics Content -->\n @if (!isLoading && !error) {\n <div class=\"analytics-content\">\n <!-- Summary Cards -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-tachometer-alt\"></i> Overview\n </ng-template>\n <div class=\"summary-cards\">\n <div class=\"summary-card\">\n <div class=\"card-icon prompts\">\n <i class=\"fas fa-microchip\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Total Prompts</h3>\n <div class=\"metric-value\">{{ promptMetrics.totalCount }}</div>\n <div class=\"metric-detail\">\n <span class=\"success\">{{ promptMetrics.statusBreakdown.success }} successful</span>\n @if (promptMetrics.statusBreakdown.failed > 0) {\n <span class=\"failed\">{{ promptMetrics.statusBreakdown.failed }} failed</span>\n }\n </div>\n </div>\n </div>\n <div class=\"summary-card\">\n <div class=\"card-icon actions\">\n <i class=\"fas fa-cog\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Total Actions</h3>\n <div class=\"metric-value\">{{ actionMetrics.totalCount }}</div>\n <div class=\"metric-detail\">\n <span class=\"success\">{{ actionMetrics.statusBreakdown.success }} successful</span>\n @if (actionMetrics.statusBreakdown.failed > 0) {\n <span class=\"failed\">{{ actionMetrics.statusBreakdown.failed }} failed</span>\n }\n </div>\n </div>\n </div>\n <div class=\"summary-card\">\n <div class=\"card-icon cost\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Total Cost</h3>\n <!-- The run's OWN spend plus anything it dispatched. A workflow's cost lives on\n Task rows and the prompt runs those tasks produced, which the run's step list\n cannot reach \u2014 so before this the headline figure silently omitted the most\n expensive thing many runs do. -->\n <div class=\"metric-value\">\n {{ formatCost(promptMetrics.costBreakdown.totalCost + DispatchedCost.Cost) }}\n </div>\n @if (HasDispatchedWork) {\n <div class=\"metric-detail cache-detail\">\n <span>{{ formatCost(promptMetrics.costBreakdown.totalCost) }} this run</span>\n <span>+ {{ formatCost(DispatchedCost.Cost) }} across\n {{ DispatchedCost.NodeCount }} workflow step{{ DispatchedCost.NodeCount === 1 ? '' : 's' }}</span>\n </div>\n }\n <div class=\"metric-detail cache-detail\">\n <span>{{ totalTokensProcessed | number }} tokens</span>\n @if (promptMetrics.tokenUsage.totalCacheRead > 0 || promptMetrics.tokenUsage.totalCacheWrite > 0) {\n <span>incl. {{ (promptMetrics.tokenUsage.totalCacheRead + promptMetrics.tokenUsage.totalCacheWrite) | number }} cached</span>\n }\n @if (inputCost > 0 || outputCost > 0) {\n <span>input {{ formatCost(inputCost) }} &middot; output {{ formatCost(outputCost) }}</span>\n }\n @if (cacheSavings > 0) {\n <span class=\"success\">saved {{ formatCost(cacheSavings) }} ({{ cacheSavingsPct | number:'1.0-0' }}%) via cache</span>\n }\n </div>\n </div>\n </div>\n <div class=\"summary-card\">\n <div class=\"card-icon cache\">\n <i class=\"fas fa-bolt\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Prompt Cache</h3>\n <div class=\"metric-value\">{{ promptMetrics.tokenUsage.totalCacheRead | number }}</div>\n <div class=\"metric-detail cache-detail\">\n <span>tokens read from cache</span>\n @if (promptMetrics.tokenUsage.totalCacheWrite > 0) {\n <span>{{ promptMetrics.tokenUsage.totalCacheWrite | number }} written</span>\n }\n @if (promptMetrics.tokenUsage.totalCacheRead > 0 || promptMetrics.tokenUsage.totalCacheWrite > 0) {\n <span>{{ cacheHitRatePct | number:'1.0-0' }}% hit rate</span>\n }\n </div>\n </div>\n </div>\n <div class=\"summary-card\">\n <div class=\"card-icon time\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"card-content\">\n <h3>Execution Time</h3>\n <div class=\"metric-value\">{{ formatDuration(promptMetrics.totalExecutionTime + actionMetrics.totalExecutionTime) }}</div>\n <div class=\"metric-detail\">\n <span>{{ timelineMetrics.totalSteps }} total steps</span>\n </div>\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Prompt Analytics -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-microchip\"></i> Prompt Analytics\n </ng-template>\n <div class=\"analytics-panel\">\n <!-- View Mode Toggle -->\n @if (promptMetrics.totalCount > 0) {\n <div class=\"view-mode-toggle\">\n <button mjButton\n variant=\"flat\"\n (click)=\"toggleViewMode()\">\n <i class=\"fas\" [ngClass]=\"viewMode === 'grid' ? 'fa-expand-arrows-alt' : 'fa-compress-arrows-alt'\"></i>\n {{ viewMode === 'grid' ? 'Expand All' : 'Collapse All' }}\n </button>\n </div>\n }\n <!-- No prompts message -->\n @if (promptMetrics.totalCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-info\"\n Title=\"No prompt executions found in this agent run.\"\n Message=\"This agent run may have only executed actions without any AI prompts.\" />\n }\n @if (promptMetrics.totalCount > 0) {\n <div class=\"charts-grid\">\n <!-- Model Distribution -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['modelDistribution']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('modelDistribution')\">\n <h3><i class=\"fas fa-chart-pie\"></i> Prompts by Model</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['modelDistribution'] ? 'Collapse Model Distribution chart' : 'Expand Model Distribution chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['modelDistribution'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"modelDistributionChart\" #modelDistributionChart></div>\n @if (promptMetrics.byModel.size > 0) {\n <div class=\"chart-legend\">\n @for (item of promptMetrics.byModel | keyvalue; track trackByKey($index, item)) {\n <div class=\"legend-item\">\n <span class=\"legend-color\" [style.backgroundColor]=\"getModelColor(item.key)\"></span>\n <span class=\"legend-label\">{{ item.key }}: {{ item.value.count }} ({{ (item.value.count / promptMetrics.totalCount * 100).toFixed(1) }}%)</span>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Execution Time by Vendor -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['executionTime']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('executionTime')\">\n <h3><i class=\"fas fa-clock\"></i> Average Execution Time by Vendor</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['executionTime'] ? 'Collapse Average Execution Time by Vendor chart' : 'Expand Average Execution Time by Vendor chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['executionTime'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"executionTimeChart\" #executionTimeChart></div>\n </div>\n </div>\n </div>\n <!-- Cost by Vendor -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['costByVendor']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('costByVendor')\">\n <h3><i class=\"fas fa-dollar-sign\"></i> Cost Distribution by Vendor</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['costByVendor'] ? 'Collapse Cost Distribution by Vendor chart' : 'Expand Cost Distribution by Vendor chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['costByVendor'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"costByVendorChart\" #costByVendorChart></div>\n <div class=\"chart-total\">Total: {{ formatCost(promptMetrics.costBreakdown.totalCost) }}</div>\n </div>\n </div>\n </div>\n <!-- Token Usage -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['tokenUsage']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('tokenUsage')\">\n <h3><i class=\"fas fa-coins\"></i> Token Usage by Model</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['tokenUsage'] ? 'Collapse Token Usage by Model chart' : 'Expand Token Usage by Model chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['tokenUsage'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"tokenUsageChart\" #tokenUsageChart></div>\n </div>\n </div>\n </div>\n </div>\n }\n <!-- Additional Prompt Analytics Charts -->\n @if (promptMetrics.totalCount > 0) {\n <div class=\"charts-grid\" style=\"margin-top: 20px;\">\n <!-- Prompt Execution Time Distribution -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['promptTime']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('promptTime')\">\n <h3><i class=\"fas fa-hourglass-half\"></i> Average Execution Time by Prompt</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['promptTime'] ? 'Collapse Average Execution Time by Prompt chart' : 'Expand Average Execution Time by Prompt chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptTime'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"promptTimeDistributionChart\" #promptTimeDistributionChart></div>\n </div>\n </div>\n </div>\n <!-- Prompt Token Usage -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['promptToken']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('promptToken')\">\n <h3><i class=\"fas fa-database\"></i> Token Usage by Prompt</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['promptToken'] ? 'Collapse Token Usage by Prompt chart' : 'Expand Token Usage by Prompt chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptToken'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"promptTokenDistributionChart\" #promptTokenDistributionChart></div>\n </div>\n </div>\n </div>\n <!-- Prompt Cost Distribution -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['promptCost']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('promptCost')\">\n <h3><i class=\"fas fa-chart-pie\"></i> Cost Distribution by Prompt</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['promptCost'] ? 'Collapse Cost Distribution by Prompt chart' : 'Expand Cost Distribution by Prompt chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptCost'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"promptCostDistributionChart\" #promptCostDistributionChart></div>\n </div>\n </div>\n </div>\n <!-- Prompt Count by Name -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['promptCount']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('promptCount')\">\n <h3><i class=\"fas fa-list-ol\"></i> Prompt Execution Count</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['promptCount'] ? 'Collapse Prompt Execution Count chart' : 'Expand Prompt Execution Count chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptCount'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"promptCountByNameChart\" #promptCountByNameChart></div>\n </div>\n </div>\n </div>\n </div>\n }\n <!-- Detailed Prompt Metrics -->\n <div class=\"detailed-metrics\">\n <button mjButton\n variant=\"flat\"\n (click)=\"promptDetailsExpanded = !promptDetailsExpanded\">\n <i class=\"fas\" [ngClass]=\"promptDetailsExpanded ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n Detailed Prompt Metrics\n </button>\n @if (promptDetailsExpanded) {\n <div class=\"metrics-table\">\n <table>\n <thead>\n <tr>\n <th>Prompt Name</th>\n <th>Count</th>\n <th>Avg Time</th>\n <th>Total Time</th>\n <th>Success Rate</th>\n </tr>\n </thead>\n <tbody>\n @for (prompt of promptMetrics.byPrompt | keyvalue; track trackByKey($index, prompt)) {\n <tr>\n <td>{{ prompt.key }}</td>\n <td>{{ prompt.value.count }}</td>\n <td>{{ formatDuration(prompt.value.avgTime) }}</td>\n <td>{{ formatDuration(prompt.value.totalTime) }}</td>\n <td>\n <span class=\"success-rate\">\n <!-- Calculate success rate for this prompt -->\n {{ calculatePromptSuccessRate(prompt.key) }}%\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Action Analytics -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-cog\"></i> Action Analytics\n </ng-template>\n <div class=\"analytics-panel\">\n <div class=\"charts-grid\">\n <!-- Action Success Rate -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['actionSuccess']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('actionSuccess')\">\n <h3><i class=\"fas fa-chart-bar\"></i> Action Success Rate</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['actionSuccess'] ? 'Collapse Action Success Rate chart' : 'Expand Action Success Rate chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['actionSuccess'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"actionSuccessRateChart\" #actionSuccessRateChart></div>\n </div>\n </div>\n </div>\n <!-- Step Type Distribution -->\n <div class=\"chart-card\" [class.expanded]=\"expandedCharts['stepType']\">\n <div class=\"chart-card-header\" (click)=\"toggleChartExpansion('stepType')\">\n <h3><i class=\"fas fa-layer-group\"></i> Step Type Distribution</h3>\n <button class=\"expand-btn\" [attr.aria-label]=\"expandedCharts['stepType'] ? 'Collapse Step Type Distribution chart' : 'Expand Step Type Distribution chart'\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['stepType'] ? 'fa-compress' : 'fa-expand'\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"stepTypeChart\" #stepTypeChart></div>\n </div>\n </div>\n </div>\n </div>\n <!-- Detailed Action Metrics -->\n <div class=\"detailed-metrics\">\n <button mjButton\n variant=\"flat\"\n (click)=\"actionDetailsExpanded = !actionDetailsExpanded\">\n <i class=\"fas\" [ngClass]=\"actionDetailsExpanded ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n Detailed Action Metrics\n </button>\n @if (actionDetailsExpanded) {\n <div class=\"metrics-table\">\n <table>\n <thead>\n <tr>\n <th>Action Name</th>\n <th>Count</th>\n <th>Avg Time</th>\n <th>Success Rate</th>\n <th>Type</th>\n </tr>\n </thead>\n <tbody>\n @for (action of actionMetrics.byAction | keyvalue; track trackByKey($index, action)) {\n <tr>\n <td>{{ action.key }}</td>\n <td>{{ action.value.count }}</td>\n <td>{{ formatDuration(action.value.avgTime) }}</td>\n <td>\n <span class=\"success-rate\" [class.high]=\"action.value.successRate > 0.9\"\n [class.medium]=\"action.value.successRate > 0.7 && action.value.successRate <= 0.9\"\n [class.low]=\"action.value.successRate <= 0.7\">\n {{ (action.value.successRate * 100).toFixed(1) }}%\n </span>\n </td>\n <td>{{ getActionType(action.key) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n <!-- Error Analysis -->\n <div class=\"error-analysis-section\">\n @if (actionMetrics.errorAnalysis.size > 0) {\n <div class=\"error-analysis\">\n <h3>\n <i class=\"fas fa-exclamation-triangle\"></i>\n Common Errors\n </h3>\n <p class=\"error-analysis-description\">\n This section shows the most frequent error messages from failed actions, helping identify systemic issues that may need attention.\n </p>\n <div class=\"error-list\">\n @for (error of getTopErrors(); track trackByErrorMessage($index, error)) {\n <div class=\"error-item\">\n <span class=\"error-count\">{{ error.count }}x</span>\n <span class=\"error-message\">{{ error.message }}</span>\n </div>\n }\n </div>\n </div>\n }\n @if (actionMetrics.errorAnalysis.size === 0) {\n <mj-empty-state\n Variant=\"success\"\n Message=\"No action errors detected in this run. All actions completed successfully!\" />\n }\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Model Performance Comparison -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-chart-line\"></i> Model Performance Comparison\n </ng-template>\n <div class=\"analytics-panel\">\n <div class=\"model-comparison\">\n <table>\n <thead>\n <tr>\n <th>Model</th>\n <th>Vendor</th>\n <th>Prompts</th>\n <th>Avg Time</th>\n <th>Total Cost</th>\n <th>Avg Cost/Prompt</th>\n <th>Input Tokens</th>\n <th>Output Tokens</th>\n </tr>\n </thead>\n <tbody>\n @for (model of getModelPerformanceData(); track trackByModelName($index, model)) {\n <tr>\n <td>{{ model.name }}</td>\n <td>{{ model.vendor }}</td>\n <td>{{ model.count }}</td>\n <td>{{ formatDuration(model.avgTime) }}</td>\n <td>{{ formatCost(model.totalCost) }}</td>\n <td>{{ formatCost(model.avgCost) }}</td>\n <td>{{ model.inputTokens | number:'1.0-0' }}</td>\n <td>{{ model.outputTokens | number:'1.0-0' }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Timeline Analysis -->\n <mj-accordion-panel [Expanded]=\"true\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-stream\"></i> Execution Timeline Analysis\n </ng-template>\n <div class=\"analytics-panel\">\n <div class=\"timeline-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-label\">Total Steps</span>\n <span class=\"stat-value\">{{ timelineMetrics.totalSteps }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Parallel Executions</span>\n <span class=\"stat-value\">{{ timelineMetrics.parallelExecutions }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Max Nesting Depth</span>\n <span class=\"stat-value\">{{ timelineMetrics.deepestNesting }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Sub-Agent Runs</span>\n <span class=\"stat-value\">{{ subAgentRuns.length }}</span>\n </div>\n </div>\n <div class=\"step-breakdown\">\n <h3>Steps by Type</h3>\n <div class=\"step-type-list\">\n @for (type of timelineMetrics.stepsByType | keyvalue; track trackByKey($index, type)) {\n <div class=\"step-type-item\">\n <i class=\"fas\" [ngClass]=\"getStepTypeIcon(type.key)\"></i>\n <span class=\"type-name\">{{ type.key }}</span>\n <span class=\"type-count\">{{ type.value }}</span>\n <span class=\"type-percentage\">({{ (type.value / timelineMetrics.totalSteps * 100).toFixed(1) }}%)</span>\n </div>\n }\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n </div>\n }\n</div>", styles: [".analytics-container {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background-color: var(--mj-bg-surface-sunken);\n}\n\n/* Loading State */\n.loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 300px;\n color: var(--mj-text-muted);\n}\n\n.loading-state i {\n margin-bottom: 15px;\n}\n\n/* Summary Cards */\n.summary-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n margin-bottom: 30px;\n}\n\n.summary-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 20px;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.summary-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);\n}\n\n.card-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-right: 20px;\n font-size: 24px;\n color: var(--mj-text-inverse);\n}\n\n.card-icon.prompts {\n background: var(--mj-brand-primary);\n}\n\n.card-icon.actions {\n background: var(--mj-status-error);\n}\n\n.card-icon.cost {\n background: var(--mj-status-success);\n}\n\n.card-icon.time {\n background: var(--mj-status-warning);\n}\n\n.card-icon.cache {\n background: var(--mj-status-info);\n}\n\n.card-content h3 {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.metric-detail {\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.metric-detail .success {\n color: var(--mj-status-success);\n margin-right: 10px;\n}\n\n.metric-detail .failed {\n color: var(--mj-status-error);\n}\n\n/* Cache card stacks its facts (caption / written / hit rate) one per line. */\n.metric-detail.cache-detail span {\n display: block;\n}\n\n/* Analytics Panels */\n.analytics-panel {\n padding: 15px;\n}\n\n/* Accordion Panel Styling */\n.analytics-content mj-accordion-panel {\n display: block;\n margin-bottom: 12px;\n}\n\n/* Charts */\n.charts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 20px;\n margin-bottom: 20px;\n}\n\n/* Chart Cards */\n.chart-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n.chart-card.expanded {\n grid-column: 1 / -1;\n}\n\n.chart-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background-color: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n cursor: pointer;\n user-select: none;\n}\n\n.chart-card-header:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.chart-card-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.chart-card-header h3 i {\n font-size: 16px;\n color: var(--mj-text-muted);\n}\n\n.expand-btn {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.expand-btn:hover {\n color: var(--mj-text-secondary);\n}\n\n.chart-card-body {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n}\n\n.chart-card.expanded .chart-card-body {\n padding: 24px;\n}\n\n.chart-card.expanded .chart-container > div {\n min-height: 400px;\n}\n\n/* View Mode Toggle */\n.view-mode-toggle {\n display: flex;\n justify-content: flex-end;\n margin-bottom: 16px;\n}\n\n.view-mode-toggle button {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.chart-container {\n position: relative;\n}\n\n.chart-container h3 {\n margin: 0 0 10px 0;\n font-size: 15px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.chart-container > div {\n min-height: 220px;\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* Ensure SVG charts are centered */\n.chart-container svg {\n display: block;\n margin: 0 auto;\n}\n\n.chart-legend {\n margin-top: 10px;\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n font-size: 12px;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n}\n\n.legend-color {\n width: 16px;\n height: 16px;\n border-radius: 3px;\n}\n\n.chart-total {\n text-align: center;\n margin-top: 10px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n/* Detailed Metrics */\n.detailed-metrics {\n margin-top: 20px;\n border-top: 1px solid var(--mj-border-default);\n padding-top: 20px;\n}\n\n.detailed-metrics button {\n margin-bottom: 15px;\n}\n\n.detailed-metrics button i {\n margin-right: 8px;\n}\n\n.metrics-table {\n overflow-x: auto;\n}\n\n.metrics-table table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.metrics-table th {\n background-color: var(--mj-bg-surface-sunken);\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: var(--mj-text-secondary);\n border-bottom: 2px solid var(--mj-border-strong);\n}\n\n.metrics-table td {\n padding: 12px;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n.metrics-table tr:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.success-rate {\n font-weight: 500;\n}\n\n.success-rate.high {\n color: var(--mj-status-success);\n}\n\n.success-rate.medium {\n color: var(--mj-status-warning);\n}\n\n.success-rate.low {\n color: var(--mj-status-error);\n}\n\n/* Error Analysis */\n.error-analysis {\n margin-top: 30px;\n padding: 20px;\n background-color: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-radius: 8px;\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface));\n}\n\n.error-analysis h3 {\n margin: 0 0 15px 0;\n color: var(--mj-status-error);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-analysis-description {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin-bottom: 20px;\n line-height: 1.5;\n}\n\n.error-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.error-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 10px;\n background-color: var(--mj-bg-surface);\n border-radius: 4px;\n font-size: 14px;\n}\n\n.error-count {\n background-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.error-message {\n flex: 1;\n color: var(--mj-text-secondary);\n}\n\n/* Model Comparison Table */\n.model-comparison {\n overflow-x: auto;\n}\n\n.model-comparison table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.model-comparison th {\n background-color: var(--mj-bg-surface-sunken);\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: var(--mj-text-secondary);\n border-bottom: 2px solid var(--mj-border-strong);\n white-space: nowrap;\n}\n\n.model-comparison td {\n padding: 12px;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n.model-comparison tr:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n/* Timeline Analysis */\n.timeline-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 20px;\n margin-bottom: 30px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px;\n background-color: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.stat-label {\n font-size: 14px;\n color: var(--mj-text-muted);\n margin-bottom: 8px;\n}\n\n.stat-value {\n font-size: 32px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.step-breakdown h3 {\n margin: 0 0 15px 0;\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.step-type-list {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 12px;\n}\n\n.step-type-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px;\n background-color: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.step-type-item i {\n width: 30px;\n text-align: center;\n color: var(--mj-text-muted);\n}\n\n.type-name {\n flex: 1;\n font-weight: 500;\n}\n\n.type-count {\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.type-percentage {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-left: 5px;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .summary-cards {\n grid-template-columns: 1fr;\n }\n \n .charts-grid {\n grid-template-columns: 1fr;\n }\n \n .timeline-stats {\n grid-template-columns: repeat(2, 1fr);\n }\n}"] }]
2310
2366
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.AIAgentRunCostService }], { agentRunId: [{
2311
2367
  type: Input
2368
+ }], RunTree: [{
2369
+ type: Input
2312
2370
  }], modelDistributionChart: [{
2313
2371
  type: ViewChild,
2314
2372
  args: ['modelDistributionChart', { static: false }]
@@ -2340,5 +2398,5 @@ export class AIAgentRunAnalyticsComponent extends BaseAngularComponent {
2340
2398
  type: ViewChild,
2341
2399
  args: ['promptCountByNameChart', { static: false }]
2342
2400
  }] }); })();
2343
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAgentRunAnalyticsComponent, { className: "AIAgentRunAnalyticsComponent", filePath: "src/lib/custom/ai-agent-run/ai-agent-run-analytics.component.ts", lineNumber: 82 }); })();
2401
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAgentRunAnalyticsComponent, { className: "AIAgentRunAnalyticsComponent", filePath: "src/lib/custom/ai-agent-run/ai-agent-run-analytics.component.ts", lineNumber: 83 }); })();
2344
2402
  //# sourceMappingURL=ai-agent-run-analytics.component.js.map