diff --git a/LinkToolAddin.csproj b/LinkToolAddin.csproj
index c53da32..a4143cc 100644
--- a/LinkToolAddin.csproj
+++ b/LinkToolAddin.csproj
@@ -98,6 +98,7 @@
+
diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json
index e98eaad..5a2c881 100644
--- a/Properties/launchSettings.json
+++ b/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"LinkToolAddin": {
"commandName": "Executable",
- "executablePath": "C:\\Users\\PeterZhong\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\ArcGISPro.exe",
+ "executablePath": "C:\\Program Files\\ArcGIS\\Pro\\bin\\ArcGISPro.exe",
"applicationUrl": "https://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
diff --git a/host/Gateway.cs b/host/Gateway.cs
index 847fcd3..2380d4f 100644
--- a/host/Gateway.cs
+++ b/host/Gateway.cs
@@ -8,7 +8,9 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
+using System.Xml;
using System.Xml.Linq;
+using ArcGIS.Desktop.Framework.Dialogs;
using LinkToolAddin.client;
using LinkToolAddin.client.prompt;
using LinkToolAddin.host.llm;
@@ -23,6 +25,7 @@ using Microsoft.Extensions.AI;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Types;
using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Schema.Generation;
using Tool = LinkToolAddin.host.mcp.Tool;
@@ -52,8 +55,8 @@ public class Gateway
Content = message
});
bool goOn = true;
- string pattern = "[\\s\\S]*?<\\/tool_use>";
- string promptPattern = "[\\s\\S]*?<\\/prompt>";
+ string pattern = "^[\\s\\S]*?<\\/tool_use>$";
+ string promptPattern = "^[\\s\\S]*?<\\/prompt>$";
McpServerList mcpServerList = new McpServerList();
while (goOn)
{
@@ -65,6 +68,7 @@ public class Gateway
TopP = 1,
MaxTokens = 1000,
});
+ log.Info(reponse);
messages.Add(new Message
{
Role = "assistant",
@@ -213,18 +217,20 @@ public class Gateway
private static async Task GetToolInfos(McpServerList mcpServerList)
{
+ int loop = 0;
StringBuilder toolInfos = new StringBuilder();
foreach (McpServer mcpServer in mcpServerList.GetAllServers())
{
+ loop++;
+ if (loop > 3)
+ {
+ MessageBox.Show("达到最大循环次数", "退出循环");
+ break;
+ }
if (mcpServer is InnerMcpServer)
{
- string serverName = mcpServer.Name;
- if (serverName is null)
- {
- continue;
- }
- Type type = Type.GetType("LinkToolAddin.client.tool." + serverName);
- Type type2 = Type.GetType("LinkToolAddin.client.tool.ArcGisPro");
+ InnerMcpServer innerMcpServer = (InnerMcpServer)mcpServer;
+ Type type = Type.GetType("LinkToolAddin.client.tool." + innerMcpServer.Name);
MethodInfo[] methods = type.GetMethods();
foreach (MethodInfo method in methods)
{
@@ -237,12 +243,14 @@ public class Gateway
{
Tool = new Tool
{
- Name = methodName,
+ Name = innerMcpServer.Name + ":" + methodName,
Description = methodDescription,
Arguments = methodParamSchema
}
};
- toolInfos.AppendLine(JsonConvert.DeserializeXmlNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
+ XNode node = JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition));
+ toolInfos.AppendLine(node.ToString());
+ toolInfos.AppendLine();
}
}
}
@@ -252,7 +260,7 @@ public class Gateway
IList tools = await client.GetToolListAsync();
foreach (McpClientTool tool in tools)
{
- string toolName = tool.Name;
+ string toolName = (mcpServer as SseMcpServer).Name + ":" + tool.Name;
string toolDescription = tool.Description;
string toolParamSchema = tool.JsonSchema.ToString();
McpToolDefinition toolDefinition = new McpToolDefinition
@@ -265,6 +273,7 @@ public class Gateway
}
};
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
+ toolInfos.AppendLine();
}
}else if (mcpServer is StdioMcpServer)
{
@@ -272,7 +281,7 @@ public class Gateway
IList tools = await client.GetToolListAsync();
foreach (McpClientTool tool in tools)
{
- string toolName = tool.Name;
+ string toolName = (mcpServer as StdioMcpServer).Name + ":" + tool.Name;;
string toolDescription = tool.Description;
string toolParamSchema = tool.JsonSchema.ToString();
McpToolDefinition toolDefinition = new McpToolDefinition
@@ -281,16 +290,25 @@ public class Gateway
{
Name = toolName,
Description = toolDescription,
- Arguments = toolParamSchema
+ Arguments = CompressJson(toolParamSchema)
}
};
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
+ toolInfos.AppendLine();
}
}
}
return toolInfos.ToString();
}
+ public static string CompressJson(string json)
+ {
+ // 解析JSON并自动去除无关空白
+ var token = JToken.Parse(json);
+ // 序列化为无格式紧凑字符串
+ return token.ToString(Newtonsoft.Json.Formatting.None);
+ }
+
private static string GenerateMethodParamSchema(MethodInfo method)
{
var generator = new JSchemaGenerator
@@ -316,8 +334,11 @@ public class Gateway
paramSchema.Properties.Add(param.Name, typeSchema);
}
-
- return paramSchema.ToString();
+ var settings = new JsonSerializerSettings {
+ Formatting = Newtonsoft.Json.Formatting.None, // 关键设置:禁用缩进和换行
+ NullValueHandling = NullValueHandling.Ignore // 可选:忽略空值
+ };
+ return JsonConvert.SerializeObject(paramSchema, settings);;
}
public static async void TestChatMessage(string message, string model, string gdbPath,
diff --git a/host/prompt/SystemPrompt.cs b/host/prompt/SystemPrompt.cs
index 186439b..48938d5 100644
--- a/host/prompt/SystemPrompt.cs
+++ b/host/prompt/SystemPrompt.cs
@@ -2,7 +2,7 @@
public class SystemPrompt
{
- public static string SysPromptTemplate = "现在你是一个精通ArcGIS Pro的专家,请以此身份回答用户的问题。";
+ public static string SysPromptTemplate = "现在你是一个精通ArcGIS Pro的专家,请以此身份回答用户的问题。你有以下工具可以调用{{toolInfos}},用户的数据库路径是{{gdbPath}}。MCP工具调用的格式要求示例:\n search\n {\\\"query\\\": \\\"上海 人口\\\"}\n";
public static string ContinuePromptTemplate = "上一个工具执行的结果如下,请据此继续执行";
diff --git a/ui/dockpane/TestDockpane.xaml b/ui/dockpane/TestDockpane.xaml
index 4782989..e550084 100644
--- a/ui/dockpane/TestDockpane.xaml
+++ b/ui/dockpane/TestDockpane.xaml
@@ -18,11 +18,20 @@
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui/dockpane/TestDockpane.xaml.cs b/ui/dockpane/TestDockpane.xaml.cs
index 802464a..d67e5c9 100644
--- a/ui/dockpane/TestDockpane.xaml.cs
+++ b/ui/dockpane/TestDockpane.xaml.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
using LinkToolAddin.client;
@@ -146,12 +147,27 @@ namespace LinkToolAddin.ui.dockpane
private void TestWorkflow_OnClick(object sender, RoutedEventArgs e)
{
- Gateway.SendMessage("你有什么工具","qwen-max","test.gdb",ShowMessage);
+ // 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);
+ }
+
+ public void AddReply(MessageListItem msg)
+ {
+ string content = msg.content;
+ log.Info(content);
+ string originContent = ReplyTextBox.Text;
+ ReplyTextBox.Text = originContent + content;
+ }
}
}
diff --git a/ui/dockpane/TestDockpaneViewModel.cs b/ui/dockpane/TestDockpaneViewModel.cs
index 0661d9c..daf9d4c 100644
--- a/ui/dockpane/TestDockpaneViewModel.cs
+++ b/ui/dockpane/TestDockpaneViewModel.cs
@@ -41,7 +41,7 @@ namespace LinkToolAddin.ui.dockpane
///
/// Text shown near the top of the DockPane.
///
- private string _heading = "My DockPane";
+ private string _heading = "Test Dockpane";
public string Heading
{
get => _heading;