using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Effects; using System.Windows.Threading; namespace AxCopilot.Services.Agent; public class NotifyTool : IAgentTool { public string Name => "notify_tool"; public string Description => "Send a notification to the user. Use this when: a long-running task completes, an important result needs attention, or you want to inform the user of something. The notification appears as an in-app toast message."; public ToolParameterSchema Parameters { get { ToolParameterSchema toolParameterSchema = new ToolParameterSchema(); Dictionary obj = new Dictionary { ["title"] = new ToolProperty { Type = "string", Description = "Notification title (short, 1-2 words)" }, ["message"] = new ToolProperty { Type = "string", Description = "Notification message (detail text)" } }; ToolProperty obj2 = new ToolProperty { Type = "string", Description = "Notification level: info (default), success, warning, error" }; int num = 4; List list = new List(num); CollectionsMarshal.SetCount(list, num); Span span = CollectionsMarshal.AsSpan(list); span[0] = "info"; span[1] = "success"; span[2] = "warning"; span[3] = "error"; obj2.Enum = list; obj["level"] = obj2; toolParameterSchema.Properties = obj; num = 2; List list2 = new List(num); CollectionsMarshal.SetCount(list2, num); Span span2 = CollectionsMarshal.AsSpan(list2); span2[0] = "title"; span2[1] = "message"; toolParameterSchema.Required = list2; return toolParameterSchema; } } public Task ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default(CancellationToken)) { string title = args.GetProperty("title").GetString() ?? "알림"; string message = args.GetProperty("message").GetString() ?? ""; JsonElement value; string level = (args.TryGetProperty("level", out value) ? (value.GetString() ?? "info") : "info"); try { ((DispatcherObject)Application.Current).Dispatcher.Invoke((Action)delegate { ShowToast(title, message, level); }); return Task.FromResult(ToolResult.Ok("✓ Notification sent: [" + level + "] " + title)); } catch (Exception ex) { return Task.FromResult(ToolResult.Fail("알림 전송 실패: " + ex.Message)); } } private static void ShowToast(string title, string message, string level) { //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Expected O, but got Unknown Window mainWindow = Application.Current.MainWindow; if (mainWindow == null) { return; } if (1 == 0) { } (string, string) tuple = level switch { "success" => ("\ue73e", "#34D399"), "warning" => ("\ue7ba", "#F59E0B"), "error" => ("\uea39", "#F87171"), _ => ("\ue946", "#4B5EFC"), }; if (1 == 0) { } (string, string) tuple2 = tuple; string item = tuple2.Item1; string item2 = tuple2.Item2; Border toast = new Border { Background = new SolidColorBrush(Color.FromRgb(26, 27, 46)), CornerRadius = new CornerRadius(10.0), Padding = new Thickness(16.0, 12.0, 16.0, 12.0), Margin = new Thickness(0.0, 0.0, 20.0, 20.0), MinWidth = 280.0, MaxWidth = 400.0, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Bottom, Effect = new DropShadowEffect { BlurRadius = 16.0, ShadowDepth = 4.0, Opacity = 0.4, Color = Colors.Black } }; StackPanel stackPanel = new StackPanel(); StackPanel stackPanel2 = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0.0, 0.0, 0.0, 4.0) }; stackPanel2.Children.Add(new TextBlock { Text = item, FontFamily = new FontFamily("Segoe MDL2 Assets"), FontSize = 14.0, Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(item2)), Margin = new Thickness(0.0, 0.0, 8.0, 0.0), VerticalAlignment = VerticalAlignment.Center }); stackPanel2.Children.Add(new TextBlock { Text = title, FontSize = 13.0, FontWeight = FontWeights.SemiBold, Foreground = Brushes.White, VerticalAlignment = VerticalAlignment.Center }); stackPanel.Children.Add(stackPanel2); if (!string.IsNullOrEmpty(message)) { stackPanel.Children.Add(new TextBlock { Text = ((message.Length > 200) ? (message.Substring(0, 200) + "...") : message), FontSize = 12.0, Foreground = new SolidColorBrush(Color.FromRgb(170, 170, 204)), TextWrapping = TextWrapping.Wrap }); } toast.Child = stackPanel; object content = mainWindow.Content; Grid grid = content as Grid; if (grid != null) { Grid.SetRowSpan(toast, (grid.RowDefinitions.Count <= 0) ? 1 : grid.RowDefinitions.Count); Grid.SetColumnSpan(toast, (grid.ColumnDefinitions.Count <= 0) ? 1 : grid.ColumnDefinitions.Count); grid.Children.Add(toast); DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5.0) }; timer.Tick += delegate { timer.Stop(); grid.Children.Remove(toast); }; timer.Start(); } } }