v0.1.4版本 #2
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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. 调用下一个工具时确保参数继承前序输出。请据此继续执行";
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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>
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user