1. 修复ArcGIS Pro工具范围结果为空的问题
2. 识别单条消息末尾的[DONE]
This commit is contained in:
parent
ea021135a3
commit
9fe13fa719
@ -6,8 +6,11 @@ using System.Threading.Tasks;
|
|||||||
using ArcGIS.Core.Data;
|
using ArcGIS.Core.Data;
|
||||||
using ArcGIS.Core.Data.Raster;
|
using ArcGIS.Core.Data.Raster;
|
||||||
using ArcGIS.Core.Geometry;
|
using ArcGIS.Core.Geometry;
|
||||||
|
using ArcGIS.Desktop.Core.Geoprocessing;
|
||||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||||
using LinkToolAddin.server;
|
using LinkToolAddin.server;
|
||||||
|
using LinkToolAddin.ui.dockpane;
|
||||||
|
using log4net;
|
||||||
using ModelContextProtocol.Server;
|
using ModelContextProtocol.Server;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
@ -16,14 +19,40 @@ namespace LinkToolAddin.client.tool;
|
|||||||
|
|
||||||
public class ArcGisPro
|
public class ArcGisPro
|
||||||
{
|
{
|
||||||
[McpServerTool, Description("可以通过调用ArcGIS Pro的地理处理工具实现一些数据处理功能。")]
|
private static ILog log = LogManager.GetLogger(typeof(ArcGisPro));
|
||||||
|
[McpServerTool, Description("可以通过调用ArcGIS Pro的地理处理工具实现一些数据处理功能,传入参数必须严格遵循ArcGIS Pro调用工具的标准调用名和参数要求知识库。")]
|
||||||
public static async Task<JsonRpcResultEntity> ArcGisProTool(string toolName, List<string> toolParams)
|
public static async Task<JsonRpcResultEntity> ArcGisProTool(string toolName, List<string> toolParams)
|
||||||
{
|
{
|
||||||
// Call the ArcGIS Pro method and get the result
|
IGPResult results = await Geoprocessing.ExecuteToolAsync(toolName, toolParams);
|
||||||
var result = await server.CallArcGISPro.CallArcGISProTool(toolName, toolParams);
|
JsonRpcResultEntity jsonRpcResultEntity;
|
||||||
|
if (results.IsFailed)
|
||||||
// Serialize the result back to a JSON string
|
{
|
||||||
return result;
|
log.Error(results.ErrorMessages);
|
||||||
|
jsonRpcResultEntity = new JsonRpcErrorEntity()
|
||||||
|
{
|
||||||
|
Error = new Error()
|
||||||
|
{
|
||||||
|
Code = results.ErrorCode,
|
||||||
|
Message = JsonConvert.SerializeObject(results.ErrorMessages)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}else if(results.HasWarnings)
|
||||||
|
{
|
||||||
|
log.Warn(results.Messages);
|
||||||
|
jsonRpcResultEntity = new JsonRpcSuccessEntity
|
||||||
|
{
|
||||||
|
Result = JsonConvert.SerializeObject(results.Messages)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.Info("success gp tool");
|
||||||
|
jsonRpcResultEntity = new JsonRpcSuccessEntity
|
||||||
|
{
|
||||||
|
Result = JsonConvert.SerializeObject(results.Messages)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return jsonRpcResultEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
[McpServerTool, Description("查看指定数据的坐标系、范围、几何类型、是否有Z坐标和M坐标,获取字段列表等")]
|
[McpServerTool, Description("查看指定数据的坐标系、范围、几何类型、是否有Z坐标和M坐标,获取字段列表等")]
|
||||||
|
|||||||
@ -222,7 +222,7 @@ public class Gateway
|
|||||||
};
|
};
|
||||||
callback?.Invoke(chatMessageListItem);
|
callback?.Invoke(chatMessageListItem);
|
||||||
}
|
}
|
||||||
if (reponse == "[DONE]")
|
if (reponse.EndsWith("[DONE]"))
|
||||||
{
|
{
|
||||||
goOn = false;
|
goOn = false;
|
||||||
}
|
}
|
||||||
@ -467,15 +467,20 @@ public class Gateway
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
string content = chunk;
|
||||||
|
if (content.EndsWith("[DONE]"))
|
||||||
|
{
|
||||||
|
content = content.Substring(0, content.Length - 6);
|
||||||
|
}
|
||||||
//普通流式消息卡片
|
//普通流式消息卡片
|
||||||
MessageListItem chatMessageListItem = new ChatMessageItem()
|
MessageListItem chatMessageListItem = new ChatMessageItem()
|
||||||
{
|
{
|
||||||
content = chunk,
|
content = content,
|
||||||
role = "assistant",
|
role = "assistant",
|
||||||
type = MessageType.CHAT_MESSAGE,
|
type = MessageType.CHAT_MESSAGE,
|
||||||
id = timestamp.ToString()
|
id = timestamp.ToString()
|
||||||
};
|
};
|
||||||
messageContent = chunk;
|
messageContent = content;
|
||||||
callback?.Invoke(chatMessageListItem);
|
callback?.Invoke(chatMessageListItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,14 +20,16 @@ public class SystemPrompt
|
|||||||
"4.如果目前工作已经完成无法知道用户其他需求时,一定要单独输出一条内容为'[DONE]'的消息表示工具调用结束。不要在文本的末尾。" +
|
"4.如果目前工作已经完成无法知道用户其他需求时,一定要单独输出一条内容为'[DONE]'的消息表示工具调用结束。不要在文本的末尾。" +
|
||||||
"5.不得在同一消息中混合说明文字与工具调用。" +
|
"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>。应为字符串类型,可以表示文件或其他输出类型。" +
|
||||||
"工具调用示例:MCP工具调用的格式要求示例:以下是使用虚拟工具的示例:<tool_use>\\n <name>gaode:maps_geo</name>\\n <arguments>{\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}</arguments>\\n</tool_use>";
|
"工具调用示例:MCP工具调用的格式要求示例:以下是使用虚拟工具的示例:<tool_use>\\n <name>gaode:maps_geo</name>\\n <arguments>{\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}</arguments>\\n</tool_use>"+
|
||||||
|
"特别地:需要调用ArcGIS Pro工具前必须先查询帮助文档、标准调用名和参数后再进行调用";
|
||||||
//"现在你是一个精通地理信息分析和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请始终遵循此格式以确保工具调用被正确解析和执行。";
|
//"现在你是一个精通地理信息分析和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请始终遵循此格式以确保工具调用被正确解析和执行。";
|
||||||
|
|
||||||
public static string ContinuePromptTemplate = "这是上述工具调用的结果。{{toolResult}}\n请根据以下执行结果,清晰解释执行结果并执行下一步操作。" +
|
public static string ContinuePromptTemplate = "这是上述工具调用的结果。{{toolResult}}\n请根据以下执行结果,清晰解释执行结果并执行下一步操作。" +
|
||||||
"执行下一步工具的要求:1. 解析工具输出结果2. 调用下一个工具时确保参数继承前序输出。请据此继续执行";
|
"执行下一步工具的要求:1. 解析工具输出结果2. 调用下一个工具时确保参数继承前序输出。请据此继续执行";
|
||||||
|
|
||||||
public static string ErrorPromptTemplate = "执行上一个工具的时候出现以下错误,需按以下流程处理:1. 错误解析:分析错误类型及具体原因(见下方错误信息),根据错误信息选择修复方案,```" +
|
public static string ErrorPromptTemplate = "执行上一个工具的时候出现以下错误,需按以下流程处理:1. 错误解析:分析错误类型及具体原因(见下方错误信息),根据错误信息选择修复方案,```" +
|
||||||
"2. 修复方案:(1)根据错误类型生成对应的工具重试策略(2)参数调整:明确需要修改的参数及修改方式。3. 工具重试:使用调整后的参数重新调用工具。错误信息如下,请根据报错信息重试,4.如果没有具体的错误描述信息请检查输出文件是否已经存在,若已经存在默认执行成功";
|
"2. 修复方案:(1)根据错误类型生成对应的工具重试策略(2)参数调整:明确需要修改的参数及修改方式。3. 工具重试:使用调整后的参数重新调用工具。错误信息如下,请根据报错信息重试,4.如果没有具体的错误描述信息请检查输出文件是否已经存在,若已经存在默认执行成功"+
|
||||||
|
"5.查询可能相关的知识库和帮助文档,纠正调用参数中存在的错误";
|
||||||
|
|
||||||
public static string SysPrompt(string gdbPath, string toolInfos)
|
public static string SysPrompt(string gdbPath, string toolInfos)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -199,7 +199,7 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
{
|
{
|
||||||
string userPrompt = PromptTestTextBox.Text;
|
string userPrompt = PromptTestTextBox.Text;
|
||||||
// Gateway.SendMessage(userPrompt,"qwen-max","C:/Project/test.gdb",AddReply);
|
// Gateway.SendMessage(userPrompt,"qwen-max","C:/Project/test.gdb",AddReply);
|
||||||
Gateway.SendMessageStream(userPrompt,"qwen-max", "F:\\secondsemester\\linktool\\test\\linktooltest\\linktooltest.gdb", AddReplyStream);
|
Gateway.SendMessageStream(userPrompt,"qwen-max", "D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\20250420_AiDemoProject.gdb", AddReplyStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddReplyStream(MessageListItem msg)
|
public void AddReplyStream(MessageListItem msg)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user