v0.1.4版本 #2

Merged
PeterZhong merged 70 commits from host into master 2025-06-15 14:42:58 +00:00
9 changed files with 159 additions and 45 deletions
Showing only changes of commit ea021135a3 - Show all commits

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using ArcGIS.Core.Data; using ArcGIS.Core.Data;
using ArcGIS.Core.Data.Raster; using ArcGIS.Core.Data.Raster;
@ -9,6 +10,7 @@ using ArcGIS.Desktop.Framework.Threading.Tasks;
using LinkToolAddin.server; using LinkToolAddin.server;
using ModelContextProtocol.Server; using ModelContextProtocol.Server;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace LinkToolAddin.client.tool; namespace LinkToolAddin.client.tool;

View File

@ -22,4 +22,28 @@ public class KnowledgeBase
}; };
return result; return result;
} }
[McpServerTool, Description("查询ArcGIS Pro调用工具的标准调用名和参数要求知识库")]
public static async Task<JsonRpcResultEntity> QueryArcgisToolDoc(string query)
{
DocDb docDb = new DocDb("sk-db177155677e438f832860e7f4da6afc", DocDb.KnowledgeBase.ArcGISProToolDoc);
KnowledgeResult knowledgeResult = await docDb.Retrieve(query);
JsonRpcResultEntity result = new JsonRpcSuccessEntity()
{
Result = JsonConvert.SerializeObject(knowledgeResult.ChunkList),
};
return result;
}
[McpServerTool, Description("查询使用ArcGIS Pro进行任务规划和解决实际问题的案例知识库")]
public static async Task<JsonRpcResultEntity> QueryArcgisExampleDoc(string query)
{
DocDb docDb = new DocDb("sk-db177155677e438f832860e7f4da6afc", DocDb.KnowledgeBase.ArcGISProApplicantExample);
KnowledgeResult knowledgeResult = await docDb.Retrieve(query);
JsonRpcResultEntity result = new JsonRpcSuccessEntity()
{
Result = JsonConvert.SerializeObject(knowledgeResult.ChunkList),
};
return result;
}
} }

View File

@ -8,6 +8,7 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Documents;
using System.Xml; using System.Xml;
using System.Xml.Linq; using System.Xml.Linq;
using ArcGIS.Desktop.Framework.Dialogs; using ArcGIS.Desktop.Framework.Dialogs;
@ -37,6 +38,13 @@ namespace LinkToolAddin.host;
public class Gateway public class Gateway
{ {
private static ILog log = LogManager.GetLogger(typeof(Gateway)); private static ILog log = LogManager.GetLogger(typeof(Gateway));
private static bool goOn = true;
public static void StopConversation()
{
goOn = false;
}
public static async void SendMessage(string message, string model, string gdbPath, Action<MessageListItem> callback) public static async void SendMessage(string message, string model, string gdbPath, Action<MessageListItem> callback)
{ {
Llm bailian = new Bailian Llm bailian = new Bailian
@ -240,12 +248,19 @@ public class Gateway
Role = "user", Role = "user",
Content = message Content = message
}); });
bool goOn = true; goOn = true;
string toolPattern = "^<tool_use>[\\s\\S]*?<\\/tool_use>$"; string toolPattern = "^<tool_use>[\\s\\S]*?<\\/tool_use>$";
string promptPattern = "^<prompt>[\\s\\S]*?<\\/prompt>$"; string promptPattern = "^<prompt>[\\s\\S]*?<\\/prompt>$";
McpServerList mcpServerList = new McpServerList(); McpServerList mcpServerList = new McpServerList();
int loop = 0;
while (goOn) while (goOn)
{ {
loop++;
if (loop > 20)
{
MessageBox.Show("达到最大循环次数", "退出循环");
break;
}
LlmJsonContent jsonContent = new LlmJsonContent() LlmJsonContent jsonContent = new LlmJsonContent()
{ {
Model = model, Model = model,
@ -266,6 +281,11 @@ public class Gateway
if (Regex.IsMatch(chunk, toolPattern)) if (Regex.IsMatch(chunk, toolPattern))
{ {
//返回工具卡片 //返回工具卡片
messages.Add(new Message
{
Role = "assistant",
Content = chunk
});
XElement toolUse = XElement.Parse(chunk); XElement toolUse = XElement.Parse(chunk);
string fullToolName = toolUse.Element("name")?.Value; string fullToolName = toolUse.Element("name")?.Value;
string toolArgs = toolUse.Element("arguments")?.Value; string toolArgs = toolUse.Element("arguments")?.Value;
@ -290,13 +310,14 @@ public class Gateway
messages.Add(new Message messages.Add(new Message
{ {
Role = "user", Role = "user",
Content = toolResponse.IsError ? SystemPrompt.ErrorPromptTemplate : SystemPrompt.ContinuePromptTemplate // Content = toolResponse.IsError ? SystemPrompt.ErrorPromptTemplate : SystemPrompt.ContinuePromptTemplate
}); Content = toolResponse.IsError ? SystemPrompt.ErrorPromptTemplate : SystemPrompt.ContinuePrompt(JsonConvert.SerializeObject(toolResponse))
messages.Add(new Message
{
Role = "user",
Content = JsonConvert.SerializeObject(toolResponse)
}); });
// messages.Add(new Message
// {
// Role = "user",
// Content = JsonConvert.SerializeObject(toolResponse)
// });
callback?.Invoke(toolMessageItem); callback?.Invoke(toolMessageItem);
}else if (mcpServer is StdioMcpServer) }else if (mcpServer is StdioMcpServer)
{ {
@ -315,19 +336,35 @@ public class Gateway
messages.Add(new Message messages.Add(new Message
{ {
Role = "user", Role = "user",
Content = toolResponse.IsError ? SystemPrompt.ErrorPromptTemplate : SystemPrompt.ContinuePromptTemplate // Content = toolResponse.IsError ? SystemPrompt.ErrorPromptTemplate : SystemPrompt.ContinuePromptTemplate
}); Content = toolResponse.IsError ? SystemPrompt.ErrorPromptTemplate : SystemPrompt.ContinuePrompt(JsonConvert.SerializeObject(toolResponse))
messages.Add(new Message
{
Role = "user",
Content = JsonConvert.SerializeObject(toolResponse)
}); });
// messages.Add(new Message
// {
// Role = "user",
// Content = JsonConvert.SerializeObject(toolResponse)
// });
callback?.Invoke(toolMessageItem); callback?.Invoke(toolMessageItem);
}else if (mcpServer is InnerMcpServer) }else if (mcpServer is InnerMcpServer)
{ {
Type type = Type.GetType("LinkToolAddin.client.tool."+serverName); Type type = Type.GetType("LinkToolAddin.client.tool."+serverName);
MethodInfo method = type.GetMethod(toolName,BindingFlags.Public | BindingFlags.Static); MethodInfo method = type.GetMethod(toolName,BindingFlags.Public | BindingFlags.Static);
var task = method.Invoke(null, toolParams.Values.ToArray()) as Task<JsonRpcResultEntity>; var methodParams = toolParams.Values.ToArray();
object[] args = new object[methodParams.Length];
for (int i = 0; i < methodParams.Length; i++)
{
if (methodParams[i].GetType() == typeof(JArray))
{
List<string> list = new List<string>();
list = (methodParams[i] as JArray).Select(token => token.ToString()).ToList();
args[i] = list;
}
else
{
args[i] = methodParams[i];
}
}
var task = method.Invoke(null, args) as Task<JsonRpcResultEntity>;
JsonRpcResultEntity innerResult = await task; JsonRpcResultEntity innerResult = await task;
if (innerResult is JsonRpcErrorEntity) if (innerResult is JsonRpcErrorEntity)
{ {
@ -365,13 +402,14 @@ public class Gateway
messages.Add(new Message messages.Add(new Message
{ {
Role = "user", Role = "user",
Content = SystemPrompt.ContinuePromptTemplate // Content = SystemPrompt.ContinuePromptTemplate
}); Content = SystemPrompt.ContinuePrompt(JsonConvert.SerializeObject(innerResult))
messages.Add(new Message
{
Role = "user",
Content = JsonConvert.SerializeObject(innerResult)
}); });
// messages.Add(new Message
// {
// Role = "user",
// Content = JsonConvert.SerializeObject(innerResult)
// });
callback?.Invoke(toolMessageItem); callback?.Invoke(toolMessageItem);
} }
} }
@ -451,16 +489,9 @@ public class Gateway
private static async Task<string> GetToolInfos(McpServerList mcpServerList) private static async Task<string> GetToolInfos(McpServerList mcpServerList)
{ {
int loop = 0;
StringBuilder toolInfos = new StringBuilder(); StringBuilder toolInfos = new StringBuilder();
foreach (McpServer mcpServer in mcpServerList.GetAllServers()) foreach (McpServer mcpServer in mcpServerList.GetAllServers())
{ {
loop++;
if (loop > 3)
{
MessageBox.Show("达到最大循环次数", "退出循环");
break;
}
if (mcpServer is InnerMcpServer) if (mcpServer is InnerMcpServer)
{ {
InnerMcpServer innerMcpServer = (InnerMcpServer)mcpServer; InnerMcpServer innerMcpServer = (InnerMcpServer)mcpServer;

View File

@ -28,6 +28,13 @@ public class McpServerList
Description = "可以调用arcgis的地理处理工具或执行python代码等", Description = "可以调用arcgis的地理处理工具或执行python代码等",
IsActive = true IsActive = true
}); });
servers.Add("KnowledgeBase", new InnerMcpServer
{
Name = "KnowledgeBase",
Type = "inner",
Description = "可以调用进行查询知识库,获取相关参考信息。",
IsActive = true
});
} }
public McpServer GetServer(string name) public McpServer GetServer(string name)

View File

@ -7,20 +7,21 @@ public class SystemPrompt
"指令:您可以使用一组工具来回答用户的问题。还可以通过<prompt></prompt>调用用户提示词,从而使你更好地理解和完成用户的任务。整个流程结束之后单独输出一条内容为'[DONE]'的消息,前后不要有任何说明文字。" + "指令:您可以使用一组工具来回答用户的问题。还可以通过<prompt></prompt>调用用户提示词,从而使你更好地理解和完成用户的任务。整个流程结束之后单独输出一条内容为'[DONE]'的消息,前后不要有任何说明文字。" +
"调用工具要求:如果要调用工具,每次消息只能使用一个工具,用户的回复中将包含该工具的调用结果。您需要通过逐步使用工具来完成给定任务,每次工具调用需基于前一次的结果。成功调用工具之后应该马上调用下一个工具。你还可以通过<prompt></prompt>的方式来调用用户提示词,你能更好地理解和解决用户的问题。" + "调用工具要求:如果要调用工具,每次消息只能使用一个工具,用户的回复中将包含该工具的调用结果。您需要通过逐步使用工具来完成给定任务,每次工具调用需基于前一次的结果。成功调用工具之后应该马上调用下一个工具。你还可以通过<prompt></prompt>的方式来调用用户提示词,你能更好地理解和解决用户的问题。" +
"工具调用背景:你有以下工具可以调用{{toolInfos}},用户的数据库路径是{{gdbPath}}。" + "工具调用背景:你有以下工具可以调用{{toolInfos}},用户的数据库路径是{{gdbPath}}。" +
"输出风格:每次仅调用一个工具,必须基于前序工具的输出结果进行下一步操作。工具调用使用 XML 风格的标签进行格式化。如果需要进行文字说明请确保输出内容不采用Markdown格式或其他特殊文本标记文字说明应以普通段落形式呈现并且不含工具调用或prompt的XML标签。" + "输出风格:每次仅调用一个工具,必须基于前序工具的输出结果进行下一步操作。工具调用使用 XML 风格的标签进行格式化以单独信息格式输出,前后没有文字信息。" +
"如果需要进行文字说明,请只有文字内容,以普通段落形式呈现没有其他格式。" +
"工具调用格式:工具名称包含在一对标签内,每个参数也需用对应的标签包裹。结构如下:<tool_use>\n <name>{tool_name}</name>\n <arguments>{json_arguments}</arguments>\n</tool_use>。" + "工具调用格式:工具名称包含在一对标签内,每个参数也需用对应的标签包裹。结构如下:<tool_use>\n <name>{tool_name}</name>\n <arguments>{json_arguments}</arguments>\n</tool_use>。" +
"工具名称:需与所使用工具的精确名称一致。" + "工具名称:需与所使用工具的精确名称一致。" +
"参数:应为包含工具所需参数的 JSON 对象。例如:<tool_use>\\n <name>gaode:maps_geo</name>\\n <arguments>{\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}</arguments>\\n</tool_use>" + "参数:应为包含工具所需参数的 JSON 对象。例如:<tool_use>\\n <name>gaode:maps_geo</name>\\n <arguments>{\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}</arguments>\\n</tool_use>" +
"注意事项1.无论是调用工具还是调用提示词必须是单独的一条消息只输出调用格式的内容前后不能有描述性文字。内容为相应格式的XML文本调用消息中不能加任何其它文字说明" + "你必须严格遵守以下输出规则:" +
"只有单独一条的调用请求文本程序才能识别并调用从而将结果反馈给你。2.如果需要进行文字说明请先进行文字说明其中不含工具调用和prompt的XML也不要用markdown格式" + "1.XML工具调用格式必须在下一条单独输出如果前面有文字将永远无法调用工具。" +
"3.用户时间宝贵,成功调用过的工具不应重复调用,应该尽快执行下一个工具。" + //"只有单独一条的调用请求文本程序才能识别并调用,从而将结果反馈给你。" +
"4.整个工具流程调用结束后,一定要单独输出一条内容为'[DONE]'的消息表示工具调用结束。不要在文本的末尾。" + "2.文字说明如果紧跟着工具调用的XML将暴露程序XML会在下一条单独输出因此文字描述后面一定不能输出工具调用的XML格式。" +
"3.用户时间宝贵,不得重复调用上一次已成功执行的工具调用,除非有新的参数或上下文变化。" +
"4.如果目前工作已经完成无法知道用户其他需求时,一定要单独输出一条内容为'[DONE]'的消息表示工具调用结束。不要在文本的末尾。" +
"5.不得在同一消息中混合说明文字与工具调用。" +
"结果:用户将以以下格式返回工具调用结果:<tool_use_result>\n <name>{tool_name}</name>\n <result>{result}</result>\n</tool_use_result>。应为字符串类型,可以表示文件或其他输出类型。" + "结果:用户将以以下格式返回工具调用结果:<tool_use_result>\n <name>{tool_name}</name>\n <result>{result}</result>\n</tool_use_result>。应为字符串类型,可以表示文件或其他输出类型。" +
"例如,若工具返回.shp 文件,可在下一步操作中这样使用:<tool_use_result>\n <name>ArcGIS_Pro:GP</name>\n <result>{\"output_file\": \"source.shp\"}</result>\n</tool_use_result>" + "工具调用示例:MCP工具调用的格式要求示例以下是使用虚拟工具的示例<tool_use>\\n <name>gaode:maps_geo</name>\\n <arguments>{\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}</arguments>\\n</tool_use>";
"请始终遵循此格式以确保工具调用被正确解析和执行。" + //"现在你是一个精通地理信息分析和ArcGIS Pro软件的专家请以此身份回答用户的问题。\r\n\r\n指令\r\n你需要使用一组工具来回答用户的问题。也可以通过 <prompt> 标签调用用户提示词,以帮助你更好地理解任务。所有操作完成后,在最后一条输出中包含 '[DONE]',但不要单独发送这条消息。\r\n\r\n调用工具要求\r\n1. 每次只能调用一个工具,并等待用户的反馈结果。\r\n2. 所有工具调用都必须基于前一步的结果进行推理和决策。\r\n3. 工具调用必须以 XML 格式输出,并且必须作为**独立的一条消息输出**,前后不得有任何解释性文字或说明内容。\r\n4. 如果需要提供解释、说明或引导信息,请先单独输出一段普通文本,**其中不能包含任何 XML 标签或格式**。\r\n5. 不得重复调用已经成功执行过的工具,除非有新的参数或上下文需要重新调用。\r\n\r\n工具调用背景\r\n你有以下工具可以调用{{toolInfos}} \r\n用户的数据库路径是{{gdbPath}}\r\n\r\n输出风格\r\n- 所有工具调用都必须使用标准 XML 格式输出,并且每条消息只包含一次调用。\r\n- 文字说明必须单独输出,且为普通段落格式,不含任何 XML 或 Markdown 标记。\r\n- 输出顺序应为:【可选的文字说明】→【必选的工具调用】,或者仅输出工具调用。\r\n\r\n工具调用格式示例\r\n<tool_use>\r\n <name>{tool_name}</name>\r\n <arguments>{json_arguments}</arguments>\r\n</tool_use>\r\n\r\n例如\r\n<tool_use>\r\n <name>gaode:maps_geo</name>\r\n <arguments>{\"address\":\"广州市政府, 广州市\", \"city\":\"广州\"}</arguments>\r\n</tool_use>\r\n\r\n注意事项\r\n1. 工具名称必须与实际工具完全一致。\r\n2. 参数必须为合法 JSON 格式,且符合工具要求。\r\n3. 用户时间宝贵,请高效调用工具,尽快完成任务。\r\n4. 最终完成时应在最后一次响应中包含 [DONE],而不是单独输出。\r\n\r\n工具调用结果返回格式\r\n用户将以如下格式返回工具调用结果\r\n<tool_use_result>\r\n <name>{tool_name}</name>\r\n <result>{result}</result>\r\n</tool_use_result>\r\n\r\n例如\r\n<tool_use_result>\r\n <name>ArcGIS_Pro:GP</name>\r\n <result>{\"output_file\": \"source.shp\"}</result>\r\n</tool_use_result>\r\n\r\n请始终遵循此格式以确保工具调用被正确解析和执行。";
"工具调用示例:MCP工具调用的格式要求示例以下是使用虚拟工具的示例<tool_use>\n <name>search</name>\n <arguments>{\\\"query\\\": \\\"上海 人口\\\"}</arguments>\n</tool_use>\n";
public static string ContinuePromptTemplate = "这是上述工具调用的结果。{{toolResult}}\n请根据以下执行结果,清晰解释执行结果并执行下一步操作。" + public static string ContinuePromptTemplate = "这是上述工具调用的结果。{{toolResult}}\n请根据以下执行结果,清晰解释执行结果并执行下一步操作。" +
"执行下一步工具的要求1. 解析工具输出结果2. 调用下一个工具时确保参数继承前序输出。请据此继续执行"; "执行下一步工具的要求1. 解析工具输出结果2. 调用下一个工具时确保参数继承前序输出。请据此继续执行";

View File

@ -21,13 +21,14 @@ public class DocDb
{ {
ArcGISProHelpDoc, ArcGISProHelpDoc,
ArcGISProToolDoc, ArcGISProToolDoc,
TaskPlanningDoc,
ArcGISProApplicantExample ArcGISProApplicantExample
} }
public Dictionary<KnowledgeBase, string> knowledgeBase = new Dictionary<KnowledgeBase, string> public Dictionary<KnowledgeBase, string> knowledgeBase = new Dictionary<KnowledgeBase, string>
{ {
{KnowledgeBase.ArcGISProHelpDoc,"6a77c5a68de64f469b79fcdcde9d5001"} {KnowledgeBase.ArcGISProHelpDoc,"6a77c5a68de64f469b79fcdcde9d5001"},
{KnowledgeBase.ArcGISProToolDoc,"080f8925318247ea822a9e12db5cb5cd"},
{KnowledgeBase.ArcGISProApplicantExample,"eef60f7c879b4e8597138c261578d2a5"}
}; };
public async Task<KnowledgeResult> Retrieve(string query) public async Task<KnowledgeResult> Retrieve(string query)

View File

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using ArcGIS.Desktop.Core.Geoprocessing; using ArcGIS.Desktop.Core.Geoprocessing;
using ArcGIS.Desktop.Framework.Dialogs; using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Framework.Threading.Tasks; using ArcGIS.Desktop.Framework.Threading.Tasks;
using Newtonsoft.Json;
namespace LinkToolAddin.server; namespace LinkToolAddin.server;
@ -22,7 +23,7 @@ public class CallArcGISPro
Error = new Error() Error = new Error()
{ {
Code = results.ErrorCode, Code = results.ErrorCode,
Message = results.ErrorMessages.ToString() Message = JsonConvert.SerializeObject(results.ErrorMessages)
} }
}; };
} }
@ -30,7 +31,7 @@ public class CallArcGISPro
{ {
jsonRpcResultEntity = new JsonRpcSuccessEntity jsonRpcResultEntity = new JsonRpcSuccessEntity
{ {
Result = results.Messages.ToString() Result = JsonConvert.SerializeObject(results.Messages)
}; };
} }
return jsonRpcResultEntity; return jsonRpcResultEntity;

View File

@ -20,7 +20,9 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="24"/> <RowDefinition Height="24"/>
<RowDefinition Height="24"/> <RowDefinition Height="24"/>
<RowDefinition Height="240"/> <RowDefinition Height="480"/>
<RowDefinition Height="24"/>
<RowDefinition Height="24"/>
<RowDefinition Height="24"/> <RowDefinition Height="24"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Button Grid.Row="0" Content="Test Workflow" Name="TestServer" Click="TestWorkflow_OnClick"></Button> <Button Grid.Row="0" Content="Test Workflow" Name="TestServer" Click="TestWorkflow_OnClick"></Button>
@ -31,9 +33,11 @@
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" ToolTip="输入测试提示词" Name="PromptTestTextBox"></TextBox> <TextBox Grid.Row="0" Grid.Column="0" ToolTip="输入测试提示词" Name="PromptTestTextBox"></TextBox>
<Button Grid.Row="0" Grid.Column="1" Content="测试" Name="PromptTestButton" Click="PromptTestButton_OnClick"></Button> <Button Grid.Row="0" Grid.Column="1" Content="发送" Name="PromptTestButton" Click="PromptTestButton_OnClick"></Button>
</Grid> </Grid>
<TextBox Grid.Row="2" ToolTip="大模型回复" Name="ReplyTextBox" TextWrapping="Wrap"></TextBox> <TextBox Grid.Row="2" ToolTip="大模型回复" Name="ReplyTextBox" TextWrapping="Wrap"></TextBox>
<Button Grid.Row="3" Content="Test Stream" Name="TestStream" Click="TestStream_OnClick"></Button> <Button Grid.Row="3" Content="停止回答" Name="StopConversation" Click="StopConversation_OnClick"></Button>
<Button Grid.Row="4" Content="Test Stream" Name="TestStream" Click="TestStream_OnClick"></Button>
<Button Grid.Row="5" Content="Test Arcgis Tool" Name="TestArcGisTool" Click="TestArcGisTool_OnClick"></Button>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -1,12 +1,18 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Xml.Linq;
using LinkToolAddin.client; using LinkToolAddin.client;
using LinkToolAddin.host; using LinkToolAddin.host;
using LinkToolAddin.host.llm; using LinkToolAddin.host.llm;
using LinkToolAddin.host.llm.entity; using LinkToolAddin.host.llm.entity;
using LinkToolAddin.host.mcp;
using LinkToolAddin.host.prompt;
using LinkToolAddin.message; using LinkToolAddin.message;
using LinkToolAddin.resource; using LinkToolAddin.resource;
using LinkToolAddin.server; using LinkToolAddin.server;
@ -231,5 +237,42 @@ namespace LinkToolAddin.ui.dockpane
{ {
Request_Bailian_Stream_Test(); 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);
}
}
} }
} }