Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 322437a00f | |||
| 51b1cc1b7d | |||
| 6a0a5c6084 | |||
| 178b92a714 |
@ -2,7 +2,7 @@
|
|||||||
"profiles": {
|
"profiles": {
|
||||||
"LinkToolAddin": {
|
"LinkToolAddin": {
|
||||||
"commandName": "Executable",
|
"commandName": "Executable",
|
||||||
"executablePath": "C:\\Program Files\\ArcGIS\\Pro\\bin\\ArcGISPro.exe",
|
"executablePath": "C:/Program Files/ArcGIS/Pro/bin/ArcGISPro.exe",
|
||||||
"applicationUrl": "https://localhost:5001",
|
"applicationUrl": "https://localhost:5001",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
|||||||
@ -590,37 +590,37 @@ public class Gateway
|
|||||||
return JsonConvert.SerializeObject(paramSchema, settings);;
|
return JsonConvert.SerializeObject(paramSchema, settings);;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void TestChatMessage(string message, string model, string gdbPath,
|
public static async void TestChatMessage(string message, string model, string gdbPath,//生成并返回一个聊天消息(ChatMessageItem),模拟AI助手的响应。通过回调函数 callback 将消息传递到前端显示。1
|
||||||
Action<MessageListItem> callback)
|
Action<MessageListItem> callback)
|
||||||
{
|
{
|
||||||
MessageListItem chatListItem = new ChatMessageItem
|
MessageListItem chatListItem = new ChatMessageItem//返回的东西1
|
||||||
{
|
{
|
||||||
content = message,
|
content = message,
|
||||||
role = "assistant",
|
role = "assistant",//角色,assistant是ai的回答,user用户的回答,sistant系统提示词1
|
||||||
type = MessageType.CHAT_MESSAGE,
|
type = MessageType.CHAT_MESSAGE,//根据type判断是工具卡还是聊天卡1
|
||||||
id = "testmsg12345"
|
id = "testmsg12345"//琅哥虚构的,定位可以用,引用选中凭id找1
|
||||||
};
|
};
|
||||||
callback?.Invoke(chatListItem);
|
callback?.Invoke(chatListItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void TestToolMessage(string message, string model, string gdbPath, Action<MessageListItem> callback)
|
public static async void TestToolMessage(string message, string model, string gdbPath, Action<MessageListItem> callback)//同上1
|
||||||
{
|
{
|
||||||
MessageListItem toolListItem = new ToolMessageItem
|
MessageListItem toolListItem = new ToolMessageItem
|
||||||
{
|
{
|
||||||
content = message,
|
content = message,//大模型生成的信息,正常来说是个x啥?1
|
||||||
type = MessageType.TOOL_MESSAGE,
|
type = MessageType.TOOL_MESSAGE,
|
||||||
toolName = "arcgis_pro.executeTool",
|
toolName = "arcgis_pro.executeTool",//要调用的工具名称,大模型工具不是arcgis工具,调⽤ArcGIS Pro.GP工具调用1
|
||||||
toolParams = new Dictionary<string, object>
|
toolParams = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{"gp_name","analysis.Buffer"},
|
{"gp_name","analysis.Buffer"},//传参要传Arcgis的工具名
|
||||||
{"gp_params","[\"C:\\test.gdb\\river\",\"30 Meters\"]"}
|
{"gp_params","[\"C:\\test.gdb\\river\",\"30 Meters\"]"}//工具参数,数组,字符串要转成数组,前端要调用OpenTrueDialog,没听懂1
|
||||||
},
|
},
|
||||||
id = "testtool123456",
|
id = "testtool123456",
|
||||||
status = "success",
|
status = "success",//显示勾
|
||||||
role = "user",
|
role = "user",
|
||||||
result = "成功创建缓冲区"
|
result = "成功创建缓冲区"
|
||||||
};
|
};
|
||||||
callback?.Invoke(toolListItem);
|
callback?.Invoke(toolListItem);//这些调用结果显示在前端,显示点后面的工具名称,用户点的时候展开1
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void TestWorkflow(string message, string model, string gdbPath, Action<MessageListItem> callback)
|
public static async void TestWorkflow(string message, string model, string gdbPath, Action<MessageListItem> callback)
|
||||||
|
|||||||
@ -16,13 +16,40 @@
|
|||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid>
|
|
||||||
|
<Grid Margin="10" Background="White">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="4*"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="10"/>
|
||||||
|
<RowDefinition Height="1*"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<DockPanel Grid.Row="0" LastChildFill="true" KeyboardNavigation.TabNavigation="Local" Height="30">
|
|
||||||
<Button Content="Test Server" Name="TestServer" Click="TestServer_OnClick"></Button>
|
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto" Name="MessageScrollViewer">
|
||||||
</DockPanel>
|
|
||||||
</Grid>
|
</ScrollViewer>
|
||||||
|
|
||||||
|
<DockPanel Grid.Row="2" Background="AliceBlue" Margin="0,0,0,0">
|
||||||
|
<Button
|
||||||
|
x:Name="SendButton"
|
||||||
|
Content="发送"
|
||||||
|
Width="45"
|
||||||
|
Height="40"
|
||||||
|
Margin="5,0,5,0"
|
||||||
|
Background="#FFD0E0F0"
|
||||||
|
BorderBrush="#FFA0B0C0"
|
||||||
|
BorderThickness="1"
|
||||||
|
Padding="0"
|
||||||
|
DockPanel.Dock="Right"
|
||||||
|
Click="Send_0nclick"/>
|
||||||
|
|
||||||
|
<TextBox x:Name="InputTextBox"
|
||||||
|
Height="40"
|
||||||
|
Margin="5,0,5,0"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Background="White"
|
||||||
|
BorderBrush="#FFD0D0D0"
|
||||||
|
BorderThickness="1"
|
||||||
|
Padding="5"/>
|
||||||
|
</DockPanel>
|
||||||
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,36 +1,41 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Documents;
|
|
||||||
using ArcGIS.Desktop.Core.Geoprocessing;
|
using ArcGIS.Desktop.Core.Geoprocessing;
|
||||||
using LinkToolAddin.client;
|
using LinkToolAddin.client;
|
||||||
|
using LinkToolAddin.host;
|
||||||
using LinkToolAddin.host.llm;
|
using LinkToolAddin.host.llm;
|
||||||
using LinkToolAddin.host.llm.entity;
|
using LinkToolAddin.host.llm.entity;
|
||||||
|
using LinkToolAddin.message;
|
||||||
using LinkToolAddin.resource;
|
using LinkToolAddin.resource;
|
||||||
using LinkToolAddin.server;
|
using LinkToolAddin.server;
|
||||||
using log4net;
|
using log4net;
|
||||||
using log4net.Appender;
|
using log4net.Appender;
|
||||||
using log4net.Config;
|
using log4net.Config;
|
||||||
using log4net.Layout;
|
using log4net.Layout;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using ModelContextProtocol.Client;
|
using ModelContextProtocol.Client;
|
||||||
using ModelContextProtocol.Protocol.Types;
|
using ModelContextProtocol.Protocol.Types;
|
||||||
using ModelContextProtocol.Server;
|
using ModelContextProtocol.Server;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace LinkToolAddin.ui.dockpane
|
namespace LinkToolAddin.ui.dockpane
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for DialogDockpaneView.xaml
|
/// Interaction logic for DialogDockpaneView.xaml
|
||||||
|
/// 显示消息列表、输入框和发送按钮
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class DialogDockpaneView : UserControl
|
public partial class DialogDockpaneView : UserControl
|
||||||
{
|
{
|
||||||
@ -81,5 +86,69 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
log.Info("Info 日志(控制台和文件可见)");
|
log.Info("Info 日志(控制台和文件可见)");
|
||||||
log.Error("Error 日志(严重问题)");
|
log.Error("Error 日志(严重问题)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Send_0nclick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
string userInput = InputTextBox.Text.Trim();
|
||||||
|
if (string.IsNullOrEmpty(userInput)) return;
|
||||||
|
var userMessage = new ChatMessageItem
|
||||||
|
{
|
||||||
|
id = Guid.NewGuid().ToString(),
|
||||||
|
role = "user",
|
||||||
|
content = userInput,
|
||||||
|
type = MessageType.CHAT_MESSAGE
|
||||||
|
};
|
||||||
|
// 使用统一方法显示消息
|
||||||
|
NewMessage(userMessage);
|
||||||
|
|
||||||
|
// 清空输入框
|
||||||
|
InputTextBox.Clear();
|
||||||
|
|
||||||
|
Gateway.SendMessageStream(InputTextBox.Text, model: "qwen-max", gdbPath: "c: /user.gdb", NewMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NewMessage(MessageListItem messagelistItem)
|
||||||
|
{
|
||||||
|
// 创建用于显示消息内容的 TextBlock
|
||||||
|
TextBlock textBlock = new TextBlock();
|
||||||
|
textBlock.Text = InputTextBox.Text;
|
||||||
|
textBlock.TextWrapping = TextWrapping.Wrap; // 自动换行
|
||||||
|
textBlock.VerticalAlignment = VerticalAlignment.Center;
|
||||||
|
|
||||||
|
// 创建 Border 作为消息气泡容器
|
||||||
|
Border border = new Border();
|
||||||
|
border.Child = textBlock;
|
||||||
|
border.CornerRadius = new CornerRadius(10);
|
||||||
|
border.Padding = new Thickness(10);
|
||||||
|
border.Margin = new Thickness(5);
|
||||||
|
|
||||||
|
// 设置默认宽度限制
|
||||||
|
border.MaxWidth = 300;
|
||||||
|
|
||||||
|
if (messagelistItem.role == "user")
|
||||||
|
{
|
||||||
|
// 浅蓝色背景,靠右
|
||||||
|
border.Background = new SolidColorBrush(Color.FromRgb(212, 229, 239)); // 浅蓝
|
||||||
|
border.HorizontalAlignment = HorizontalAlignment.Right;
|
||||||
|
}
|
||||||
|
else if (messagelistItem.role == "assistant")
|
||||||
|
{
|
||||||
|
// 浅灰背景,靠左
|
||||||
|
border.Background = new SolidColorBrush(Color.FromRgb(240, 240, 240)); // 浅灰
|
||||||
|
border.HorizontalAlignment = HorizontalAlignment.Left;
|
||||||
|
|
||||||
|
if (messagelistItem.type == MessageType.TOOL_MESSAGE)
|
||||||
|
{
|
||||||
|
border.BorderBrush = new SolidColorBrush(Color.FromRgb(212, 220, 223)); // 灰蓝色边框
|
||||||
|
border.BorderThickness = new Thickness(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 把气泡添加到 MessageListView 显示
|
||||||
|
MessageListView.Items.Add(border);
|
||||||
|
|
||||||
|
// 自动滚动到底部
|
||||||
|
MessageScrollViewer.ScrollToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,8 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Logging.Console;
|
using Microsoft.Extensions.Logging.Console;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using LinkToolAddin.message;
|
||||||
|
|
||||||
namespace LinkToolAddin.ui.dockpane
|
namespace LinkToolAddin.ui.dockpane
|
||||||
{
|
{
|
||||||
@ -28,12 +30,17 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
{
|
{
|
||||||
private const string _dockPaneID = "DialogDockpane";
|
private const string _dockPaneID = "DialogDockpane";
|
||||||
|
|
||||||
|
private ObservableCollection<MessageListItem> _message = new ObservableCollection<MessageListItem>();
|
||||||
|
//ObservableCollection<T> 是 .NET 提供的一个特殊集合类,它会在集合发生变化时自动通知 UI 更新,它实现了 INotifyCollectionChanged 接口,UI 绑定后可以自动刷新。
|
||||||
|
public ObservableCollection<MessageListItem> Messages => _message;
|
||||||
|
//定义了一个只读属性 Messages,返回内部的 _messages 集合。
|
||||||
|
//该属性将被绑定到 UI 的 ItemsControl.ItemsSource 上,这样 UI 就能实时显示新消息。
|
||||||
protected DialogDockpaneViewModel() { }
|
protected DialogDockpaneViewModel() { }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Show the DockPane.
|
/// Show the DockPane.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static void Show()
|
internal static void Show()//显示面板
|
||||||
{
|
{
|
||||||
DockPane pane = FrameworkApplication.DockPaneManager.Find(_dockPaneID);
|
DockPane pane = FrameworkApplication.DockPaneManager.Find(_dockPaneID);
|
||||||
if (pane == null)
|
if (pane == null)
|
||||||
@ -45,18 +52,18 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Text shown near the top of the DockPane.
|
/// Text shown near the top of the DockPane.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private string _heading = "My DockPane";
|
private string _heading = "My DockPane";//标题栏文字
|
||||||
public string Heading
|
public string Heading
|
||||||
{
|
{
|
||||||
get => _heading;
|
get => _heading;//绑定到 UI 上的标题文字,默认是 "My DockPane"。
|
||||||
set => SetProperty(ref _heading, value);
|
set => SetProperty(ref _heading, value);//属性变更通知方法,用于支持数据绑定
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Button implementation to show the DockPane.
|
/// Button implementation to show the DockPane.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class DialogDockpane_ShowButton : Button
|
internal class DialogDockpane_ShowButton : Button//用于打开面板
|
||||||
{
|
{
|
||||||
protected override void OnClick()
|
protected override void OnClick()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -24,7 +24,7 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for TestDockpaneView.xaml
|
/// Interaction logic for TestDockpaneView.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class TestDockpaneView : UserControl
|
public partial class TestDockpaneView : UserControl//类1
|
||||||
{
|
{
|
||||||
private static ILog log = LogManager.GetLogger(typeof(TestDockpaneView));
|
private static ILog log = LogManager.GetLogger(typeof(TestDockpaneView));
|
||||||
|
|
||||||
@ -33,11 +33,11 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
|
|
||||||
public TestDockpaneView()
|
public TestDockpaneView()
|
||||||
{
|
{
|
||||||
InitLogger();
|
InitLogger();//初始化日志输出器1
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void InitLogger()
|
protected void InitLogger()//要复制代码(到哪去)1
|
||||||
{
|
{
|
||||||
// 1. 创建控制台输出器(Appender)
|
// 1. 创建控制台输出器(Appender)
|
||||||
var consoleAppender = new ConsoleAppender
|
var consoleAppender = new ConsoleAppender
|
||||||
@ -83,7 +83,7 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
ArcGISProMcpServer.TestMcpServer();
|
ArcGISProMcpServer.TestMcpServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void StdioMcp_test()
|
private async void StdioMcp_test()//标准输入输出的MCP测试,复制过去看能不能返回,有没有东西1
|
||||||
{
|
{
|
||||||
List<string> args = new List<string>();
|
List<string> args = new List<string>();
|
||||||
args.Add("mcp-server-time");
|
args.Add("mcp-server-time");
|
||||||
@ -96,7 +96,7 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
}
|
}
|
||||||
CallToolResponse response = await stdioMcpClient.CallToolAsync("get_current_time",
|
CallToolResponse response = await stdioMcpClient.CallToolAsync("get_current_time",
|
||||||
new Dictionary<string, object> { { "timezone", "America/New_York" } });
|
new Dictionary<string, object> { { "timezone", "America/New_York" } });
|
||||||
log.Info(JsonConvert.SerializeObject(response));
|
log.Info(JsonConvert.SerializeObject(response));//log看有没有东西和报错,实际调试看对应按钮控制台有没有东西1
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SseMcp_test()
|
private async void SseMcp_test()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user