diff --git a/LinkToolAddin.csproj b/LinkToolAddin.csproj index bece90c..33ff34b 100644 --- a/LinkToolAddin.csproj +++ b/LinkToolAddin.csproj @@ -6,6 +6,10 @@ true CA1416 net8.0-windows + true + false + 0.1.1 + LinkTool灵图 diff --git a/host/Gateway.cs b/host/Gateway.cs index 78889e8..428ed47 100644 --- a/host/Gateway.cs +++ b/host/Gateway.cs @@ -15,6 +15,7 @@ using System.Xml.Linq; using ArcGIS.Desktop.Internal.Mapping.Locate; using LinkToolAddin.client; using LinkToolAddin.client.prompt; +using LinkToolAddin.client.tool; using LinkToolAddin.host.llm; using LinkToolAddin.host.llm.entity; using LinkToolAddin.host.mcp; @@ -257,10 +258,11 @@ public class Gateway PromptServerList promptServerList = new PromptServerList(); int loop = 0; string messageContent = ""; //一次请求下完整的response + bool queriedKnowledge = false; while (goOn) { loop++; - if (loop > 20) + if (loop > 500) { MessageBox.Show("达到最大循环次数", "退出循环"); break; @@ -389,8 +391,8 @@ public class Gateway }); MessageListItem toolMessageListItem = new ToolMessageItem() { - content = "", - result = "", + content = toolName, + result = "工具运行中" + toolName, toolName = toolName, toolParams = toolParams, role = "user", @@ -426,6 +428,7 @@ public class Gateway Content = messageContent }); } + Thread.Sleep(100); /*统一处理本次请求中的MCP工具调用需求*/ foreach (McpToolRequest mcpToolRequest in mcpToolRequests) { @@ -492,6 +495,62 @@ public class Gateway } else if (mcpServer is InnerMcpServer) { + InnerMcpServer innerMcpServer = mcpServer as InnerMcpServer; + string mcpServerName = innerMcpServer.Name; + if (toolName == "ArcGisProTool" && queriedKnowledge == false) + { + JsonRpcResultEntity knowledgeResult = await KnowledgeBase.QueryArcgisToolDoc(toolParams["toolName"].ToString()); + if (knowledgeResult is JsonRpcSuccessEntity) + { + JsonRpcSuccessEntity knowledgeSuccessResult = knowledgeResult as JsonRpcSuccessEntity; + MessageListItem toolMessageItem = new ToolMessageItem + { + toolName = "QueryArcgisToolDoc", + toolParams = new Dictionary(){{"query",toolParams["toolName"].ToString()}}, + type = MessageType.TOOL_MESSAGE, + status = "success", + content = JsonConvert.SerializeObject(knowledgeSuccessResult.Result), + result = JsonConvert.SerializeObject(knowledgeSuccessResult.Result), + id = (timestamp + 4).ToString(), + role = "user" + }; + messages.Add(new Message + { + Role = "user", + Content = SystemPrompt.ToolContinuePrompt(JsonConvert.SerializeObject(knowledgeSuccessResult)) + }); + Application.Current.Dispatcher.Invoke(() => + { + callback?.Invoke(toolMessageItem); + }); + queriedKnowledge = true; + } + else + { + JsonRpcErrorEntity knowledgeErrorResult = knowledgeResult as JsonRpcErrorEntity; + MessageListItem toolMessageItem = new ToolMessageItem + { + toolName = "QueryArcgisToolDoc", + toolParams = new Dictionary(){{"query",toolParams["toolName"].ToString()}}, + type = MessageType.TOOL_MESSAGE, + status = "fail", + content = JsonConvert.SerializeObject(knowledgeErrorResult.Error), + result = JsonConvert.SerializeObject(knowledgeErrorResult.Error), + id = (timestamp + 4).ToString(), + role = "user" + }; + messages.Add(new Message + { + Role = "user", + Content = SystemPrompt.ErrorPrompt(JsonConvert.SerializeObject(knowledgeErrorResult)) + }); + Application.Current.Dispatcher.Invoke(() => + { + callback?.Invoke(toolMessageItem); + }); + } + continue; + } Type type = Type.GetType("LinkToolAddin.client.tool." + (mcpServer as InnerMcpServer).Name); MethodInfo method = type.GetMethod(toolName, BindingFlags.Public | BindingFlags.Static); var methodParams = toolParams.Values.ToArray(); @@ -512,6 +571,7 @@ public class Gateway var task = method.Invoke(null, args) as Task; JsonRpcResultEntity innerResult = await task; + queriedKnowledge = false; if (innerResult is JsonRpcErrorEntity) { MessageListItem toolMessageItem = new ToolMessageItem @@ -573,24 +633,25 @@ public class Gateway try { string promptContent = DynamicPrompt.GetPrompt(promptRequest.PromptName, promptRequest.PromptArgs); - messages.Add(new Message - { - Role = "user", - Content = promptContent - }); - MessageListItem toolMessageItem = new ToolMessageItem + MessageListItem promptMessageItem = new ToolMessageItem { toolName = "调用提示词", - toolParams = null, + toolParams = new Dictionary(), type = MessageType.TOOL_MESSAGE, status = "success", content = "成功调用提示词:"+promptRequest.PromptName, id = (timestamp+1).ToString(), + role = "user", result = "成功调用提示词:"+promptRequest.PromptName }; Application.Current.Dispatcher.Invoke(() => { - callback?.Invoke(toolMessageItem); + callback?.Invoke(promptMessageItem); + }); + messages.Add(new Message + { + Role = "user", + Content = promptContent }); } catch (Exception e) diff --git a/host/prompt/SystemPrompt.cs b/host/prompt/SystemPrompt.cs index 2295d68..b6db27c 100644 --- a/host/prompt/SystemPrompt.cs +++ b/host/prompt/SystemPrompt.cs @@ -49,4 +49,11 @@ public class SystemPrompt errPrompt = errPrompt.Replace("{{toolResult}}", toolResult); return errPrompt; } + + public static string ToolContinuePrompt(string toolResult) + { + string continuePrompt = "根据你需要调用的工具查询到如下帮助文档内容,请严格按照帮助文档中的参数和名称要求再次生成准确的工具调用请求以确保工具调用成功。\n{{toolResult}}"; + continuePrompt = continuePrompt.Replace("{{toolResult}}", toolResult); + return continuePrompt; + } } \ No newline at end of file diff --git a/ui/VersionButton.cs b/ui/VersionButton.cs index bc4df57..bbc7a75 100644 --- a/ui/VersionButton.cs +++ b/ui/VersionButton.cs @@ -22,7 +22,7 @@ namespace LinkToolAddin { internal class VersionButton : Button { - private string version = "0.1.1"; + private string version = "0.1.2"; protected override void OnClick() { MessageBox.Show($"当前LinkTool版本为{version}", "版本信息"); diff --git a/ui/dockpane/DialogDockpane.xaml.cs b/ui/dockpane/DialogDockpane.xaml.cs index 3e623ae..45e9cec 100644 --- a/ui/dockpane/DialogDockpane.xaml.cs +++ b/ui/dockpane/DialogDockpane.xaml.cs @@ -117,6 +117,7 @@ namespace LinkToolAddin.ui.dockpane QuestionTextbox.Text = ""; borderItemsDict[timestamp.ToString()] = userMsgBoder; ChatHistoryStackPanel.Children.Add(userMsgBoder); + StatusTextBlock.Text = "正在读取用户输入"; Gateway.SendMessageStream(question,"qwen3-235b-a22b",defaultGdbPath,NewMessage_Recall); } @@ -133,6 +134,10 @@ namespace LinkToolAddin.ui.dockpane //不存在该消息,需添加到ListView中 if (msg.content == "") { + if (msg.type == MessageType.END_TAG) + { + StatusTextBlock.Text = ""; + } return; } idList.Add(msgId); @@ -167,9 +172,6 @@ namespace LinkToolAddin.ui.dockpane borderItemsDict[msgId] = border; ChatHistoryStackPanel.Children.Add(border); StatusTextBlock.Text = "回答生成中"; - }else if (msg.type == MessageType.END_TAG) - { - StatusTextBlock.Text = ""; } } } @@ -183,6 +185,10 @@ namespace LinkToolAddin.ui.dockpane borderItemsDict.TryRemove(msgId, out Border border); messageDict.TryRemove(msgId, out MessageListItem tempMsg); idList.Remove(msgId); + if (msg.type == MessageType.END_TAG) + { + StatusTextBlock.Text = ""; + } } if (msg.role == "user") { @@ -218,9 +224,6 @@ namespace LinkToolAddin.ui.dockpane TextBox textBox = grid.Children[1] as TextBox; textBox.Text = msg.content; StatusTextBlock.Text = "回答生成中"; - }else if (msg.type == MessageType.END_TAG) - { - StatusTextBlock.Text = ""; } } }