@memberjunction/ng-core-entity-forms 2.111.1 → 2.112.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 +10 -10
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-diagram.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-diagram.component.js +45 -45
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-diagram.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js +6 -7
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/FlowAgentType/mj-integrated-flow-editor.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/FlowAgentType/mj-integrated-flow-editor.component.js +17 -32
- package/dist/lib/custom/AIAgents/FlowAgentType/mj-integrated-flow-editor.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js +37 -36
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/agent-advanced-settings-dialog.component.js +2 -2
- package/dist/lib/custom/AIAgents/agent-advanced-settings-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/agent-permissions-dialog.component.d.ts +1 -1
- package/dist/lib/custom/AIAgents/agent-permissions-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/agent-permissions-dialog.component.js +18 -25
- package/dist/lib/custom/AIAgents/agent-permissions-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js +10 -11
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js +159 -147
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js +11 -10
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +36 -32
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +5 -5
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +15 -13
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js +13 -15
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +28 -23
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
- 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 +15 -12
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +105 -86
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js +13 -20
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.js +4 -7
- package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.js +99 -80
- package/dist/lib/custom/Actions/action-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 +24 -17
- package/dist/lib/custom/Actions/action-test-harness.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-category-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/Queries/query-category-dialog.component.js +8 -8
- package/dist/lib/custom/Queries/query-category-dialog.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.d.ts +2 -2
- package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.js +32 -44
- package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-run-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/Queries/query-run-dialog.component.js +24 -22
- package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.js +15 -21
- package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
- package/dist/lib/custom/Templates/template-params-grid.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/template-params-grid.component.js +29 -17
- package/dist/lib/custom/Templates/template-params-grid.component.js.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.js +25 -26
- package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
- 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 +335 -274
- 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.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js +8 -8
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js +24 -28
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js.map +1 -1
- 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 +25 -30
- 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.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +20 -21
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.js +6 -7
- package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
- package/dist/lib/generated/Entities/AIAgent/sections/aiagent-form-overview.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/AIAgent/sections/aiagent-form-overview.component.js +47 -33
- package/dist/lib/generated/Entities/AIAgent/sections/aiagent-form-overview.component.js.map +1 -1
- package/dist/lib/shared/components/template-editor.component.d.ts.map +1 -1
- package/dist/lib/shared/components/template-editor.component.js +26 -27
- package/dist/lib/shared/components/template-editor.component.js.map +1 -1
- package/package.json +16 -17
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Component, Input, ViewChild, ChangeDetectionStrategy } from '@angular/core';
|
|
1
|
+
import { Component, Input, ViewChild, ChangeDetectionStrategy, } from '@angular/core';
|
|
2
2
|
import { Subject } from 'rxjs';
|
|
3
|
-
import { RunView } from '@memberjunction/
|
|
3
|
+
import { RunView } from '@memberjunction/global';
|
|
4
4
|
import * as d3 from 'd3';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
import * as i1 from "./ai-agent-run-cost.service";
|
|
@@ -791,7 +791,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
791
791
|
promptCost: false,
|
|
792
792
|
promptCount: false,
|
|
793
793
|
actionSuccess: false,
|
|
794
|
-
stepType: false
|
|
794
|
+
stepType: false,
|
|
795
795
|
};
|
|
796
796
|
this.viewMode = 'grid';
|
|
797
797
|
// Loading state
|
|
@@ -816,7 +816,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
816
816
|
prompts: true,
|
|
817
817
|
actions: true,
|
|
818
818
|
models: true,
|
|
819
|
-
timeline: true
|
|
819
|
+
timeline: true,
|
|
820
820
|
};
|
|
821
821
|
}
|
|
822
822
|
ngOnInit() {
|
|
@@ -829,7 +829,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
829
829
|
this.destroy$.next();
|
|
830
830
|
this.destroy$.complete();
|
|
831
831
|
// Clear all active timeouts
|
|
832
|
-
this.activeTimeouts.forEach(timeoutId => {
|
|
832
|
+
this.activeTimeouts.forEach((timeoutId) => {
|
|
833
833
|
clearTimeout(timeoutId);
|
|
834
834
|
});
|
|
835
835
|
this.activeTimeouts.length = 0;
|
|
@@ -849,31 +849,54 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
849
849
|
this.promptTimeDistributionChart,
|
|
850
850
|
this.promptTokenDistributionChart,
|
|
851
851
|
this.promptCostDistributionChart,
|
|
852
|
-
this.promptCountByNameChart
|
|
852
|
+
this.promptCountByNameChart,
|
|
853
853
|
];
|
|
854
854
|
// More comprehensive D3 cleanup
|
|
855
|
-
chartRefs.forEach(chartRef => {
|
|
855
|
+
chartRefs.forEach((chartRef) => {
|
|
856
856
|
if (chartRef?.nativeElement) {
|
|
857
857
|
const element = chartRef.nativeElement;
|
|
858
858
|
const d3Element = d3.select(element);
|
|
859
859
|
// Remove ALL possible event listeners (comprehensive list)
|
|
860
860
|
const allEventTypes = [
|
|
861
|
-
'click',
|
|
862
|
-
'
|
|
863
|
-
'
|
|
864
|
-
'
|
|
865
|
-
'
|
|
866
|
-
'
|
|
861
|
+
'click',
|
|
862
|
+
'dblclick',
|
|
863
|
+
'mousedown',
|
|
864
|
+
'mouseup',
|
|
865
|
+
'mouseover',
|
|
866
|
+
'mouseout',
|
|
867
|
+
'mousemove',
|
|
868
|
+
'mouseenter',
|
|
869
|
+
'mouseleave',
|
|
870
|
+
'contextmenu',
|
|
871
|
+
'touchstart',
|
|
872
|
+
'touchend',
|
|
873
|
+
'touchmove',
|
|
874
|
+
'touchcancel',
|
|
875
|
+
'wheel',
|
|
876
|
+
'scroll',
|
|
877
|
+
'resize',
|
|
878
|
+
'focus',
|
|
879
|
+
'blur',
|
|
880
|
+
'keydown',
|
|
881
|
+
'keyup',
|
|
882
|
+
'keypress',
|
|
883
|
+
'drag',
|
|
884
|
+
'dragstart',
|
|
885
|
+
'dragend',
|
|
886
|
+
'dragover',
|
|
887
|
+
'dragenter',
|
|
888
|
+
'dragleave',
|
|
889
|
+
'drop',
|
|
867
890
|
];
|
|
868
891
|
// Remove event listeners from all child elements
|
|
869
892
|
d3Element.selectAll('*').each(function () {
|
|
870
893
|
const node = d3.select(this);
|
|
871
|
-
allEventTypes.forEach(eventType => {
|
|
894
|
+
allEventTypes.forEach((eventType) => {
|
|
872
895
|
node.on(eventType, null);
|
|
873
896
|
});
|
|
874
897
|
});
|
|
875
898
|
// Remove event listeners from the main element too
|
|
876
|
-
allEventTypes.forEach(eventType => {
|
|
899
|
+
allEventTypes.forEach((eventType) => {
|
|
877
900
|
d3Element.on(eventType, null);
|
|
878
901
|
});
|
|
879
902
|
// Cancel any ongoing transitions
|
|
@@ -952,7 +975,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
952
975
|
{
|
|
953
976
|
EntityName: 'MJ: AI Agent Run Steps',
|
|
954
977
|
ExtraFilter: `AgentRunID IN ('${agentRunIds.join("','")}')`,
|
|
955
|
-
}
|
|
978
|
+
},
|
|
956
979
|
]);
|
|
957
980
|
// Process results
|
|
958
981
|
if (results[0].Success && results[0].Results && results[0].Results.length > 0) {
|
|
@@ -967,13 +990,11 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
967
990
|
const actionSteps = results[2].Results || [];
|
|
968
991
|
// Now load the actual action logs
|
|
969
992
|
if (actionSteps.length > 0) {
|
|
970
|
-
const actionLogIds = actionSteps
|
|
971
|
-
.map(s => s.TargetLogID)
|
|
972
|
-
.filter(id => id != null);
|
|
993
|
+
const actionLogIds = actionSteps.map((s) => s.TargetLogID).filter((id) => id != null);
|
|
973
994
|
if (actionLogIds.length > 0) {
|
|
974
995
|
const actionResult = await rv.RunView({
|
|
975
996
|
EntityName: 'Action Execution Logs',
|
|
976
|
-
ExtraFilter: `ID IN ('${actionLogIds.join("','")}')
|
|
997
|
+
ExtraFilter: `ID IN ('${actionLogIds.join("','")}')`,
|
|
977
998
|
});
|
|
978
999
|
if (actionResult.Success) {
|
|
979
1000
|
this.allActionLogs = actionResult.Results || [];
|
|
@@ -995,7 +1016,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
995
1016
|
byPrompt: new Map(),
|
|
996
1017
|
statusBreakdown: { success: 0, failed: 0, timeout: 0 },
|
|
997
1018
|
costBreakdown: { totalCost: 0, byModel: new Map(), byVendor: new Map() },
|
|
998
|
-
tokenUsage: { totalInput: 0, totalOutput: 0, byModel: new Map() }
|
|
1019
|
+
tokenUsage: { totalInput: 0, totalOutput: 0, byModel: new Map() },
|
|
999
1020
|
};
|
|
1000
1021
|
}
|
|
1001
1022
|
initializeActionMetrics() {
|
|
@@ -1006,7 +1027,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1006
1027
|
byAction: new Map(),
|
|
1007
1028
|
byType: new Map(),
|
|
1008
1029
|
statusBreakdown: { success: 0, failed: 0, timeout: 0 },
|
|
1009
|
-
errorAnalysis: new Map()
|
|
1030
|
+
errorAnalysis: new Map(),
|
|
1010
1031
|
};
|
|
1011
1032
|
}
|
|
1012
1033
|
initializeTimelineMetrics() {
|
|
@@ -1015,7 +1036,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1015
1036
|
stepsByType: new Map(),
|
|
1016
1037
|
parallelExecutions: 0,
|
|
1017
1038
|
deepestNesting: 0,
|
|
1018
|
-
criticalPath: { steps: [], totalTime: 0 }
|
|
1039
|
+
criticalPath: { steps: [], totalTime: 0 },
|
|
1019
1040
|
};
|
|
1020
1041
|
}
|
|
1021
1042
|
calculatePromptMetrics() {
|
|
@@ -1094,7 +1115,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1094
1115
|
actionMetric.avgTime = actionMetric.totalTime / actionMetric.count;
|
|
1095
1116
|
// Track success rate
|
|
1096
1117
|
if (actionLog.ResultCode === 'Success') {
|
|
1097
|
-
const successCount =
|
|
1118
|
+
const successCount = actionMetric.successRate * (actionMetric.count - 1) + 1;
|
|
1098
1119
|
actionMetric.successRate = successCount / actionMetric.count;
|
|
1099
1120
|
}
|
|
1100
1121
|
else {
|
|
@@ -1153,29 +1174,35 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1153
1174
|
// Model distribution pie chart
|
|
1154
1175
|
this.modelDistributionChartData = {
|
|
1155
1176
|
labels: Array.from(this.promptMetrics.byModel.keys()),
|
|
1156
|
-
datasets: [
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1177
|
+
datasets: [
|
|
1178
|
+
{
|
|
1179
|
+
data: Array.from(this.promptMetrics.byModel.values()).map((m) => m.count),
|
|
1180
|
+
backgroundColor: this.generateColors(this.promptMetrics.byModel.size),
|
|
1181
|
+
},
|
|
1182
|
+
],
|
|
1160
1183
|
};
|
|
1161
1184
|
// Execution time by vendor bar chart
|
|
1162
1185
|
this.executionTimeChartData = {
|
|
1163
1186
|
labels: Array.from(this.promptMetrics.byVendor.keys()),
|
|
1164
|
-
datasets: [
|
|
1187
|
+
datasets: [
|
|
1188
|
+
{
|
|
1165
1189
|
label: 'Average Execution Time (ms)',
|
|
1166
|
-
data: Array.from(this.promptMetrics.byVendor.values()).map(v => v.avgTime),
|
|
1190
|
+
data: Array.from(this.promptMetrics.byVendor.values()).map((v) => v.avgTime),
|
|
1167
1191
|
backgroundColor: 'rgba(54, 162, 235, 0.5)',
|
|
1168
1192
|
borderColor: 'rgba(54, 162, 235, 1)',
|
|
1169
|
-
borderWidth: 1
|
|
1170
|
-
}
|
|
1193
|
+
borderWidth: 1,
|
|
1194
|
+
},
|
|
1195
|
+
],
|
|
1171
1196
|
};
|
|
1172
1197
|
// Cost by vendor doughnut chart
|
|
1173
1198
|
this.costByVendorChartData = {
|
|
1174
1199
|
labels: Array.from(this.promptMetrics.costBreakdown.byVendor.keys()),
|
|
1175
|
-
datasets: [
|
|
1200
|
+
datasets: [
|
|
1201
|
+
{
|
|
1176
1202
|
data: Array.from(this.promptMetrics.costBreakdown.byVendor.values()),
|
|
1177
|
-
backgroundColor: this.generateColors(this.promptMetrics.costBreakdown.byVendor.size)
|
|
1178
|
-
}
|
|
1203
|
+
backgroundColor: this.generateColors(this.promptMetrics.costBreakdown.byVendor.size),
|
|
1204
|
+
},
|
|
1205
|
+
],
|
|
1179
1206
|
};
|
|
1180
1207
|
// Token usage stacked bar chart
|
|
1181
1208
|
const tokenModels = Array.from(this.promptMetrics.tokenUsage.byModel.keys());
|
|
@@ -1184,34 +1211,38 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1184
1211
|
datasets: [
|
|
1185
1212
|
{
|
|
1186
1213
|
label: 'Input Tokens',
|
|
1187
|
-
data: tokenModels.map(m => this.promptMetrics.tokenUsage.byModel.get(m)?.input || 0),
|
|
1188
|
-
backgroundColor: 'rgba(255, 99, 132, 0.5)'
|
|
1214
|
+
data: tokenModels.map((m) => this.promptMetrics.tokenUsage.byModel.get(m)?.input || 0),
|
|
1215
|
+
backgroundColor: 'rgba(255, 99, 132, 0.5)',
|
|
1189
1216
|
},
|
|
1190
1217
|
{
|
|
1191
1218
|
label: 'Output Tokens',
|
|
1192
|
-
data: tokenModels.map(m => this.promptMetrics.tokenUsage.byModel.get(m)?.output || 0),
|
|
1193
|
-
backgroundColor: 'rgba(75, 192, 192, 0.5)'
|
|
1194
|
-
}
|
|
1195
|
-
]
|
|
1219
|
+
data: tokenModels.map((m) => this.promptMetrics.tokenUsage.byModel.get(m)?.output || 0),
|
|
1220
|
+
backgroundColor: 'rgba(75, 192, 192, 0.5)',
|
|
1221
|
+
},
|
|
1222
|
+
],
|
|
1196
1223
|
};
|
|
1197
1224
|
// Action success rate bar chart
|
|
1198
1225
|
this.actionSuccessRateChartData = {
|
|
1199
1226
|
labels: Array.from(this.actionMetrics.byAction.keys()),
|
|
1200
|
-
datasets: [
|
|
1227
|
+
datasets: [
|
|
1228
|
+
{
|
|
1201
1229
|
label: 'Success Rate (%)',
|
|
1202
|
-
data: Array.from(this.actionMetrics.byAction.values()).map(a => a.successRate * 100),
|
|
1230
|
+
data: Array.from(this.actionMetrics.byAction.values()).map((a) => a.successRate * 100),
|
|
1203
1231
|
backgroundColor: 'rgba(75, 192, 192, 0.5)',
|
|
1204
1232
|
borderColor: 'rgba(75, 192, 192, 1)',
|
|
1205
|
-
borderWidth: 1
|
|
1206
|
-
}
|
|
1233
|
+
borderWidth: 1,
|
|
1234
|
+
},
|
|
1235
|
+
],
|
|
1207
1236
|
};
|
|
1208
1237
|
// Step type distribution pie chart
|
|
1209
1238
|
this.stepTypeDistributionChartData = {
|
|
1210
1239
|
labels: Array.from(this.timelineMetrics.stepsByType.keys()),
|
|
1211
|
-
datasets: [
|
|
1240
|
+
datasets: [
|
|
1241
|
+
{
|
|
1212
1242
|
data: Array.from(this.timelineMetrics.stepsByType.values()),
|
|
1213
|
-
backgroundColor: this.generateColors(this.timelineMetrics.stepsByType.size)
|
|
1214
|
-
}
|
|
1243
|
+
backgroundColor: this.generateColors(this.timelineMetrics.stepsByType.size),
|
|
1244
|
+
},
|
|
1245
|
+
],
|
|
1215
1246
|
};
|
|
1216
1247
|
}
|
|
1217
1248
|
generateColors(count) {
|
|
@@ -1225,7 +1256,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1225
1256
|
'rgba(199, 199, 199, 0.5)',
|
|
1226
1257
|
'rgba(83, 102, 255, 0.5)',
|
|
1227
1258
|
'rgba(255, 99, 255, 0.5)',
|
|
1228
|
-
'rgba(99, 255, 132, 0.5)'
|
|
1259
|
+
'rgba(99, 255, 132, 0.5)',
|
|
1229
1260
|
];
|
|
1230
1261
|
// Repeat colors if needed
|
|
1231
1262
|
const result = [];
|
|
@@ -1272,7 +1303,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1272
1303
|
const element = this.modelDistributionChart.nativeElement;
|
|
1273
1304
|
const data = Array.from(this.promptMetrics.byModel.entries()).map(([name, metrics]) => ({
|
|
1274
1305
|
name,
|
|
1275
|
-
value: metrics.count
|
|
1306
|
+
value: metrics.count,
|
|
1276
1307
|
}));
|
|
1277
1308
|
if (data.length === 0)
|
|
1278
1309
|
return;
|
|
@@ -1282,37 +1313,37 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1282
1313
|
const width = isExpanded ? 500 : 300;
|
|
1283
1314
|
const height = isExpanded ? 400 : 220;
|
|
1284
1315
|
const radius = Math.min(width, height) / 2 - 40;
|
|
1285
|
-
const svg = d3
|
|
1316
|
+
const svg = d3
|
|
1317
|
+
.select(element)
|
|
1286
1318
|
.append('svg')
|
|
1287
1319
|
.attr('width', width)
|
|
1288
1320
|
.attr('height', height)
|
|
1289
1321
|
.append('g')
|
|
1290
1322
|
.attr('transform', `translate(${width / 2}, ${height / 2})`);
|
|
1291
1323
|
const color = d3.scaleOrdinal(d3.schemeCategory10);
|
|
1292
|
-
const pie = d3
|
|
1293
|
-
.
|
|
1324
|
+
const pie = d3
|
|
1325
|
+
.pie()
|
|
1326
|
+
.value((d) => d.value)
|
|
1294
1327
|
.sort(null);
|
|
1295
|
-
const arc = d3.arc()
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
.data(pie(data))
|
|
1300
|
-
.enter()
|
|
1301
|
-
.append('g');
|
|
1302
|
-
arcs.append('path')
|
|
1328
|
+
const arc = d3.arc().innerRadius(0).outerRadius(radius);
|
|
1329
|
+
const arcs = svg.selectAll('arc').data(pie(data)).enter().append('g');
|
|
1330
|
+
arcs
|
|
1331
|
+
.append('path')
|
|
1303
1332
|
.attr('d', arc)
|
|
1304
1333
|
.attr('fill', (d, i) => color(i.toString()))
|
|
1305
1334
|
.attr('stroke', 'white')
|
|
1306
1335
|
.style('stroke-width', '2px');
|
|
1307
1336
|
// Add labels
|
|
1308
|
-
arcs
|
|
1337
|
+
arcs
|
|
1338
|
+
.append('text')
|
|
1309
1339
|
.attr('transform', (d) => `translate(${arc.centroid(d)})`)
|
|
1310
1340
|
.attr('text-anchor', 'middle')
|
|
1311
1341
|
.style('font-size', '12px')
|
|
1312
1342
|
.style('fill', 'white')
|
|
1313
|
-
.text((d) => d.data.value > 0 ? d.data.value : '');
|
|
1343
|
+
.text((d) => (d.data.value > 0 ? d.data.value : ''));
|
|
1314
1344
|
// Add title
|
|
1315
|
-
svg
|
|
1345
|
+
svg
|
|
1346
|
+
.append('text')
|
|
1316
1347
|
.attr('x', 0)
|
|
1317
1348
|
.attr('y', -radius - 25)
|
|
1318
1349
|
.attr('text-anchor', 'middle')
|
|
@@ -1324,7 +1355,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1324
1355
|
const element = this.executionTimeChart.nativeElement;
|
|
1325
1356
|
const data = Array.from(this.promptMetrics.byVendor.entries()).map(([name, metrics]) => ({
|
|
1326
1357
|
name,
|
|
1327
|
-
value: metrics.avgTime
|
|
1358
|
+
value: metrics.avgTime,
|
|
1328
1359
|
}));
|
|
1329
1360
|
if (data.length === 0)
|
|
1330
1361
|
return;
|
|
@@ -1334,41 +1365,47 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1334
1365
|
const margin = { top: 40, right: 20, bottom: 70, left: 60 };
|
|
1335
1366
|
const width = (isExpanded ? 600 : 320) - margin.left - margin.right;
|
|
1336
1367
|
const height = (isExpanded ? 350 : 200) - margin.top - margin.bottom;
|
|
1337
|
-
const svg = d3
|
|
1368
|
+
const svg = d3
|
|
1369
|
+
.select(element)
|
|
1338
1370
|
.append('svg')
|
|
1339
1371
|
.attr('width', width + margin.left + margin.right)
|
|
1340
1372
|
.attr('height', height + margin.top + margin.bottom)
|
|
1341
1373
|
.append('g')
|
|
1342
1374
|
.attr('transform', `translate(${margin.left},${margin.top})`);
|
|
1343
|
-
const x = d3
|
|
1375
|
+
const x = d3
|
|
1376
|
+
.scaleBand()
|
|
1344
1377
|
.range([0, width])
|
|
1345
|
-
.domain(data.map(d => d.name))
|
|
1378
|
+
.domain(data.map((d) => d.name))
|
|
1346
1379
|
.padding(0.1);
|
|
1347
|
-
const y = d3
|
|
1348
|
-
.
|
|
1380
|
+
const y = d3
|
|
1381
|
+
.scaleLinear()
|
|
1382
|
+
.domain([0, d3.max(data, (d) => d.value) || 0])
|
|
1349
1383
|
.range([height, 0]);
|
|
1350
1384
|
// Add bars
|
|
1351
|
-
svg
|
|
1385
|
+
svg
|
|
1386
|
+
.selectAll('.bar')
|
|
1352
1387
|
.data(data)
|
|
1353
|
-
.enter()
|
|
1388
|
+
.enter()
|
|
1389
|
+
.append('rect')
|
|
1354
1390
|
.attr('class', 'bar')
|
|
1355
|
-
.attr('x', d => x(d.name) || 0)
|
|
1391
|
+
.attr('x', (d) => x(d.name) || 0)
|
|
1356
1392
|
.attr('width', x.bandwidth())
|
|
1357
|
-
.attr('y', d => y(d.value))
|
|
1358
|
-
.attr('height', d => height - y(d.value))
|
|
1393
|
+
.attr('y', (d) => y(d.value))
|
|
1394
|
+
.attr('height', (d) => height - y(d.value))
|
|
1359
1395
|
.attr('fill', '#36a2eb');
|
|
1360
1396
|
// Add x axis
|
|
1361
|
-
svg
|
|
1397
|
+
svg
|
|
1398
|
+
.append('g')
|
|
1362
1399
|
.attr('transform', `translate(0,${height})`)
|
|
1363
1400
|
.call(d3.axisBottom(x))
|
|
1364
1401
|
.selectAll('text')
|
|
1365
1402
|
.attr('transform', 'rotate(-45)')
|
|
1366
1403
|
.style('text-anchor', 'end');
|
|
1367
1404
|
// Add y axis
|
|
1368
|
-
svg.append('g')
|
|
1369
|
-
.call(d3.axisLeft(y).tickFormat(d => `${d}ms`));
|
|
1405
|
+
svg.append('g').call(d3.axisLeft(y).tickFormat((d) => `${d}ms`));
|
|
1370
1406
|
// Add title
|
|
1371
|
-
svg
|
|
1407
|
+
svg
|
|
1408
|
+
.append('text')
|
|
1372
1409
|
.attr('x', width / 2)
|
|
1373
1410
|
.attr('y', -20)
|
|
1374
1411
|
.attr('text-anchor', 'middle')
|
|
@@ -1380,7 +1417,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1380
1417
|
const element = this.costByVendorChart.nativeElement;
|
|
1381
1418
|
const data = Array.from(this.promptMetrics.costBreakdown.byVendor.entries()).map(([name, cost]) => ({
|
|
1382
1419
|
name,
|
|
1383
|
-
value: cost
|
|
1420
|
+
value: cost,
|
|
1384
1421
|
}));
|
|
1385
1422
|
if (data.length === 0)
|
|
1386
1423
|
return;
|
|
@@ -1389,30 +1426,32 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1389
1426
|
const width = 300;
|
|
1390
1427
|
const height = 220;
|
|
1391
1428
|
const radius = Math.min(width, height) / 2 - 40;
|
|
1392
|
-
const svg = d3
|
|
1429
|
+
const svg = d3
|
|
1430
|
+
.select(element)
|
|
1393
1431
|
.append('svg')
|
|
1394
1432
|
.attr('width', width)
|
|
1395
1433
|
.attr('height', height)
|
|
1396
1434
|
.append('g')
|
|
1397
1435
|
.attr('transform', `translate(${width / 2}, ${height / 2})`);
|
|
1398
1436
|
const color = d3.scaleOrdinal(d3.schemeSet2);
|
|
1399
|
-
const pie = d3
|
|
1400
|
-
.
|
|
1437
|
+
const pie = d3
|
|
1438
|
+
.pie()
|
|
1439
|
+
.value((d) => d.value)
|
|
1401
1440
|
.sort(null);
|
|
1402
|
-
const arc = d3
|
|
1441
|
+
const arc = d3
|
|
1442
|
+
.arc()
|
|
1403
1443
|
.innerRadius(radius * 0.5) // Doughnut chart
|
|
1404
1444
|
.outerRadius(radius);
|
|
1405
|
-
const arcs = svg.selectAll('arc')
|
|
1406
|
-
|
|
1407
|
-
.
|
|
1408
|
-
.append('g');
|
|
1409
|
-
arcs.append('path')
|
|
1445
|
+
const arcs = svg.selectAll('arc').data(pie(data)).enter().append('g');
|
|
1446
|
+
arcs
|
|
1447
|
+
.append('path')
|
|
1410
1448
|
.attr('d', arc)
|
|
1411
1449
|
.attr('fill', (d, i) => color(i.toString()))
|
|
1412
1450
|
.attr('stroke', 'white')
|
|
1413
1451
|
.style('stroke-width', '2px');
|
|
1414
1452
|
// Add title
|
|
1415
|
-
svg
|
|
1453
|
+
svg
|
|
1454
|
+
.append('text')
|
|
1416
1455
|
.attr('x', 0)
|
|
1417
1456
|
.attr('y', -radius - 25)
|
|
1418
1457
|
.attr('text-anchor', 'middle')
|
|
@@ -1423,15 +1462,15 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1423
1462
|
renderTokenUsageChart() {
|
|
1424
1463
|
const element = this.tokenUsageChart.nativeElement;
|
|
1425
1464
|
const models = Array.from(this.promptMetrics.tokenUsage.byModel.keys());
|
|
1426
|
-
const inputData = models.map(model => ({
|
|
1465
|
+
const inputData = models.map((model) => ({
|
|
1427
1466
|
model,
|
|
1428
1467
|
type: 'Input',
|
|
1429
|
-
value: this.promptMetrics.tokenUsage.byModel.get(model)?.input || 0
|
|
1468
|
+
value: this.promptMetrics.tokenUsage.byModel.get(model)?.input || 0,
|
|
1430
1469
|
}));
|
|
1431
|
-
const outputData = models.map(model => ({
|
|
1470
|
+
const outputData = models.map((model) => ({
|
|
1432
1471
|
model,
|
|
1433
1472
|
type: 'Output',
|
|
1434
|
-
value: this.promptMetrics.tokenUsage.byModel.get(model)?.output || 0
|
|
1473
|
+
value: this.promptMetrics.tokenUsage.byModel.get(model)?.output || 0,
|
|
1435
1474
|
}));
|
|
1436
1475
|
const data = [...inputData, ...outputData];
|
|
1437
1476
|
if (data.length === 0)
|
|
@@ -1441,71 +1480,73 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1441
1480
|
const margin = { top: 40, right: 100, bottom: 70, left: 60 };
|
|
1442
1481
|
const width = 320 - margin.left - margin.right;
|
|
1443
1482
|
const height = 200 - margin.top - margin.bottom;
|
|
1444
|
-
const svg = d3
|
|
1483
|
+
const svg = d3
|
|
1484
|
+
.select(element)
|
|
1445
1485
|
.append('svg')
|
|
1446
1486
|
.attr('width', width + margin.left + margin.right)
|
|
1447
1487
|
.attr('height', height + margin.top + margin.bottom)
|
|
1448
1488
|
.append('g')
|
|
1449
1489
|
.attr('transform', `translate(${margin.left},${margin.top})`);
|
|
1450
|
-
const x0 = d3.scaleBand()
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
.
|
|
1454
|
-
const x1 = d3.scaleBand()
|
|
1455
|
-
.padding(0.05)
|
|
1456
|
-
.domain(['Input', 'Output'])
|
|
1457
|
-
.rangeRound([0, x0.bandwidth()]);
|
|
1458
|
-
const y = d3.scaleLinear()
|
|
1490
|
+
const x0 = d3.scaleBand().rangeRound([0, width]).paddingInner(0.1).domain(models);
|
|
1491
|
+
const x1 = d3.scaleBand().padding(0.05).domain(['Input', 'Output']).rangeRound([0, x0.bandwidth()]);
|
|
1492
|
+
const y = d3
|
|
1493
|
+
.scaleLinear()
|
|
1459
1494
|
.rangeRound([height, 0])
|
|
1460
|
-
.domain([0, d3.max(data, d => d.value) || 0]);
|
|
1461
|
-
const color = d3.scaleOrdinal()
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
svg.append('g')
|
|
1495
|
+
.domain([0, d3.max(data, (d) => d.value) || 0]);
|
|
1496
|
+
const color = d3.scaleOrdinal().domain(['Input', 'Output']).range(['#ff6384', '#4bc0c0']);
|
|
1497
|
+
const grouped = d3.group(data, (d) => d.model);
|
|
1498
|
+
svg
|
|
1499
|
+
.append('g')
|
|
1466
1500
|
.selectAll('g')
|
|
1467
1501
|
.data(grouped)
|
|
1468
|
-
.enter()
|
|
1469
|
-
.
|
|
1502
|
+
.enter()
|
|
1503
|
+
.append('g')
|
|
1504
|
+
.attr('transform', (d) => `translate(${x0(d[0]) || 0},0)`)
|
|
1470
1505
|
.selectAll('rect')
|
|
1471
|
-
.data(d => d[1])
|
|
1472
|
-
.enter()
|
|
1473
|
-
.
|
|
1474
|
-
.attr('
|
|
1506
|
+
.data((d) => d[1])
|
|
1507
|
+
.enter()
|
|
1508
|
+
.append('rect')
|
|
1509
|
+
.attr('x', (d) => x1(d.type) || 0)
|
|
1510
|
+
.attr('y', (d) => y(d.value))
|
|
1475
1511
|
.attr('width', x1.bandwidth())
|
|
1476
|
-
.attr('height', d => height - y(d.value))
|
|
1477
|
-
.attr('fill', d => color(d.type));
|
|
1512
|
+
.attr('height', (d) => height - y(d.value))
|
|
1513
|
+
.attr('fill', (d) => color(d.type));
|
|
1478
1514
|
// Add x axis
|
|
1479
|
-
svg
|
|
1515
|
+
svg
|
|
1516
|
+
.append('g')
|
|
1480
1517
|
.attr('transform', `translate(0,${height})`)
|
|
1481
1518
|
.call(d3.axisBottom(x0))
|
|
1482
1519
|
.selectAll('text')
|
|
1483
1520
|
.attr('transform', 'rotate(-45)')
|
|
1484
1521
|
.style('text-anchor', 'end');
|
|
1485
1522
|
// Add y axis
|
|
1486
|
-
svg.append('g')
|
|
1487
|
-
.call(d3.axisLeft(y));
|
|
1523
|
+
svg.append('g').call(d3.axisLeft(y));
|
|
1488
1524
|
// Add legend
|
|
1489
|
-
const legend = svg
|
|
1525
|
+
const legend = svg
|
|
1526
|
+
.append('g')
|
|
1490
1527
|
.attr('font-family', 'sans-serif')
|
|
1491
1528
|
.attr('font-size', 10)
|
|
1492
1529
|
.attr('text-anchor', 'end')
|
|
1493
1530
|
.selectAll('g')
|
|
1494
1531
|
.data(['Input', 'Output'])
|
|
1495
|
-
.enter()
|
|
1532
|
+
.enter()
|
|
1533
|
+
.append('g')
|
|
1496
1534
|
.attr('transform', (d, i) => `translate(0,${i * 20})`);
|
|
1497
|
-
legend
|
|
1535
|
+
legend
|
|
1536
|
+
.append('rect')
|
|
1498
1537
|
.attr('x', width + 70)
|
|
1499
1538
|
.attr('width', 19)
|
|
1500
1539
|
.attr('height', 19)
|
|
1501
|
-
.attr('fill', d => color(d));
|
|
1502
|
-
legend
|
|
1540
|
+
.attr('fill', (d) => color(d));
|
|
1541
|
+
legend
|
|
1542
|
+
.append('text')
|
|
1503
1543
|
.attr('x', width + 65)
|
|
1504
1544
|
.attr('y', 9.5)
|
|
1505
1545
|
.attr('dy', '0.32em')
|
|
1506
|
-
.text(d => d);
|
|
1546
|
+
.text((d) => d);
|
|
1507
1547
|
// Add title
|
|
1508
|
-
svg
|
|
1548
|
+
svg
|
|
1549
|
+
.append('text')
|
|
1509
1550
|
.attr('x', width / 2)
|
|
1510
1551
|
.attr('y', -20)
|
|
1511
1552
|
.attr('text-anchor', 'middle')
|
|
@@ -1517,7 +1558,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1517
1558
|
const element = this.actionSuccessRateChart.nativeElement;
|
|
1518
1559
|
const data = Array.from(this.actionMetrics.byAction.entries()).map(([name, metrics]) => ({
|
|
1519
1560
|
name,
|
|
1520
|
-
value: metrics.successRate * 100
|
|
1561
|
+
value: metrics.successRate * 100,
|
|
1521
1562
|
}));
|
|
1522
1563
|
if (data.length === 0)
|
|
1523
1564
|
return;
|
|
@@ -1526,41 +1567,44 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1526
1567
|
const margin = { top: 40, right: 20, bottom: 100, left: 60 };
|
|
1527
1568
|
const width = 320 - margin.left - margin.right;
|
|
1528
1569
|
const height = 200 - margin.top - margin.bottom;
|
|
1529
|
-
const svg = d3
|
|
1570
|
+
const svg = d3
|
|
1571
|
+
.select(element)
|
|
1530
1572
|
.append('svg')
|
|
1531
1573
|
.attr('width', width + margin.left + margin.right)
|
|
1532
1574
|
.attr('height', height + margin.top + margin.bottom)
|
|
1533
1575
|
.append('g')
|
|
1534
1576
|
.attr('transform', `translate(${margin.left},${margin.top})`);
|
|
1535
|
-
const x = d3
|
|
1577
|
+
const x = d3
|
|
1578
|
+
.scaleBand()
|
|
1536
1579
|
.range([0, width])
|
|
1537
|
-
.domain(data.map(d => d.name))
|
|
1580
|
+
.domain(data.map((d) => d.name))
|
|
1538
1581
|
.padding(0.1);
|
|
1539
|
-
const y = d3.scaleLinear()
|
|
1540
|
-
.domain([0, 100])
|
|
1541
|
-
.range([height, 0]);
|
|
1582
|
+
const y = d3.scaleLinear().domain([0, 100]).range([height, 0]);
|
|
1542
1583
|
// Add bars with color based on success rate
|
|
1543
|
-
svg
|
|
1584
|
+
svg
|
|
1585
|
+
.selectAll('.bar')
|
|
1544
1586
|
.data(data)
|
|
1545
|
-
.enter()
|
|
1587
|
+
.enter()
|
|
1588
|
+
.append('rect')
|
|
1546
1589
|
.attr('class', 'bar')
|
|
1547
|
-
.attr('x', d => x(d.name) || 0)
|
|
1590
|
+
.attr('x', (d) => x(d.name) || 0)
|
|
1548
1591
|
.attr('width', x.bandwidth())
|
|
1549
|
-
.attr('y', d => y(d.value))
|
|
1550
|
-
.attr('height', d => height - y(d.value))
|
|
1551
|
-
.attr('fill', d => d.value > 90 ? '#4bc0c0' : d.value > 70 ? '#ffce56' : '#ff6384');
|
|
1592
|
+
.attr('y', (d) => y(d.value))
|
|
1593
|
+
.attr('height', (d) => height - y(d.value))
|
|
1594
|
+
.attr('fill', (d) => (d.value > 90 ? '#4bc0c0' : d.value > 70 ? '#ffce56' : '#ff6384'));
|
|
1552
1595
|
// Add x axis
|
|
1553
|
-
svg
|
|
1596
|
+
svg
|
|
1597
|
+
.append('g')
|
|
1554
1598
|
.attr('transform', `translate(0,${height})`)
|
|
1555
1599
|
.call(d3.axisBottom(x))
|
|
1556
1600
|
.selectAll('text')
|
|
1557
1601
|
.attr('transform', 'rotate(-45)')
|
|
1558
1602
|
.style('text-anchor', 'end');
|
|
1559
1603
|
// Add y axis
|
|
1560
|
-
svg.append('g')
|
|
1561
|
-
.call(d3.axisLeft(y).tickFormat(d => `${d}%`));
|
|
1604
|
+
svg.append('g').call(d3.axisLeft(y).tickFormat((d) => `${d}%`));
|
|
1562
1605
|
// Add title
|
|
1563
|
-
svg
|
|
1606
|
+
svg
|
|
1607
|
+
.append('text')
|
|
1564
1608
|
.attr('x', width / 2)
|
|
1565
1609
|
.attr('y', -20)
|
|
1566
1610
|
.attr('text-anchor', 'middle')
|
|
@@ -1572,7 +1616,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1572
1616
|
const element = this.stepTypeChart.nativeElement;
|
|
1573
1617
|
const data = Array.from(this.timelineMetrics.stepsByType.entries()).map(([name, value]) => ({
|
|
1574
1618
|
name,
|
|
1575
|
-
value
|
|
1619
|
+
value,
|
|
1576
1620
|
}));
|
|
1577
1621
|
if (data.length === 0)
|
|
1578
1622
|
return;
|
|
@@ -1581,30 +1625,29 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1581
1625
|
const width = 300;
|
|
1582
1626
|
const height = 220;
|
|
1583
1627
|
const radius = Math.min(width, height) / 2 - 40;
|
|
1584
|
-
const svg = d3
|
|
1628
|
+
const svg = d3
|
|
1629
|
+
.select(element)
|
|
1585
1630
|
.append('svg')
|
|
1586
1631
|
.attr('width', width)
|
|
1587
1632
|
.attr('height', height)
|
|
1588
1633
|
.append('g')
|
|
1589
1634
|
.attr('transform', `translate(${width / 2}, ${height / 2})`);
|
|
1590
1635
|
const color = d3.scaleOrdinal(d3.schemeSet3);
|
|
1591
|
-
const pie = d3
|
|
1592
|
-
.
|
|
1636
|
+
const pie = d3
|
|
1637
|
+
.pie()
|
|
1638
|
+
.value((d) => d.value)
|
|
1593
1639
|
.sort(null);
|
|
1594
|
-
const arc = d3.arc()
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
.data(pie(data))
|
|
1599
|
-
.enter()
|
|
1600
|
-
.append('g');
|
|
1601
|
-
arcs.append('path')
|
|
1640
|
+
const arc = d3.arc().innerRadius(0).outerRadius(radius);
|
|
1641
|
+
const arcs = svg.selectAll('arc').data(pie(data)).enter().append('g');
|
|
1642
|
+
arcs
|
|
1643
|
+
.append('path')
|
|
1602
1644
|
.attr('d', arc)
|
|
1603
1645
|
.attr('fill', (d, i) => color(i.toString()))
|
|
1604
1646
|
.attr('stroke', 'white')
|
|
1605
1647
|
.style('stroke-width', '2px');
|
|
1606
1648
|
// Add labels
|
|
1607
|
-
arcs
|
|
1649
|
+
arcs
|
|
1650
|
+
.append('text')
|
|
1608
1651
|
.attr('transform', (d) => {
|
|
1609
1652
|
const centroid = arc.centroid(d);
|
|
1610
1653
|
return `translate(${centroid})`;
|
|
@@ -1612,9 +1655,10 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1612
1655
|
.attr('text-anchor', 'middle')
|
|
1613
1656
|
.style('font-size', '12px')
|
|
1614
1657
|
.style('fill', 'white')
|
|
1615
|
-
.text((d) => d.data.value > 0 ? d.data.value : '');
|
|
1658
|
+
.text((d) => (d.data.value > 0 ? d.data.value : ''));
|
|
1616
1659
|
// Add title
|
|
1617
|
-
svg
|
|
1660
|
+
svg
|
|
1661
|
+
.append('text')
|
|
1618
1662
|
.attr('x', 0)
|
|
1619
1663
|
.attr('y', -radius - 25)
|
|
1620
1664
|
.attr('text-anchor', 'middle')
|
|
@@ -1623,8 +1667,8 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1623
1667
|
.text('Step Type Distribution');
|
|
1624
1668
|
}
|
|
1625
1669
|
calculatePromptSuccessRate(promptName) {
|
|
1626
|
-
const successfulRuns = this.allPromptRuns.filter(run => run.Prompt === promptName && run.Success === true).length;
|
|
1627
|
-
const totalRuns = this.allPromptRuns.filter(run => run.Prompt === promptName).length;
|
|
1670
|
+
const successfulRuns = this.allPromptRuns.filter((run) => run.Prompt === promptName && run.Success === true).length;
|
|
1671
|
+
const totalRuns = this.allPromptRuns.filter((run) => run.Prompt === promptName).length;
|
|
1628
1672
|
if (totalRuns === 0)
|
|
1629
1673
|
return '0';
|
|
1630
1674
|
return ((successfulRuns / totalRuns) * 100).toFixed(1);
|
|
@@ -1640,14 +1684,14 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1640
1684
|
if (this.viewMode === 'grid') {
|
|
1641
1685
|
this.viewMode = 'expanded';
|
|
1642
1686
|
// Expand all charts
|
|
1643
|
-
Object.keys(this.expandedCharts).forEach(key => {
|
|
1687
|
+
Object.keys(this.expandedCharts).forEach((key) => {
|
|
1644
1688
|
this.expandedCharts[key] = true;
|
|
1645
1689
|
});
|
|
1646
1690
|
}
|
|
1647
1691
|
else {
|
|
1648
1692
|
this.viewMode = 'grid';
|
|
1649
1693
|
// Collapse all charts
|
|
1650
|
-
Object.keys(this.expandedCharts).forEach(key => {
|
|
1694
|
+
Object.keys(this.expandedCharts).forEach((key) => {
|
|
1651
1695
|
this.expandedCharts[key] = false;
|
|
1652
1696
|
});
|
|
1653
1697
|
}
|
|
@@ -1693,7 +1737,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1693
1737
|
totalCost: 0,
|
|
1694
1738
|
avgCost: 0,
|
|
1695
1739
|
inputTokens: 0,
|
|
1696
|
-
outputTokens: 0
|
|
1740
|
+
outputTokens: 0,
|
|
1697
1741
|
});
|
|
1698
1742
|
}
|
|
1699
1743
|
const data = modelData.get(key);
|
|
@@ -1710,14 +1754,14 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1710
1754
|
}
|
|
1711
1755
|
getStepTypeIcon(stepType) {
|
|
1712
1756
|
const iconMap = {
|
|
1713
|
-
|
|
1714
|
-
|
|
1757
|
+
Prompts: 'fa-microchip',
|
|
1758
|
+
Actions: 'fa-cog',
|
|
1715
1759
|
'Sub-Agent': 'fa-robot',
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1760
|
+
Start: 'fa-play-circle',
|
|
1761
|
+
End: 'fa-stop-circle',
|
|
1762
|
+
Decision: 'fa-code-branch',
|
|
1763
|
+
Loop: 'fa-sync',
|
|
1764
|
+
Error: 'fa-exclamation-triangle',
|
|
1721
1765
|
};
|
|
1722
1766
|
return iconMap[stepType] || 'fa-circle';
|
|
1723
1767
|
}
|
|
@@ -1733,7 +1777,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1733
1777
|
'rgba(199, 199, 199, 0.5)',
|
|
1734
1778
|
'rgba(83, 102, 255, 0.5)',
|
|
1735
1779
|
'rgba(255, 99, 255, 0.5)',
|
|
1736
|
-
'rgba(99, 255, 132, 0.5)'
|
|
1780
|
+
'rgba(99, 255, 132, 0.5)',
|
|
1737
1781
|
];
|
|
1738
1782
|
// Use a simple hash of the model name to consistently pick a color
|
|
1739
1783
|
let hash = 0;
|
|
@@ -1747,7 +1791,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1747
1791
|
const data = Array.from(this.promptMetrics.byPrompt.entries())
|
|
1748
1792
|
.map(([name, metrics]) => ({
|
|
1749
1793
|
name: name.length > 20 ? name.substring(0, 20) + '...' : name,
|
|
1750
|
-
value: metrics.avgTime
|
|
1794
|
+
value: metrics.avgTime,
|
|
1751
1795
|
}))
|
|
1752
1796
|
.sort((a, b) => b.value - a.value)
|
|
1753
1797
|
.slice(0, 10); // Top 10 prompts by avg time
|
|
@@ -1758,31 +1802,37 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1758
1802
|
const margin = { top: 40, right: 20, bottom: 120, left: 80 };
|
|
1759
1803
|
const width = 320 - margin.left - margin.right;
|
|
1760
1804
|
const height = 200 - margin.top - margin.bottom;
|
|
1761
|
-
const svg = d3
|
|
1805
|
+
const svg = d3
|
|
1806
|
+
.select(element)
|
|
1762
1807
|
.append('svg')
|
|
1763
1808
|
.attr('width', width + margin.left + margin.right)
|
|
1764
1809
|
.attr('height', height + margin.top + margin.bottom)
|
|
1765
1810
|
.append('g')
|
|
1766
1811
|
.attr('transform', `translate(${margin.left},${margin.top})`);
|
|
1767
|
-
const x = d3
|
|
1812
|
+
const x = d3
|
|
1813
|
+
.scaleBand()
|
|
1768
1814
|
.range([0, width])
|
|
1769
|
-
.domain(data.map(d => d.name))
|
|
1815
|
+
.domain(data.map((d) => d.name))
|
|
1770
1816
|
.padding(0.1);
|
|
1771
|
-
const y = d3
|
|
1772
|
-
.
|
|
1817
|
+
const y = d3
|
|
1818
|
+
.scaleLinear()
|
|
1819
|
+
.domain([0, d3.max(data, (d) => d.value) || 0])
|
|
1773
1820
|
.range([height, 0]);
|
|
1774
1821
|
// Add bars
|
|
1775
|
-
svg
|
|
1822
|
+
svg
|
|
1823
|
+
.selectAll('.bar')
|
|
1776
1824
|
.data(data)
|
|
1777
|
-
.enter()
|
|
1825
|
+
.enter()
|
|
1826
|
+
.append('rect')
|
|
1778
1827
|
.attr('class', 'bar')
|
|
1779
|
-
.attr('x', d => x(d.name) || 0)
|
|
1828
|
+
.attr('x', (d) => x(d.name) || 0)
|
|
1780
1829
|
.attr('width', x.bandwidth())
|
|
1781
|
-
.attr('y', d => y(d.value))
|
|
1782
|
-
.attr('height', d => height - y(d.value))
|
|
1830
|
+
.attr('y', (d) => y(d.value))
|
|
1831
|
+
.attr('height', (d) => height - y(d.value))
|
|
1783
1832
|
.attr('fill', '#667eea');
|
|
1784
1833
|
// Add x axis
|
|
1785
|
-
svg
|
|
1834
|
+
svg
|
|
1835
|
+
.append('g')
|
|
1786
1836
|
.attr('transform', `translate(0,${height})`)
|
|
1787
1837
|
.call(d3.axisBottom(x))
|
|
1788
1838
|
.selectAll('text')
|
|
@@ -1790,10 +1840,10 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1790
1840
|
.style('text-anchor', 'end')
|
|
1791
1841
|
.style('font-size', '10px');
|
|
1792
1842
|
// Add y axis
|
|
1793
|
-
svg.append('g')
|
|
1794
|
-
.call(d3.axisLeft(y).tickFormat(d => `${d}ms`));
|
|
1843
|
+
svg.append('g').call(d3.axisLeft(y).tickFormat((d) => `${d}ms`));
|
|
1795
1844
|
// Add title
|
|
1796
|
-
svg
|
|
1845
|
+
svg
|
|
1846
|
+
.append('text')
|
|
1797
1847
|
.attr('x', width / 2)
|
|
1798
1848
|
.attr('y', -20)
|
|
1799
1849
|
.attr('text-anchor', 'middle')
|
|
@@ -1813,18 +1863,18 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1813
1863
|
promptTokenData.set(promptName, existing);
|
|
1814
1864
|
}
|
|
1815
1865
|
const topPrompts = Array.from(promptTokenData.entries())
|
|
1816
|
-
.sort((a, b) =>
|
|
1866
|
+
.sort((a, b) => b[1].input + b[1].output - (a[1].input + a[1].output))
|
|
1817
1867
|
.slice(0, 8)
|
|
1818
1868
|
.map(([name]) => name);
|
|
1819
|
-
const inputData = topPrompts.map(prompt => ({
|
|
1869
|
+
const inputData = topPrompts.map((prompt) => ({
|
|
1820
1870
|
prompt: prompt.length > 15 ? prompt.substring(0, 15) + '...' : prompt,
|
|
1821
1871
|
type: 'Input',
|
|
1822
|
-
value: promptTokenData.get(prompt)?.input || 0
|
|
1872
|
+
value: promptTokenData.get(prompt)?.input || 0,
|
|
1823
1873
|
}));
|
|
1824
|
-
const outputData = topPrompts.map(prompt => ({
|
|
1874
|
+
const outputData = topPrompts.map((prompt) => ({
|
|
1825
1875
|
prompt: prompt.length > 15 ? prompt.substring(0, 15) + '...' : prompt,
|
|
1826
1876
|
type: 'Output',
|
|
1827
|
-
value: promptTokenData.get(prompt)?.output || 0
|
|
1877
|
+
value: promptTokenData.get(prompt)?.output || 0,
|
|
1828
1878
|
}));
|
|
1829
1879
|
const data = [...inputData, ...outputData];
|
|
1830
1880
|
if (data.length === 0)
|
|
@@ -1834,42 +1884,44 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1834
1884
|
const margin = { top: 40, right: 100, bottom: 100, left: 80 };
|
|
1835
1885
|
const width = 320 - margin.left - margin.right;
|
|
1836
1886
|
const height = 200 - margin.top - margin.bottom;
|
|
1837
|
-
const svg = d3
|
|
1887
|
+
const svg = d3
|
|
1888
|
+
.select(element)
|
|
1838
1889
|
.append('svg')
|
|
1839
1890
|
.attr('width', width + margin.left + margin.right)
|
|
1840
1891
|
.attr('height', height + margin.top + margin.bottom)
|
|
1841
1892
|
.append('g')
|
|
1842
1893
|
.attr('transform', `translate(${margin.left},${margin.top})`);
|
|
1843
|
-
const x0 = d3
|
|
1894
|
+
const x0 = d3
|
|
1895
|
+
.scaleBand()
|
|
1844
1896
|
.rangeRound([0, width])
|
|
1845
1897
|
.paddingInner(0.1)
|
|
1846
|
-
.domain(topPrompts.map(p => p.length > 15 ? p.substring(0, 15) + '...' : p));
|
|
1847
|
-
const x1 = d3.scaleBand()
|
|
1848
|
-
|
|
1849
|
-
.
|
|
1850
|
-
.rangeRound([0, x0.bandwidth()]);
|
|
1851
|
-
const y = d3.scaleLinear()
|
|
1898
|
+
.domain(topPrompts.map((p) => (p.length > 15 ? p.substring(0, 15) + '...' : p)));
|
|
1899
|
+
const x1 = d3.scaleBand().padding(0.05).domain(['Input', 'Output']).rangeRound([0, x0.bandwidth()]);
|
|
1900
|
+
const y = d3
|
|
1901
|
+
.scaleLinear()
|
|
1852
1902
|
.rangeRound([height, 0])
|
|
1853
|
-
.domain([0, d3.max(data, d => d.value) || 0]);
|
|
1854
|
-
const color = d3.scaleOrdinal()
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
svg.append('g')
|
|
1903
|
+
.domain([0, d3.max(data, (d) => d.value) || 0]);
|
|
1904
|
+
const color = d3.scaleOrdinal().domain(['Input', 'Output']).range(['#764ba2', '#667eea']);
|
|
1905
|
+
const grouped = d3.group(data, (d) => d.prompt);
|
|
1906
|
+
svg
|
|
1907
|
+
.append('g')
|
|
1859
1908
|
.selectAll('g')
|
|
1860
1909
|
.data(grouped)
|
|
1861
|
-
.enter()
|
|
1862
|
-
.
|
|
1910
|
+
.enter()
|
|
1911
|
+
.append('g')
|
|
1912
|
+
.attr('transform', (d) => `translate(${x0(d[0]) || 0},0)`)
|
|
1863
1913
|
.selectAll('rect')
|
|
1864
|
-
.data(d => d[1])
|
|
1865
|
-
.enter()
|
|
1866
|
-
.
|
|
1867
|
-
.attr('
|
|
1914
|
+
.data((d) => d[1])
|
|
1915
|
+
.enter()
|
|
1916
|
+
.append('rect')
|
|
1917
|
+
.attr('x', (d) => x1(d.type) || 0)
|
|
1918
|
+
.attr('y', (d) => y(d.value))
|
|
1868
1919
|
.attr('width', x1.bandwidth())
|
|
1869
|
-
.attr('height', d => height - y(d.value))
|
|
1870
|
-
.attr('fill', d => color(d.type));
|
|
1920
|
+
.attr('height', (d) => height - y(d.value))
|
|
1921
|
+
.attr('fill', (d) => color(d.type));
|
|
1871
1922
|
// Add x axis
|
|
1872
|
-
svg
|
|
1923
|
+
svg
|
|
1924
|
+
.append('g')
|
|
1873
1925
|
.attr('transform', `translate(0,${height})`)
|
|
1874
1926
|
.call(d3.axisBottom(x0))
|
|
1875
1927
|
.selectAll('text')
|
|
@@ -1877,29 +1929,33 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1877
1929
|
.style('text-anchor', 'end')
|
|
1878
1930
|
.style('font-size', '10px');
|
|
1879
1931
|
// Add y axis
|
|
1880
|
-
svg.append('g')
|
|
1881
|
-
.call(d3.axisLeft(y).tickFormat(d => d3.format('.2s')(d)));
|
|
1932
|
+
svg.append('g').call(d3.axisLeft(y).tickFormat((d) => d3.format('.2s')(d)));
|
|
1882
1933
|
// Add legend
|
|
1883
|
-
const legend = svg
|
|
1934
|
+
const legend = svg
|
|
1935
|
+
.append('g')
|
|
1884
1936
|
.attr('font-family', 'sans-serif')
|
|
1885
1937
|
.attr('font-size', 10)
|
|
1886
1938
|
.attr('text-anchor', 'end')
|
|
1887
1939
|
.selectAll('g')
|
|
1888
1940
|
.data(['Input', 'Output'])
|
|
1889
|
-
.enter()
|
|
1941
|
+
.enter()
|
|
1942
|
+
.append('g')
|
|
1890
1943
|
.attr('transform', (d, i) => `translate(0,${i * 20})`);
|
|
1891
|
-
legend
|
|
1944
|
+
legend
|
|
1945
|
+
.append('rect')
|
|
1892
1946
|
.attr('x', width + 70)
|
|
1893
1947
|
.attr('width', 19)
|
|
1894
1948
|
.attr('height', 19)
|
|
1895
|
-
.attr('fill', d => color(d));
|
|
1896
|
-
legend
|
|
1949
|
+
.attr('fill', (d) => color(d));
|
|
1950
|
+
legend
|
|
1951
|
+
.append('text')
|
|
1897
1952
|
.attr('x', width + 65)
|
|
1898
1953
|
.attr('y', 9.5)
|
|
1899
1954
|
.attr('dy', '0.32em')
|
|
1900
|
-
.text(d => d);
|
|
1955
|
+
.text((d) => d);
|
|
1901
1956
|
// Add title
|
|
1902
|
-
svg
|
|
1957
|
+
svg
|
|
1958
|
+
.append('text')
|
|
1903
1959
|
.attr('x', width / 2)
|
|
1904
1960
|
.attr('y', -20)
|
|
1905
1961
|
.attr('text-anchor', 'middle')
|
|
@@ -1920,7 +1976,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1920
1976
|
.filter(([_, cost]) => cost > 0)
|
|
1921
1977
|
.map(([name, cost]) => ({
|
|
1922
1978
|
name: name.length > 20 ? name.substring(0, 20) + '...' : name,
|
|
1923
|
-
value: cost
|
|
1979
|
+
value: cost,
|
|
1924
1980
|
}))
|
|
1925
1981
|
.sort((a, b) => b.value - a.value)
|
|
1926
1982
|
.slice(0, 10); // Top 10 prompts by cost
|
|
@@ -1931,30 +1987,32 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1931
1987
|
const width = 300;
|
|
1932
1988
|
const height = 220;
|
|
1933
1989
|
const radius = Math.min(width, height) / 2 - 40;
|
|
1934
|
-
const svg = d3
|
|
1990
|
+
const svg = d3
|
|
1991
|
+
.select(element)
|
|
1935
1992
|
.append('svg')
|
|
1936
1993
|
.attr('width', width)
|
|
1937
1994
|
.attr('height', height)
|
|
1938
1995
|
.append('g')
|
|
1939
1996
|
.attr('transform', `translate(${width / 2}, ${height / 2})`);
|
|
1940
1997
|
const color = d3.scaleOrdinal(d3.schemePurples[9].slice(2));
|
|
1941
|
-
const pie = d3
|
|
1942
|
-
.
|
|
1998
|
+
const pie = d3
|
|
1999
|
+
.pie()
|
|
2000
|
+
.value((d) => d.value)
|
|
1943
2001
|
.sort((a, b) => b.value - a.value);
|
|
1944
|
-
const arc = d3
|
|
2002
|
+
const arc = d3
|
|
2003
|
+
.arc()
|
|
1945
2004
|
.innerRadius(radius * 0.5)
|
|
1946
2005
|
.outerRadius(radius);
|
|
1947
|
-
const arcs = svg.selectAll('arc')
|
|
1948
|
-
|
|
1949
|
-
.
|
|
1950
|
-
.append('g');
|
|
1951
|
-
arcs.append('path')
|
|
2006
|
+
const arcs = svg.selectAll('arc').data(pie(data)).enter().append('g');
|
|
2007
|
+
arcs
|
|
2008
|
+
.append('path')
|
|
1952
2009
|
.attr('d', arc)
|
|
1953
2010
|
.attr('fill', (d, i) => color(i.toString()))
|
|
1954
2011
|
.attr('stroke', 'white')
|
|
1955
2012
|
.style('stroke-width', '2px');
|
|
1956
2013
|
// Add title
|
|
1957
|
-
svg
|
|
2014
|
+
svg
|
|
2015
|
+
.append('text')
|
|
1958
2016
|
.attr('x', 0)
|
|
1959
2017
|
.attr('y', -radius - 25)
|
|
1960
2018
|
.attr('text-anchor', 'middle')
|
|
@@ -1962,13 +2020,15 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1962
2020
|
.style('font-weight', 'bold')
|
|
1963
2021
|
.text('Cost Distribution by Prompt');
|
|
1964
2022
|
// Add total cost in center
|
|
1965
|
-
svg
|
|
2023
|
+
svg
|
|
2024
|
+
.append('text')
|
|
1966
2025
|
.attr('text-anchor', 'middle')
|
|
1967
2026
|
.attr('dy', '-0.5em')
|
|
1968
2027
|
.style('font-size', '14px')
|
|
1969
2028
|
.style('font-weight', 'bold')
|
|
1970
2029
|
.text('Total Cost');
|
|
1971
|
-
svg
|
|
2030
|
+
svg
|
|
2031
|
+
.append('text')
|
|
1972
2032
|
.attr('text-anchor', 'middle')
|
|
1973
2033
|
.attr('dy', '1em')
|
|
1974
2034
|
.style('font-size', '18px')
|
|
@@ -1980,7 +2040,7 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1980
2040
|
const data = Array.from(this.promptMetrics.byPrompt.entries())
|
|
1981
2041
|
.map(([name, metrics]) => ({
|
|
1982
2042
|
name: name.length > 20 ? name.substring(0, 20) + '...' : name,
|
|
1983
|
-
value: metrics.count
|
|
2043
|
+
value: metrics.count,
|
|
1984
2044
|
}))
|
|
1985
2045
|
.sort((a, b) => b.value - a.value)
|
|
1986
2046
|
.slice(0, 10); // Top 10 prompts by count
|
|
@@ -1991,58 +2051,61 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
1991
2051
|
const margin = { top: 40, right: 20, bottom: 120, left: 60 };
|
|
1992
2052
|
const width = 320 - margin.left - margin.right;
|
|
1993
2053
|
const height = 200 - margin.top - margin.bottom;
|
|
1994
|
-
const svg = d3
|
|
2054
|
+
const svg = d3
|
|
2055
|
+
.select(element)
|
|
1995
2056
|
.append('svg')
|
|
1996
2057
|
.attr('width', width + margin.left + margin.right)
|
|
1997
2058
|
.attr('height', height + margin.top + margin.bottom)
|
|
1998
2059
|
.append('g')
|
|
1999
2060
|
.attr('transform', `translate(${margin.left},${margin.top})`);
|
|
2000
|
-
const x = d3
|
|
2061
|
+
const x = d3
|
|
2062
|
+
.scaleBand()
|
|
2001
2063
|
.range([0, width])
|
|
2002
|
-
.domain(data.map(d => d.name))
|
|
2064
|
+
.domain(data.map((d) => d.name))
|
|
2003
2065
|
.padding(0.1);
|
|
2004
|
-
const y = d3
|
|
2005
|
-
.
|
|
2066
|
+
const y = d3
|
|
2067
|
+
.scaleLinear()
|
|
2068
|
+
.domain([0, d3.max(data, (d) => d.value) || 0])
|
|
2006
2069
|
.range([height, 0]);
|
|
2007
2070
|
// Create gradient
|
|
2008
|
-
const gradient = svg
|
|
2071
|
+
const gradient = svg
|
|
2072
|
+
.append('defs')
|
|
2009
2073
|
.append('linearGradient')
|
|
2010
2074
|
.attr('id', 'promptCountGradient')
|
|
2011
2075
|
.attr('x1', '0%')
|
|
2012
2076
|
.attr('y1', '0%')
|
|
2013
2077
|
.attr('x2', '0%')
|
|
2014
2078
|
.attr('y2', '100%');
|
|
2015
|
-
gradient.append('stop')
|
|
2016
|
-
|
|
2017
|
-
.attr('stop-color', '#667eea')
|
|
2018
|
-
.attr('stop-opacity', 1);
|
|
2019
|
-
gradient.append('stop')
|
|
2020
|
-
.attr('offset', '100%')
|
|
2021
|
-
.attr('stop-color', '#764ba2')
|
|
2022
|
-
.attr('stop-opacity', 1);
|
|
2079
|
+
gradient.append('stop').attr('offset', '0%').attr('stop-color', '#667eea').attr('stop-opacity', 1);
|
|
2080
|
+
gradient.append('stop').attr('offset', '100%').attr('stop-color', '#764ba2').attr('stop-opacity', 1);
|
|
2023
2081
|
// Add bars
|
|
2024
|
-
svg
|
|
2082
|
+
svg
|
|
2083
|
+
.selectAll('.bar')
|
|
2025
2084
|
.data(data)
|
|
2026
|
-
.enter()
|
|
2085
|
+
.enter()
|
|
2086
|
+
.append('rect')
|
|
2027
2087
|
.attr('class', 'bar')
|
|
2028
|
-
.attr('x', d => x(d.name) || 0)
|
|
2088
|
+
.attr('x', (d) => x(d.name) || 0)
|
|
2029
2089
|
.attr('width', x.bandwidth())
|
|
2030
|
-
.attr('y', d => y(d.value))
|
|
2031
|
-
.attr('height', d => height - y(d.value))
|
|
2090
|
+
.attr('y', (d) => y(d.value))
|
|
2091
|
+
.attr('height', (d) => height - y(d.value))
|
|
2032
2092
|
.attr('fill', 'url(#promptCountGradient)');
|
|
2033
2093
|
// Add value labels on bars
|
|
2034
|
-
svg
|
|
2094
|
+
svg
|
|
2095
|
+
.selectAll('.bar-label')
|
|
2035
2096
|
.data(data)
|
|
2036
|
-
.enter()
|
|
2097
|
+
.enter()
|
|
2098
|
+
.append('text')
|
|
2037
2099
|
.attr('class', 'bar-label')
|
|
2038
|
-
.attr('x', d => (x(d.name) || 0) + x.bandwidth() / 2)
|
|
2039
|
-
.attr('y', d => y(d.value) - 5)
|
|
2100
|
+
.attr('x', (d) => (x(d.name) || 0) + x.bandwidth() / 2)
|
|
2101
|
+
.attr('y', (d) => y(d.value) - 5)
|
|
2040
2102
|
.attr('text-anchor', 'middle')
|
|
2041
2103
|
.style('font-size', '12px')
|
|
2042
2104
|
.style('font-weight', 'bold')
|
|
2043
|
-
.text(d => d.value);
|
|
2105
|
+
.text((d) => d.value);
|
|
2044
2106
|
// Add x axis
|
|
2045
|
-
svg
|
|
2107
|
+
svg
|
|
2108
|
+
.append('g')
|
|
2046
2109
|
.attr('transform', `translate(0,${height})`)
|
|
2047
2110
|
.call(d3.axisBottom(x))
|
|
2048
2111
|
.selectAll('text')
|
|
@@ -2050,10 +2113,10 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
2050
2113
|
.style('text-anchor', 'end')
|
|
2051
2114
|
.style('font-size', '10px');
|
|
2052
2115
|
// Add y axis
|
|
2053
|
-
svg.append('g')
|
|
2054
|
-
.call(d3.axisLeft(y));
|
|
2116
|
+
svg.append('g').call(d3.axisLeft(y));
|
|
2055
2117
|
// Add title
|
|
2056
|
-
svg
|
|
2118
|
+
svg
|
|
2119
|
+
.append('text')
|
|
2057
2120
|
.attr('x', width / 2)
|
|
2058
2121
|
.attr('y', -20)
|
|
2059
2122
|
.attr('text-anchor', 'middle')
|
|
@@ -2097,15 +2160,13 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
2097
2160
|
const stepsResult = await rv.RunView({
|
|
2098
2161
|
EntityName: 'MJ: AI Agent Run Steps',
|
|
2099
2162
|
ExtraFilter: `AgentRunID IN ('${agentRunIds.join("','")}') AND StepType = 'Prompt'`,
|
|
2100
|
-
ResultType: 'simple'
|
|
2163
|
+
ResultType: 'simple',
|
|
2101
2164
|
});
|
|
2102
2165
|
if (!stepsResult.Success || !stepsResult.Results || stepsResult.Results.length === 0) {
|
|
2103
2166
|
return [];
|
|
2104
2167
|
}
|
|
2105
2168
|
// Extract the TargetLogID values (these are the prompt run IDs)
|
|
2106
|
-
const promptRunIds = stepsResult.Results
|
|
2107
|
-
.map(step => step.TargetLogID)
|
|
2108
|
-
.filter(id => id); // Remove any null/undefined values
|
|
2169
|
+
const promptRunIds = stepsResult.Results.map((step) => step.TargetLogID).filter((id) => id); // Remove any null/undefined values
|
|
2109
2170
|
if (promptRunIds.length === 0) {
|
|
2110
2171
|
return [];
|
|
2111
2172
|
}
|
|
@@ -2114,9 +2175,9 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
2114
2175
|
EntityName: 'MJ: AI Prompt Runs',
|
|
2115
2176
|
ExtraFilter: `ID IN ('${promptRunIds.join("','")}')`,
|
|
2116
2177
|
OrderBy: 'RunAt',
|
|
2117
|
-
ResultType: 'simple'
|
|
2178
|
+
ResultType: 'simple',
|
|
2118
2179
|
});
|
|
2119
|
-
return promptResult.Success ?
|
|
2180
|
+
return promptResult.Success ? promptResult.Results || [] : [];
|
|
2120
2181
|
}
|
|
2121
2182
|
/**
|
|
2122
2183
|
* TrackBy function for keyvalue pipe
|
|
@@ -2209,5 +2270,5 @@ export class AIAgentRunAnalyticsComponent {
|
|
|
2209
2270
|
type: ViewChild,
|
|
2210
2271
|
args: ['promptCountByNameChart', { static: false }]
|
|
2211
2272
|
}] }); })();
|
|
2212
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAgentRunAnalyticsComponent, { className: "AIAgentRunAnalyticsComponent", filePath: "src/lib/custom/ai-agent-run/ai-agent-run-analytics.component.ts", lineNumber:
|
|
2273
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAgentRunAnalyticsComponent, { className: "AIAgentRunAnalyticsComponent", filePath: "src/lib/custom/ai-agent-run/ai-agent-run-analytics.component.ts", lineNumber: 79 }); })();
|
|
2213
2274
|
//# sourceMappingURL=ai-agent-run-analytics.component.js.map
|