LinkToolAddin/ui/dockpane/TestDockpane.xaml.cs
2025-05-29 21:01:07 +08:00

279 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;
using LinkToolAddin.client;
using LinkToolAddin.host;
using LinkToolAddin.host.llm;
using LinkToolAddin.host.llm.entity;
using LinkToolAddin.host.mcp;
using LinkToolAddin.host.prompt;
using LinkToolAddin.message;
using LinkToolAddin.resource;
using LinkToolAddin.server;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Layout;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Types;
using Newtonsoft.Json;
namespace LinkToolAddin.ui.dockpane
{
/// <summary>
/// Interaction logic for TestDockpaneView.xaml
/// </summary>
public partial class TestDockpaneView : UserControl
{
private static ILog log = LogManager.GetLogger(typeof(TestDockpaneView));
private List<string> idList = new List<string>();
private Dictionary<string,MessageListItem> messageDict = new Dictionary<string,MessageListItem>();
public TestDockpaneView()
{
InitLogger();
InitializeComponent();
}
protected void InitLogger()
{
// 1. 创建控制台输出器Appender
var consoleAppender = new ConsoleAppender
{
Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"),
Threshold = log4net.Core.Level.Info // 仅输出 Info 及以上级别
};
consoleAppender.ActivateOptions(); // 激活配置
// 2. 创建文件滚动输出器(按大小滚动)
var fileAppender = new RollingFileAppender
{
File = System.IO.Path.Combine("Logs", "linktool_app.log"), // 日志文件路径
AppendToFile = true, // 追加模式
RollingStyle = RollingFileAppender.RollingMode.Size, // 按文件大小滚动
MaxSizeRollBackups = 10, // 保留 10 个历史文件
MaximumFileSize = "1MB", // 单个文件最大 1MB
StaticLogFileName = true, // 固定文件名(否则自动追加序号)
Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"),
Threshold = log4net.Core.Level.Info // 仅输出 Info 及以上级别
};
fileAppender.ActivateOptions(); // 激活配置
// 3. 直接通过 BasicConfigurator 注册 Appender
BasicConfigurator.Configure(consoleAppender, fileAppender);
log = LogManager.GetLogger(typeof(DialogDockpaneView));
// 测试日志输出
log.Debug("Debug 日志(控制台可见)");
log.Info("Info 日志(控制台和文件可见)");
log.Error("Error 日志(严重问题)");
}
public void CallBack(string str,object obj)
{
log.Info($"CallBack {str}");
}
private async void TestServer_OnClick(object sender, RoutedEventArgs e)
{
log.Info("TestServer Clicked");
ArcGISProMcpServer.TestMcpServer();
}
private async void StdioMcp_test()
{
List<string> args = new List<string>();
args.Add("mcp-server-time");
args.Add("--local-timezone=America/New_York");
McpClient stdioMcpClient = new StdioMcpClient("uvx",args);
IList<McpClientTool> tools = await stdioMcpClient.GetToolListAsync();
foreach (McpClientTool tool in tools)
{
log.Info(tool.JsonSchema.ToString());
}
CallToolResponse response = await stdioMcpClient.CallToolAsync("get_current_time",
new Dictionary<string, object> { { "timezone", "America/New_York" } });
log.Info(JsonConvert.SerializeObject(response));
}
private async void SseMcp_test()
{
SseMcpClient client = new SseMcpClient("https://mcp.amap.com/sse?key=ed418512c94ade8f83d42c37b77d2bb2");
IList<McpClientTool> tools = await client.GetToolListAsync();
foreach (McpClientTool tool in tools)
{
log.Info(tool.JsonSchema.ToString());
}
}
private async void Retrieve_Test()
{
log.Info("TestServer Clicked");
// string jsonRpcString = @"{""jsonrpc"":""2.0"",""method"":""CallArcGISPro.CallArcGISProTool"",""params"":{""toolName"":""analysis.Buffer"",""toolParams"":""[\""D:/01_Development/02_ArcGIS_Pro_Project/20250319_GisAi/Test.gdb/河流\"",\""D:/01_Development/02_ArcGIS_Pro_Project/20250319_GisAi/Test.gdb/河流buffer\"",\""100\""]""},""id"":1}";
DocDb docDb = new DocDb("sk-db177155677e438f832860e7f4da6afc", DocDb.KnowledgeBase.ArcGISProHelpDoc);
string query = "缓冲区";
KnowledgeResult knowledgeResult = await docDb.Retrieve(query);
log.Info(JsonConvert.SerializeObject(knowledgeResult.ChunkList));
}
private async void Request_Bailian_Test()
{
Llm bailian = new Bailian
{
api_key = "sk-db177155677e438f832860e7f4da6afc",
app_id = "6a77c5a68de64f469b79fcdcde9d5001",
};
string reponse = await bailian.SendChatAsync(new LlmJsonContent()
{
Model = "qwen-max",
Messages = new List<Message>()
{
new Message()
{
Role = "user",
Content = "你是谁"
}
},
Temperature = 0.7,
TopP = 1,
MaxTokens = 1000,
});
log.Info(reponse);
}
private async void Request_Bailian_Stream_Test()
{
LlmJsonContent jsonContent = new LlmJsonContent()
{
Model = "qwen-max",
Messages = new List<Message>()
{
new Message()
{
Role = "user",
Content = "给我写一篇1000字的高考议论文"
}
},
Temperature = 0.7,
TopP = 1,
MaxTokens = 1000,
Stream = true
};
Llm bailian = new Bailian
{
api_key = "sk-db177155677e438f832860e7f4da6afc",
app_id = "6a77c5a68de64f469b79fcdcde9d5001",
};
await foreach (var chunk in bailian.SendChatStreamAsync(jsonContent))
{
log.Info(chunk);
}
}
private void TestButton_OnClick(object sender, RoutedEventArgs e)
{
throw new System.NotImplementedException();
}
private void TestWorkflow_OnClick(object sender, RoutedEventArgs e)
{
// Gateway.SendMessage("你有什么工具可以调用的?","qwen-max","test.gdb",ShowMessage);
Gateway.TestWorkflow("dafdfdgdagdgui","","",AddReply);
}
public void ShowMessage(MessageListItem msg)
{
log.Info(msg.content);
}
private void PromptTestButton_OnClick(object sender, RoutedEventArgs e)
{
string userPrompt = PromptTestTextBox.Text;
// Gateway.SendMessage(userPrompt,"qwen-max","C:/Project/test.gdb",AddReply);
Gateway.SendMessageStream(userPrompt,"qwen-max", "F:\\secondsemester\\linktool\\test\\linktooltest\\linktooltest.gdb", AddReplyStream);
}
public void AddReplyStream(MessageListItem msg)
{
string id = msg.id;
if (idList.Contains(id))
{
messageDict[id] = msg;
}
else
{
idList.Add(id);
messageDict.Add(msg.id, msg);
}
ReplyTextBox.Clear();
StringBuilder builder = new StringBuilder();
foreach (KeyValuePair<string,MessageListItem> pair in messageDict)
{
MessageListItem msgItem = pair.Value;
builder.AppendLine(msgItem.content);
ReplyTextBox.Text = builder.ToString();
ReplyTextBox.ScrollToEnd();
}
}
public void AddReply(MessageListItem msg)
{
string content = msg.content;
log.Info(content);
string originContent = ReplyTextBox.Text;
ReplyTextBox.Text = originContent + content;
}
private void TestStream_OnClick(object sender, RoutedEventArgs e)
{
Request_Bailian_Stream_Test();
}
private void StopConversation_OnClick(object sender, RoutedEventArgs e)
{
Gateway.StopConversation();
}
private async void TestArcGisTool_OnClick(object sender, RoutedEventArgs e)
{
string xmlStr =
"<tool_use>\n<name>ArcGisPro:ArcGisProTool</name>\n<arguments>{\"toolName\": \"Buffer\", \"toolParams\": [\"D:\\\\01_Project\\\\20250305_LinkTool\\\\20250420_AiDemoProject\\\\20250420_AiDemoProject.gdb\\\\LandUse_2005_Copy\", \"D:\\\\01_Project\\\\20250305_LinkTool\\\\20250420_AiDemoProject\\\\20250420_AiDemoProject.gdb\\\\LandUse_2005_Buffer30m\", \"30 Meters\", \"NONE\", \"ROUND\", \"ALL\"]}</arguments>\n</tool_use>";
XElement toolUse = XElement.Parse(xmlStr);
string fullToolName = toolUse.Element("name")?.Value;
string toolArgs = toolUse.Element("arguments")?.Value;
Dictionary<string, object> toolParams = JsonConvert.DeserializeObject<Dictionary<string, object>>(toolArgs);
string serverName = fullToolName.Contains(":") ? fullToolName.Split(':')[0] : fullToolName;
string toolName = fullToolName.Contains(":") ? fullToolName.Split(':')[1] : fullToolName;
McpServerList mcpServerList = new McpServerList();
McpServer mcpServer = mcpServerList.GetServer(serverName);
if (mcpServer is InnerMcpServer)
{
Type type = Type.GetType("LinkToolAddin.client.tool." + serverName);
var toolParamsValues = toolParams.Values.ToArray();
MethodInfo method = type.GetMethod(toolName, BindingFlags.Public | BindingFlags.Static);
var task = method.Invoke(null, toolParams.Values.ToArray()) as Task<JsonRpcResultEntity>;
JsonRpcResultEntity innerResult = await task;
MessageListItem toolMessageItem = new ToolMessageItem
{
toolName = toolName,
toolParams = toolParams,
type = MessageType.TOOL_MESSAGE,
status = "fail",
content = JsonConvert.SerializeObject(innerResult),
id = "1test"
};
AddReply(toolMessageItem);
}
}
}
}