v0.1.4版本 #2
@ -98,6 +98,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Folder Include="doc\" />
|
||||||
<Folder Include="resource\" />
|
<Folder Include="resource\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"profiles": {
|
"profiles": {
|
||||||
"LinkToolAddin": {
|
"LinkToolAddin": {
|
||||||
"commandName": "Executable",
|
"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",
|
"applicationUrl": "https://localhost:5001",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
|||||||
@ -8,7 +8,9 @@ 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.Xml;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using ArcGIS.Desktop.Framework.Dialogs;
|
||||||
using LinkToolAddin.client;
|
using LinkToolAddin.client;
|
||||||
using LinkToolAddin.client.prompt;
|
using LinkToolAddin.client.prompt;
|
||||||
using LinkToolAddin.host.llm;
|
using LinkToolAddin.host.llm;
|
||||||
@ -23,6 +25,7 @@ using Microsoft.Extensions.AI;
|
|||||||
using ModelContextProtocol.Client;
|
using ModelContextProtocol.Client;
|
||||||
using ModelContextProtocol.Protocol.Types;
|
using ModelContextProtocol.Protocol.Types;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using Newtonsoft.Json.Schema;
|
using Newtonsoft.Json.Schema;
|
||||||
using Newtonsoft.Json.Schema.Generation;
|
using Newtonsoft.Json.Schema.Generation;
|
||||||
using Tool = LinkToolAddin.host.mcp.Tool;
|
using Tool = LinkToolAddin.host.mcp.Tool;
|
||||||
@ -52,8 +55,8 @@ public class Gateway
|
|||||||
Content = message
|
Content = message
|
||||||
});
|
});
|
||||||
bool goOn = true;
|
bool goOn = true;
|
||||||
string pattern = "<tool_use>[\\s\\S]*?<\\/tool_use>";
|
string pattern = "^<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();
|
||||||
while (goOn)
|
while (goOn)
|
||||||
{
|
{
|
||||||
@ -65,6 +68,7 @@ public class Gateway
|
|||||||
TopP = 1,
|
TopP = 1,
|
||||||
MaxTokens = 1000,
|
MaxTokens = 1000,
|
||||||
});
|
});
|
||||||
|
log.Info(reponse);
|
||||||
messages.Add(new Message
|
messages.Add(new Message
|
||||||
{
|
{
|
||||||
Role = "assistant",
|
Role = "assistant",
|
||||||
@ -213,18 +217,20 @@ 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)
|
||||||
{
|
{
|
||||||
string serverName = mcpServer.Name;
|
InnerMcpServer innerMcpServer = (InnerMcpServer)mcpServer;
|
||||||
if (serverName is null)
|
Type type = Type.GetType("LinkToolAddin.client.tool." + innerMcpServer.Name);
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Type type = Type.GetType("LinkToolAddin.client.tool." + serverName);
|
|
||||||
Type type2 = Type.GetType("LinkToolAddin.client.tool.ArcGisPro");
|
|
||||||
MethodInfo[] methods = type.GetMethods();
|
MethodInfo[] methods = type.GetMethods();
|
||||||
foreach (MethodInfo method in methods)
|
foreach (MethodInfo method in methods)
|
||||||
{
|
{
|
||||||
@ -237,12 +243,14 @@ public class Gateway
|
|||||||
{
|
{
|
||||||
Tool = new Tool
|
Tool = new Tool
|
||||||
{
|
{
|
||||||
Name = methodName,
|
Name = innerMcpServer.Name + ":" + methodName,
|
||||||
Description = methodDescription,
|
Description = methodDescription,
|
||||||
Arguments = methodParamSchema
|
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<McpClientTool> tools = await client.GetToolListAsync();
|
IList<McpClientTool> tools = await client.GetToolListAsync();
|
||||||
foreach (McpClientTool tool in tools)
|
foreach (McpClientTool tool in tools)
|
||||||
{
|
{
|
||||||
string toolName = tool.Name;
|
string toolName = (mcpServer as SseMcpServer).Name + ":" + tool.Name;
|
||||||
string toolDescription = tool.Description;
|
string toolDescription = tool.Description;
|
||||||
string toolParamSchema = tool.JsonSchema.ToString();
|
string toolParamSchema = tool.JsonSchema.ToString();
|
||||||
McpToolDefinition toolDefinition = new McpToolDefinition
|
McpToolDefinition toolDefinition = new McpToolDefinition
|
||||||
@ -265,6 +273,7 @@ public class Gateway
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
|
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
|
||||||
|
toolInfos.AppendLine();
|
||||||
}
|
}
|
||||||
}else if (mcpServer is StdioMcpServer)
|
}else if (mcpServer is StdioMcpServer)
|
||||||
{
|
{
|
||||||
@ -272,7 +281,7 @@ public class Gateway
|
|||||||
IList<McpClientTool> tools = await client.GetToolListAsync();
|
IList<McpClientTool> tools = await client.GetToolListAsync();
|
||||||
foreach (McpClientTool tool in tools)
|
foreach (McpClientTool tool in tools)
|
||||||
{
|
{
|
||||||
string toolName = tool.Name;
|
string toolName = (mcpServer as StdioMcpServer).Name + ":" + tool.Name;;
|
||||||
string toolDescription = tool.Description;
|
string toolDescription = tool.Description;
|
||||||
string toolParamSchema = tool.JsonSchema.ToString();
|
string toolParamSchema = tool.JsonSchema.ToString();
|
||||||
McpToolDefinition toolDefinition = new McpToolDefinition
|
McpToolDefinition toolDefinition = new McpToolDefinition
|
||||||
@ -281,16 +290,25 @@ public class Gateway
|
|||||||
{
|
{
|
||||||
Name = toolName,
|
Name = toolName,
|
||||||
Description = toolDescription,
|
Description = toolDescription,
|
||||||
Arguments = toolParamSchema
|
Arguments = CompressJson(toolParamSchema)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
|
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
|
||||||
|
toolInfos.AppendLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return toolInfos.ToString();
|
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)
|
private static string GenerateMethodParamSchema(MethodInfo method)
|
||||||
{
|
{
|
||||||
var generator = new JSchemaGenerator
|
var generator = new JSchemaGenerator
|
||||||
@ -316,8 +334,11 @@ public class Gateway
|
|||||||
|
|
||||||
paramSchema.Properties.Add(param.Name, typeSchema);
|
paramSchema.Properties.Add(param.Name, typeSchema);
|
||||||
}
|
}
|
||||||
|
var settings = new JsonSerializerSettings {
|
||||||
return paramSchema.ToString();
|
Formatting = Newtonsoft.Json.Formatting.None, // 关键设置:禁用缩进和换行
|
||||||
|
NullValueHandling = NullValueHandling.Ignore // 可选:忽略空值
|
||||||
|
};
|
||||||
|
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,
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
public class SystemPrompt
|
public class SystemPrompt
|
||||||
{
|
{
|
||||||
public static string SysPromptTemplate = "现在你是一个精通ArcGIS Pro的专家,请以此身份回答用户的问题。";
|
public static string SysPromptTemplate = "现在你是一个精通ArcGIS Pro的专家,请以此身份回答用户的问题。你有以下工具可以调用{{toolInfos}},用户的数据库路径是{{gdbPath}}。MCP工具调用的格式要求示例:<tool_use>\n <name>search</name>\n <arguments>{\\\"query\\\": \\\"上海 人口\\\"}</arguments>\n</tool_use>";
|
||||||
|
|
||||||
public static string ContinuePromptTemplate = "上一个工具执行的结果如下,请据此继续执行";
|
public static string ContinuePromptTemplate = "上一个工具执行的结果如下,请据此继续执行";
|
||||||
|
|
||||||
|
|||||||
@ -18,11 +18,20 @@
|
|||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="24"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="24"/>
|
||||||
|
<RowDefinition Height="240"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<DockPanel Grid.Row="0" LastChildFill="true" KeyboardNavigation.TabNavigation="Local" Height="30">
|
<Button Grid.Row="0" Content="Test Workflow" Name="TestServer" Click="TestWorkflow_OnClick"></Button>
|
||||||
<Button Content="Test Workflow" Name="TestWorkflow" Click="TestWorkflow_OnClick"></Button>
|
<Grid Grid.Row="1">
|
||||||
</DockPanel>
|
<Grid.RowDefinitions><RowDefinition Height="24"/></Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<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>
|
||||||
|
</Grid>
|
||||||
|
<TextBox Grid.Row="2" ToolTip="大模型回复" Name="ReplyTextBox" TextWrapping="Wrap"></TextBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using LinkToolAddin.client;
|
using LinkToolAddin.client;
|
||||||
@ -146,12 +147,27 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
|
|
||||||
private void TestWorkflow_OnClick(object sender, RoutedEventArgs e)
|
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)
|
public void ShowMessage(MessageListItem msg)
|
||||||
{
|
{
|
||||||
log.Info(msg.content);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,7 @@ 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 = "Test Dockpane";
|
||||||
public string Heading
|
public string Heading
|
||||||
{
|
{
|
||||||
get => _heading;
|
get => _heading;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user