1198 lines
35 KiB
C#
1198 lines
35 KiB
C#
using System;
|
|
using System.CodeDom.Compiler;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Interop;
|
|
using System.Windows.Markup;
|
|
using System.Windows.Media;
|
|
using System.Windows.Shapes;
|
|
using System.Windows.Threading;
|
|
using AxCopilot.Services.Agent;
|
|
|
|
namespace AxCopilot.Views;
|
|
|
|
public class WorkflowAnalyzerWindow : Window, IComponentConnector
|
|
{
|
|
private record WaterfallEntry(string Label, long StartMs, long DurationMs, string Type, bool IsBottleneck = false);
|
|
|
|
private readonly DateTime _startTime = DateTime.Now;
|
|
|
|
private int _totalToolCalls;
|
|
|
|
private int _totalInputTokens;
|
|
|
|
private int _totalOutputTokens;
|
|
|
|
private int _maxIteration;
|
|
|
|
private int _successCount;
|
|
|
|
private int _failCount;
|
|
|
|
private string _logLevel = "simple";
|
|
|
|
private bool _autoScroll = true;
|
|
|
|
private string _activeTab = "timeline";
|
|
|
|
private readonly List<WaterfallEntry> _waterfallEntries = new List<WaterfallEntry>();
|
|
|
|
private readonly Dictionary<string, long> _toolTimeAccum = new Dictionary<string, long>();
|
|
|
|
private readonly List<(int Iteration, int Input, int Output)> _tokenTrend = new List<(int, int, int)>();
|
|
|
|
private long _lastEventMs;
|
|
|
|
private const int WM_NCHITTEST = 132;
|
|
|
|
private const int HTLEFT = 10;
|
|
|
|
private const int HTRIGHT = 11;
|
|
|
|
private const int HTTOP = 12;
|
|
|
|
private const int HTTOPLEFT = 13;
|
|
|
|
private const int HTTOPRIGHT = 14;
|
|
|
|
private const int HTBOTTOM = 15;
|
|
|
|
private const int HTBOTTOMLEFT = 16;
|
|
|
|
private const int HTBOTTOMRIGHT = 17;
|
|
|
|
internal Border BtnClear;
|
|
|
|
internal Border BtnMinimize;
|
|
|
|
internal Border BtnClose;
|
|
|
|
internal TextBlock CardElapsed;
|
|
|
|
internal TextBlock CardIterations;
|
|
|
|
internal TextBlock CardTokens;
|
|
|
|
internal TextBlock CardInputTokens;
|
|
|
|
internal TextBlock CardOutputTokens;
|
|
|
|
internal TextBlock CardToolCalls;
|
|
|
|
internal Border TabTimeline;
|
|
|
|
internal TextBlock TabTimelineIcon;
|
|
|
|
internal TextBlock TabTimelineText;
|
|
|
|
internal Border TabBottleneck;
|
|
|
|
internal TextBlock TabBottleneckIcon;
|
|
|
|
internal TextBlock TabBottleneckText;
|
|
|
|
internal ScrollViewer TimelineScroller;
|
|
|
|
internal StackPanel TimelinePanel;
|
|
|
|
internal ScrollViewer BottleneckScroller;
|
|
|
|
internal StackPanel BottleneckPanel;
|
|
|
|
internal Canvas WaterfallCanvas;
|
|
|
|
internal StackPanel ToolTimePanel;
|
|
|
|
internal Canvas TokenTrendCanvas;
|
|
|
|
internal Border DetailPanel;
|
|
|
|
internal TextBlock DetailTitle;
|
|
|
|
internal TextBlock DetailBadge;
|
|
|
|
internal TextBlock DetailMeta;
|
|
|
|
internal TextBlock DetailContent;
|
|
|
|
internal TextBlock StatusText;
|
|
|
|
internal TextBlock LogLevelBadge;
|
|
|
|
private bool _contentLoaded;
|
|
|
|
[DllImport("user32.dll")]
|
|
private static extern nint SendMessage(nint hWnd, int msg, nint wParam, nint lParam);
|
|
|
|
public WorkflowAnalyzerWindow()
|
|
{
|
|
InitializeComponent();
|
|
base.SourceInitialized += delegate
|
|
{
|
|
((HwndSource)PresentationSource.FromVisual(this))?.AddHook(WndProc);
|
|
};
|
|
_logLevel = (Application.Current as App)?.SettingsService?.Settings.Llm.AgentLogLevel ?? "simple";
|
|
TextBlock logLevelBadge = LogLevelBadge;
|
|
string logLevel = _logLevel;
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string text = ((logLevel == "debug") ? "DEBUG" : ((!(logLevel == "detailed")) ? "SIMPLE" : "DETAILED"));
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
logLevelBadge.Text = text;
|
|
base.Loaded += delegate
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
Rect workArea = SystemParameters.WorkArea;
|
|
base.Left = ((Rect)(ref workArea)).Right - base.ActualWidth - 20.0;
|
|
base.Top = ((Rect)(ref workArea)).Bottom - base.ActualHeight - 20.0;
|
|
UpdateTabVisuals();
|
|
};
|
|
TimelineScroller.ScrollChanged += delegate(object _, ScrollChangedEventArgs e)
|
|
{
|
|
_autoScroll = Math.Abs(e.ExtentHeight - e.ViewportHeight - e.VerticalOffset) < 30.0;
|
|
};
|
|
}
|
|
|
|
public void OnAgentEvent(AgentEvent evt)
|
|
{
|
|
if (!((DispatcherObject)this).Dispatcher.CheckAccess())
|
|
{
|
|
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
|
{
|
|
OnAgentEvent(evt);
|
|
});
|
|
return;
|
|
}
|
|
if (evt.Iteration > _maxIteration)
|
|
{
|
|
_maxIteration = evt.Iteration;
|
|
}
|
|
if (evt.InputTokens > 0)
|
|
{
|
|
_totalInputTokens += evt.InputTokens;
|
|
}
|
|
if (evt.OutputTokens > 0)
|
|
{
|
|
_totalOutputTokens += evt.OutputTokens;
|
|
}
|
|
if (evt.Type == AgentEventType.ToolCall)
|
|
{
|
|
_totalToolCalls++;
|
|
}
|
|
if (evt.Type == AgentEventType.ToolResult)
|
|
{
|
|
_successCount++;
|
|
}
|
|
if (evt.Type == AgentEventType.Error)
|
|
{
|
|
_failCount++;
|
|
}
|
|
UpdateSummaryCards();
|
|
CollectBottleneckData(evt);
|
|
Border element = CreateTimelineNode(evt);
|
|
TimelinePanel.Children.Add(element);
|
|
if (_autoScroll)
|
|
{
|
|
TimelineScroller.ScrollToEnd();
|
|
}
|
|
TextBlock statusText = StatusText;
|
|
AgentEventType type = evt.Type;
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string text = type switch
|
|
{
|
|
AgentEventType.Complete => "✓ 완료",
|
|
AgentEventType.Error => "⚠ 오류: " + Truncate(evt.Summary, 60),
|
|
AgentEventType.ToolCall => "실행 중: " + evt.ToolName,
|
|
AgentEventType.Thinking => "사고 중...",
|
|
AgentEventType.Planning => "계획 수립 중...",
|
|
_ => StatusText.Text,
|
|
};
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
statusText.Text = text;
|
|
if (evt.Type == AgentEventType.Complete)
|
|
{
|
|
RenderBottleneckCharts();
|
|
}
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
TimelinePanel.Children.Clear();
|
|
DetailPanel.Visibility = Visibility.Collapsed;
|
|
_totalToolCalls = 0;
|
|
_totalInputTokens = 0;
|
|
_totalOutputTokens = 0;
|
|
_maxIteration = 0;
|
|
_successCount = 0;
|
|
_failCount = 0;
|
|
_waterfallEntries.Clear();
|
|
_toolTimeAccum.Clear();
|
|
_tokenTrend.Clear();
|
|
_lastEventMs = 0L;
|
|
UpdateSummaryCards();
|
|
ClearBottleneckCharts();
|
|
StatusText.Text = "대기 중...";
|
|
}
|
|
|
|
public void SwitchToTimelineTab()
|
|
{
|
|
_activeTab = "timeline";
|
|
UpdateTabVisuals();
|
|
}
|
|
|
|
public void SwitchToBottleneckTab()
|
|
{
|
|
_activeTab = "bottleneck";
|
|
UpdateTabVisuals();
|
|
RenderBottleneckCharts();
|
|
}
|
|
|
|
private void TabTimeline_Click(object sender, MouseButtonEventArgs e)
|
|
{
|
|
_activeTab = "timeline";
|
|
UpdateTabVisuals();
|
|
}
|
|
|
|
private void TabBottleneck_Click(object sender, MouseButtonEventArgs e)
|
|
{
|
|
_activeTab = "bottleneck";
|
|
UpdateTabVisuals();
|
|
RenderBottleneckCharts();
|
|
}
|
|
|
|
private void UpdateTabVisuals()
|
|
{
|
|
Brush brush = (TryFindResource("AccentColor") as Brush) ?? Brushes.CornflowerBlue;
|
|
Brush brush2 = (TryFindResource("ItemBackground") as Brush) ?? new SolidColorBrush(Color.FromArgb(21, byte.MaxValue, byte.MaxValue, byte.MaxValue));
|
|
Brush brush3 = (TryFindResource("PrimaryText") as Brush) ?? Brushes.White;
|
|
bool flag = _activeTab == "timeline";
|
|
TabTimeline.Background = (flag ? brush : brush2);
|
|
TabBottleneck.Background = ((!flag) ? brush : brush2);
|
|
TabTimelineIcon.Foreground = (flag ? Brushes.White : brush3);
|
|
TabTimelineText.Foreground = (flag ? Brushes.White : brush3);
|
|
TabBottleneckIcon.Foreground = ((!flag) ? Brushes.White : brush3);
|
|
TabBottleneckText.Foreground = ((!flag) ? Brushes.White : brush3);
|
|
TimelineScroller.Visibility = ((!flag) ? Visibility.Collapsed : Visibility.Visible);
|
|
BottleneckScroller.Visibility = (flag ? Visibility.Collapsed : Visibility.Visible);
|
|
DetailPanel.Visibility = ((!flag || DetailPanel.Tag == null) ? Visibility.Collapsed : Visibility.Visible);
|
|
}
|
|
|
|
private void CollectBottleneckData(AgentEvent evt)
|
|
{
|
|
long num = (long)(evt.Timestamp - _startTime).TotalMilliseconds;
|
|
if (evt.Type == AgentEventType.Thinking && evt.Iteration > 0)
|
|
{
|
|
_lastEventMs = num;
|
|
}
|
|
else if (evt.Type == AgentEventType.ToolCall)
|
|
{
|
|
if (_lastEventMs > 0)
|
|
{
|
|
long num2 = num - _lastEventMs;
|
|
if (num2 > 100)
|
|
{
|
|
_waterfallEntries.Add(new WaterfallEntry($"LLM #{evt.Iteration}", _lastEventMs, num2, "llm"));
|
|
}
|
|
}
|
|
_lastEventMs = num;
|
|
}
|
|
else if (evt.Type == AgentEventType.ToolResult && evt.ElapsedMs > 0)
|
|
{
|
|
long startMs = num - evt.ElapsedMs;
|
|
_waterfallEntries.Add(new WaterfallEntry(evt.ToolName, startMs, evt.ElapsedMs, "tool"));
|
|
string toolName = evt.ToolName;
|
|
_toolTimeAccum[toolName] = _toolTimeAccum.GetValueOrDefault(toolName) + evt.ElapsedMs;
|
|
_lastEventMs = num;
|
|
}
|
|
else if (evt.Type == AgentEventType.Complete && _lastEventMs > 0)
|
|
{
|
|
long num3 = num - _lastEventMs;
|
|
if (num3 > 100)
|
|
{
|
|
_waterfallEntries.Add(new WaterfallEntry("LLM (마무리)", _lastEventMs, num3, "llm"));
|
|
}
|
|
}
|
|
if ((evt.InputTokens > 0 || evt.OutputTokens > 0) && evt.Iteration > 0)
|
|
{
|
|
int num4 = _tokenTrend.FindIndex(((int Iteration, int Input, int Output) t) => t.Iteration == evt.Iteration);
|
|
if (num4 >= 0)
|
|
{
|
|
(int, int, int) tuple = _tokenTrend[num4];
|
|
_tokenTrend[num4] = (evt.Iteration, tuple.Item2 + evt.InputTokens, tuple.Item3 + evt.OutputTokens);
|
|
}
|
|
else
|
|
{
|
|
_tokenTrend.Add((evt.Iteration, evt.InputTokens, evt.OutputTokens));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ClearBottleneckCharts()
|
|
{
|
|
WaterfallCanvas.Children.Clear();
|
|
ToolTimePanel.Children.Clear();
|
|
TokenTrendCanvas.Children.Clear();
|
|
}
|
|
|
|
private void RenderBottleneckCharts()
|
|
{
|
|
ClearBottleneckCharts();
|
|
RenderWaterfallChart();
|
|
RenderToolTimeChart();
|
|
RenderTokenTrendChart();
|
|
}
|
|
|
|
private void RenderWaterfallChart()
|
|
{
|
|
if (_waterfallEntries.Count == 0)
|
|
{
|
|
WaterfallCanvas.Height = 40.0;
|
|
TextBlock textBlock = new TextBlock();
|
|
textBlock.Text = "실행 데이터가 없습니다";
|
|
textBlock.FontSize = 11.0;
|
|
textBlock.Foreground = (TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray;
|
|
TextBlock element = textBlock;
|
|
Canvas.SetLeft(element, 10.0);
|
|
Canvas.SetTop(element, 10.0);
|
|
WaterfallCanvas.Children.Add(element);
|
|
return;
|
|
}
|
|
double num = _waterfallEntries.Average((WaterfallEntry e) => e.DurationMs);
|
|
long num2 = _waterfallEntries.Max((WaterfallEntry e) => e.StartMs + e.DurationMs);
|
|
if (num2 <= 0)
|
|
{
|
|
num2 = 1L;
|
|
}
|
|
int num3 = 22;
|
|
double num4 = 90.0;
|
|
int val = _waterfallEntries.Count * num3 + 10;
|
|
WaterfallCanvas.Height = Math.Max(val, 60);
|
|
double num5 = ((WaterfallCanvas.ActualWidth > 0.0) ? WaterfallCanvas.ActualWidth : 480.0);
|
|
double num6 = num5 - num4 - 60.0;
|
|
for (int num7 = 0; num7 < _waterfallEntries.Count; num7++)
|
|
{
|
|
WaterfallEntry waterfallEntry = _waterfallEntries[num7];
|
|
int num8 = num7 * num3 + 4;
|
|
Color color = (((double)waterfallEntry.DurationMs >= num * 2.0) ? Color.FromRgb(239, 68, 68) : (((double)waterfallEntry.DurationMs >= num * 1.5) ? Color.FromRgb(249, 115, 22) : ((!(waterfallEntry.Type == "llm")) ? Color.FromRgb(52, 211, 153) : Color.FromRgb(96, 165, 250))));
|
|
TextBlock element2 = new TextBlock
|
|
{
|
|
Text = Truncate(waterfallEntry.Label, 12),
|
|
FontSize = 10.0,
|
|
FontFamily = new FontFamily("Consolas"),
|
|
Foreground = new SolidColorBrush(color),
|
|
Width = num4,
|
|
TextAlignment = TextAlignment.Right
|
|
};
|
|
Canvas.SetLeft(element2, 0.0);
|
|
Canvas.SetTop(element2, num8 + 2);
|
|
WaterfallCanvas.Children.Add(element2);
|
|
double num9 = (double)waterfallEntry.StartMs / (double)num2 * num6;
|
|
double num10 = Math.Max((double)waterfallEntry.DurationMs / (double)num2 * num6, 3.0);
|
|
Rectangle element3 = new Rectangle
|
|
{
|
|
Width = num10,
|
|
Height = 14.0,
|
|
RadiusX = 3.0,
|
|
RadiusY = 3.0,
|
|
Fill = new SolidColorBrush(color),
|
|
Opacity = 0.85,
|
|
ToolTip = waterfallEntry.Label + ": " + FormatMs(waterfallEntry.DurationMs)
|
|
};
|
|
Canvas.SetLeft(element3, num4 + 8.0 + num9);
|
|
Canvas.SetTop(element3, num8 + 1);
|
|
WaterfallCanvas.Children.Add(element3);
|
|
TextBlock element4 = new TextBlock
|
|
{
|
|
Text = FormatMs(waterfallEntry.DurationMs),
|
|
FontSize = 9.0,
|
|
Foreground = new SolidColorBrush(color),
|
|
FontFamily = new FontFamily("Consolas")
|
|
};
|
|
Canvas.SetLeft(element4, num4 + 8.0 + num9 + num10 + 4.0);
|
|
Canvas.SetTop(element4, num8 + 3);
|
|
WaterfallCanvas.Children.Add(element4);
|
|
if ((double)waterfallEntry.DurationMs >= num * 2.0)
|
|
{
|
|
TextBlock element5 = new TextBlock
|
|
{
|
|
Text = "\ud83d\udd34",
|
|
FontSize = 9.0
|
|
};
|
|
Canvas.SetLeft(element5, num4 + 8.0 + num9 + num10 + 44.0);
|
|
Canvas.SetTop(element5, num8 + 2);
|
|
WaterfallCanvas.Children.Add(element5);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void RenderToolTimeChart()
|
|
{
|
|
ToolTimePanel.Children.Clear();
|
|
if (_toolTimeAccum.Count == 0)
|
|
{
|
|
ToolTimePanel.Children.Add(new TextBlock
|
|
{
|
|
Text = "도구 실행 데이터가 없습니다",
|
|
FontSize = 11.0,
|
|
Foreground = ((TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray),
|
|
Margin = new Thickness(0.0, 4.0, 0.0, 4.0)
|
|
});
|
|
return;
|
|
}
|
|
long num = _waterfallEntries.Where((WaterfallEntry e) => e.Type == "llm").Sum((WaterfallEntry e) => e.DurationMs);
|
|
List<(string, long)> list = _toolTimeAccum.Select<KeyValuePair<string, long>, (string, long)>((KeyValuePair<string, long> kv) => (Name: kv.Key, Ms: kv.Value)).ToList();
|
|
if (num > 0)
|
|
{
|
|
list.Add(("LLM 호출", num));
|
|
}
|
|
List<(string, long)> list2 = list.OrderByDescending<(string, long), long>(((string Name, long Ms) e) => e.Ms).ToList();
|
|
long num2 = list2.Max<(string, long)>(((string Name, long Ms) e) => e.Ms);
|
|
if (num2 <= 0)
|
|
{
|
|
num2 = 1L;
|
|
}
|
|
foreach (var item3 in list2)
|
|
{
|
|
string item = item3.Item1;
|
|
long item2 = item3.Item2;
|
|
bool flag = item2 == list2[0].Item2;
|
|
Color color = ((item == "LLM 호출") ? Color.FromRgb(96, 165, 250) : (flag ? Color.FromRgb(239, 68, 68) : Color.FromRgb(52, 211, 153)));
|
|
Grid grid = new Grid
|
|
{
|
|
Margin = new Thickness(0.0, 2.0, 0.0, 2.0)
|
|
};
|
|
grid.ColumnDefinitions.Add(new ColumnDefinition
|
|
{
|
|
Width = new GridLength(90.0)
|
|
});
|
|
grid.ColumnDefinitions.Add(new ColumnDefinition
|
|
{
|
|
Width = new GridLength(1.0, GridUnitType.Star)
|
|
});
|
|
grid.ColumnDefinitions.Add(new ColumnDefinition
|
|
{
|
|
Width = new GridLength(60.0)
|
|
});
|
|
TextBlock element = new TextBlock
|
|
{
|
|
Text = Truncate(item, 12),
|
|
FontSize = 11.0,
|
|
FontFamily = new FontFamily("Consolas"),
|
|
Foreground = new SolidColorBrush(color),
|
|
TextAlignment = TextAlignment.Right,
|
|
VerticalAlignment = VerticalAlignment.Center,
|
|
Margin = new Thickness(0.0, 0.0, 8.0, 0.0)
|
|
};
|
|
Grid.SetColumn(element, 0);
|
|
double barWidth = (double)item2 / (double)num2;
|
|
Border barBorder = new Border
|
|
{
|
|
Background = new SolidColorBrush(color),
|
|
CornerRadius = new CornerRadius(3.0),
|
|
Height = 14.0,
|
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|
Width = 0.0,
|
|
Opacity = 0.8
|
|
};
|
|
Border barContainer = new Border
|
|
{
|
|
Margin = new Thickness(0.0, 2.0, 0.0, 2.0)
|
|
};
|
|
barContainer.Child = barBorder;
|
|
barContainer.SizeChanged += delegate
|
|
{
|
|
barBorder.Width = Math.Max(barContainer.ActualWidth * barWidth, 4.0);
|
|
};
|
|
Grid.SetColumn(barContainer, 1);
|
|
TextBlock element2 = new TextBlock
|
|
{
|
|
Text = FormatMs(item2),
|
|
FontSize = 10.0,
|
|
Foreground = new SolidColorBrush(color),
|
|
FontFamily = new FontFamily("Consolas"),
|
|
VerticalAlignment = VerticalAlignment.Center,
|
|
Margin = new Thickness(4.0, 0.0, 0.0, 0.0)
|
|
};
|
|
Grid.SetColumn(element2, 2);
|
|
grid.Children.Add(element);
|
|
grid.Children.Add(barContainer);
|
|
grid.Children.Add(element2);
|
|
ToolTimePanel.Children.Add(grid);
|
|
}
|
|
}
|
|
|
|
private void RenderTokenTrendChart()
|
|
{
|
|
TokenTrendCanvas.Children.Clear();
|
|
if (_tokenTrend.Count < 2)
|
|
{
|
|
TokenTrendCanvas.Height = 40.0;
|
|
TokenTrendCanvas.Children.Add(new TextBlock
|
|
{
|
|
Text = ((_tokenTrend.Count == 0) ? "토큰 데이터가 없습니다" : "2회 이상 반복이 필요합니다"),
|
|
FontSize = 11.0,
|
|
Foreground = ((TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray)
|
|
});
|
|
Canvas.SetLeft(TokenTrendCanvas.Children[0], 10.0);
|
|
Canvas.SetTop(TokenTrendCanvas.Children[0], 10.0);
|
|
return;
|
|
}
|
|
TokenTrendCanvas.Height = 100.0;
|
|
double num = ((TokenTrendCanvas.ActualWidth > 0.0) ? TokenTrendCanvas.ActualWidth : 480.0);
|
|
double canvasHeight = 90.0;
|
|
double marginLeft = 45.0;
|
|
double num2 = 10.0;
|
|
double chartWidth = num - marginLeft - num2;
|
|
List<(int Iteration, int Input, int Output)> sorted = _tokenTrend.OrderBy(((int Iteration, int Input, int Output) t) => t.Iteration).ToList();
|
|
int maxToken = sorted.Max(((int Iteration, int Input, int Output) t) => Math.Max(t.Input, t.Output));
|
|
if (maxToken <= 0)
|
|
{
|
|
maxToken = 1;
|
|
}
|
|
for (int num3 = 0; num3 <= 2; num3++)
|
|
{
|
|
double num4 = canvasHeight * (1.0 - (double)num3 / 2.0);
|
|
int num5 = maxToken * num3 / 2;
|
|
Line line = new Line();
|
|
line.X1 = marginLeft;
|
|
line.Y1 = num4;
|
|
line.X2 = num - num2;
|
|
line.Y2 = num4;
|
|
line.Stroke = (TryFindResource("BorderColor") as Brush) ?? Brushes.Gray;
|
|
line.StrokeThickness = 0.5;
|
|
line.Opacity = 0.4;
|
|
Line element = line;
|
|
TokenTrendCanvas.Children.Add(element);
|
|
TextBlock textBlock = new TextBlock();
|
|
textBlock.Text = ((num5 >= 1000) ? $"{(double)num5 / 1000.0:F0}k" : num5.ToString());
|
|
textBlock.FontSize = 9.0;
|
|
textBlock.Foreground = (TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray;
|
|
textBlock.TextAlignment = TextAlignment.Right;
|
|
textBlock.Width = marginLeft - 6.0;
|
|
TextBlock element2 = textBlock;
|
|
Canvas.SetLeft(element2, 0.0);
|
|
Canvas.SetTop(element2, num4 - 6.0);
|
|
TokenTrendCanvas.Children.Add(element2);
|
|
}
|
|
DrawPolyline(((IEnumerable<(int, int, int)>)sorted).Select((Func<(int, int, int), int, Point>)(((int Iteration, int Input, int Output) t, int i) => new Point(marginLeft + (double)i / (double)(sorted.Count - 1) * chartWidth, canvasHeight * (1.0 - (double)t.Input / (double)maxToken)))).ToList(), "#3B82F6");
|
|
DrawPolyline(((IEnumerable<(int, int, int)>)sorted).Select((Func<(int, int, int), int, Point>)(((int Iteration, int Input, int Output) t, int i) => new Point(marginLeft + (double)i / (double)(sorted.Count - 1) * chartWidth, canvasHeight * (1.0 - (double)t.Output / (double)maxToken)))).ToList(), "#10B981");
|
|
foreach (var item in sorted)
|
|
{
|
|
int iter = item.Iteration;
|
|
int num6 = sorted.FindIndex(((int Iteration, int Input, int Output) t) => t.Iteration == iter);
|
|
double num7 = marginLeft + (double)num6 / (double)(sorted.Count - 1) * chartWidth;
|
|
TextBlock textBlock = new TextBlock();
|
|
textBlock.Text = $"#{iter}";
|
|
textBlock.FontSize = 9.0;
|
|
textBlock.Foreground = (TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray;
|
|
TextBlock element3 = textBlock;
|
|
Canvas.SetLeft(element3, num7 - 8.0);
|
|
Canvas.SetTop(element3, canvasHeight + 2.0);
|
|
TokenTrendCanvas.Children.Add(element3);
|
|
}
|
|
StackPanel stackPanel = new StackPanel
|
|
{
|
|
Orientation = Orientation.Horizontal
|
|
};
|
|
stackPanel.Children.Add(CreateLegendDot("#3B82F6", "입력"));
|
|
stackPanel.Children.Add(CreateLegendDot("#10B981", "출력"));
|
|
Canvas.SetRight(stackPanel, 10.0);
|
|
Canvas.SetTop(stackPanel, 0.0);
|
|
TokenTrendCanvas.Children.Add(stackPanel);
|
|
if (sorted.Count < 3)
|
|
{
|
|
return;
|
|
}
|
|
List<int> list = sorted.Select(((int Iteration, int Input, int Output) t) => t.Input).ToList();
|
|
bool flag = true;
|
|
for (int num8 = 1; num8 < list.Count; num8++)
|
|
{
|
|
if (list[num8] <= list[num8 - 1])
|
|
{
|
|
flag = false;
|
|
break;
|
|
}
|
|
}
|
|
if (flag)
|
|
{
|
|
if (list[list.Count - 1] > list[0] * 2)
|
|
{
|
|
TextBlock element4 = new TextBlock
|
|
{
|
|
Text = "⚠ 컨텍스트 크기 급증",
|
|
FontSize = 10.0,
|
|
Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68)),
|
|
FontWeight = FontWeights.SemiBold
|
|
};
|
|
Canvas.SetLeft(element4, marginLeft + 4.0);
|
|
Canvas.SetTop(element4, 0.0);
|
|
TokenTrendCanvas.Children.Add(element4);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawPolyline(List<Point> points, string colorHex)
|
|
{
|
|
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
|
|
if (points.Count < 2)
|
|
{
|
|
return;
|
|
}
|
|
Color color = (Color)ColorConverter.ConvertFromString(colorHex);
|
|
Polyline polyline = new Polyline
|
|
{
|
|
Stroke = new SolidColorBrush(color),
|
|
StrokeThickness = 2.0,
|
|
StrokeLineJoin = PenLineJoin.Round
|
|
};
|
|
foreach (Point point in points)
|
|
{
|
|
polyline.Points.Add(point);
|
|
}
|
|
TokenTrendCanvas.Children.Add(polyline);
|
|
foreach (Point point2 in points)
|
|
{
|
|
Point current2 = point2;
|
|
Ellipse element = new Ellipse
|
|
{
|
|
Width = 6.0,
|
|
Height = 6.0,
|
|
Fill = new SolidColorBrush(color)
|
|
};
|
|
Canvas.SetLeft(element, ((Point)(ref current2)).X - 3.0);
|
|
Canvas.SetTop(element, ((Point)(ref current2)).Y - 3.0);
|
|
TokenTrendCanvas.Children.Add(element);
|
|
}
|
|
}
|
|
|
|
private static StackPanel CreateLegendDot(string colorHex, string text)
|
|
{
|
|
Color color = (Color)ColorConverter.ConvertFromString(colorHex);
|
|
StackPanel stackPanel = new StackPanel
|
|
{
|
|
Orientation = Orientation.Horizontal,
|
|
Margin = new Thickness(8.0, 0.0, 0.0, 0.0)
|
|
};
|
|
stackPanel.Children.Add(new Ellipse
|
|
{
|
|
Width = 6.0,
|
|
Height = 6.0,
|
|
Fill = new SolidColorBrush(color),
|
|
VerticalAlignment = VerticalAlignment.Center,
|
|
Margin = new Thickness(0.0, 0.0, 3.0, 0.0)
|
|
});
|
|
stackPanel.Children.Add(new TextBlock
|
|
{
|
|
Text = text,
|
|
FontSize = 9.0,
|
|
Foreground = new SolidColorBrush(color),
|
|
VerticalAlignment = VerticalAlignment.Center
|
|
});
|
|
return stackPanel;
|
|
}
|
|
|
|
private Border CreateTimelineNode(AgentEvent evt)
|
|
{
|
|
(string Icon, Color Color, string Label) eventVisual = GetEventVisual(evt);
|
|
string item = eventVisual.Icon;
|
|
Color item2 = eventVisual.Color;
|
|
string item3 = eventVisual.Label;
|
|
Border node = new Border
|
|
{
|
|
Background = Brushes.Transparent,
|
|
Margin = new Thickness(0.0, 1.0, 0.0, 1.0),
|
|
Padding = new Thickness(8.0, 6.0, 8.0, 6.0),
|
|
CornerRadius = new CornerRadius(8.0),
|
|
Cursor = Cursors.Hand,
|
|
Tag = evt
|
|
};
|
|
Grid grid = new Grid();
|
|
grid.ColumnDefinitions.Add(new ColumnDefinition
|
|
{
|
|
Width = new GridLength(28.0)
|
|
});
|
|
grid.ColumnDefinitions.Add(new ColumnDefinition
|
|
{
|
|
Width = new GridLength(3.0)
|
|
});
|
|
grid.ColumnDefinitions.Add(new ColumnDefinition
|
|
{
|
|
Width = new GridLength(1.0, GridUnitType.Star)
|
|
});
|
|
Border border = new Border
|
|
{
|
|
Width = 22.0,
|
|
Height = 22.0,
|
|
CornerRadius = new CornerRadius(11.0),
|
|
Background = new SolidColorBrush(item2),
|
|
HorizontalAlignment = HorizontalAlignment.Center,
|
|
VerticalAlignment = VerticalAlignment.Top,
|
|
Margin = new Thickness(0.0, 2.0, 0.0, 0.0)
|
|
};
|
|
border.Child = new TextBlock
|
|
{
|
|
Text = item,
|
|
FontFamily = new FontFamily("Segoe MDL2 Assets"),
|
|
FontSize = 10.0,
|
|
Foreground = Brushes.White,
|
|
HorizontalAlignment = HorizontalAlignment.Center,
|
|
VerticalAlignment = VerticalAlignment.Center
|
|
};
|
|
Grid.SetColumn(border, 0);
|
|
grid.Children.Add(border);
|
|
Rectangle rectangle = new Rectangle();
|
|
rectangle.Width = 2.0;
|
|
rectangle.Fill = (TryFindResource("BorderColor") as Brush) ?? Brushes.Gray;
|
|
rectangle.HorizontalAlignment = HorizontalAlignment.Center;
|
|
rectangle.VerticalAlignment = VerticalAlignment.Stretch;
|
|
rectangle.Opacity = 0.4;
|
|
Rectangle element = rectangle;
|
|
Grid.SetColumn(element, 1);
|
|
grid.Children.Add(element);
|
|
StackPanel stackPanel = new StackPanel
|
|
{
|
|
Margin = new Thickness(8.0, 0.0, 0.0, 0.0)
|
|
};
|
|
StackPanel stackPanel2 = new StackPanel
|
|
{
|
|
Orientation = Orientation.Horizontal
|
|
};
|
|
stackPanel2.Children.Add(new TextBlock
|
|
{
|
|
Text = item3,
|
|
FontSize = 12.0,
|
|
FontWeight = FontWeights.SemiBold,
|
|
Foreground = ((TryFindResource("PrimaryText") as Brush) ?? Brushes.White),
|
|
VerticalAlignment = VerticalAlignment.Center
|
|
});
|
|
if (evt.ElapsedMs > 0)
|
|
{
|
|
stackPanel2.Children.Add(new TextBlock
|
|
{
|
|
Text = ((evt.ElapsedMs >= 1000) ? $" {(double)evt.ElapsedMs / 1000.0:F1}s" : $" {evt.ElapsedMs}ms"),
|
|
FontSize = 10.0,
|
|
Foreground = ((evt.ElapsedMs > 3000) ? Brushes.OrangeRed : ((TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray)),
|
|
VerticalAlignment = VerticalAlignment.Center
|
|
});
|
|
}
|
|
stackPanel2.Children.Add(new TextBlock
|
|
{
|
|
Text = $" {evt.Timestamp:HH:mm:ss}",
|
|
FontSize = 9.0,
|
|
Foreground = ((TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray),
|
|
VerticalAlignment = VerticalAlignment.Center,
|
|
Opacity = 0.6
|
|
});
|
|
stackPanel.Children.Add(stackPanel2);
|
|
if (!string.IsNullOrEmpty(evt.Summary))
|
|
{
|
|
stackPanel.Children.Add(new TextBlock
|
|
{
|
|
Text = Truncate(evt.Summary, 120),
|
|
FontSize = 11.0,
|
|
Foreground = ((TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray),
|
|
TextWrapping = TextWrapping.Wrap,
|
|
Margin = new Thickness(0.0, 2.0, 0.0, 0.0),
|
|
LineHeight = 16.0
|
|
});
|
|
}
|
|
if (evt.InputTokens > 0 || evt.OutputTokens > 0)
|
|
{
|
|
StackPanel stackPanel3 = new StackPanel
|
|
{
|
|
Orientation = Orientation.Horizontal,
|
|
Margin = new Thickness(0.0, 3.0, 0.0, 0.0)
|
|
};
|
|
stackPanel3.Children.Add(CreateBadge($"↑{evt.InputTokens:#,0}", "#3B82F6"));
|
|
stackPanel3.Children.Add(CreateBadge($"↓{evt.OutputTokens:#,0}", "#10B981"));
|
|
stackPanel.Children.Add(stackPanel3);
|
|
}
|
|
Grid.SetColumn(stackPanel, 2);
|
|
grid.Children.Add(stackPanel);
|
|
node.Child = grid;
|
|
Brush hoverBrush = (TryFindResource("ItemHoverBackground") as Brush) ?? new SolidColorBrush(Color.FromArgb(24, byte.MaxValue, byte.MaxValue, byte.MaxValue));
|
|
node.MouseEnter += delegate
|
|
{
|
|
node.Background = hoverBrush;
|
|
};
|
|
node.MouseLeave += delegate
|
|
{
|
|
node.Background = Brushes.Transparent;
|
|
};
|
|
node.MouseLeftButtonUp += delegate
|
|
{
|
|
ShowDetail(evt);
|
|
};
|
|
return node;
|
|
}
|
|
|
|
private static (string Icon, Color Color, string Label) GetEventVisual(AgentEvent evt)
|
|
{
|
|
AgentEventType type = evt.Type;
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
(string, Color, string) result = type switch
|
|
{
|
|
AgentEventType.Thinking => ("\ue7ba", Color.FromRgb(96, 165, 250), "사고"),
|
|
AgentEventType.Planning => ("\ue9d5", Color.FromRgb(167, 139, 250), "계획"),
|
|
AgentEventType.StepStart => ("\ue72a", Color.FromRgb(96, 165, 250), $"단계 {evt.StepCurrent}/{evt.StepTotal}"),
|
|
AgentEventType.StepDone => ("\ue73e", Color.FromRgb(52, 211, 153), "단계 완료"),
|
|
AgentEventType.ToolCall => ("\ue756", Color.FromRgb(251, 191, 36), evt.ToolName),
|
|
AgentEventType.ToolResult => ("\ue73e", Color.FromRgb(52, 211, 153), evt.ToolName + " ✓"),
|
|
AgentEventType.SkillCall => ("\ue768", Color.FromRgb(167, 139, 250), "스킬: " + evt.ToolName),
|
|
AgentEventType.Error => ("\ue783", Color.FromRgb(248, 113, 113), evt.ToolName + " ✗"),
|
|
AgentEventType.Complete => ("\ue930", Color.FromRgb(52, 211, 153), "완료"),
|
|
AgentEventType.Decision => ("\ue8c8", Color.FromRgb(251, 191, 36), "의사결정"),
|
|
_ => ("\ue946", Color.FromRgb(107, 114, 128), "이벤트"),
|
|
};
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Border CreateBadge(string text, string colorHex)
|
|
{
|
|
Color color = (Color)ColorConverter.ConvertFromString(colorHex);
|
|
return new Border
|
|
{
|
|
Background = new SolidColorBrush(Color.FromArgb(48, color.R, color.G, color.B)),
|
|
CornerRadius = new CornerRadius(4.0),
|
|
Padding = new Thickness(5.0, 1.0, 5.0, 1.0),
|
|
Margin = new Thickness(0.0, 0.0, 4.0, 0.0),
|
|
Child = new TextBlock
|
|
{
|
|
Text = text,
|
|
FontSize = 9.0,
|
|
Foreground = new SolidColorBrush(color),
|
|
FontWeight = FontWeights.SemiBold
|
|
}
|
|
};
|
|
}
|
|
|
|
private void ShowDetail(AgentEvent evt)
|
|
{
|
|
DetailPanel.Visibility = Visibility.Visible;
|
|
DetailPanel.Tag = evt;
|
|
(string Icon, Color Color, string Label) eventVisual = GetEventVisual(evt);
|
|
Color item = eventVisual.Color;
|
|
string item2 = eventVisual.Label;
|
|
DetailTitle.Text = item2;
|
|
DetailBadge.Text = (evt.Success ? "성공" : "실패");
|
|
DetailBadge.Background = new SolidColorBrush(evt.Success ? Color.FromRgb(52, 211, 153) : Color.FromRgb(248, 113, 113));
|
|
string text = $"시간: {evt.Timestamp:HH:mm:ss.fff}";
|
|
if (evt.ElapsedMs > 0)
|
|
{
|
|
text = text + " | 소요: " + ((evt.ElapsedMs >= 1000) ? $"{(double)evt.ElapsedMs / 1000.0:F1}s" : $"{evt.ElapsedMs}ms");
|
|
}
|
|
if (evt.InputTokens > 0 || evt.OutputTokens > 0)
|
|
{
|
|
text += $" | 토큰: 입력 {evt.InputTokens:#,0} / 출력 {evt.OutputTokens:#,0}";
|
|
}
|
|
if (evt.Iteration > 0)
|
|
{
|
|
text += $" | 반복 #{evt.Iteration}";
|
|
}
|
|
DetailMeta.Text = text;
|
|
string text2 = evt.Summary ?? "";
|
|
if (!string.IsNullOrEmpty(evt.ToolInput))
|
|
{
|
|
text2 = text2 + "\n\n파라미터:\n" + Truncate(evt.ToolInput, 500);
|
|
}
|
|
if (!string.IsNullOrEmpty(evt.FilePath))
|
|
{
|
|
text2 = text2 + "\n파일: " + evt.FilePath;
|
|
}
|
|
DetailContent.Text = text2;
|
|
}
|
|
|
|
private void UpdateSummaryCards()
|
|
{
|
|
double totalSeconds = (DateTime.Now - _startTime).TotalSeconds;
|
|
CardElapsed.Text = ((totalSeconds >= 60.0) ? $"{totalSeconds / 60.0:F0}m {totalSeconds % 60.0:F0}s" : $"{totalSeconds:F1}s");
|
|
CardIterations.Text = _maxIteration.ToString();
|
|
int num = _totalInputTokens + _totalOutputTokens;
|
|
CardTokens.Text = ((num >= 1000) ? $"{(double)num / 1000.0:F1}k" : num.ToString());
|
|
CardInputTokens.Text = ((_totalInputTokens >= 1000) ? $"{(double)_totalInputTokens / 1000.0:F1}k" : _totalInputTokens.ToString());
|
|
CardOutputTokens.Text = ((_totalOutputTokens >= 1000) ? $"{(double)_totalOutputTokens / 1000.0:F1}k" : _totalOutputTokens.ToString());
|
|
CardToolCalls.Text = _totalToolCalls.ToString();
|
|
}
|
|
|
|
private static string FormatMs(long ms)
|
|
{
|
|
return (ms >= 1000) ? $"{(double)ms / 1000.0:F1}s" : $"{ms}ms";
|
|
}
|
|
|
|
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
|
{
|
|
object originalSource = e.OriginalSource;
|
|
DependencyObject val = (DependencyObject)((originalSource is DependencyObject) ? originalSource : null);
|
|
while (val != null && val != sender)
|
|
{
|
|
Border border = val as Border;
|
|
bool flag = border != null;
|
|
bool flag2 = flag;
|
|
if (flag2)
|
|
{
|
|
bool flag3;
|
|
switch (border.Name)
|
|
{
|
|
case "BtnClose":
|
|
case "BtnMinimize":
|
|
case "BtnClear":
|
|
flag3 = true;
|
|
break;
|
|
default:
|
|
flag3 = false;
|
|
break;
|
|
}
|
|
flag2 = flag3;
|
|
}
|
|
if (flag2)
|
|
{
|
|
return;
|
|
}
|
|
val = VisualTreeHelper.GetParent(val);
|
|
}
|
|
if (e.ClickCount == 1)
|
|
{
|
|
DragMove();
|
|
}
|
|
}
|
|
|
|
private void BtnClose_Click(object sender, MouseButtonEventArgs e)
|
|
{
|
|
Hide();
|
|
}
|
|
|
|
private void BtnMinimize_Click(object sender, MouseButtonEventArgs e)
|
|
{
|
|
base.WindowState = WindowState.Minimized;
|
|
}
|
|
|
|
private void BtnClear_Click(object sender, MouseButtonEventArgs e)
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
private void TitleBtn_MouseEnter(object sender, MouseEventArgs e)
|
|
{
|
|
if (sender is Border border)
|
|
{
|
|
border.Background = (TryFindResource("ItemHoverBackground") as Brush) ?? new SolidColorBrush(Color.FromArgb(24, byte.MaxValue, byte.MaxValue, byte.MaxValue));
|
|
}
|
|
}
|
|
|
|
private void TitleBtn_MouseLeave(object sender, MouseEventArgs e)
|
|
{
|
|
if (sender is Border border)
|
|
{
|
|
border.Background = Brushes.Transparent;
|
|
}
|
|
}
|
|
|
|
private static string Truncate(string text, int maxLen)
|
|
{
|
|
return (text.Length <= maxLen) ? text : (text.Substring(0, maxLen) + "…");
|
|
}
|
|
|
|
private nint WndProc(nint hwnd, int msg, nint wParam, nint lParam, ref bool handled)
|
|
{
|
|
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
|
|
if (msg == 132)
|
|
{
|
|
Point val = PointFromScreen(new Point((double)(short)(((IntPtr)lParam).ToInt32() & 0xFFFF), (double)(short)((((IntPtr)lParam).ToInt32() >> 16) & 0xFFFF)));
|
|
double actualWidth = base.ActualWidth;
|
|
double actualHeight = base.ActualHeight;
|
|
if (((Point)(ref val)).X < 8.0 && ((Point)(ref val)).Y < 8.0)
|
|
{
|
|
handled = true;
|
|
return 13;
|
|
}
|
|
if (((Point)(ref val)).X > actualWidth - 8.0 && ((Point)(ref val)).Y < 8.0)
|
|
{
|
|
handled = true;
|
|
return 14;
|
|
}
|
|
if (((Point)(ref val)).X < 8.0 && ((Point)(ref val)).Y > actualHeight - 8.0)
|
|
{
|
|
handled = true;
|
|
return 16;
|
|
}
|
|
if (((Point)(ref val)).X > actualWidth - 8.0 && ((Point)(ref val)).Y > actualHeight - 8.0)
|
|
{
|
|
handled = true;
|
|
return 17;
|
|
}
|
|
if (((Point)(ref val)).X < 8.0)
|
|
{
|
|
handled = true;
|
|
return 10;
|
|
}
|
|
if (((Point)(ref val)).X > actualWidth - 8.0)
|
|
{
|
|
handled = true;
|
|
return 11;
|
|
}
|
|
if (((Point)(ref val)).Y < 8.0)
|
|
{
|
|
handled = true;
|
|
return 12;
|
|
}
|
|
if (((Point)(ref val)).Y > actualHeight - 8.0)
|
|
{
|
|
handled = true;
|
|
return 15;
|
|
}
|
|
}
|
|
return IntPtr.Zero;
|
|
}
|
|
|
|
[DebuggerNonUserCode]
|
|
[GeneratedCode("PresentationBuildTasks", "10.0.5.0")]
|
|
public void InitializeComponent()
|
|
{
|
|
if (!_contentLoaded)
|
|
{
|
|
_contentLoaded = true;
|
|
Uri resourceLocator = new Uri("/AxCopilot;component/views/workflowanalyzerwindow.xaml", UriKind.Relative);
|
|
Application.LoadComponent(this, resourceLocator);
|
|
}
|
|
}
|
|
|
|
[DebuggerNonUserCode]
|
|
[GeneratedCode("PresentationBuildTasks", "10.0.5.0")]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
void IComponentConnector.Connect(int connectionId, object target)
|
|
{
|
|
switch (connectionId)
|
|
{
|
|
case 1:
|
|
((Grid)target).MouseLeftButtonDown += TitleBar_MouseLeftButtonDown;
|
|
break;
|
|
case 2:
|
|
BtnClear = (Border)target;
|
|
BtnClear.MouseLeftButtonUp += BtnClear_Click;
|
|
BtnClear.MouseEnter += TitleBtn_MouseEnter;
|
|
BtnClear.MouseLeave += TitleBtn_MouseLeave;
|
|
break;
|
|
case 3:
|
|
BtnMinimize = (Border)target;
|
|
BtnMinimize.MouseLeftButtonUp += BtnMinimize_Click;
|
|
BtnMinimize.MouseEnter += TitleBtn_MouseEnter;
|
|
BtnMinimize.MouseLeave += TitleBtn_MouseLeave;
|
|
break;
|
|
case 4:
|
|
BtnClose = (Border)target;
|
|
BtnClose.MouseLeftButtonUp += BtnClose_Click;
|
|
BtnClose.MouseEnter += TitleBtn_MouseEnter;
|
|
BtnClose.MouseLeave += TitleBtn_MouseLeave;
|
|
break;
|
|
case 5:
|
|
CardElapsed = (TextBlock)target;
|
|
break;
|
|
case 6:
|
|
CardIterations = (TextBlock)target;
|
|
break;
|
|
case 7:
|
|
CardTokens = (TextBlock)target;
|
|
break;
|
|
case 8:
|
|
CardInputTokens = (TextBlock)target;
|
|
break;
|
|
case 9:
|
|
CardOutputTokens = (TextBlock)target;
|
|
break;
|
|
case 10:
|
|
CardToolCalls = (TextBlock)target;
|
|
break;
|
|
case 11:
|
|
TabTimeline = (Border)target;
|
|
TabTimeline.MouseLeftButtonUp += TabTimeline_Click;
|
|
break;
|
|
case 12:
|
|
TabTimelineIcon = (TextBlock)target;
|
|
break;
|
|
case 13:
|
|
TabTimelineText = (TextBlock)target;
|
|
break;
|
|
case 14:
|
|
TabBottleneck = (Border)target;
|
|
TabBottleneck.MouseLeftButtonUp += TabBottleneck_Click;
|
|
break;
|
|
case 15:
|
|
TabBottleneckIcon = (TextBlock)target;
|
|
break;
|
|
case 16:
|
|
TabBottleneckText = (TextBlock)target;
|
|
break;
|
|
case 17:
|
|
TimelineScroller = (ScrollViewer)target;
|
|
break;
|
|
case 18:
|
|
TimelinePanel = (StackPanel)target;
|
|
break;
|
|
case 19:
|
|
BottleneckScroller = (ScrollViewer)target;
|
|
break;
|
|
case 20:
|
|
BottleneckPanel = (StackPanel)target;
|
|
break;
|
|
case 21:
|
|
WaterfallCanvas = (Canvas)target;
|
|
break;
|
|
case 22:
|
|
ToolTimePanel = (StackPanel)target;
|
|
break;
|
|
case 23:
|
|
TokenTrendCanvas = (Canvas)target;
|
|
break;
|
|
case 24:
|
|
DetailPanel = (Border)target;
|
|
break;
|
|
case 25:
|
|
DetailTitle = (TextBlock)target;
|
|
break;
|
|
case 26:
|
|
DetailBadge = (TextBlock)target;
|
|
break;
|
|
case 27:
|
|
DetailMeta = (TextBlock)target;
|
|
break;
|
|
case 28:
|
|
DetailContent = (TextBlock)target;
|
|
break;
|
|
case 29:
|
|
StatusText = (TextBlock)target;
|
|
break;
|
|
case 30:
|
|
LogLevelBadge = (TextBlock)target;
|
|
break;
|
|
default:
|
|
_contentLoaded = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|