diff --git a/LinkToolAddin.csproj b/LinkToolAddin.csproj index 0f3f990..bece90c 100644 --- a/LinkToolAddin.csproj +++ b/LinkToolAddin.csproj @@ -120,6 +120,26 @@ Always + + + Always + + + + Always + + + + Always + + + + Always + + + + Always + diff --git a/common/LocalResource.cs b/common/LocalResource.cs index fc1e719..4f4e53a 100644 --- a/common/LocalResource.cs +++ b/common/LocalResource.cs @@ -1,5 +1,7 @@ using System; using System.IO; +using System.Windows.Controls; +using System.Windows.Media.Imaging; namespace LinkToolAddin.common; @@ -8,12 +10,6 @@ public class LocalResource public static string ReadFileByResource(string resourceName) { var assembly = System.Reflection.Assembly.GetExecutingAssembly(); - - string[] resourceNames = assembly.GetManifestResourceNames(); - foreach (string name in resourceNames) - { - Console.WriteLine(name); - } using (Stream stream = assembly.GetManifestResourceStream(resourceName)) { @@ -28,4 +24,24 @@ public class LocalResource } } } + + public static BitmapImage ReadImageByResource(string resourceName) + { + var assembly = System.Reflection.Assembly.GetExecutingAssembly(); + using (Stream stream = assembly.GetManifestResourceStream(resourceName)) + { + if (stream == null) + { + Console.WriteLine("资源未找到,请检查资源名称是否正确。"); + return null; + } + + // 如果是 WPF,可以转换为 BitmapImage + BitmapImage bitmap = new BitmapImage(); + bitmap.BeginInit(); + bitmap.StreamSource = stream; + bitmap.EndInit(); + return bitmap; + } + } } \ No newline at end of file diff --git a/host/Gateway.cs b/host/Gateway.cs index 2a789c5..78889e8 100644 --- a/host/Gateway.cs +++ b/host/Gateway.cs @@ -282,12 +282,28 @@ public class Gateway { //如果本次回复不包含任何工具的调用或提示词的调用,则不再请求 goOn = false; + MessageListItem endMessageListItem1 = new ChatMessageItem + { + type = MessageType.END_TAG, + content = "", + id = (timestamp+3).ToString(), + role = "assistant" + }; + callback?.Invoke(endMessageListItem1); break; } await foreach(LlmStreamChat llmStreamChat in bailian.SendChatStreamAsync(jsonContent)) { if (!goOn) { + MessageListItem endMessageListItem2 = new ChatMessageItem + { + type = MessageType.END_TAG, + content = "", + id = (timestamp+3).ToString(), + role = "assistant" + }; + callback?.Invoke(endMessageListItem2); break; } @@ -299,7 +315,7 @@ public class Gateway content = llmStreamChat.Choices[0].Delta.ResoningContent, role = "assistant", type = MessageType.REASON_MESSAGE, - id = (timestamp-1).ToString() + id = (timestamp+2).ToString() }; Application.Current.Dispatcher.Invoke(() => { @@ -352,6 +368,14 @@ public class Gateway else { //包含工具调用请求的消息 + XElement toolUse = XElement.Parse(matched); + string fullToolName = toolUse.Element("name")?.Value; + string toolArgs = toolUse.Element("arguments")?.Value; + Dictionary toolParams = JsonConvert.DeserializeObject>(toolArgs); + string serverName = fullToolName.Contains(":") ? fullToolName.Split(':')[0] : fullToolName; + string toolName = fullToolName.Contains(":") ? fullToolName.Split(':')[1] : fullToolName; + McpServer mcpServer = mcpServerList.GetServer(serverName); + //将工具调用请求添加至列表中待一次回答完整后再统一进行调用 MessageListItem chatMessageListItem = new ChatMessageItem() { content = remaining, @@ -363,14 +387,21 @@ public class Gateway { callback?.Invoke(chatMessageListItem); }); - XElement toolUse = XElement.Parse(matched); - string fullToolName = toolUse.Element("name")?.Value; - string toolArgs = toolUse.Element("arguments")?.Value; - Dictionary toolParams = JsonConvert.DeserializeObject>(toolArgs); - string serverName = fullToolName.Contains(":") ? fullToolName.Split(':')[0] : fullToolName; - string toolName = fullToolName.Contains(":") ? fullToolName.Split(':')[1] : fullToolName; - McpServer mcpServer = mcpServerList.GetServer(serverName); - //将工具调用请求添加至列表中待一次回答完整后再统一进行调用 + MessageListItem toolMessageListItem = new ToolMessageItem() + { + content = "", + result = "", + toolName = toolName, + toolParams = toolParams, + role = "user", + type = MessageType.TOOL_MESSAGE, + id = (timestamp+1).ToString(), + status = "loading" + }; + Application.Current.Dispatcher.Invoke(() => + { + callback?.Invoke(toolMessageListItem); + }); mcpToolRequests = new List(); McpToolRequest mcpToolRequest = new McpToolRequest() { @@ -415,7 +446,9 @@ public class Gateway type = MessageType.TOOL_MESSAGE, status = toolResponse.IsError ? "fail" : "success", content = JsonConvert.SerializeObject(toolResponse), - id = (timestamp + 1).ToString() + result = JsonConvert.SerializeObject(toolResponse), + id = (timestamp + 1).ToString(), + role = "user" }; messages.Add(new Message { @@ -441,7 +474,9 @@ public class Gateway type = MessageType.TOOL_MESSAGE, status = toolResponse.IsError ? "fail" : "success", content = JsonConvert.SerializeObject(toolResponse), - id = (timestamp + 1).ToString() + result = JsonConvert.SerializeObject(toolResponse), + id = (timestamp + 1).ToString(), + role = "user" }; messages.Add(new Message { @@ -486,7 +521,9 @@ public class Gateway type = MessageType.TOOL_MESSAGE, status = "fail", content = JsonConvert.SerializeObject(innerResult), - id = (timestamp + 1).ToString() + result = JsonConvert.SerializeObject(innerResult), + id = (timestamp + 1).ToString(), + role = "user" }; messages.Add(new Message { @@ -507,7 +544,9 @@ public class Gateway type = MessageType.TOOL_MESSAGE, status = "success", content = JsonConvert.SerializeObject(innerResult), - id = (timestamp + 1).ToString() + result = JsonConvert.SerializeObject(innerResult), + id = (timestamp + 1).ToString(), + role = "user" }; messages.Add(new Message { @@ -546,7 +585,8 @@ public class Gateway type = MessageType.TOOL_MESSAGE, status = "success", content = "成功调用提示词:"+promptRequest.PromptName, - id = (timestamp+1).ToString() + id = (timestamp+1).ToString(), + result = "成功调用提示词:"+promptRequest.PromptName }; Application.Current.Dispatcher.Invoke(() => { @@ -559,6 +599,14 @@ public class Gateway log.Error(e.Message); } } + MessageListItem endMessageListItem = new ChatMessageItem + { + type = MessageType.END_TAG, + content = "", + id = (timestamp+3).ToString(), + role = "assistant" + }; + callback?.Invoke(endMessageListItem); } } diff --git a/resource/img/fold.png b/resource/img/fold.png new file mode 100644 index 0000000..2690b19 Binary files /dev/null and b/resource/img/fold.png differ diff --git a/resource/img/linktool.png b/resource/img/linktool.png new file mode 100644 index 0000000..37264c2 Binary files /dev/null and b/resource/img/linktool.png differ diff --git a/resource/img/tool.png b/resource/img/tool.png new file mode 100644 index 0000000..09bee43 Binary files /dev/null and b/resource/img/tool.png differ diff --git a/resource/img/unfold.png b/resource/img/unfold.png new file mode 100644 index 0000000..749e87e Binary files /dev/null and b/resource/img/unfold.png differ diff --git a/resource/img/user.png b/resource/img/user.png new file mode 100644 index 0000000..a992685 Binary files /dev/null and b/resource/img/user.png differ diff --git a/ui/VersionButton.cs b/ui/VersionButton.cs index 62e157d..bc4df57 100644 --- a/ui/VersionButton.cs +++ b/ui/VersionButton.cs @@ -22,7 +22,7 @@ namespace LinkToolAddin { internal class VersionButton : Button { - private string version = "0.1.0"; + private string version = "0.1.1"; protected override void OnClick() { MessageBox.Show($"当前LinkTool版本为{version}", "版本信息"); diff --git a/ui/dockpane/DialogDockpane.xaml b/ui/dockpane/DialogDockpane.xaml index 84e7de1..d232eaa 100644 --- a/ui/dockpane/DialogDockpane.xaml +++ b/ui/dockpane/DialogDockpane.xaml @@ -5,9 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:ui="clr-namespace:LinkToolAddin.ui.dockpane" xmlns:extensions="clr-namespace:ArcGIS.Desktop.Extensions;assembly=ArcGIS.Desktop.Extensions" - xmlns:controls="clr-namespace:ArcGIS.Desktop.Framework.Controls;assembly=ArcGIS.Desktop.Framework" + xmlns:controls="clr-namespace:ArcGIS.Desktop.Framework.Controls;assembly=ArcGIS.Desktop.Framework" + xmlns:system="clr-namespace:System;assembly=System.Runtime" mc:Ignorable="d" - d:DesignHeight="300" d:DesignWidth="300" + d:DesignHeight="650" d:DesignWidth="300" d:DataContext="{Binding Path=ui.DialogDockpaneViewModel}"> @@ -16,13 +17,39 @@ - + - + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ui/dockpane/DialogDockpane.xaml.cs b/ui/dockpane/DialogDockpane.xaml.cs index aa2ea7f..3e623ae 100644 --- a/ui/dockpane/DialogDockpane.xaml.cs +++ b/ui/dockpane/DialogDockpane.xaml.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Net.Http; @@ -12,10 +14,15 @@ using Microsoft.Extensions.Logging; using System.Text.Json; using System.Threading; using System.Windows.Documents; +using System.Windows.Media; +using ArcGIS.Desktop.Core; using ArcGIS.Desktop.Core.Geoprocessing; using LinkToolAddin.client; +using LinkToolAddin.common; +using LinkToolAddin.host; using LinkToolAddin.host.llm; using LinkToolAddin.host.llm.entity; +using LinkToolAddin.message; using LinkToolAddin.resource; using LinkToolAddin.server; using log4net; @@ -29,17 +36,26 @@ using Newtonsoft.Json; namespace LinkToolAddin.ui.dockpane { + public class ItemModel + { + public string Content { get; set; } + } /// /// Interaction logic for DialogDockpaneView.xaml /// public partial class DialogDockpaneView : UserControl { private static ILog log = LogManager.GetLogger(typeof(DialogDockpaneView)); - + + private List idList = new List(); + private ConcurrentDictionary messageDict = new ConcurrentDictionary(); + private ConcurrentDictionary borderItemsDict = new ConcurrentDictionary(); + public DialogDockpaneView() { InitLogger(); InitializeComponent(); + DataContext = this; } private async void TestServer_OnClick(object sender, RoutedEventArgs e) @@ -81,5 +97,396 @@ namespace LinkToolAddin.ui.dockpane log.Info("Info 日志(控制台和文件可见)"); log.Error("Error 日志(严重问题)"); } + + private void SendButton_OnClick(object sender, RoutedEventArgs e) + { + string question = QuestionTextbox.Text; + string defaultGdbPath = Project.Current.DefaultGeodatabasePath; + string gdbPath = @""; + long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + MessageListItem userMsg = new ChatMessageItem() + { + content = question, + role = "user", + type = MessageType.CHAT_MESSAGE, + id = timestamp.ToString() + }; + Border userMsgBoder = GetUserChatBorder(userMsg); + idList.Add(timestamp.ToString()); + messageDict[timestamp.ToString()] = userMsg; + QuestionTextbox.Text = ""; + borderItemsDict[timestamp.ToString()] = userMsgBoder; + ChatHistoryStackPanel.Children.Add(userMsgBoder); + Gateway.SendMessageStream(question,"qwen3-235b-a22b",defaultGdbPath,NewMessage_Recall); + } + + public void NewMessage_Recall(MessageListItem msg) + { + string msgId = msg.id; + log.Info(msg.content); + double verticalOffset = ScrollViewer.VerticalOffset; + double viewportHeight = ScrollViewer.ViewportHeight; + double contentHeight = ChatHistoryStackPanel.ActualHeight; + double tolerance = 24; + if (!idList.Contains(msgId)) + { + //不存在该消息,需添加到ListView中 + if (msg.content == "") + { + return; + } + idList.Add(msgId); + messageDict[msgId] = msg; + if (msg.role == "user") + { + if (msg.type == MessageType.TOOL_MESSAGE) + { + Border border = GetToolChatBorder(msg); + borderItemsDict[msgId] = border; + ChatHistoryStackPanel.Children.Add(border); + StatusTextBlock.Text = "正在执行工具"; + }else if (msg.type == MessageType.CHAT_MESSAGE) + { + Border border = GetUserChatBorder(msg); + borderItemsDict[msgId] = border; + ChatHistoryStackPanel.Children.Add(border); + StatusTextBlock.Text = "正在读取用户输入"; + } + } + else if(msg.role == "assistant") + { + if (msg.type == MessageType.REASON_MESSAGE) + { + Border border = GetAiReasonBorder(msg); + borderItemsDict[msgId] = border; + ChatHistoryStackPanel.Children.Add(border); + StatusTextBlock.Text = "深度思考中"; + }else if (msg.type == MessageType.CHAT_MESSAGE) + { + Border border = GetAiChatBorder(msg); + borderItemsDict[msgId] = border; + ChatHistoryStackPanel.Children.Add(border); + StatusTextBlock.Text = "回答生成中"; + }else if (msg.type == MessageType.END_TAG) + { + StatusTextBlock.Text = ""; + } + } + } + else + { + //已有该消息,只需要修改内容 + messageDict[msgId] = msg; + if (msg.content == "") + { + ChatHistoryStackPanel.Children.Remove(borderItemsDict[msgId]); + borderItemsDict.TryRemove(msgId, out Border border); + messageDict.TryRemove(msgId, out MessageListItem tempMsg); + idList.Remove(msgId); + } + if (msg.role == "user") + { + if (msg.type == MessageType.TOOL_MESSAGE) + { + Border borderItem = borderItemsDict[msgId]; + Grid grid = borderItem.Child as Grid; + TextBlock textBlock = grid.Children[1] as TextBlock; + textBlock.Text = (msg as ToolMessageItem).toolName; + StatusTextBlock.Text = "正在执行工具"; + }else if (msg.type == MessageType.CHAT_MESSAGE) + { + Border borderItem = borderItemsDict[msgId]; + Grid grid = borderItem.Child as Grid; + TextBox textBox = grid.Children[1] as TextBox; + textBox.Text = msg.content; + StatusTextBlock.Text = "正在读取用户输入"; + } + } + else + { + if (msg.type == MessageType.REASON_MESSAGE) + { + Border borderItem = borderItemsDict[msgId]; + Grid grid = borderItem.Child as Grid; + TextBox textBox = grid.Children[0] as TextBox; + textBox.Text = msg.content; + StatusTextBlock.Text = "深度思考中"; + }else if (msg.type == MessageType.CHAT_MESSAGE) + { + Border borderItem = borderItemsDict[msgId]; + Grid grid = borderItem.Child as Grid; + TextBox textBox = grid.Children[1] as TextBox; + textBox.Text = msg.content; + StatusTextBlock.Text = "回答生成中"; + }else if (msg.type == MessageType.END_TAG) + { + StatusTextBlock.Text = ""; + } + } + } + if (Math.Abs(verticalOffset + viewportHeight - contentHeight) < tolerance) + { + ScrollViewer.ScrollToBottom(); + } + } + + private Border GetAiChatBorder(MessageListItem msg) + { + Border border = new Border(); + border.Margin = new Thickness(8, 12, 8, 12); + border.BorderThickness = new Thickness(0); + // border.Background = Brushes.DarkSeaGreen; + Grid grid = new Grid(); + Image icon = new Image() + { + Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.linktool.png"), + Stretch = Stretch.Fill, + HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top + }; + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)}); + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)}); + TextBox textBox = new TextBox(); + grid.Children.Add(icon); + grid.Children.Add(textBox); + Grid.SetColumn(icon, 0); + Grid.SetColumn(textBox, 1); + textBox.IsReadOnly = true; + textBox.BorderThickness = new Thickness(0); + textBox.Background = Brushes.Transparent; + textBox.Text = msg.content; + textBox.TextWrapping = TextWrapping.Wrap; + border.Child = grid; + return border; + } + + private Border GetAiReasonBorder(MessageListItem msg) + { + Border border = new Border(); + border.Margin = new Thickness(8, 12, 8, 12); + border.BorderThickness = new Thickness(0); + // border.Background = Brushes.DarkSeaGreen; + Grid grid = new Grid(); + Image icon = new Image() + { + Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.linktool.png"), + Stretch = Stretch.Fill, + HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top + }; + Image fold = new Image() + { + Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.fold.png"), + Stretch = Stretch.Fill, + HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top + }; + Image unfold = new Image() + { + Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.unfold.png"), + Stretch = Stretch.Fill, + HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top + }; + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)}); + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)}); + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(16, GridUnitType.Pixel)}); + TextBox textBox = new TextBox(); + // grid.Children.Add(icon); + grid.Children.Add(textBox); + // Grid.SetColumn(icon, 0); + Grid.SetColumn(textBox, 1); + textBox.IsReadOnly = true; + textBox.Foreground = Brushes.Gray; + textBox.BorderThickness = new Thickness(2,0,0,0); + textBox.BorderBrush = Brushes.Gray; + textBox.Background = Brushes.Transparent; + textBox.Text = msg.content; + textBox.TextWrapping = TextWrapping.Wrap; + Button button = new Button(); + StackPanel panel = new StackPanel(); + panel.Orientation = Orientation.Horizontal; + panel.Children.Add(fold); + button.Content = panel; + button.BorderThickness = new Thickness(0); + button.Background = Brushes.Transparent; + button.Width = 16; + button.Height = 16; + button.Padding = new Thickness(0); + button.HorizontalAlignment = HorizontalAlignment.Center; + button.VerticalAlignment = VerticalAlignment.Top; + button.Tag = "fold"; + button.Click += FoldButton_OnClick; + Grid.SetColumn(button, 2); + grid.Children.Add(button); + border.Child = grid; + return border; + } + + private void FoldButton_OnClick(object sender, RoutedEventArgs e) + { + Button button = sender as Button; + string tag = button.Tag.ToString(); + if (tag == "fold") + { + button.Tag = "unfold"; + Grid grid = button.Parent as Grid; + TextBox textBox = grid.Children[0] as TextBox; + textBox.Visibility = Visibility.Collapsed; + StackPanel stackPanel = button.Content as StackPanel; + Image unfold = new Image() + { + Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.unfold.png"), + Stretch = Stretch.Fill, + HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top + }; + stackPanel.Children.Clear(); + stackPanel.Children.Add(unfold); + } + else + { + button.Tag = "fold"; + Image fold = new Image() + { + Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.fold.png"), + Stretch = Stretch.Fill, + HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top + }; + Grid grid = button.Parent as Grid; + TextBox textBox = grid.Children[0] as TextBox; + textBox.Visibility = Visibility.Visible; + StackPanel stackPanel = button.Content as StackPanel; + stackPanel.Children.Clear(); + stackPanel.Children.Add(fold); + } + + } + + private Border GetUserChatBorder(MessageListItem msg) + { + Border border = new Border(); + border.Margin = new Thickness(8, 12, 8, 12); + border.BorderThickness = new Thickness(0); + // border.Background = Brushes.DarkSeaGreen; + Grid grid = new Grid(); + Image icon = new Image() + { + Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.user.png"), + Stretch = Stretch.Fill, + HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top + }; + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)}); + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)}); + TextBox textBox = new TextBox(); + textBox.HorizontalAlignment = HorizontalAlignment.Right; + grid.Children.Add(icon); + grid.Children.Add(textBox); + Grid.SetColumn(icon, 1); + Grid.SetColumn(textBox, 0); + textBox.Background = Brushes.Transparent; + textBox.IsReadOnly = true; + textBox.BorderThickness = new Thickness(0); + textBox.Text = msg.content; + textBox.TextWrapping = TextWrapping.Wrap; + border.Child = grid; + return border; + } + + private Border GetToolChatBorder(MessageListItem msg) + { + Border border = new Border(); + border.Margin = new Thickness(24); + border.Padding = new Thickness(8); + border.BorderThickness = new Thickness(1); + border.BorderBrush = Brushes.Gray; + border.CornerRadius = new CornerRadius(3); + // border.Background = Brushes.DarkSeaGreen; + Grid grid = new Grid(); + Image icon = new Image() + { + Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.tool.png"), + Stretch = Stretch.Fill, + HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center + }; + icon.Margin = new Thickness(0, 0, 8, 0); + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)}); + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)}); + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(36, GridUnitType.Pixel)}); + grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(36, GridUnitType.Pixel)}); + TextBlock textBlock = new TextBlock(); + ToolMessageItem toolMsg = msg as ToolMessageItem; + textBlock.Text = toolMsg.toolName + " | " + toolMsg.status; + textBlock.TextWrapping = TextWrapping.Wrap; + grid.Children.Add(icon); + grid.Children.Add(textBlock); + Grid.SetColumn(icon, 0); + Grid.SetColumn(textBlock, 1); + Button argsButton = new Button(); + argsButton.Content = "参数"; + argsButton.Tag = msg as ToolMessageItem; + argsButton.Click += ToolArgsButton_OnClick; + border.Child = grid; + Button resButton = new Button(); + resButton.Content = "结果"; + resButton.Tag = msg as ToolMessageItem; + resButton.Click += ToolResButton_OnClick; + grid.Children.Add(argsButton); + Grid.SetColumn(argsButton, 2); + grid.Children.Add(resButton); + Grid.SetColumn(resButton, 3); + return border; + } + + private void ToolArgsButton_OnClick(object sender, RoutedEventArgs e) + { + Button button = sender as Button; + ToolMessageItem toolItem = button.Tag as ToolMessageItem; + ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(JsonConvert.SerializeObject(toolItem.toolParams),toolItem.toolName+"工具参数"); + } + + private void ToolResButton_OnClick(object sender, RoutedEventArgs e) + { + Button button = sender as Button; + ToolMessageItem toolItem = button.Tag as ToolMessageItem; + ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(toolItem.result,toolItem.toolName+"运行结果"); + } + + private void TestButton_OnClick(object sender, RoutedEventArgs e) + { + long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + MessageListItem toolMessageItem = new ToolMessageItem + { + toolName = "toolName", + toolParams = new Dictionary(), + type = MessageType.TOOL_MESSAGE, + status = "success", + content = "JsonConvert.SerializeObject(toolResponse)", + id = (timestamp + 1).ToString(), + role = "user" + }; + NewMessage_Recall(toolMessageItem); + } + + private void ClearButton_OnClick(object sender, RoutedEventArgs e) + { + idList.Clear(); + messageDict.Clear(); + borderItemsDict.Clear(); + ChatHistoryStackPanel.Children.Clear(); + QuestionTextbox.Clear(); + StatusTextBlock.Text = ""; + } + + private void TopButton_OnClick(object sender, RoutedEventArgs e) + { + ScrollViewer.ScrollToTop(); + } + + private void BottomButton_OnClick(object sender, RoutedEventArgs e) + { + ScrollViewer.ScrollToBottom(); + } + + private void StopButton_OnClick(object sender, RoutedEventArgs e) + { + Gateway.StopConversation(); + StatusTextBlock.Text = ""; + } } } diff --git a/ui/dockpane/DialogDockpaneViewModel.cs b/ui/dockpane/DialogDockpaneViewModel.cs index 1d7a4e5..42258fc 100644 --- a/ui/dockpane/DialogDockpaneViewModel.cs +++ b/ui/dockpane/DialogDockpaneViewModel.cs @@ -14,6 +14,7 @@ using ArcGIS.Desktop.Layouts; using ArcGIS.Desktop.Mapping; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -27,8 +28,14 @@ namespace LinkToolAddin.ui.dockpane internal class DialogDockpaneViewModel : DockPane { private const string _dockPaneID = "DialogDockpane"; + + public ObservableCollection Items { get; set; } - protected DialogDockpaneViewModel() { } + protected DialogDockpaneViewModel() + { + Items = new ObservableCollection(); + Items.Add(new ItemModel(){Content = "adfdfdafdfs"}); + } /// /// Show the DockPane. diff --git a/ui/message/MessageListItem.cs b/ui/message/MessageListItem.cs index 9b97709..3b0ce37 100644 --- a/ui/message/MessageListItem.cs +++ b/ui/message/MessageListItem.cs @@ -5,6 +5,7 @@ public enum MessageType TOOL_MESSAGE, CHAT_MESSAGE, REASON_MESSAGE, + END_TAG } public interface MessageListItem