@memberjunction/ng-core-entity-forms 2.74.0 → 2.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-diagram.component.d.ts +109 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-diagram.component.d.ts.map +1 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-diagram.component.js +2020 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-diagram.component.js.map +1 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.d.ts +32 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.d.ts.map +1 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js +413 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js.map +1 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/step-info-control.component.d.ts +9 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/step-info-control.component.d.ts.map +1 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/step-info-control.component.js +84 -0
- package/dist/lib/custom/AIAgents/FlowAgentType/step-info-control.component.js.map +1 -0
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +34 -6
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js +656 -520
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts +11 -6
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +459 -448
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.js +51 -49
- package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-test-harness.component.d.ts.map +1 -1
- package/dist/lib/custom/Actions/action-test-harness.component.js +5 -3
- package/dist/lib/custom/Actions/action-test-harness.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts +35 -7
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +235 -219
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.d.ts +37 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js +117 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts +49 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js +211 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts +33 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +265 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js +0 -8
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts +4 -8
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +47 -189
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts +71 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js +931 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +10 -4
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +257 -295
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
- package/dist/lib/custom/custom-forms.module.d.ts +30 -25
- package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
- package/dist/lib/custom/custom-forms.module.js +31 -4
- package/dist/lib/custom/custom-forms.module.js.map +1 -1
- package/dist/lib/generated/Entities/AIAgent/aiagent.form.component.js +34 -14
- package/dist/lib/generated/Entities/AIAgent/aiagent.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/AIAgentStep/aiagentstep.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/AIAgentStep/aiagentstep.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/AIAgentStep/aiagentstep.form.component.js +80 -0
- package/dist/lib/generated/Entities/AIAgentStep/aiagentstep.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/AIAgentStep/sections/details.component.d.ts +11 -0
- package/dist/lib/generated/Entities/AIAgentStep/sections/details.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/AIAgentStep/sections/details.component.js +277 -0
- package/dist/lib/generated/Entities/AIAgentStep/sections/details.component.js.map +1 -0
- package/dist/lib/generated/Entities/AIAgentStepPath/aiagentsteppath.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/AIAgentStepPath/aiagentsteppath.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/AIAgentStepPath/aiagentsteppath.form.component.js +59 -0
- package/dist/lib/generated/Entities/AIAgentStepPath/aiagentsteppath.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/AIAgentStepPath/sections/details.component.d.ts +11 -0
- package/dist/lib/generated/Entities/AIAgentStepPath/sections/details.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/AIAgentStepPath/sections/details.component.js +147 -0
- package/dist/lib/generated/Entities/AIAgentStepPath/sections/details.component.js.map +1 -0
- package/dist/lib/generated/Entities/AIAgentType/sections/details.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/AIAgentType/sections/details.component.js +31 -4
- package/dist/lib/generated/Entities/AIAgentType/sections/details.component.js.map +1 -1
- package/dist/lib/generated/Entities/AIPrompt/aiprompt.form.component.js +16 -6
- package/dist/lib/generated/Entities/AIPrompt/aiprompt.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/AIPromptRun/sections/details.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/AIPromptRun/sections/details.component.js +15 -4
- package/dist/lib/generated/Entities/AIPromptRun/sections/details.component.js.map +1 -1
- package/dist/lib/generated/Entities/Action/action.form.component.js +19 -9
- package/dist/lib/generated/Entities/Action/action.form.component.js.map +1 -1
- package/dist/lib/generated/generated-forms.module.d.ts +294 -285
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +183 -110
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +21 -17
|
@@ -3,9 +3,10 @@ import { Subject } from 'rxjs';
|
|
|
3
3
|
import { RunView } from '@memberjunction/core';
|
|
4
4
|
import * as d3 from 'd3';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
|
-
import * as i1 from "
|
|
7
|
-
import * as i2 from "@
|
|
8
|
-
import * as i3 from "@progress/kendo-angular-
|
|
6
|
+
import * as i1 from "./ai-agent-run-cost.service";
|
|
7
|
+
import * as i2 from "@angular/common";
|
|
8
|
+
import * as i3 from "@progress/kendo-angular-layout";
|
|
9
|
+
import * as i4 from "@progress/kendo-angular-buttons";
|
|
9
10
|
const _c0 = ["modelDistributionChart"];
|
|
10
11
|
const _c1 = ["executionTimeChart"];
|
|
11
12
|
const _c2 = ["costByVendorChart"];
|
|
@@ -40,11 +41,11 @@ function AIAgentRunAnalyticsComponent_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
|
40
41
|
i0.ɵɵtextInterpolate(ctx_r1.error);
|
|
41
42
|
} }
|
|
42
43
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_3_Template(rf, ctx) { if (rf & 1) {
|
|
43
|
-
i0.ɵɵelement(0, "i",
|
|
44
|
+
i0.ɵɵelement(0, "i", 24);
|
|
44
45
|
i0.ɵɵtext(1, " Overview ");
|
|
45
46
|
} }
|
|
46
47
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_4_span_12_Template(rf, ctx) { if (rf & 1) {
|
|
47
|
-
i0.ɵɵelementStart(0, "span",
|
|
48
|
+
i0.ɵɵelementStart(0, "span", 40);
|
|
48
49
|
i0.ɵɵtext(1);
|
|
49
50
|
i0.ɵɵelementEnd();
|
|
50
51
|
} if (rf & 2) {
|
|
@@ -53,7 +54,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_4_span_12_Template(rf, c
|
|
|
53
54
|
i0.ɵɵtextInterpolate1("", ctx_r1.promptMetrics.statusBreakdown.failed, " failed");
|
|
54
55
|
} }
|
|
55
56
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_4_span_24_Template(rf, ctx) { if (rf & 1) {
|
|
56
|
-
i0.ɵɵelementStart(0, "span",
|
|
57
|
+
i0.ɵɵelementStart(0, "span", 40);
|
|
57
58
|
i0.ɵɵtext(1);
|
|
58
59
|
i0.ɵɵelementEnd();
|
|
59
60
|
} if (rf & 2) {
|
|
@@ -62,56 +63,56 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_4_span_24_Template(rf, c
|
|
|
62
63
|
i0.ɵɵtextInterpolate1("", ctx_r1.actionMetrics.statusBreakdown.failed, " failed");
|
|
63
64
|
} }
|
|
64
65
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_4_Template(rf, ctx) { if (rf & 1) {
|
|
65
|
-
i0.ɵɵelementStart(0, "div",
|
|
66
|
-
i0.ɵɵelement(3, "i",
|
|
66
|
+
i0.ɵɵelementStart(0, "div", 25)(1, "div", 26)(2, "div", 27);
|
|
67
|
+
i0.ɵɵelement(3, "i", 28);
|
|
67
68
|
i0.ɵɵelementEnd();
|
|
68
|
-
i0.ɵɵelementStart(4, "div",
|
|
69
|
+
i0.ɵɵelementStart(4, "div", 29)(5, "h3");
|
|
69
70
|
i0.ɵɵtext(6, "Total Prompts");
|
|
70
71
|
i0.ɵɵelementEnd();
|
|
71
|
-
i0.ɵɵelementStart(7, "div",
|
|
72
|
+
i0.ɵɵelementStart(7, "div", 30);
|
|
72
73
|
i0.ɵɵtext(8);
|
|
73
74
|
i0.ɵɵelementEnd();
|
|
74
|
-
i0.ɵɵelementStart(9, "div",
|
|
75
|
+
i0.ɵɵelementStart(9, "div", 31)(10, "span", 32);
|
|
75
76
|
i0.ɵɵtext(11);
|
|
76
77
|
i0.ɵɵelementEnd();
|
|
77
|
-
i0.ɵɵtemplate(12, AIAgentRunAnalyticsComponent_div_3_ng_template_4_span_12_Template, 2, 1, "span",
|
|
78
|
+
i0.ɵɵtemplate(12, AIAgentRunAnalyticsComponent_div_3_ng_template_4_span_12_Template, 2, 1, "span", 33);
|
|
78
79
|
i0.ɵɵelementEnd()()();
|
|
79
|
-
i0.ɵɵelementStart(13, "div",
|
|
80
|
-
i0.ɵɵelement(15, "i",
|
|
80
|
+
i0.ɵɵelementStart(13, "div", 26)(14, "div", 34);
|
|
81
|
+
i0.ɵɵelement(15, "i", 35);
|
|
81
82
|
i0.ɵɵelementEnd();
|
|
82
|
-
i0.ɵɵelementStart(16, "div",
|
|
83
|
+
i0.ɵɵelementStart(16, "div", 29)(17, "h3");
|
|
83
84
|
i0.ɵɵtext(18, "Total Actions");
|
|
84
85
|
i0.ɵɵelementEnd();
|
|
85
|
-
i0.ɵɵelementStart(19, "div",
|
|
86
|
+
i0.ɵɵelementStart(19, "div", 30);
|
|
86
87
|
i0.ɵɵtext(20);
|
|
87
88
|
i0.ɵɵelementEnd();
|
|
88
|
-
i0.ɵɵelementStart(21, "div",
|
|
89
|
+
i0.ɵɵelementStart(21, "div", 31)(22, "span", 32);
|
|
89
90
|
i0.ɵɵtext(23);
|
|
90
91
|
i0.ɵɵelementEnd();
|
|
91
|
-
i0.ɵɵtemplate(24, AIAgentRunAnalyticsComponent_div_3_ng_template_4_span_24_Template, 2, 1, "span",
|
|
92
|
+
i0.ɵɵtemplate(24, AIAgentRunAnalyticsComponent_div_3_ng_template_4_span_24_Template, 2, 1, "span", 33);
|
|
92
93
|
i0.ɵɵelementEnd()()();
|
|
93
|
-
i0.ɵɵelementStart(25, "div",
|
|
94
|
-
i0.ɵɵelement(27, "i",
|
|
94
|
+
i0.ɵɵelementStart(25, "div", 26)(26, "div", 36);
|
|
95
|
+
i0.ɵɵelement(27, "i", 37);
|
|
95
96
|
i0.ɵɵelementEnd();
|
|
96
|
-
i0.ɵɵelementStart(28, "div",
|
|
97
|
+
i0.ɵɵelementStart(28, "div", 29)(29, "h3");
|
|
97
98
|
i0.ɵɵtext(30, "Total Cost");
|
|
98
99
|
i0.ɵɵelementEnd();
|
|
99
|
-
i0.ɵɵelementStart(31, "div",
|
|
100
|
+
i0.ɵɵelementStart(31, "div", 30);
|
|
100
101
|
i0.ɵɵtext(32);
|
|
101
102
|
i0.ɵɵelementEnd();
|
|
102
|
-
i0.ɵɵelementStart(33, "div",
|
|
103
|
+
i0.ɵɵelementStart(33, "div", 31)(34, "span");
|
|
103
104
|
i0.ɵɵtext(35);
|
|
104
105
|
i0.ɵɵelementEnd()()()();
|
|
105
|
-
i0.ɵɵelementStart(36, "div",
|
|
106
|
-
i0.ɵɵelement(38, "i",
|
|
106
|
+
i0.ɵɵelementStart(36, "div", 26)(37, "div", 38);
|
|
107
|
+
i0.ɵɵelement(38, "i", 39);
|
|
107
108
|
i0.ɵɵelementEnd();
|
|
108
|
-
i0.ɵɵelementStart(39, "div",
|
|
109
|
+
i0.ɵɵelementStart(39, "div", 29)(40, "h3");
|
|
109
110
|
i0.ɵɵtext(41, "Execution Time");
|
|
110
111
|
i0.ɵɵelementEnd();
|
|
111
|
-
i0.ɵɵelementStart(42, "div",
|
|
112
|
+
i0.ɵɵelementStart(42, "div", 30);
|
|
112
113
|
i0.ɵɵtext(43);
|
|
113
114
|
i0.ɵɵelementEnd();
|
|
114
|
-
i0.ɵɵelementStart(44, "div",
|
|
115
|
+
i0.ɵɵelementStart(44, "div", 31)(45, "span");
|
|
115
116
|
i0.ɵɵtext(46);
|
|
116
117
|
i0.ɵɵelementEnd()()()()();
|
|
117
118
|
} if (rf & 2) {
|
|
@@ -138,14 +139,14 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_4_Template(rf, ctx) { if
|
|
|
138
139
|
i0.ɵɵtextInterpolate1("", ctx_r1.timelineMetrics.totalSteps, " total steps");
|
|
139
140
|
} }
|
|
140
141
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_6_Template(rf, ctx) { if (rf & 1) {
|
|
141
|
-
i0.ɵɵelement(0, "i",
|
|
142
|
+
i0.ɵɵelement(0, "i", 28);
|
|
142
143
|
i0.ɵɵtext(1, " Prompt Analytics ");
|
|
143
144
|
} }
|
|
144
145
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
145
146
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
146
|
-
i0.ɵɵelementStart(0, "div",
|
|
147
|
+
i0.ɵɵelementStart(0, "div", 50)(1, "button", 51);
|
|
147
148
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleViewMode()); });
|
|
148
|
-
i0.ɵɵelement(2, "i",
|
|
149
|
+
i0.ɵɵelement(2, "i", 48);
|
|
149
150
|
i0.ɵɵtext(3);
|
|
150
151
|
i0.ɵɵelementEnd()();
|
|
151
152
|
} if (rf & 2) {
|
|
@@ -156,19 +157,19 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_1_Template(rf, ctx
|
|
|
156
157
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.viewMode === "grid" ? "Expand All" : "Collapse All", " ");
|
|
157
158
|
} }
|
|
158
159
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
159
|
-
i0.ɵɵelementStart(0, "div",
|
|
160
|
-
i0.ɵɵelement(1, "i",
|
|
160
|
+
i0.ɵɵelementStart(0, "div", 52);
|
|
161
|
+
i0.ɵɵelement(1, "i", 53);
|
|
161
162
|
i0.ɵɵelementStart(2, "p");
|
|
162
163
|
i0.ɵɵtext(3, "No prompt executions found in this agent run.");
|
|
163
164
|
i0.ɵɵelementEnd();
|
|
164
|
-
i0.ɵɵelementStart(4, "p",
|
|
165
|
+
i0.ɵɵelementStart(4, "p", 54);
|
|
165
166
|
i0.ɵɵtext(5, "This agent run may have only executed actions without any AI prompts.");
|
|
166
167
|
i0.ɵɵelementEnd()();
|
|
167
168
|
} }
|
|
168
169
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_div_12_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
169
|
-
i0.ɵɵelementStart(0, "div",
|
|
170
|
-
i0.ɵɵelement(1, "span",
|
|
171
|
-
i0.ɵɵelementStart(2, "span",
|
|
170
|
+
i0.ɵɵelementStart(0, "div", 71);
|
|
171
|
+
i0.ɵɵelement(1, "span", 72);
|
|
172
|
+
i0.ɵɵelementStart(2, "span", 73);
|
|
172
173
|
i0.ɵɵtext(3);
|
|
173
174
|
i0.ɵɵelementEnd()();
|
|
174
175
|
} if (rf & 2) {
|
|
@@ -180,8 +181,8 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_div_12_div_1_Tem
|
|
|
180
181
|
i0.ɵɵtextInterpolate3("", item_r6.key, ": ", item_r6.value.count, " (", (item_r6.value.count / ctx_r1.promptMetrics.totalCount * 100).toFixed(1), "%)");
|
|
181
182
|
} }
|
|
182
183
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_div_12_Template(rf, ctx) { if (rf & 1) {
|
|
183
|
-
i0.ɵɵelementStart(0, "div",
|
|
184
|
-
i0.ɵɵtemplate(1, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_div_12_div_1_Template, 4, 5, "div",
|
|
184
|
+
i0.ɵɵelementStart(0, "div", 69);
|
|
185
|
+
i0.ɵɵtemplate(1, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_div_12_div_1_Template, 4, 5, "div", 70);
|
|
185
186
|
i0.ɵɵpipe(2, "keyvalue");
|
|
186
187
|
i0.ɵɵelementEnd();
|
|
187
188
|
} if (rf & 2) {
|
|
@@ -191,56 +192,56 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_div_12_Template(
|
|
|
191
192
|
} }
|
|
192
193
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
193
194
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
194
|
-
i0.ɵɵelementStart(0, "div",
|
|
195
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "div", 56)(2, "div", 57);
|
|
195
196
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("modelDistribution")); });
|
|
196
197
|
i0.ɵɵelementStart(3, "h3");
|
|
197
|
-
i0.ɵɵelement(4, "i",
|
|
198
|
+
i0.ɵɵelement(4, "i", 58);
|
|
198
199
|
i0.ɵɵtext(5, " Prompts by Model");
|
|
199
200
|
i0.ɵɵelementEnd();
|
|
200
|
-
i0.ɵɵelementStart(6, "button",
|
|
201
|
-
i0.ɵɵelement(7, "i",
|
|
201
|
+
i0.ɵɵelementStart(6, "button", 59);
|
|
202
|
+
i0.ɵɵelement(7, "i", 48);
|
|
202
203
|
i0.ɵɵelementEnd()();
|
|
203
|
-
i0.ɵɵelementStart(8, "div",
|
|
204
|
-
i0.ɵɵelement(10, "div",
|
|
205
|
-
i0.ɵɵtemplate(12, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_div_12_Template, 3, 3, "div",
|
|
204
|
+
i0.ɵɵelementStart(8, "div", 60)(9, "div", 61);
|
|
205
|
+
i0.ɵɵelement(10, "div", 62, 0);
|
|
206
|
+
i0.ɵɵtemplate(12, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_div_12_Template, 3, 3, "div", 63);
|
|
206
207
|
i0.ɵɵelementEnd()()();
|
|
207
|
-
i0.ɵɵelementStart(13, "div",
|
|
208
|
+
i0.ɵɵelementStart(13, "div", 56)(14, "div", 57);
|
|
208
209
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_Template_div_click_14_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("executionTime")); });
|
|
209
210
|
i0.ɵɵelementStart(15, "h3");
|
|
210
|
-
i0.ɵɵelement(16, "i",
|
|
211
|
+
i0.ɵɵelement(16, "i", 39);
|
|
211
212
|
i0.ɵɵtext(17, " Average Execution Time by Vendor");
|
|
212
213
|
i0.ɵɵelementEnd();
|
|
213
|
-
i0.ɵɵelementStart(18, "button",
|
|
214
|
-
i0.ɵɵelement(19, "i",
|
|
214
|
+
i0.ɵɵelementStart(18, "button", 59);
|
|
215
|
+
i0.ɵɵelement(19, "i", 48);
|
|
215
216
|
i0.ɵɵelementEnd()();
|
|
216
|
-
i0.ɵɵelementStart(20, "div",
|
|
217
|
-
i0.ɵɵelement(22, "div",
|
|
217
|
+
i0.ɵɵelementStart(20, "div", 60)(21, "div", 61);
|
|
218
|
+
i0.ɵɵelement(22, "div", 64, 1);
|
|
218
219
|
i0.ɵɵelementEnd()()();
|
|
219
|
-
i0.ɵɵelementStart(24, "div",
|
|
220
|
+
i0.ɵɵelementStart(24, "div", 56)(25, "div", 57);
|
|
220
221
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_Template_div_click_25_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("costByVendor")); });
|
|
221
222
|
i0.ɵɵelementStart(26, "h3");
|
|
222
|
-
i0.ɵɵelement(27, "i",
|
|
223
|
+
i0.ɵɵelement(27, "i", 37);
|
|
223
224
|
i0.ɵɵtext(28, " Cost Distribution by Vendor");
|
|
224
225
|
i0.ɵɵelementEnd();
|
|
225
|
-
i0.ɵɵelementStart(29, "button",
|
|
226
|
-
i0.ɵɵelement(30, "i",
|
|
226
|
+
i0.ɵɵelementStart(29, "button", 59);
|
|
227
|
+
i0.ɵɵelement(30, "i", 48);
|
|
227
228
|
i0.ɵɵelementEnd()();
|
|
228
|
-
i0.ɵɵelementStart(31, "div",
|
|
229
|
-
i0.ɵɵelement(33, "div",
|
|
230
|
-
i0.ɵɵelementStart(35, "div",
|
|
229
|
+
i0.ɵɵelementStart(31, "div", 60)(32, "div", 61);
|
|
230
|
+
i0.ɵɵelement(33, "div", 65, 2);
|
|
231
|
+
i0.ɵɵelementStart(35, "div", 66);
|
|
231
232
|
i0.ɵɵtext(36);
|
|
232
233
|
i0.ɵɵelementEnd()()()();
|
|
233
|
-
i0.ɵɵelementStart(37, "div",
|
|
234
|
+
i0.ɵɵelementStart(37, "div", 56)(38, "div", 57);
|
|
234
235
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_Template_div_click_38_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("tokenUsage")); });
|
|
235
236
|
i0.ɵɵelementStart(39, "h3");
|
|
236
|
-
i0.ɵɵelement(40, "i",
|
|
237
|
+
i0.ɵɵelement(40, "i", 67);
|
|
237
238
|
i0.ɵɵtext(41, " Token Usage by Model");
|
|
238
239
|
i0.ɵɵelementEnd();
|
|
239
|
-
i0.ɵɵelementStart(42, "button",
|
|
240
|
-
i0.ɵɵelement(43, "i",
|
|
240
|
+
i0.ɵɵelementStart(42, "button", 59);
|
|
241
|
+
i0.ɵɵelement(43, "i", 48);
|
|
241
242
|
i0.ɵɵelementEnd()();
|
|
242
|
-
i0.ɵɵelementStart(44, "div",
|
|
243
|
-
i0.ɵɵelement(46, "div",
|
|
243
|
+
i0.ɵɵelementStart(44, "div", 60)(45, "div", 61);
|
|
244
|
+
i0.ɵɵelement(46, "div", 68, 3);
|
|
244
245
|
i0.ɵɵelementEnd()()()();
|
|
245
246
|
} if (rf & 2) {
|
|
246
247
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -267,53 +268,53 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_Template(rf, ctx
|
|
|
267
268
|
} }
|
|
268
269
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_4_Template(rf, ctx) { if (rf & 1) {
|
|
269
270
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
270
|
-
i0.ɵɵelementStart(0, "div",
|
|
271
|
+
i0.ɵɵelementStart(0, "div", 74)(1, "div", 56)(2, "div", 57);
|
|
271
272
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_4_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptTime")); });
|
|
272
273
|
i0.ɵɵelementStart(3, "h3");
|
|
273
|
-
i0.ɵɵelement(4, "i",
|
|
274
|
+
i0.ɵɵelement(4, "i", 75);
|
|
274
275
|
i0.ɵɵtext(5, " Average Execution Time by Prompt");
|
|
275
276
|
i0.ɵɵelementEnd();
|
|
276
|
-
i0.ɵɵelementStart(6, "button",
|
|
277
|
-
i0.ɵɵelement(7, "i",
|
|
277
|
+
i0.ɵɵelementStart(6, "button", 59);
|
|
278
|
+
i0.ɵɵelement(7, "i", 48);
|
|
278
279
|
i0.ɵɵelementEnd()();
|
|
279
|
-
i0.ɵɵelementStart(8, "div",
|
|
280
|
-
i0.ɵɵelement(10, "div",
|
|
280
|
+
i0.ɵɵelementStart(8, "div", 60)(9, "div", 61);
|
|
281
|
+
i0.ɵɵelement(10, "div", 76, 4);
|
|
281
282
|
i0.ɵɵelementEnd()()();
|
|
282
|
-
i0.ɵɵelementStart(12, "div",
|
|
283
|
+
i0.ɵɵelementStart(12, "div", 56)(13, "div", 57);
|
|
283
284
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_4_Template_div_click_13_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptToken")); });
|
|
284
285
|
i0.ɵɵelementStart(14, "h3");
|
|
285
|
-
i0.ɵɵelement(15, "i",
|
|
286
|
+
i0.ɵɵelement(15, "i", 77);
|
|
286
287
|
i0.ɵɵtext(16, " Token Usage by Prompt");
|
|
287
288
|
i0.ɵɵelementEnd();
|
|
288
|
-
i0.ɵɵelementStart(17, "button",
|
|
289
|
-
i0.ɵɵelement(18, "i",
|
|
289
|
+
i0.ɵɵelementStart(17, "button", 59);
|
|
290
|
+
i0.ɵɵelement(18, "i", 48);
|
|
290
291
|
i0.ɵɵelementEnd()();
|
|
291
|
-
i0.ɵɵelementStart(19, "div",
|
|
292
|
-
i0.ɵɵelement(21, "div",
|
|
292
|
+
i0.ɵɵelementStart(19, "div", 60)(20, "div", 61);
|
|
293
|
+
i0.ɵɵelement(21, "div", 78, 5);
|
|
293
294
|
i0.ɵɵelementEnd()()();
|
|
294
|
-
i0.ɵɵelementStart(23, "div",
|
|
295
|
+
i0.ɵɵelementStart(23, "div", 56)(24, "div", 57);
|
|
295
296
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_4_Template_div_click_24_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptCost")); });
|
|
296
297
|
i0.ɵɵelementStart(25, "h3");
|
|
297
|
-
i0.ɵɵelement(26, "i",
|
|
298
|
+
i0.ɵɵelement(26, "i", 58);
|
|
298
299
|
i0.ɵɵtext(27, " Cost Distribution by Prompt");
|
|
299
300
|
i0.ɵɵelementEnd();
|
|
300
|
-
i0.ɵɵelementStart(28, "button",
|
|
301
|
-
i0.ɵɵelement(29, "i",
|
|
301
|
+
i0.ɵɵelementStart(28, "button", 59);
|
|
302
|
+
i0.ɵɵelement(29, "i", 48);
|
|
302
303
|
i0.ɵɵelementEnd()();
|
|
303
|
-
i0.ɵɵelementStart(30, "div",
|
|
304
|
-
i0.ɵɵelement(32, "div",
|
|
304
|
+
i0.ɵɵelementStart(30, "div", 60)(31, "div", 61);
|
|
305
|
+
i0.ɵɵelement(32, "div", 79, 6);
|
|
305
306
|
i0.ɵɵelementEnd()()();
|
|
306
|
-
i0.ɵɵelementStart(34, "div",
|
|
307
|
+
i0.ɵɵelementStart(34, "div", 56)(35, "div", 57);
|
|
307
308
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_4_Template_div_click_35_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("promptCount")); });
|
|
308
309
|
i0.ɵɵelementStart(36, "h3");
|
|
309
|
-
i0.ɵɵelement(37, "i",
|
|
310
|
+
i0.ɵɵelement(37, "i", 80);
|
|
310
311
|
i0.ɵɵtext(38, " Prompt Execution Count");
|
|
311
312
|
i0.ɵɵelementEnd();
|
|
312
|
-
i0.ɵɵelementStart(39, "button",
|
|
313
|
-
i0.ɵɵelement(40, "i",
|
|
313
|
+
i0.ɵɵelementStart(39, "button", 59);
|
|
314
|
+
i0.ɵɵelement(40, "i", 48);
|
|
314
315
|
i0.ɵɵelementEnd()();
|
|
315
|
-
i0.ɵɵelementStart(41, "div",
|
|
316
|
-
i0.ɵɵelement(43, "div",
|
|
316
|
+
i0.ɵɵelementStart(41, "div", 60)(42, "div", 61);
|
|
317
|
+
i0.ɵɵelement(43, "div", 81, 7);
|
|
317
318
|
i0.ɵɵelementEnd()()()();
|
|
318
319
|
} if (rf & 2) {
|
|
319
320
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -347,7 +348,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_9_tr_15_Template(r
|
|
|
347
348
|
i0.ɵɵelementStart(7, "td");
|
|
348
349
|
i0.ɵɵtext(8);
|
|
349
350
|
i0.ɵɵelementEnd();
|
|
350
|
-
i0.ɵɵelementStart(9, "td")(10, "span",
|
|
351
|
+
i0.ɵɵelementStart(9, "td")(10, "span", 84);
|
|
351
352
|
i0.ɵɵtext(11);
|
|
352
353
|
i0.ɵɵelementEnd()()();
|
|
353
354
|
} if (rf & 2) {
|
|
@@ -365,7 +366,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_9_tr_15_Template(r
|
|
|
365
366
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.calculatePromptSuccessRate(prompt_r8.key), "% ");
|
|
366
367
|
} }
|
|
367
368
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_9_Template(rf, ctx) { if (rf & 1) {
|
|
368
|
-
i0.ɵɵelementStart(0, "div",
|
|
369
|
+
i0.ɵɵelementStart(0, "div", 82)(1, "table")(2, "thead")(3, "tr")(4, "th");
|
|
369
370
|
i0.ɵɵtext(5, "Prompt Name");
|
|
370
371
|
i0.ɵɵelementEnd();
|
|
371
372
|
i0.ɵɵelementStart(6, "th");
|
|
@@ -381,7 +382,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_9_Template(rf, ctx
|
|
|
381
382
|
i0.ɵɵtext(13, "Success Rate");
|
|
382
383
|
i0.ɵɵelementEnd()()();
|
|
383
384
|
i0.ɵɵelementStart(14, "tbody");
|
|
384
|
-
i0.ɵɵtemplate(15, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_9_tr_15_Template, 12, 5, "tr",
|
|
385
|
+
i0.ɵɵtemplate(15, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_9_tr_15_Template, 12, 5, "tr", 83);
|
|
385
386
|
i0.ɵɵpipe(16, "keyvalue");
|
|
386
387
|
i0.ɵɵelementEnd()()();
|
|
387
388
|
} if (rf & 2) {
|
|
@@ -391,14 +392,14 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_9_Template(rf, ctx
|
|
|
391
392
|
} }
|
|
392
393
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_7_Template(rf, ctx) { if (rf & 1) {
|
|
393
394
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
394
|
-
i0.ɵɵelementStart(0, "div",
|
|
395
|
-
i0.ɵɵtemplate(1, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_1_Template, 4, 2, "div",
|
|
396
|
-
i0.ɵɵelementStart(5, "div",
|
|
395
|
+
i0.ɵɵelementStart(0, "div", 41);
|
|
396
|
+
i0.ɵɵtemplate(1, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_1_Template, 4, 2, "div", 42)(2, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_2_Template, 6, 0, "div", 43)(3, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_3_Template, 48, 14, "div", 44)(4, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_4_Template, 45, 12, "div", 45);
|
|
397
|
+
i0.ɵɵelementStart(5, "div", 46)(6, "button", 47);
|
|
397
398
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_7_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.promptDetailsExpanded = !ctx_r1.promptDetailsExpanded); });
|
|
398
|
-
i0.ɵɵelement(7, "i",
|
|
399
|
+
i0.ɵɵelement(7, "i", 48);
|
|
399
400
|
i0.ɵɵtext(8, " Detailed Prompt Metrics ");
|
|
400
401
|
i0.ɵɵelementEnd();
|
|
401
|
-
i0.ɵɵtemplate(9, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_9_Template, 17, 3, "div",
|
|
402
|
+
i0.ɵɵtemplate(9, AIAgentRunAnalyticsComponent_div_3_ng_template_7_div_9_Template, 17, 3, "div", 49);
|
|
402
403
|
i0.ɵɵelementEnd()();
|
|
403
404
|
} if (rf & 2) {
|
|
404
405
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -416,7 +417,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_7_Template(rf, ctx) { if
|
|
|
416
417
|
i0.ɵɵproperty("ngIf", ctx_r1.promptDetailsExpanded);
|
|
417
418
|
} }
|
|
418
419
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_9_Template(rf, ctx) { if (rf & 1) {
|
|
419
|
-
i0.ɵɵelement(0, "i",
|
|
420
|
+
i0.ɵɵelement(0, "i", 35);
|
|
420
421
|
i0.ɵɵtext(1, " Action Analytics ");
|
|
421
422
|
} }
|
|
422
423
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_tr_15_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -429,7 +430,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_tr_15_Template
|
|
|
429
430
|
i0.ɵɵelementStart(5, "td");
|
|
430
431
|
i0.ɵɵtext(6);
|
|
431
432
|
i0.ɵɵelementEnd();
|
|
432
|
-
i0.ɵɵelementStart(7, "td")(8, "span",
|
|
433
|
+
i0.ɵɵelementStart(7, "td")(8, "span", 84);
|
|
433
434
|
i0.ɵɵtext(9);
|
|
434
435
|
i0.ɵɵelementEnd()();
|
|
435
436
|
i0.ɵɵelementStart(10, "td");
|
|
@@ -452,7 +453,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_tr_15_Template
|
|
|
452
453
|
i0.ɵɵtextInterpolate(ctx_r1.getActionType(action_r10.key));
|
|
453
454
|
} }
|
|
454
455
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_Template(rf, ctx) { if (rf & 1) {
|
|
455
|
-
i0.ɵɵelementStart(0, "div",
|
|
456
|
+
i0.ɵɵelementStart(0, "div", 82)(1, "table")(2, "thead")(3, "tr")(4, "th");
|
|
456
457
|
i0.ɵɵtext(5, "Action Name");
|
|
457
458
|
i0.ɵɵelementEnd();
|
|
458
459
|
i0.ɵɵelementStart(6, "th");
|
|
@@ -468,7 +469,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_Template(rf, c
|
|
|
468
469
|
i0.ɵɵtext(13, "Type");
|
|
469
470
|
i0.ɵɵelementEnd()()();
|
|
470
471
|
i0.ɵɵelementStart(14, "tbody");
|
|
471
|
-
i0.ɵɵtemplate(15, AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_tr_15_Template, 12, 11, "tr",
|
|
472
|
+
i0.ɵɵtemplate(15, AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_tr_15_Template, 12, 11, "tr", 83);
|
|
472
473
|
i0.ɵɵpipe(16, "keyvalue");
|
|
473
474
|
i0.ɵɵelementEnd()()();
|
|
474
475
|
} if (rf & 2) {
|
|
@@ -477,10 +478,10 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_Template(rf, c
|
|
|
477
478
|
i0.ɵɵproperty("ngForOf", i0.ɵɵpipeBind1(16, 1, ctx_r1.actionMetrics.byAction));
|
|
478
479
|
} }
|
|
479
480
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_30_div_7_Template(rf, ctx) { if (rf & 1) {
|
|
480
|
-
i0.ɵɵelementStart(0, "div",
|
|
481
|
+
i0.ɵɵelementStart(0, "div", 97)(1, "span", 98);
|
|
481
482
|
i0.ɵɵtext(2);
|
|
482
483
|
i0.ɵɵelementEnd();
|
|
483
|
-
i0.ɵɵelementStart(3, "span",
|
|
484
|
+
i0.ɵɵelementStart(3, "span", 99);
|
|
484
485
|
i0.ɵɵtext(4);
|
|
485
486
|
i0.ɵɵelementEnd()();
|
|
486
487
|
} if (rf & 2) {
|
|
@@ -491,15 +492,15 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_30_div_7_Template
|
|
|
491
492
|
i0.ɵɵtextInterpolate(error_r11.message);
|
|
492
493
|
} }
|
|
493
494
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_30_Template(rf, ctx) { if (rf & 1) {
|
|
494
|
-
i0.ɵɵelementStart(0, "div",
|
|
495
|
-
i0.ɵɵelement(2, "i",
|
|
495
|
+
i0.ɵɵelementStart(0, "div", 92)(1, "h3");
|
|
496
|
+
i0.ɵɵelement(2, "i", 93);
|
|
496
497
|
i0.ɵɵtext(3, " Common Errors ");
|
|
497
498
|
i0.ɵɵelementEnd();
|
|
498
|
-
i0.ɵɵelementStart(4, "p",
|
|
499
|
+
i0.ɵɵelementStart(4, "p", 94);
|
|
499
500
|
i0.ɵɵtext(5, " This section shows the most frequent error messages from failed actions, helping identify systemic issues that may need attention. ");
|
|
500
501
|
i0.ɵɵelementEnd();
|
|
501
|
-
i0.ɵɵelementStart(6, "div",
|
|
502
|
-
i0.ɵɵtemplate(7, AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_30_div_7_Template, 5, 2, "div",
|
|
502
|
+
i0.ɵɵelementStart(6, "div", 95);
|
|
503
|
+
i0.ɵɵtemplate(7, AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_30_div_7_Template, 5, 2, "div", 96);
|
|
503
504
|
i0.ɵɵelementEnd()();
|
|
504
505
|
} if (rf & 2) {
|
|
505
506
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -507,47 +508,47 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_30_Template(rf, c
|
|
|
507
508
|
i0.ɵɵproperty("ngForOf", ctx_r1.getTopErrors());
|
|
508
509
|
} }
|
|
509
510
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_31_Template(rf, ctx) { if (rf & 1) {
|
|
510
|
-
i0.ɵɵelementStart(0, "div",
|
|
511
|
-
i0.ɵɵelement(1, "i",
|
|
511
|
+
i0.ɵɵelementStart(0, "div", 100);
|
|
512
|
+
i0.ɵɵelement(1, "i", 101);
|
|
512
513
|
i0.ɵɵelementStart(2, "p");
|
|
513
514
|
i0.ɵɵtext(3, "No action errors detected in this run. All actions completed successfully!");
|
|
514
515
|
i0.ɵɵelementEnd()();
|
|
515
516
|
} }
|
|
516
517
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_10_Template(rf, ctx) { if (rf & 1) {
|
|
517
518
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
518
|
-
i0.ɵɵelementStart(0, "div",
|
|
519
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 55)(2, "div", 56)(3, "div", 57);
|
|
519
520
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_10_Template_div_click_3_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("actionSuccess")); });
|
|
520
521
|
i0.ɵɵelementStart(4, "h3");
|
|
521
|
-
i0.ɵɵelement(5, "i",
|
|
522
|
+
i0.ɵɵelement(5, "i", 85);
|
|
522
523
|
i0.ɵɵtext(6, " Action Success Rate");
|
|
523
524
|
i0.ɵɵelementEnd();
|
|
524
|
-
i0.ɵɵelementStart(7, "button",
|
|
525
|
-
i0.ɵɵelement(8, "i",
|
|
525
|
+
i0.ɵɵelementStart(7, "button", 59);
|
|
526
|
+
i0.ɵɵelement(8, "i", 48);
|
|
526
527
|
i0.ɵɵelementEnd()();
|
|
527
|
-
i0.ɵɵelementStart(9, "div",
|
|
528
|
-
i0.ɵɵelement(11, "div",
|
|
528
|
+
i0.ɵɵelementStart(9, "div", 60)(10, "div", 61);
|
|
529
|
+
i0.ɵɵelement(11, "div", 86, 8);
|
|
529
530
|
i0.ɵɵelementEnd()()();
|
|
530
|
-
i0.ɵɵelementStart(13, "div",
|
|
531
|
+
i0.ɵɵelementStart(13, "div", 56)(14, "div", 57);
|
|
531
532
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_10_Template_div_click_14_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleChartExpansion("stepType")); });
|
|
532
533
|
i0.ɵɵelementStart(15, "h3");
|
|
533
|
-
i0.ɵɵelement(16, "i",
|
|
534
|
+
i0.ɵɵelement(16, "i", 87);
|
|
534
535
|
i0.ɵɵtext(17, " Step Type Distribution");
|
|
535
536
|
i0.ɵɵelementEnd();
|
|
536
|
-
i0.ɵɵelementStart(18, "button",
|
|
537
|
-
i0.ɵɵelement(19, "i",
|
|
537
|
+
i0.ɵɵelementStart(18, "button", 59);
|
|
538
|
+
i0.ɵɵelement(19, "i", 48);
|
|
538
539
|
i0.ɵɵelementEnd()();
|
|
539
|
-
i0.ɵɵelementStart(20, "div",
|
|
540
|
-
i0.ɵɵelement(22, "div",
|
|
540
|
+
i0.ɵɵelementStart(20, "div", 60)(21, "div", 61);
|
|
541
|
+
i0.ɵɵelement(22, "div", 88, 9);
|
|
541
542
|
i0.ɵɵelementEnd()()()();
|
|
542
|
-
i0.ɵɵelementStart(24, "div",
|
|
543
|
+
i0.ɵɵelementStart(24, "div", 46)(25, "button", 47);
|
|
543
544
|
i0.ɵɵlistener("click", function AIAgentRunAnalyticsComponent_div_3_ng_template_10_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.actionDetailsExpanded = !ctx_r1.actionDetailsExpanded); });
|
|
544
|
-
i0.ɵɵelement(26, "i",
|
|
545
|
+
i0.ɵɵelement(26, "i", 48);
|
|
545
546
|
i0.ɵɵtext(27, " Detailed Action Metrics ");
|
|
546
547
|
i0.ɵɵelementEnd();
|
|
547
|
-
i0.ɵɵtemplate(28, AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_Template, 17, 3, "div",
|
|
548
|
+
i0.ɵɵtemplate(28, AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_28_Template, 17, 3, "div", 49);
|
|
548
549
|
i0.ɵɵelementEnd();
|
|
549
|
-
i0.ɵɵelementStart(29, "div",
|
|
550
|
-
i0.ɵɵtemplate(30, AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_30_Template, 8, 1, "div",
|
|
550
|
+
i0.ɵɵelementStart(29, "div", 89);
|
|
551
|
+
i0.ɵɵtemplate(30, AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_30_Template, 8, 1, "div", 90)(31, AIAgentRunAnalyticsComponent_div_3_ng_template_10_div_31_Template, 4, 0, "div", 91);
|
|
551
552
|
i0.ɵɵelementEnd()();
|
|
552
553
|
} if (rf & 2) {
|
|
553
554
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -569,7 +570,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_10_Template(rf, ctx) { i
|
|
|
569
570
|
i0.ɵɵproperty("ngIf", ctx_r1.actionMetrics.errorAnalysis.size === 0);
|
|
570
571
|
} }
|
|
571
572
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_12_Template(rf, ctx) { if (rf & 1) {
|
|
572
|
-
i0.ɵɵelement(0, "i",
|
|
573
|
+
i0.ɵɵelement(0, "i", 102);
|
|
573
574
|
i0.ɵɵtext(1, " Model Performance Comparison ");
|
|
574
575
|
} }
|
|
575
576
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_13_tr_22_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -620,7 +621,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_13_tr_22_Template(rf, ct
|
|
|
620
621
|
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(18, 11, model_r12.outputTokens, "1.0-0"));
|
|
621
622
|
} }
|
|
622
623
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_13_Template(rf, ctx) { if (rf & 1) {
|
|
623
|
-
i0.ɵɵelementStart(0, "div",
|
|
624
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 103)(2, "table")(3, "thead")(4, "tr")(5, "th");
|
|
624
625
|
i0.ɵɵtext(6, "Model");
|
|
625
626
|
i0.ɵɵelementEnd();
|
|
626
627
|
i0.ɵɵelementStart(7, "th");
|
|
@@ -645,7 +646,7 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_13_Template(rf, ctx) { i
|
|
|
645
646
|
i0.ɵɵtext(20, "Output Tokens");
|
|
646
647
|
i0.ɵɵelementEnd()()();
|
|
647
648
|
i0.ɵɵelementStart(21, "tbody");
|
|
648
|
-
i0.ɵɵtemplate(22, AIAgentRunAnalyticsComponent_div_3_ng_template_13_tr_22_Template, 19, 14, "tr",
|
|
649
|
+
i0.ɵɵtemplate(22, AIAgentRunAnalyticsComponent_div_3_ng_template_13_tr_22_Template, 19, 14, "tr", 83);
|
|
649
650
|
i0.ɵɵelementEnd()()()();
|
|
650
651
|
} if (rf & 2) {
|
|
651
652
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -653,19 +654,19 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_13_Template(rf, ctx) { i
|
|
|
653
654
|
i0.ɵɵproperty("ngForOf", ctx_r1.getModelPerformanceData());
|
|
654
655
|
} }
|
|
655
656
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_15_Template(rf, ctx) { if (rf & 1) {
|
|
656
|
-
i0.ɵɵelement(0, "i",
|
|
657
|
+
i0.ɵɵelement(0, "i", 104);
|
|
657
658
|
i0.ɵɵtext(1, " Execution Timeline Analysis ");
|
|
658
659
|
} }
|
|
659
660
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_16_div_26_Template(rf, ctx) { if (rf & 1) {
|
|
660
|
-
i0.ɵɵelementStart(0, "div",
|
|
661
|
-
i0.ɵɵelement(1, "i",
|
|
662
|
-
i0.ɵɵelementStart(2, "span",
|
|
661
|
+
i0.ɵɵelementStart(0, "div", 112);
|
|
662
|
+
i0.ɵɵelement(1, "i", 48);
|
|
663
|
+
i0.ɵɵelementStart(2, "span", 113);
|
|
663
664
|
i0.ɵɵtext(3);
|
|
664
665
|
i0.ɵɵelementEnd();
|
|
665
|
-
i0.ɵɵelementStart(4, "span",
|
|
666
|
+
i0.ɵɵelementStart(4, "span", 114);
|
|
666
667
|
i0.ɵɵtext(5);
|
|
667
668
|
i0.ɵɵelementEnd();
|
|
668
|
-
i0.ɵɵelementStart(6, "span",
|
|
669
|
+
i0.ɵɵelementStart(6, "span", 115);
|
|
669
670
|
i0.ɵɵtext(7);
|
|
670
671
|
i0.ɵɵelementEnd()();
|
|
671
672
|
} if (rf & 2) {
|
|
@@ -681,35 +682,35 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_16_div_26_Template(rf, c
|
|
|
681
682
|
i0.ɵɵtextInterpolate1("(", (type_r13.value / ctx_r1.timelineMetrics.totalSteps * 100).toFixed(1), "%)");
|
|
682
683
|
} }
|
|
683
684
|
function AIAgentRunAnalyticsComponent_div_3_ng_template_16_Template(rf, ctx) { if (rf & 1) {
|
|
684
|
-
i0.ɵɵelementStart(0, "div",
|
|
685
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 105)(2, "div", 106)(3, "span", 107);
|
|
685
686
|
i0.ɵɵtext(4, "Total Steps");
|
|
686
687
|
i0.ɵɵelementEnd();
|
|
687
|
-
i0.ɵɵelementStart(5, "span",
|
|
688
|
+
i0.ɵɵelementStart(5, "span", 108);
|
|
688
689
|
i0.ɵɵtext(6);
|
|
689
690
|
i0.ɵɵelementEnd()();
|
|
690
|
-
i0.ɵɵelementStart(7, "div",
|
|
691
|
+
i0.ɵɵelementStart(7, "div", 106)(8, "span", 107);
|
|
691
692
|
i0.ɵɵtext(9, "Parallel Executions");
|
|
692
693
|
i0.ɵɵelementEnd();
|
|
693
|
-
i0.ɵɵelementStart(10, "span",
|
|
694
|
+
i0.ɵɵelementStart(10, "span", 108);
|
|
694
695
|
i0.ɵɵtext(11);
|
|
695
696
|
i0.ɵɵelementEnd()();
|
|
696
|
-
i0.ɵɵelementStart(12, "div",
|
|
697
|
+
i0.ɵɵelementStart(12, "div", 106)(13, "span", 107);
|
|
697
698
|
i0.ɵɵtext(14, "Max Nesting Depth");
|
|
698
699
|
i0.ɵɵelementEnd();
|
|
699
|
-
i0.ɵɵelementStart(15, "span",
|
|
700
|
+
i0.ɵɵelementStart(15, "span", 108);
|
|
700
701
|
i0.ɵɵtext(16);
|
|
701
702
|
i0.ɵɵelementEnd()();
|
|
702
|
-
i0.ɵɵelementStart(17, "div",
|
|
703
|
+
i0.ɵɵelementStart(17, "div", 106)(18, "span", 107);
|
|
703
704
|
i0.ɵɵtext(19, "Sub-Agent Runs");
|
|
704
705
|
i0.ɵɵelementEnd();
|
|
705
|
-
i0.ɵɵelementStart(20, "span",
|
|
706
|
+
i0.ɵɵelementStart(20, "span", 108);
|
|
706
707
|
i0.ɵɵtext(21);
|
|
707
708
|
i0.ɵɵelementEnd()()();
|
|
708
|
-
i0.ɵɵelementStart(22, "div",
|
|
709
|
+
i0.ɵɵelementStart(22, "div", 109)(23, "h3");
|
|
709
710
|
i0.ɵɵtext(24, "Steps by Type");
|
|
710
711
|
i0.ɵɵelementEnd();
|
|
711
|
-
i0.ɵɵelementStart(25, "div",
|
|
712
|
-
i0.ɵɵtemplate(26, AIAgentRunAnalyticsComponent_div_3_ng_template_16_div_26_Template, 8, 4, "div",
|
|
712
|
+
i0.ɵɵelementStart(25, "div", 110);
|
|
713
|
+
i0.ɵɵtemplate(26, AIAgentRunAnalyticsComponent_div_3_ng_template_16_div_26_Template, 8, 4, "div", 111);
|
|
713
714
|
i0.ɵɵpipe(27, "keyvalue");
|
|
714
715
|
i0.ɵɵelementEnd()()();
|
|
715
716
|
} if (rf & 2) {
|
|
@@ -726,23 +727,25 @@ function AIAgentRunAnalyticsComponent_div_3_ng_template_16_Template(rf, ctx) { i
|
|
|
726
727
|
i0.ɵɵproperty("ngForOf", i0.ɵɵpipeBind1(27, 5, ctx_r1.timelineMetrics.stepsByType));
|
|
727
728
|
} }
|
|
728
729
|
function AIAgentRunAnalyticsComponent_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
729
|
-
i0.ɵɵelementStart(0, "div", 19)(1, "kendo-panelbar")(2, "kendo-panelbar-item",
|
|
730
|
-
i0.ɵɵtemplate(3, AIAgentRunAnalyticsComponent_div_3_ng_template_3_Template, 2, 0, "ng-template",
|
|
730
|
+
i0.ɵɵelementStart(0, "div", 19)(1, "kendo-panelbar", 20)(2, "kendo-panelbar-item", 21);
|
|
731
|
+
i0.ɵɵtemplate(3, AIAgentRunAnalyticsComponent_div_3_ng_template_3_Template, 2, 0, "ng-template", 22)(4, AIAgentRunAnalyticsComponent_div_3_ng_template_4_Template, 47, 10, "ng-template", 23);
|
|
731
732
|
i0.ɵɵelementEnd();
|
|
732
|
-
i0.ɵɵelementStart(5, "kendo-panelbar-item",
|
|
733
|
-
i0.ɵɵtemplate(6, AIAgentRunAnalyticsComponent_div_3_ng_template_6_Template, 2, 0, "ng-template",
|
|
733
|
+
i0.ɵɵelementStart(5, "kendo-panelbar-item", 21);
|
|
734
|
+
i0.ɵɵtemplate(6, AIAgentRunAnalyticsComponent_div_3_ng_template_6_Template, 2, 0, "ng-template", 22)(7, AIAgentRunAnalyticsComponent_div_3_ng_template_7_Template, 10, 6, "ng-template", 23);
|
|
734
735
|
i0.ɵɵelementEnd();
|
|
735
|
-
i0.ɵɵelementStart(8, "kendo-panelbar-item",
|
|
736
|
-
i0.ɵɵtemplate(9, AIAgentRunAnalyticsComponent_div_3_ng_template_9_Template, 2, 0, "ng-template",
|
|
736
|
+
i0.ɵɵelementStart(8, "kendo-panelbar-item", 21);
|
|
737
|
+
i0.ɵɵtemplate(9, AIAgentRunAnalyticsComponent_div_3_ng_template_9_Template, 2, 0, "ng-template", 22)(10, AIAgentRunAnalyticsComponent_div_3_ng_template_10_Template, 32, 10, "ng-template", 23);
|
|
737
738
|
i0.ɵɵelementEnd();
|
|
738
|
-
i0.ɵɵelementStart(11, "kendo-panelbar-item",
|
|
739
|
-
i0.ɵɵtemplate(12, AIAgentRunAnalyticsComponent_div_3_ng_template_12_Template, 2, 0, "ng-template",
|
|
739
|
+
i0.ɵɵelementStart(11, "kendo-panelbar-item", 21);
|
|
740
|
+
i0.ɵɵtemplate(12, AIAgentRunAnalyticsComponent_div_3_ng_template_12_Template, 2, 0, "ng-template", 22)(13, AIAgentRunAnalyticsComponent_div_3_ng_template_13_Template, 23, 1, "ng-template", 23);
|
|
740
741
|
i0.ɵɵelementEnd();
|
|
741
|
-
i0.ɵɵelementStart(14, "kendo-panelbar-item",
|
|
742
|
-
i0.ɵɵtemplate(15, AIAgentRunAnalyticsComponent_div_3_ng_template_15_Template, 2, 0, "ng-template",
|
|
742
|
+
i0.ɵɵelementStart(14, "kendo-panelbar-item", 21);
|
|
743
|
+
i0.ɵɵtemplate(15, AIAgentRunAnalyticsComponent_div_3_ng_template_15_Template, 2, 0, "ng-template", 22)(16, AIAgentRunAnalyticsComponent_div_3_ng_template_16_Template, 28, 7, "ng-template", 23);
|
|
743
744
|
i0.ɵɵelementEnd()()();
|
|
744
745
|
} if (rf & 2) {
|
|
745
|
-
i0.ɵɵadvance(
|
|
746
|
+
i0.ɵɵadvance();
|
|
747
|
+
i0.ɵɵproperty("keepItemContent", true);
|
|
748
|
+
i0.ɵɵadvance();
|
|
746
749
|
i0.ɵɵproperty("expanded", true);
|
|
747
750
|
i0.ɵɵadvance(3);
|
|
748
751
|
i0.ɵɵproperty("expanded", true);
|
|
@@ -754,8 +757,9 @@ function AIAgentRunAnalyticsComponent_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
|
754
757
|
i0.ɵɵproperty("expanded", true);
|
|
755
758
|
} }
|
|
756
759
|
export class AIAgentRunAnalyticsComponent {
|
|
757
|
-
constructor(cdr) {
|
|
760
|
+
constructor(cdr, costService) {
|
|
758
761
|
this.cdr = cdr;
|
|
762
|
+
this.costService = costService;
|
|
759
763
|
this.destroy$ = new Subject();
|
|
760
764
|
// Chart expansion states
|
|
761
765
|
this.expandedCharts = {
|
|
@@ -837,11 +841,9 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
837
841
|
}
|
|
838
842
|
async loadAllRunData() {
|
|
839
843
|
const rv = new RunView();
|
|
840
|
-
// Get all agent
|
|
844
|
+
// Get all agent run IDs in hierarchy (including root and children)
|
|
841
845
|
const agentRunIds = await this.getAllAgentRunIds(this.agentRunId);
|
|
842
|
-
|
|
843
|
-
console.log('Number of agent run IDs:', agentRunIds.length);
|
|
844
|
-
// Batch load all data
|
|
846
|
+
// Batch load all data (except prompt runs which we'll load via shared service)
|
|
845
847
|
const results = await rv.RunViews([
|
|
846
848
|
// Main agent run
|
|
847
849
|
{
|
|
@@ -853,49 +855,28 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
853
855
|
EntityName: 'MJ: AI Agent Runs',
|
|
854
856
|
ExtraFilter: agentRunIds.length > 1 ? `ID IN ('${agentRunIds.slice(1).join("','")}')` : `ID = '00000000-0000-0000-0000-000000000000'`,
|
|
855
857
|
},
|
|
856
|
-
// All prompt runs for all agent runs - linked through AI Agent Run Steps
|
|
857
|
-
{
|
|
858
|
-
EntityName: 'MJ: AI Prompt Runs',
|
|
859
|
-
ExtraFilter: `ID IN (SELECT TargetLogID FROM __mj.vwAIAgentRunSteps WHERE AgentRunID IN ('${agentRunIds.join("','")}') AND StepType = 'Prompt')`,
|
|
860
|
-
},
|
|
861
858
|
// All action logs - need to get via steps
|
|
862
859
|
{
|
|
863
860
|
EntityName: 'MJ: AI Agent Run Steps',
|
|
864
861
|
ExtraFilter: `AgentRunID IN ('${agentRunIds.join("','")}') AND StepType = 'Actions'`,
|
|
865
862
|
},
|
|
866
|
-
// All steps for timeline analysis
|
|
863
|
+
// All steps for timeline analysis - only need basic fields like StepType
|
|
867
864
|
{
|
|
868
865
|
EntityName: 'MJ: AI Agent Run Steps',
|
|
869
866
|
ExtraFilter: `AgentRunID IN ('${agentRunIds.join("','")}')`,
|
|
870
|
-
ResultType: 'entity_object'
|
|
871
867
|
}
|
|
872
868
|
]);
|
|
873
869
|
// Process results
|
|
874
|
-
console.log('RunViews results:', results.map((r, i) => ({
|
|
875
|
-
index: i,
|
|
876
|
-
success: r.Success,
|
|
877
|
-
count: r.Results?.length || 0,
|
|
878
|
-
errorMessage: r.ErrorMessage
|
|
879
|
-
})));
|
|
880
870
|
if (results[0].Success && results[0].Results && results[0].Results.length > 0) {
|
|
881
871
|
this.agentRun = results[0].Results[0];
|
|
882
872
|
}
|
|
883
873
|
if (results[1].Success) {
|
|
884
874
|
this.subAgentRuns = results[1].Results || [];
|
|
885
875
|
}
|
|
876
|
+
// Load all prompt runs for the agent run hierarchy
|
|
877
|
+
this.allPromptRuns = await this.loadAllPromptRuns(agentRunIds);
|
|
886
878
|
if (results[2].Success) {
|
|
887
|
-
|
|
888
|
-
console.log(`Found ${this.allPromptRuns.length} prompt runs for agent run IDs:`, agentRunIds);
|
|
889
|
-
console.log('Prompt runs query:', `ID IN (SELECT TargetLogID FROM __mj.vwAIAgentRunSteps WHERE AgentRunID IN ('${agentRunIds.join("','")}') AND StepType = 'Prompts')`);
|
|
890
|
-
if (this.allPromptRuns.length > 0) {
|
|
891
|
-
console.log('First prompt run sample:', this.allPromptRuns[0]);
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
else {
|
|
895
|
-
console.error('Failed to load prompt runs:', results[2].ErrorMessage);
|
|
896
|
-
}
|
|
897
|
-
if (results[3].Success) {
|
|
898
|
-
const actionSteps = results[3].Results || [];
|
|
879
|
+
const actionSteps = results[2].Results || [];
|
|
899
880
|
// Now load the actual action logs
|
|
900
881
|
if (actionSteps.length > 0) {
|
|
901
882
|
const actionLogIds = actionSteps
|
|
@@ -912,32 +893,10 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
912
893
|
}
|
|
913
894
|
}
|
|
914
895
|
}
|
|
915
|
-
if (results[
|
|
916
|
-
this.allSteps = results[
|
|
896
|
+
if (results[3].Success) {
|
|
897
|
+
this.allSteps = results[3].Results || [];
|
|
917
898
|
}
|
|
918
899
|
}
|
|
919
|
-
async getAllAgentRunIds(rootRunId) {
|
|
920
|
-
const allIds = [rootRunId];
|
|
921
|
-
const rv = new RunView();
|
|
922
|
-
// Recursively get all sub-agent run IDs
|
|
923
|
-
const getSubRunIds = async (parentId, depth = 0) => {
|
|
924
|
-
const result = await rv.RunView({
|
|
925
|
-
EntityName: 'MJ: AI Agent Runs',
|
|
926
|
-
ExtraFilter: `ParentRunID = '${parentId}'`,
|
|
927
|
-
ResultType: 'entity_object'
|
|
928
|
-
});
|
|
929
|
-
if (result.Success && result.Results) {
|
|
930
|
-
console.log(`Found ${result.Results.length} sub-agent runs at depth ${depth} for parent ${parentId}`);
|
|
931
|
-
for (const subRun of result.Results) {
|
|
932
|
-
allIds.push(subRun.ID);
|
|
933
|
-
await getSubRunIds(subRun.ID, depth + 1); // Recursive call
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
};
|
|
937
|
-
await getSubRunIds(rootRunId);
|
|
938
|
-
console.log(`Total agent run IDs found: ${allIds.length}`);
|
|
939
|
-
return allIds;
|
|
940
|
-
}
|
|
941
900
|
initializePromptMetrics() {
|
|
942
901
|
return {
|
|
943
902
|
totalCount: 0,
|
|
@@ -2014,7 +1973,64 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
2014
1973
|
.style('font-weight', 'bold')
|
|
2015
1974
|
.text('Prompt Execution Count');
|
|
2016
1975
|
}
|
|
2017
|
-
|
|
1976
|
+
/**
|
|
1977
|
+
* Get all agent run IDs in hierarchy, starting from the root run
|
|
1978
|
+
*/
|
|
1979
|
+
async getAllAgentRunIds(rootRunId) {
|
|
1980
|
+
const rv = new RunView();
|
|
1981
|
+
const agentRunIds = [rootRunId];
|
|
1982
|
+
// Simple recursive approach to find all child runs
|
|
1983
|
+
const findChildRuns = async (parentId) => {
|
|
1984
|
+
const result = await rv.RunView({
|
|
1985
|
+
EntityName: 'MJ: AI Agent Runs',
|
|
1986
|
+
ExtraFilter: `ParentRunID = '${parentId}'`,
|
|
1987
|
+
});
|
|
1988
|
+
if (result.Success && result.Results && result.Results.length > 0) {
|
|
1989
|
+
for (const childRun of result.Results) {
|
|
1990
|
+
if (!agentRunIds.includes(childRun.ID)) {
|
|
1991
|
+
agentRunIds.push(childRun.ID);
|
|
1992
|
+
await findChildRuns(childRun.ID); // Recursively find children
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
};
|
|
1997
|
+
await findChildRuns(rootRunId);
|
|
1998
|
+
return agentRunIds;
|
|
1999
|
+
}
|
|
2000
|
+
/**
|
|
2001
|
+
* Load all prompt runs for the given agent run IDs
|
|
2002
|
+
* Uses the same approach as the cost calculation: find prompt runs via agent run steps
|
|
2003
|
+
*/
|
|
2004
|
+
async loadAllPromptRuns(agentRunIds) {
|
|
2005
|
+
if (agentRunIds.length === 0)
|
|
2006
|
+
return [];
|
|
2007
|
+
const rv = new RunView();
|
|
2008
|
+
// First, get all the prompt steps for the agent runs
|
|
2009
|
+
const stepsResult = await rv.RunView({
|
|
2010
|
+
EntityName: 'MJ: AI Agent Run Steps',
|
|
2011
|
+
ExtraFilter: `AgentRunID IN ('${agentRunIds.join("','")}') AND StepType = 'Prompt'`,
|
|
2012
|
+
ResultType: 'simple'
|
|
2013
|
+
});
|
|
2014
|
+
if (!stepsResult.Success || !stepsResult.Results || stepsResult.Results.length === 0) {
|
|
2015
|
+
return [];
|
|
2016
|
+
}
|
|
2017
|
+
// Extract the TargetLogID values (these are the prompt run IDs)
|
|
2018
|
+
const promptRunIds = stepsResult.Results
|
|
2019
|
+
.map(step => step.TargetLogID)
|
|
2020
|
+
.filter(id => id); // Remove any null/undefined values
|
|
2021
|
+
if (promptRunIds.length === 0) {
|
|
2022
|
+
return [];
|
|
2023
|
+
}
|
|
2024
|
+
// Now get the actual prompt runs
|
|
2025
|
+
const promptResult = await rv.RunView({
|
|
2026
|
+
EntityName: 'MJ: AI Prompt Runs',
|
|
2027
|
+
ExtraFilter: `ID IN ('${promptRunIds.join("','")}')`,
|
|
2028
|
+
OrderBy: 'RunAt',
|
|
2029
|
+
ResultType: 'simple'
|
|
2030
|
+
});
|
|
2031
|
+
return promptResult.Success ? (promptResult.Results || []) : [];
|
|
2032
|
+
}
|
|
2033
|
+
static { this.ɵfac = function AIAgentRunAnalyticsComponent_Factory(t) { return new (t || AIAgentRunAnalyticsComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.AIAgentRunCostService)); }; }
|
|
2018
2034
|
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AIAgentRunAnalyticsComponent, selectors: [["mj-ai-agent-run-analytics"]], viewQuery: function AIAgentRunAnalyticsComponent_Query(rf, ctx) { if (rf & 1) {
|
|
2019
2035
|
i0.ɵɵviewQuery(_c0, 5);
|
|
2020
2036
|
i0.ɵɵviewQuery(_c1, 5);
|
|
@@ -2038,9 +2054,9 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
2038
2054
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.promptTokenDistributionChart = _t.first);
|
|
2039
2055
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.promptCostDistributionChart = _t.first);
|
|
2040
2056
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.promptCountByNameChart = _t.first);
|
|
2041
|
-
} }, inputs: { agentRunId: "agentRunId" }, decls: 4, vars: 3, consts: [["modelDistributionChart", ""], ["executionTimeChart", ""], ["costByVendorChart", ""], ["tokenUsageChart", ""], ["promptTimeDistributionChart", ""], ["promptTokenDistributionChart", ""], ["promptCostDistributionChart", ""], ["promptCountByNameChart", ""], ["actionSuccessRateChart", ""], ["stepTypeChart", ""], [1, "analytics-container"], ["class", "loading-state", 4, "ngIf"], ["class", "error-state", 4, "ngIf"], ["class", "analytics-content", 4, "ngIf"], [1, "loading-state"], [1, "fas", "fa-spinner", "fa-spin", "fa-2x"], [1, "error-state"], [1, "fas", "fa-exclamation-triangle", "fa-2x"], ["kendoButton", "", 3, "click"], [1, "analytics-content"], [3, "expanded"], ["kendoPanelBarItemTitle", ""], ["kendoPanelBarContent", ""], [1, "fas", "fa-tachometer-alt"], [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"], ["class", "failed", 4, "ngIf"], [1, "card-icon", "actions"], [1, "fas", "fa-cog"], [1, "card-icon", "cost"], [1, "fas", "fa-dollar-sign"], [1, "card-icon", "time"], [1, "fas", "fa-clock"], [1, "failed"], [1, "analytics-panel"], ["class", "view-mode-toggle", 4, "ngIf"], ["class", "no-data-message", 4, "ngIf"], ["class", "charts-grid", 4, "ngIf"], ["class", "charts-grid", "style", "margin-top: 20px;", 4, "ngIf"], [1, "detailed-metrics"], ["kendoButton", "", "fillMode", "flat", 3, "click"], [1, "fas", 3, "ngClass"], ["class", "metrics-table", 4, "ngIf"], [1, "view-mode-toggle"], ["kendoButton", "", "fillMode", "flat", "size", "small", 3, "click"], [1, "no-data-message"], [1, "fas", "fa-info-circle"], [1, "small"], [1, "charts-grid"], [1, "chart-card"], [1, "chart-card-header", 3, "click"], [1, "fas", "fa-chart-pie"], [1, "expand-btn"], [1, "chart-card-body"], [1, "chart-container"], ["id", "modelDistributionChart"], ["class", "chart-legend", 4, "ngIf"], ["id", "executionTimeChart"], ["id", "costByVendorChart"], [1, "chart-total"], [1, "fas", "fa-coins"], ["id", "tokenUsageChart"], [1, "chart-legend"], ["class", "legend-item", 4, "ngFor", "ngForOf"], [1, "legend-item"], [1, "legend-color"], [1, "legend-label"], [1, "charts-grid", 2, "margin-top", "20px"], [1, "fas", "fa-hourglass-half"], ["id", "promptTimeDistributionChart"], [1, "fas", "fa-database"], ["id", "promptTokenDistributionChart"], ["id", "promptCostDistributionChart"], [1, "fas", "fa-list-ol"], ["id", "promptCountByNameChart"], [1, "metrics-table"], [4, "ngFor", "ngForOf"], [1, "success-rate"], [1, "fas", "fa-chart-bar"], ["id", "actionSuccessRateChart"], [1, "fas", "fa-layer-group"], ["id", "stepTypeChart"], [1, "error-analysis-section"], ["class", "error-analysis", 4, "ngIf"], ["class", "no-errors", 4, "ngIf"], [1, "error-analysis"], [1, "fas", "fa-exclamation-triangle"], [1, "error-analysis-description"], [1, "error-list"], ["class", "error-item", 4, "ngFor", "ngForOf"], [1, "error-item"], [1, "error-count"], [1, "error-message"], [1, "no-errors"], [1, "fas", "fa-check-circle"], [1, "fas", "fa-chart-line"], [1, "model-comparison"], [1, "fas", "fa-stream"], [1, "timeline-stats"], [1, "stat-item"], [1, "stat-label"], [1, "stat-value"], [1, "step-breakdown"], [1, "step-type-list"], ["class", "step-type-item", 4, "ngFor", "ngForOf"], [1, "step-type-item"], [1, "type-name"], [1, "type-count"], [1, "type-percentage"]], template: function AIAgentRunAnalyticsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2057
|
+
} }, inputs: { agentRunId: "agentRunId" }, decls: 4, vars: 3, consts: [["modelDistributionChart", ""], ["executionTimeChart", ""], ["costByVendorChart", ""], ["tokenUsageChart", ""], ["promptTimeDistributionChart", ""], ["promptTokenDistributionChart", ""], ["promptCostDistributionChart", ""], ["promptCountByNameChart", ""], ["actionSuccessRateChart", ""], ["stepTypeChart", ""], [1, "analytics-container"], ["class", "loading-state", 4, "ngIf"], ["class", "error-state", 4, "ngIf"], ["class", "analytics-content", 4, "ngIf"], [1, "loading-state"], [1, "fas", "fa-spinner", "fa-spin", "fa-2x"], [1, "error-state"], [1, "fas", "fa-exclamation-triangle", "fa-2x"], ["kendoButton", "", 3, "click"], [1, "analytics-content"], [3, "keepItemContent"], [3, "expanded"], ["kendoPanelBarItemTitle", ""], ["kendoPanelBarContent", ""], [1, "fas", "fa-tachometer-alt"], [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"], ["class", "failed", 4, "ngIf"], [1, "card-icon", "actions"], [1, "fas", "fa-cog"], [1, "card-icon", "cost"], [1, "fas", "fa-dollar-sign"], [1, "card-icon", "time"], [1, "fas", "fa-clock"], [1, "failed"], [1, "analytics-panel"], ["class", "view-mode-toggle", 4, "ngIf"], ["class", "no-data-message", 4, "ngIf"], ["class", "charts-grid", 4, "ngIf"], ["class", "charts-grid", "style", "margin-top: 20px;", 4, "ngIf"], [1, "detailed-metrics"], ["kendoButton", "", "fillMode", "flat", 3, "click"], [1, "fas", 3, "ngClass"], ["class", "metrics-table", 4, "ngIf"], [1, "view-mode-toggle"], ["kendoButton", "", "fillMode", "flat", "size", "small", 3, "click"], [1, "no-data-message"], [1, "fas", "fa-info-circle"], [1, "small"], [1, "charts-grid"], [1, "chart-card"], [1, "chart-card-header", 3, "click"], [1, "fas", "fa-chart-pie"], [1, "expand-btn"], [1, "chart-card-body"], [1, "chart-container"], ["id", "modelDistributionChart"], ["class", "chart-legend", 4, "ngIf"], ["id", "executionTimeChart"], ["id", "costByVendorChart"], [1, "chart-total"], [1, "fas", "fa-coins"], ["id", "tokenUsageChart"], [1, "chart-legend"], ["class", "legend-item", 4, "ngFor", "ngForOf"], [1, "legend-item"], [1, "legend-color"], [1, "legend-label"], [1, "charts-grid", 2, "margin-top", "20px"], [1, "fas", "fa-hourglass-half"], ["id", "promptTimeDistributionChart"], [1, "fas", "fa-database"], ["id", "promptTokenDistributionChart"], ["id", "promptCostDistributionChart"], [1, "fas", "fa-list-ol"], ["id", "promptCountByNameChart"], [1, "metrics-table"], [4, "ngFor", "ngForOf"], [1, "success-rate"], [1, "fas", "fa-chart-bar"], ["id", "actionSuccessRateChart"], [1, "fas", "fa-layer-group"], ["id", "stepTypeChart"], [1, "error-analysis-section"], ["class", "error-analysis", 4, "ngIf"], ["class", "no-errors", 4, "ngIf"], [1, "error-analysis"], [1, "fas", "fa-exclamation-triangle"], [1, "error-analysis-description"], [1, "error-list"], ["class", "error-item", 4, "ngFor", "ngForOf"], [1, "error-item"], [1, "error-count"], [1, "error-message"], [1, "no-errors"], [1, "fas", "fa-check-circle"], [1, "fas", "fa-chart-line"], [1, "model-comparison"], [1, "fas", "fa-stream"], [1, "timeline-stats"], [1, "stat-item"], [1, "stat-label"], [1, "stat-value"], [1, "step-breakdown"], [1, "step-type-list"], ["class", "step-type-item", 4, "ngFor", "ngForOf"], [1, "step-type-item"], [1, "type-name"], [1, "type-count"], [1, "type-percentage"]], template: function AIAgentRunAnalyticsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2042
2058
|
i0.ɵɵelementStart(0, "div", 10);
|
|
2043
|
-
i0.ɵɵtemplate(1, AIAgentRunAnalyticsComponent_div_1_Template, 4, 0, "div", 11)(2, AIAgentRunAnalyticsComponent_div_2_Template, 6, 1, "div", 12)(3, AIAgentRunAnalyticsComponent_div_3_Template, 17,
|
|
2059
|
+
i0.ɵɵtemplate(1, AIAgentRunAnalyticsComponent_div_1_Template, 4, 0, "div", 11)(2, AIAgentRunAnalyticsComponent_div_2_Template, 6, 1, "div", 12)(3, AIAgentRunAnalyticsComponent_div_3_Template, 17, 6, "div", 13);
|
|
2044
2060
|
i0.ɵɵelementEnd();
|
|
2045
2061
|
} if (rf & 2) {
|
|
2046
2062
|
i0.ɵɵadvance();
|
|
@@ -2049,12 +2065,12 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
2049
2065
|
i0.ɵɵproperty("ngIf", ctx.error && !ctx.isLoading);
|
|
2050
2066
|
i0.ɵɵadvance();
|
|
2051
2067
|
i0.ɵɵproperty("ngIf", !ctx.isLoading && !ctx.error);
|
|
2052
|
-
} }, dependencies: [i1.NgClass, i1.NgForOf, i1.NgIf, i2.PanelBarComponent, i2.PanelBarItemComponent, i2.PanelBarContentDirective, i2.PanelBarItemTitleDirective, i3.ButtonComponent, i1.DecimalPipe, i1.KeyValuePipe], styles: [".analytics-container[_ngcontent-%COMP%] {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background-color: #f8f9fa;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%], \n.error-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 300px;\n color: #6c757d;\n}\n\n.loading-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.error-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-bottom: 15px;\n}\n\n.error-state[_ngcontent-%COMP%] {\n color: #dc3545;\n}\n\n\n\n.summary-cards[_ngcontent-%COMP%] {\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[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n padding: 20px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n display: flex;\n align-items: center;\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.summary-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);\n}\n\n.card-icon[_ngcontent-%COMP%] {\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: white;\n}\n\n.card-icon.prompts[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n}\n\n.card-icon.actions[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n}\n\n.card-icon.cost[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);\n}\n\n.card-icon.time[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);\n}\n\n.card-content[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 500;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 28px;\n font-weight: 700;\n color: #212529;\n margin-bottom: 4px;\n}\n\n.metric-detail[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6c757d;\n}\n\n.metric-detail[_ngcontent-%COMP%] .success[_ngcontent-%COMP%] {\n color: #28a745;\n margin-right: 10px;\n}\n\n.metric-detail[_ngcontent-%COMP%] .failed[_ngcontent-%COMP%] {\n color: #dc3545;\n}\n\n\n\n.analytics-panel[_ngcontent-%COMP%] {\n padding: 15px;\n}\n\n\n\n .analytics-content .k-panelbar {\n border: none;\n background: transparent;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item {\n border: none;\n border-radius: 12px;\n margin-bottom: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.06);\n background: white;\n overflow: hidden;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-header {\n background: white;\n border: none;\n padding: 16px 20px;\n border-radius: 12px 12px 0 0;\n color: #2c3e50;\n font-weight: 600;\n font-size: 16px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-header:hover {\n background: #f8f9fa;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header {\n background: #2196f3;\n color: white;\n border-radius: 12px 12px 0 0;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle {\n position: absolute;\n right: 24px;\n color: inherit;\n font-size: 14px;\n transition: transform 0.2s ease;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header .k-panelbar-toggle {\n transform: rotate(180deg);\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle::before {\n content: '\\f107';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-content {\n padding: 0;\n border: none;\n background: white;\n border-radius: 0 0 12px 12px;\n}\n\n .analytics-content .k-panelbar .k-header .k-panelbar-icon {\n font-size: 18px;\n color: #2196f3;\n margin-right: 8px;\n}\n\n .analytics-content .k-panelbar .k-panelbar-expanded .k-header .k-panelbar-icon {\n color: white;\n}\n\n\n\n.charts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 20px;\n margin-bottom: 20px;\n}\n\n\n\n.chart-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n.chart-card.expanded[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.chart-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background-color: #f8f9fa;\n border-bottom: 1px solid #e9ecef;\n cursor: pointer;\n user-select: none;\n}\n\n.chart-card-header[_ngcontent-%COMP%]:hover {\n background-color: #e9ecef;\n}\n\n.chart-card-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.chart-card-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #6c757d;\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: #6c757d;\n transition: color 0.2s;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n color: #495057;\n}\n\n.chart-card-body[_ngcontent-%COMP%] {\n padding: 16px;\n background: white;\n}\n\n.chart-card.expanded[_ngcontent-%COMP%] .chart-card-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n.chart-card.expanded[_ngcontent-%COMP%] .chart-container[_ngcontent-%COMP%] > div[_ngcontent-%COMP%] {\n min-height: 400px;\n}\n\n\n\n.view-mode-toggle[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n margin-bottom: 16px;\n}\n\n.view-mode-toggle[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.chart-container[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.chart-container[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: 15px;\n font-weight: 500;\n color: #495057;\n}\n\n.chart-container[_ngcontent-%COMP%] > div[_ngcontent-%COMP%] {\n min-height: 220px;\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n\n\n.chart-container[_ngcontent-%COMP%] svg[_ngcontent-%COMP%] {\n display: block;\n margin: 0 auto;\n}\n\n.chart-legend[_ngcontent-%COMP%] {\n margin-top: 10px;\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n font-size: 12px;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n}\n\n.legend-color[_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n border-radius: 3px;\n}\n\n.chart-total[_ngcontent-%COMP%] {\n text-align: center;\n margin-top: 10px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n}\n\n\n\n.detailed-metrics[_ngcontent-%COMP%] {\n margin-top: 20px;\n border-top: 1px solid #e9ecef;\n padding-top: 20px;\n}\n\n.detailed-metrics[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n margin-bottom: 15px;\n}\n\n.detailed-metrics[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.metrics-table[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.metrics-table[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.metrics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background-color: #f8f9fa;\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: #495057;\n border-bottom: 2px solid #dee2e6;\n}\n\n.metrics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px;\n border-bottom: 1px solid #dee2e6;\n}\n\n.metrics-table[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background-color: #f8f9fa;\n}\n\n.success-rate[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.success-rate.high[_ngcontent-%COMP%] {\n color: #28a745;\n}\n\n.success-rate.medium[_ngcontent-%COMP%] {\n color: #ffc107;\n}\n\n.success-rate.low[_ngcontent-%COMP%] {\n color: #dc3545;\n}\n\n\n\n.error-analysis[_ngcontent-%COMP%] {\n margin-top: 30px;\n padding: 20px;\n background-color: #fff5f5;\n border-radius: 8px;\n border: 1px solid #f5c6cb;\n}\n\n.error-analysis[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 15px 0;\n color: #721c24;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-analysis-description[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #856404;\n margin-bottom: 20px;\n line-height: 1.5;\n}\n\n.error-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.error-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 10px;\n background-color: white;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.error-count[_ngcontent-%COMP%] {\n background-color: #dc3545;\n color: white;\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[_ngcontent-%COMP%] {\n flex: 1;\n color: #495057;\n}\n\n\n\n.no-errors[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px;\n background-color: #d4edda;\n border-radius: 8px;\n border: 1px solid #c3e6cb;\n color: #155724;\n}\n\n.no-errors[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: #28a745;\n}\n\n.no-errors[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n\n\n.no-data-message[_ngcontent-%COMP%] {\n text-align: center;\n padding: 60px 20px;\n color: #6c757d;\n}\n\n.no-data-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 20px;\n color: #dee2e6;\n}\n\n.no-data-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: 16px;\n}\n\n.no-data-message[_ngcontent-%COMP%] p.small[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #adb5bd;\n}\n\n\n\n.model-comparison[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.model-comparison[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.model-comparison[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background-color: #f8f9fa;\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: #495057;\n border-bottom: 2px solid #dee2e6;\n white-space: nowrap;\n}\n\n.model-comparison[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px;\n border-bottom: 1px solid #dee2e6;\n}\n\n.model-comparison[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background-color: #f8f9fa;\n}\n\n\n\n.timeline-stats[_ngcontent-%COMP%] {\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[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px;\n background-color: #f8f9fa;\n border-radius: 8px;\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #6c757d;\n margin-bottom: 8px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 32px;\n font-weight: 700;\n color: #212529;\n}\n\n.step-breakdown[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 15px 0;\n font-size: 16px;\n font-weight: 500;\n color: #495057;\n}\n\n.step-type-list[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 12px;\n}\n\n.step-type-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px;\n background-color: #f8f9fa;\n border-radius: 6px;\n border: 1px solid #e9ecef;\n}\n\n.step-type-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 30px;\n text-align: center;\n color: #6c757d;\n}\n\n.type-name[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n}\n\n.type-count[_ngcontent-%COMP%] {\n font-weight: 700;\n color: #212529;\n}\n\n.type-percentage[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6c757d;\n margin-left: 5px;\n}\n\n\n\n@media (max-width: 768px) {\n .summary-cards[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n \n .charts-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n \n .timeline-stats[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}"] }); }
|
|
2068
|
+
} }, dependencies: [i2.NgClass, i2.NgForOf, i2.NgIf, i3.PanelBarComponent, i3.PanelBarItemComponent, i3.PanelBarContentDirective, i3.PanelBarItemTitleDirective, i4.ButtonComponent, i2.DecimalPipe, i2.KeyValuePipe], styles: [".analytics-container[_ngcontent-%COMP%] {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background-color: #f8f9fa;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%], \n.error-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 300px;\n color: #6c757d;\n}\n\n.loading-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.error-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-bottom: 15px;\n}\n\n.error-state[_ngcontent-%COMP%] {\n color: #dc3545;\n}\n\n\n\n.summary-cards[_ngcontent-%COMP%] {\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[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n padding: 20px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n display: flex;\n align-items: center;\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.summary-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);\n}\n\n.card-icon[_ngcontent-%COMP%] {\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: white;\n}\n\n.card-icon.prompts[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n}\n\n.card-icon.actions[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n}\n\n.card-icon.cost[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);\n}\n\n.card-icon.time[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);\n}\n\n.card-content[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 500;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 28px;\n font-weight: 700;\n color: #212529;\n margin-bottom: 4px;\n}\n\n.metric-detail[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6c757d;\n}\n\n.metric-detail[_ngcontent-%COMP%] .success[_ngcontent-%COMP%] {\n color: #28a745;\n margin-right: 10px;\n}\n\n.metric-detail[_ngcontent-%COMP%] .failed[_ngcontent-%COMP%] {\n color: #dc3545;\n}\n\n\n\n.analytics-panel[_ngcontent-%COMP%] {\n padding: 15px;\n}\n\n\n\n .analytics-content .k-panelbar {\n border: none;\n background: transparent;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item {\n border: none;\n border-radius: 12px;\n margin-bottom: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.06);\n background: white;\n overflow: hidden;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-header {\n background: white;\n border: none;\n padding: 16px 20px;\n border-radius: 12px 12px 0 0;\n color: #2c3e50;\n font-weight: 600;\n font-size: 16px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-header:hover {\n background: #f8f9fa;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header {\n background: #2196f3;\n color: white;\n border-radius: 12px 12px 0 0;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle {\n position: absolute;\n right: 24px;\n color: inherit;\n font-size: 14px;\n transition: transform 0.2s ease;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header .k-panelbar-toggle {\n transform: rotate(180deg);\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle::before {\n content: '\\f107';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n}\n\n .analytics-content .k-panelbar > .k-panelbar-item > .k-content {\n padding: 0;\n border: none;\n background: white;\n border-radius: 0 0 12px 12px;\n}\n\n .analytics-content .k-panelbar .k-header .k-panelbar-icon {\n font-size: 18px;\n color: #2196f3;\n margin-right: 8px;\n}\n\n .analytics-content .k-panelbar .k-panelbar-expanded .k-header .k-panelbar-icon {\n color: white;\n}\n\n\n\n.charts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 20px;\n margin-bottom: 20px;\n}\n\n\n\n.chart-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n.chart-card.expanded[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.chart-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background-color: #f8f9fa;\n border-bottom: 1px solid #e9ecef;\n cursor: pointer;\n user-select: none;\n}\n\n.chart-card-header[_ngcontent-%COMP%]:hover {\n background-color: #e9ecef;\n}\n\n.chart-card-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.chart-card-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #6c757d;\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: #6c757d;\n transition: color 0.2s;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n color: #495057;\n}\n\n.chart-card-body[_ngcontent-%COMP%] {\n padding: 16px;\n background: white;\n}\n\n.chart-card.expanded[_ngcontent-%COMP%] .chart-card-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n.chart-card.expanded[_ngcontent-%COMP%] .chart-container[_ngcontent-%COMP%] > div[_ngcontent-%COMP%] {\n min-height: 400px;\n}\n\n\n\n.view-mode-toggle[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n margin-bottom: 16px;\n}\n\n.view-mode-toggle[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.chart-container[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.chart-container[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: 15px;\n font-weight: 500;\n color: #495057;\n}\n\n.chart-container[_ngcontent-%COMP%] > div[_ngcontent-%COMP%] {\n min-height: 220px;\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n\n\n.chart-container[_ngcontent-%COMP%] svg[_ngcontent-%COMP%] {\n display: block;\n margin: 0 auto;\n}\n\n.chart-legend[_ngcontent-%COMP%] {\n margin-top: 10px;\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n font-size: 12px;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n}\n\n.legend-color[_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n border-radius: 3px;\n}\n\n.chart-total[_ngcontent-%COMP%] {\n text-align: center;\n margin-top: 10px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n}\n\n\n\n.detailed-metrics[_ngcontent-%COMP%] {\n margin-top: 20px;\n border-top: 1px solid #e9ecef;\n padding-top: 20px;\n}\n\n.detailed-metrics[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n margin-bottom: 15px;\n}\n\n.detailed-metrics[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.metrics-table[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.metrics-table[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.metrics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background-color: #f8f9fa;\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: #495057;\n border-bottom: 2px solid #dee2e6;\n}\n\n.metrics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px;\n border-bottom: 1px solid #dee2e6;\n}\n\n.metrics-table[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background-color: #f8f9fa;\n}\n\n.success-rate[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.success-rate.high[_ngcontent-%COMP%] {\n color: #28a745;\n}\n\n.success-rate.medium[_ngcontent-%COMP%] {\n color: #ffc107;\n}\n\n.success-rate.low[_ngcontent-%COMP%] {\n color: #dc3545;\n}\n\n\n\n.error-analysis[_ngcontent-%COMP%] {\n margin-top: 30px;\n padding: 20px;\n background-color: #fff5f5;\n border-radius: 8px;\n border: 1px solid #f5c6cb;\n}\n\n.error-analysis[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 15px 0;\n color: #721c24;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-analysis-description[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #856404;\n margin-bottom: 20px;\n line-height: 1.5;\n}\n\n.error-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.error-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 10px;\n background-color: white;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.error-count[_ngcontent-%COMP%] {\n background-color: #dc3545;\n color: white;\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[_ngcontent-%COMP%] {\n flex: 1;\n color: #495057;\n}\n\n\n\n.no-errors[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px;\n background-color: #d4edda;\n border-radius: 8px;\n border: 1px solid #c3e6cb;\n color: #155724;\n}\n\n.no-errors[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: #28a745;\n}\n\n.no-errors[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n\n\n.no-data-message[_ngcontent-%COMP%] {\n text-align: center;\n padding: 60px 20px;\n color: #6c757d;\n}\n\n.no-data-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 20px;\n color: #dee2e6;\n}\n\n.no-data-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: 16px;\n}\n\n.no-data-message[_ngcontent-%COMP%] p.small[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #adb5bd;\n}\n\n\n\n.model-comparison[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.model-comparison[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.model-comparison[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background-color: #f8f9fa;\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: #495057;\n border-bottom: 2px solid #dee2e6;\n white-space: nowrap;\n}\n\n.model-comparison[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px;\n border-bottom: 1px solid #dee2e6;\n}\n\n.model-comparison[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background-color: #f8f9fa;\n}\n\n\n\n.timeline-stats[_ngcontent-%COMP%] {\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[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px;\n background-color: #f8f9fa;\n border-radius: 8px;\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #6c757d;\n margin-bottom: 8px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 32px;\n font-weight: 700;\n color: #212529;\n}\n\n.step-breakdown[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 15px 0;\n font-size: 16px;\n font-weight: 500;\n color: #495057;\n}\n\n.step-type-list[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 12px;\n}\n\n.step-type-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px;\n background-color: #f8f9fa;\n border-radius: 6px;\n border: 1px solid #e9ecef;\n}\n\n.step-type-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 30px;\n text-align: center;\n color: #6c757d;\n}\n\n.type-name[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n}\n\n.type-count[_ngcontent-%COMP%] {\n font-weight: 700;\n color: #212529;\n}\n\n.type-percentage[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6c757d;\n margin-left: 5px;\n}\n\n\n\n@media (max-width: 768px) {\n .summary-cards[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n \n .charts-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n \n .timeline-stats[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}"] }); }
|
|
2053
2069
|
}
|
|
2054
2070
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AIAgentRunAnalyticsComponent, [{
|
|
2055
2071
|
type: Component,
|
|
2056
|
-
args: [{ selector: 'mj-ai-agent-run-analytics', template: "<div class=\"analytics-container\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"isLoading\">\n <i class=\"fas fa-spinner fa-spin fa-2x\"></i>\n <p>Loading analytics data...</p>\n </div>\n\n <!-- Error State -->\n <div class=\"error-state\" *ngIf=\"error && !isLoading\">\n <i class=\"fas fa-exclamation-triangle fa-2x\"></i>\n <p>{{ error }}</p>\n <button kendoButton (click)=\"loadData()\">Retry</button>\n </div>\n\n <!-- Analytics Content -->\n <div class=\"analytics-content\" *ngIf=\"!isLoading && !error\">\n <kendo-panelbar>\n <!-- Summary Cards -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-tachometer-alt\"></i> Overview\n </ng-template>\n <ng-template kendoPanelBarContent>\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 <span class=\"failed\" *ngIf=\"promptMetrics.statusBreakdown.failed > 0\">{{ promptMetrics.statusBreakdown.failed }} failed</span>\n </div>\n </div>\n </div>\n\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 <span class=\"failed\" *ngIf=\"actionMetrics.statusBreakdown.failed > 0\">{{ actionMetrics.statusBreakdown.failed }} failed</span>\n </div>\n </div>\n </div>\n\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\">\n <span>{{ promptMetrics.tokenUsage.totalInput + promptMetrics.tokenUsage.totalOutput }} tokens</span>\n </div>\n </div>\n </div>\n\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 </ng-template>\n </kendo-panelbar-item>\n\n <!-- Prompt Analytics -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-microchip\"></i> Prompt Analytics\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"analytics-panel\">\n <!-- View Mode Toggle -->\n <div class=\"view-mode-toggle\" *ngIf=\"promptMetrics.totalCount > 0\">\n <button kendoButton \n fillMode=\"flat\" \n size=\"small\"\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 <div class=\"no-data-message\" *ngIf=\"promptMetrics.totalCount === 0\">\n <i class=\"fas fa-info-circle\"></i>\n <p>No prompt executions found in this agent run.</p>\n <p class=\"small\">This agent run may have only executed actions without any AI prompts.</p>\n </div>\n\n <div class=\"charts-grid\" *ngIf=\"promptMetrics.totalCount > 0\">\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['modelDistribution'] ? 'fa-compress' : 'fa-expand'\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"modelDistributionChart\" #modelDistributionChart></div>\n <div class=\"chart-legend\" *ngIf=\"promptMetrics.byModel.size > 0\">\n <div class=\"legend-item\" *ngFor=\"let item of promptMetrics.byModel | keyvalue\">\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 </div>\n </div>\n </div>\n </div>\n\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['executionTime'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['costByVendor'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['tokenUsage'] ? 'fa-compress' : 'fa-expand'\"></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 <div class=\"charts-grid\" style=\"margin-top: 20px;\" *ngIf=\"promptMetrics.totalCount > 0\">\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptTime'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptToken'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptCost'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptCount'] ? 'fa-compress' : 'fa-expand'\"></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 kendoButton \n fillMode=\"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 \n <div class=\"metrics-table\" *ngIf=\"promptDetailsExpanded\">\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 <tr *ngFor=\"let prompt of promptMetrics.byPrompt | keyvalue\">\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 </tbody>\n </table>\n </div>\n </div>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n\n <!-- Action Analytics -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-cog\"></i> Action Analytics\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"analytics-panel\">\n\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['actionSuccess'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['stepType'] ? 'fa-compress' : 'fa-expand'\"></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\n <!-- Detailed Action Metrics -->\n <div class=\"detailed-metrics\">\n <button kendoButton \n fillMode=\"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 \n <div class=\"metrics-table\" *ngIf=\"actionDetailsExpanded\">\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 <tr *ngFor=\"let action of actionMetrics.byAction | keyvalue\">\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 </tbody>\n </table>\n </div>\n </div>\n\n <!-- Error Analysis -->\n <div class=\"error-analysis-section\">\n <div class=\"error-analysis\" *ngIf=\"actionMetrics.errorAnalysis.size > 0\">\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 <div class=\"error-item\" *ngFor=\"let error of getTopErrors()\">\n <span class=\"error-count\">{{ error.count }}x</span>\n <span class=\"error-message\">{{ error.message }}</span>\n </div>\n </div>\n </div>\n <div class=\"no-errors\" *ngIf=\"actionMetrics.errorAnalysis.size === 0\">\n <i class=\"fas fa-check-circle\"></i>\n <p>No action errors detected in this run. All actions completed successfully!</p>\n </div>\n </div>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n\n <!-- Model Performance Comparison -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-chart-line\"></i> Model Performance Comparison\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"analytics-panel\">\n\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 <tr *ngFor=\"let model of getModelPerformanceData()\">\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 </tbody>\n </table>\n </div>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n\n <!-- Timeline Analysis -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-stream\"></i> Execution Timeline Analysis\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"analytics-panel\">\n\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\n <div class=\"step-breakdown\">\n <h3>Steps by Type</h3>\n <div class=\"step-type-list\">\n <div class=\"step-type-item\" *ngFor=\"let type of timelineMetrics.stepsByType | keyvalue\">\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 </div>\n </div>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n </kendo-panelbar>\n </div>\n</div>", styles: [".analytics-container {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background-color: #f8f9fa;\n}\n\n/* Loading and Error States */\n.loading-state,\n.error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 300px;\n color: #6c757d;\n}\n\n.loading-state i,\n.error-state i {\n margin-bottom: 15px;\n}\n\n.error-state {\n color: #dc3545;\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: white;\n border-radius: 8px;\n padding: 20px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\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: white;\n}\n\n.card-icon.prompts {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n}\n\n.card-icon.actions {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n}\n\n.card-icon.cost {\n background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);\n}\n\n.card-icon.time {\n background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);\n}\n\n.card-content h3 {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 500;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-value {\n font-size: 28px;\n font-weight: 700;\n color: #212529;\n margin-bottom: 4px;\n}\n\n.metric-detail {\n font-size: 13px;\n color: #6c757d;\n}\n\n.metric-detail .success {\n color: #28a745;\n margin-right: 10px;\n}\n\n.metric-detail .failed {\n color: #dc3545;\n}\n\n/* Analytics Panels */\n.analytics-panel {\n padding: 15px;\n}\n\n/* Kendo PanelBar Styling - Copied from AI Agent Form */\n::ng-deep .analytics-content .k-panelbar {\n border: none;\n background: transparent;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item {\n border: none;\n border-radius: 12px;\n margin-bottom: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.06);\n background: white;\n overflow: hidden;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-header {\n background: white;\n border: none;\n padding: 16px 20px;\n border-radius: 12px 12px 0 0;\n color: #2c3e50;\n font-weight: 600;\n font-size: 16px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-header:hover {\n background: #f8f9fa;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header {\n background: #2196f3;\n color: white;\n border-radius: 12px 12px 0 0;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle {\n position: absolute;\n right: 24px;\n color: inherit;\n font-size: 14px;\n transition: transform 0.2s ease;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header .k-panelbar-toggle {\n transform: rotate(180deg);\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle::before {\n content: '\\f107';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-content {\n padding: 0;\n border: none;\n background: white;\n border-radius: 0 0 12px 12px;\n}\n\n::ng-deep .analytics-content .k-panelbar .k-header .k-panelbar-icon {\n font-size: 18px;\n color: #2196f3;\n margin-right: 8px;\n}\n\n::ng-deep .analytics-content .k-panelbar .k-panelbar-expanded .k-header .k-panelbar-icon {\n color: white;\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: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\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: #f8f9fa;\n border-bottom: 1px solid #e9ecef;\n cursor: pointer;\n user-select: none;\n}\n\n.chart-card-header:hover {\n background-color: #e9ecef;\n}\n\n.chart-card-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.chart-card-header h3 i {\n font-size: 16px;\n color: #6c757d;\n}\n\n.expand-btn {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: #6c757d;\n transition: color 0.2s;\n}\n\n.expand-btn:hover {\n color: #495057;\n}\n\n.chart-card-body {\n padding: 16px;\n background: white;\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: #495057;\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: #495057;\n}\n\n/* Detailed Metrics */\n.detailed-metrics {\n margin-top: 20px;\n border-top: 1px solid #e9ecef;\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: #f8f9fa;\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: #495057;\n border-bottom: 2px solid #dee2e6;\n}\n\n.metrics-table td {\n padding: 12px;\n border-bottom: 1px solid #dee2e6;\n}\n\n.metrics-table tr:hover {\n background-color: #f8f9fa;\n}\n\n.success-rate {\n font-weight: 500;\n}\n\n.success-rate.high {\n color: #28a745;\n}\n\n.success-rate.medium {\n color: #ffc107;\n}\n\n.success-rate.low {\n color: #dc3545;\n}\n\n/* Error Analysis */\n.error-analysis {\n margin-top: 30px;\n padding: 20px;\n background-color: #fff5f5;\n border-radius: 8px;\n border: 1px solid #f5c6cb;\n}\n\n.error-analysis h3 {\n margin: 0 0 15px 0;\n color: #721c24;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-analysis-description {\n font-size: 14px;\n color: #856404;\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: white;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.error-count {\n background-color: #dc3545;\n color: white;\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: #495057;\n}\n\n/* No errors state */\n.no-errors {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px;\n background-color: #d4edda;\n border-radius: 8px;\n border: 1px solid #c3e6cb;\n color: #155724;\n}\n\n.no-errors i {\n font-size: 24px;\n color: #28a745;\n}\n\n.no-errors p {\n margin: 0;\n font-size: 14px;\n}\n\n/* No data message */\n.no-data-message {\n text-align: center;\n padding: 60px 20px;\n color: #6c757d;\n}\n\n.no-data-message i {\n font-size: 48px;\n margin-bottom: 20px;\n color: #dee2e6;\n}\n\n.no-data-message p {\n margin: 0 0 10px 0;\n font-size: 16px;\n}\n\n.no-data-message p.small {\n font-size: 14px;\n color: #adb5bd;\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: #f8f9fa;\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: #495057;\n border-bottom: 2px solid #dee2e6;\n white-space: nowrap;\n}\n\n.model-comparison td {\n padding: 12px;\n border-bottom: 1px solid #dee2e6;\n}\n\n.model-comparison tr:hover {\n background-color: #f8f9fa;\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: #f8f9fa;\n border-radius: 8px;\n}\n\n.stat-label {\n font-size: 14px;\n color: #6c757d;\n margin-bottom: 8px;\n}\n\n.stat-value {\n font-size: 32px;\n font-weight: 700;\n color: #212529;\n}\n\n.step-breakdown h3 {\n margin: 0 0 15px 0;\n font-size: 16px;\n font-weight: 500;\n color: #495057;\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: #f8f9fa;\n border-radius: 6px;\n border: 1px solid #e9ecef;\n}\n\n.step-type-item i {\n width: 30px;\n text-align: center;\n color: #6c757d;\n}\n\n.type-name {\n flex: 1;\n font-weight: 500;\n}\n\n.type-count {\n font-weight: 700;\n color: #212529;\n}\n\n.type-percentage {\n font-size: 13px;\n color: #6c757d;\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}"] }]
|
|
2057
|
-
}], () => [{ type: i0.ChangeDetectorRef }], { agentRunId: [{
|
|
2072
|
+
args: [{ selector: 'mj-ai-agent-run-analytics', template: "<div class=\"analytics-container\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"isLoading\">\n <i class=\"fas fa-spinner fa-spin fa-2x\"></i>\n <p>Loading analytics data...</p>\n </div>\n\n <!-- Error State -->\n <div class=\"error-state\" *ngIf=\"error && !isLoading\">\n <i class=\"fas fa-exclamation-triangle fa-2x\"></i>\n <p>{{ error }}</p>\n <button kendoButton (click)=\"loadData()\">Retry</button>\n </div>\n\n <!-- Analytics Content -->\n <div class=\"analytics-content\" *ngIf=\"!isLoading && !error\">\n <kendo-panelbar [keepItemContent]=\"true\">\n <!-- Summary Cards -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-tachometer-alt\"></i> Overview\n </ng-template>\n <ng-template kendoPanelBarContent>\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 <span class=\"failed\" *ngIf=\"promptMetrics.statusBreakdown.failed > 0\">{{ promptMetrics.statusBreakdown.failed }} failed</span>\n </div>\n </div>\n </div>\n\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 <span class=\"failed\" *ngIf=\"actionMetrics.statusBreakdown.failed > 0\">{{ actionMetrics.statusBreakdown.failed }} failed</span>\n </div>\n </div>\n </div>\n\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\">\n <span>{{ promptMetrics.tokenUsage.totalInput + promptMetrics.tokenUsage.totalOutput }} tokens</span>\n </div>\n </div>\n </div>\n\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 </ng-template>\n </kendo-panelbar-item>\n\n <!-- Prompt Analytics -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-microchip\"></i> Prompt Analytics\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"analytics-panel\">\n <!-- View Mode Toggle -->\n <div class=\"view-mode-toggle\" *ngIf=\"promptMetrics.totalCount > 0\">\n <button kendoButton \n fillMode=\"flat\" \n size=\"small\"\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 <div class=\"no-data-message\" *ngIf=\"promptMetrics.totalCount === 0\">\n <i class=\"fas fa-info-circle\"></i>\n <p>No prompt executions found in this agent run.</p>\n <p class=\"small\">This agent run may have only executed actions without any AI prompts.</p>\n </div>\n\n <div class=\"charts-grid\" *ngIf=\"promptMetrics.totalCount > 0\">\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['modelDistribution'] ? 'fa-compress' : 'fa-expand'\"></i>\n </button>\n </div>\n <div class=\"chart-card-body\">\n <div class=\"chart-container\">\n <div id=\"modelDistributionChart\" #modelDistributionChart></div>\n <div class=\"chart-legend\" *ngIf=\"promptMetrics.byModel.size > 0\">\n <div class=\"legend-item\" *ngFor=\"let item of promptMetrics.byModel | keyvalue\">\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 </div>\n </div>\n </div>\n </div>\n\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['executionTime'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['costByVendor'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['tokenUsage'] ? 'fa-compress' : 'fa-expand'\"></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 <div class=\"charts-grid\" style=\"margin-top: 20px;\" *ngIf=\"promptMetrics.totalCount > 0\">\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptTime'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptToken'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptCost'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['promptCount'] ? 'fa-compress' : 'fa-expand'\"></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 kendoButton \n fillMode=\"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 \n <div class=\"metrics-table\" *ngIf=\"promptDetailsExpanded\">\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 <tr *ngFor=\"let prompt of promptMetrics.byPrompt | keyvalue\">\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 </tbody>\n </table>\n </div>\n </div>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n\n <!-- Action Analytics -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-cog\"></i> Action Analytics\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"analytics-panel\">\n\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['actionSuccess'] ? 'fa-compress' : 'fa-expand'\"></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\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\">\n <i class=\"fas\" [ngClass]=\"expandedCharts['stepType'] ? 'fa-compress' : 'fa-expand'\"></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\n <!-- Detailed Action Metrics -->\n <div class=\"detailed-metrics\">\n <button kendoButton \n fillMode=\"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 \n <div class=\"metrics-table\" *ngIf=\"actionDetailsExpanded\">\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 <tr *ngFor=\"let action of actionMetrics.byAction | keyvalue\">\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 </tbody>\n </table>\n </div>\n </div>\n\n <!-- Error Analysis -->\n <div class=\"error-analysis-section\">\n <div class=\"error-analysis\" *ngIf=\"actionMetrics.errorAnalysis.size > 0\">\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 <div class=\"error-item\" *ngFor=\"let error of getTopErrors()\">\n <span class=\"error-count\">{{ error.count }}x</span>\n <span class=\"error-message\">{{ error.message }}</span>\n </div>\n </div>\n </div>\n <div class=\"no-errors\" *ngIf=\"actionMetrics.errorAnalysis.size === 0\">\n <i class=\"fas fa-check-circle\"></i>\n <p>No action errors detected in this run. All actions completed successfully!</p>\n </div>\n </div>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n\n <!-- Model Performance Comparison -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-chart-line\"></i> Model Performance Comparison\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"analytics-panel\">\n\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 <tr *ngFor=\"let model of getModelPerformanceData()\">\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 </tbody>\n </table>\n </div>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n\n <!-- Timeline Analysis -->\n <kendo-panelbar-item [expanded]=\"true\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fas fa-stream\"></i> Execution Timeline Analysis\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"analytics-panel\">\n\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\n <div class=\"step-breakdown\">\n <h3>Steps by Type</h3>\n <div class=\"step-type-list\">\n <div class=\"step-type-item\" *ngFor=\"let type of timelineMetrics.stepsByType | keyvalue\">\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 </div>\n </div>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n </kendo-panelbar>\n </div>\n</div>", styles: [".analytics-container {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background-color: #f8f9fa;\n}\n\n/* Loading and Error States */\n.loading-state,\n.error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 300px;\n color: #6c757d;\n}\n\n.loading-state i,\n.error-state i {\n margin-bottom: 15px;\n}\n\n.error-state {\n color: #dc3545;\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: white;\n border-radius: 8px;\n padding: 20px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\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: white;\n}\n\n.card-icon.prompts {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n}\n\n.card-icon.actions {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n}\n\n.card-icon.cost {\n background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);\n}\n\n.card-icon.time {\n background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);\n}\n\n.card-content h3 {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 500;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-value {\n font-size: 28px;\n font-weight: 700;\n color: #212529;\n margin-bottom: 4px;\n}\n\n.metric-detail {\n font-size: 13px;\n color: #6c757d;\n}\n\n.metric-detail .success {\n color: #28a745;\n margin-right: 10px;\n}\n\n.metric-detail .failed {\n color: #dc3545;\n}\n\n/* Analytics Panels */\n.analytics-panel {\n padding: 15px;\n}\n\n/* Kendo PanelBar Styling - Copied from AI Agent Form */\n::ng-deep .analytics-content .k-panelbar {\n border: none;\n background: transparent;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item {\n border: none;\n border-radius: 12px;\n margin-bottom: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.06);\n background: white;\n overflow: hidden;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-header {\n background: white;\n border: none;\n padding: 16px 20px;\n border-radius: 12px 12px 0 0;\n color: #2c3e50;\n font-weight: 600;\n font-size: 16px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-header:hover {\n background: #f8f9fa;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header {\n background: #2196f3;\n color: white;\n border-radius: 12px 12px 0 0;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle {\n position: absolute;\n right: 24px;\n color: inherit;\n font-size: 14px;\n transition: transform 0.2s ease;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header .k-panelbar-toggle {\n transform: rotate(180deg);\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle::before {\n content: '\\f107';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n}\n\n::ng-deep .analytics-content .k-panelbar > .k-panelbar-item > .k-content {\n padding: 0;\n border: none;\n background: white;\n border-radius: 0 0 12px 12px;\n}\n\n::ng-deep .analytics-content .k-panelbar .k-header .k-panelbar-icon {\n font-size: 18px;\n color: #2196f3;\n margin-right: 8px;\n}\n\n::ng-deep .analytics-content .k-panelbar .k-panelbar-expanded .k-header .k-panelbar-icon {\n color: white;\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: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\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: #f8f9fa;\n border-bottom: 1px solid #e9ecef;\n cursor: pointer;\n user-select: none;\n}\n\n.chart-card-header:hover {\n background-color: #e9ecef;\n}\n\n.chart-card-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.chart-card-header h3 i {\n font-size: 16px;\n color: #6c757d;\n}\n\n.expand-btn {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: #6c757d;\n transition: color 0.2s;\n}\n\n.expand-btn:hover {\n color: #495057;\n}\n\n.chart-card-body {\n padding: 16px;\n background: white;\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: #495057;\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: #495057;\n}\n\n/* Detailed Metrics */\n.detailed-metrics {\n margin-top: 20px;\n border-top: 1px solid #e9ecef;\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: #f8f9fa;\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: #495057;\n border-bottom: 2px solid #dee2e6;\n}\n\n.metrics-table td {\n padding: 12px;\n border-bottom: 1px solid #dee2e6;\n}\n\n.metrics-table tr:hover {\n background-color: #f8f9fa;\n}\n\n.success-rate {\n font-weight: 500;\n}\n\n.success-rate.high {\n color: #28a745;\n}\n\n.success-rate.medium {\n color: #ffc107;\n}\n\n.success-rate.low {\n color: #dc3545;\n}\n\n/* Error Analysis */\n.error-analysis {\n margin-top: 30px;\n padding: 20px;\n background-color: #fff5f5;\n border-radius: 8px;\n border: 1px solid #f5c6cb;\n}\n\n.error-analysis h3 {\n margin: 0 0 15px 0;\n color: #721c24;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-analysis-description {\n font-size: 14px;\n color: #856404;\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: white;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.error-count {\n background-color: #dc3545;\n color: white;\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: #495057;\n}\n\n/* No errors state */\n.no-errors {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px;\n background-color: #d4edda;\n border-radius: 8px;\n border: 1px solid #c3e6cb;\n color: #155724;\n}\n\n.no-errors i {\n font-size: 24px;\n color: #28a745;\n}\n\n.no-errors p {\n margin: 0;\n font-size: 14px;\n}\n\n/* No data message */\n.no-data-message {\n text-align: center;\n padding: 60px 20px;\n color: #6c757d;\n}\n\n.no-data-message i {\n font-size: 48px;\n margin-bottom: 20px;\n color: #dee2e6;\n}\n\n.no-data-message p {\n margin: 0 0 10px 0;\n font-size: 16px;\n}\n\n.no-data-message p.small {\n font-size: 14px;\n color: #adb5bd;\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: #f8f9fa;\n padding: 12px;\n text-align: left;\n font-weight: 600;\n color: #495057;\n border-bottom: 2px solid #dee2e6;\n white-space: nowrap;\n}\n\n.model-comparison td {\n padding: 12px;\n border-bottom: 1px solid #dee2e6;\n}\n\n.model-comparison tr:hover {\n background-color: #f8f9fa;\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: #f8f9fa;\n border-radius: 8px;\n}\n\n.stat-label {\n font-size: 14px;\n color: #6c757d;\n margin-bottom: 8px;\n}\n\n.stat-value {\n font-size: 32px;\n font-weight: 700;\n color: #212529;\n}\n\n.step-breakdown h3 {\n margin: 0 0 15px 0;\n font-size: 16px;\n font-weight: 500;\n color: #495057;\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: #f8f9fa;\n border-radius: 6px;\n border: 1px solid #e9ecef;\n}\n\n.step-type-item i {\n width: 30px;\n text-align: center;\n color: #6c757d;\n}\n\n.type-name {\n flex: 1;\n font-weight: 500;\n}\n\n.type-count {\n font-weight: 700;\n color: #212529;\n}\n\n.type-percentage {\n font-size: 13px;\n color: #6c757d;\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}"] }]
|
|
2073
|
+
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.AIAgentRunCostService }], { agentRunId: [{
|
|
2058
2074
|
type: Input
|
|
2059
2075
|
}], modelDistributionChart: [{
|
|
2060
2076
|
type: ViewChild,
|
|
@@ -2087,5 +2103,5 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
2087
2103
|
type: ViewChild,
|
|
2088
2104
|
args: ['promptCountByNameChart', { static: false }]
|
|
2089
2105
|
}] }); })();
|
|
2090
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAgentRunAnalyticsComponent, { className: "AIAgentRunAnalyticsComponent", filePath: "src/lib/custom/ai-agent-run/ai-agent-run-analytics.component.ts", lineNumber:
|
|
2106
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAgentRunAnalyticsComponent, { className: "AIAgentRunAnalyticsComponent", filePath: "src/lib/custom/ai-agent-run/ai-agent-run-analytics.component.ts", lineNumber: 68 }); })();
|
|
2091
2107
|
//# sourceMappingURL=ai-agent-run-analytics.component.js.map
|