1. 解决提示词卡片显示不出的问题

2. 强制在第一次调用ArcGIS Pro工具前先查知识库
3. 解决当前回答状态显示错误的问题
This commit is contained in:
PeterZhong 2025-06-07 23:17:29 +08:00
parent e2fd3b376c
commit 54b78d0b5c
5 changed files with 93 additions and 18 deletions

View File

@ -6,6 +6,10 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<NoWarn>CA1416</NoWarn> <NoWarn>CA1416</NoWarn>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IsPackable>false</IsPackable>
<Version>0.1.1</Version>
<Title>LinkTool灵图</Title>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Remove="Config.daml" /> <None Remove="Config.daml" />

View File

@ -15,6 +15,7 @@ using System.Xml.Linq;
using ArcGIS.Desktop.Internal.Mapping.Locate; using ArcGIS.Desktop.Internal.Mapping.Locate;
using LinkToolAddin.client; using LinkToolAddin.client;
using LinkToolAddin.client.prompt; using LinkToolAddin.client.prompt;
using LinkToolAddin.client.tool;
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.mcp;
@ -257,10 +258,11 @@ public class Gateway
PromptServerList promptServerList = new PromptServerList(); PromptServerList promptServerList = new PromptServerList();
int loop = 0; int loop = 0;
string messageContent = ""; //一次请求下完整的response string messageContent = ""; //一次请求下完整的response
bool queriedKnowledge = false;
while (goOn) while (goOn)
{ {
loop++; loop++;
if (loop > 20) if (loop > 500)
{ {
MessageBox.Show("达到最大循环次数", "退出循环"); MessageBox.Show("达到最大循环次数", "退出循环");
break; break;
@ -389,8 +391,8 @@ public class Gateway
}); });
MessageListItem toolMessageListItem = new ToolMessageItem() MessageListItem toolMessageListItem = new ToolMessageItem()
{ {
content = "", content = toolName,
result = "", result = "工具运行中" + toolName,
toolName = toolName, toolName = toolName,
toolParams = toolParams, toolParams = toolParams,
role = "user", role = "user",
@ -426,6 +428,7 @@ public class Gateway
Content = messageContent Content = messageContent
}); });
} }
Thread.Sleep(100);
/*统一处理本次请求中的MCP工具调用需求*/ /*统一处理本次请求中的MCP工具调用需求*/
foreach (McpToolRequest mcpToolRequest in mcpToolRequests) foreach (McpToolRequest mcpToolRequest in mcpToolRequests)
{ {
@ -492,6 +495,62 @@ public class Gateway
} }
else if (mcpServer is InnerMcpServer) 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<string, object>(){{"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<string, object>(){{"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); Type type = Type.GetType("LinkToolAddin.client.tool." + (mcpServer as InnerMcpServer).Name);
MethodInfo method = type.GetMethod(toolName, BindingFlags.Public | BindingFlags.Static); MethodInfo method = type.GetMethod(toolName, BindingFlags.Public | BindingFlags.Static);
var methodParams = toolParams.Values.ToArray(); var methodParams = toolParams.Values.ToArray();
@ -512,6 +571,7 @@ public class Gateway
var task = method.Invoke(null, args) as Task<JsonRpcResultEntity>; var task = method.Invoke(null, args) as Task<JsonRpcResultEntity>;
JsonRpcResultEntity innerResult = await task; JsonRpcResultEntity innerResult = await task;
queriedKnowledge = false;
if (innerResult is JsonRpcErrorEntity) if (innerResult is JsonRpcErrorEntity)
{ {
MessageListItem toolMessageItem = new ToolMessageItem MessageListItem toolMessageItem = new ToolMessageItem
@ -573,24 +633,25 @@ public class Gateway
try try
{ {
string promptContent = DynamicPrompt.GetPrompt(promptRequest.PromptName, promptRequest.PromptArgs); string promptContent = DynamicPrompt.GetPrompt(promptRequest.PromptName, promptRequest.PromptArgs);
messages.Add(new Message MessageListItem promptMessageItem = new ToolMessageItem
{
Role = "user",
Content = promptContent
});
MessageListItem toolMessageItem = new ToolMessageItem
{ {
toolName = "调用提示词", toolName = "调用提示词",
toolParams = null, toolParams = new Dictionary<string, object>(),
type = MessageType.TOOL_MESSAGE, type = MessageType.TOOL_MESSAGE,
status = "success", status = "success",
content = "成功调用提示词:"+promptRequest.PromptName, content = "成功调用提示词:"+promptRequest.PromptName,
id = (timestamp+1).ToString(), id = (timestamp+1).ToString(),
role = "user",
result = "成功调用提示词:"+promptRequest.PromptName result = "成功调用提示词:"+promptRequest.PromptName
}; };
Application.Current.Dispatcher.Invoke(() => Application.Current.Dispatcher.Invoke(() =>
{ {
callback?.Invoke(toolMessageItem); callback?.Invoke(promptMessageItem);
});
messages.Add(new Message
{
Role = "user",
Content = promptContent
}); });
} }
catch (Exception e) catch (Exception e)

View File

@ -49,4 +49,11 @@ public class SystemPrompt
errPrompt = errPrompt.Replace("{{toolResult}}", toolResult); errPrompt = errPrompt.Replace("{{toolResult}}", toolResult);
return errPrompt; return errPrompt;
} }
public static string ToolContinuePrompt(string toolResult)
{
string continuePrompt = "根据你需要调用的工具查询到如下帮助文档内容,请严格按照帮助文档中的参数和名称要求再次生成准确的工具调用请求以确保工具调用成功。\n{{toolResult}}";
continuePrompt = continuePrompt.Replace("{{toolResult}}", toolResult);
return continuePrompt;
}
} }

View File

@ -22,7 +22,7 @@ namespace LinkToolAddin
{ {
internal class VersionButton : Button internal class VersionButton : Button
{ {
private string version = "0.1.1"; private string version = "0.1.2";
protected override void OnClick() protected override void OnClick()
{ {
MessageBox.Show($"当前LinkTool版本为{version}", "版本信息"); MessageBox.Show($"当前LinkTool版本为{version}", "版本信息");

View File

@ -117,6 +117,7 @@ namespace LinkToolAddin.ui.dockpane
QuestionTextbox.Text = ""; QuestionTextbox.Text = "";
borderItemsDict[timestamp.ToString()] = userMsgBoder; borderItemsDict[timestamp.ToString()] = userMsgBoder;
ChatHistoryStackPanel.Children.Add(userMsgBoder); ChatHistoryStackPanel.Children.Add(userMsgBoder);
StatusTextBlock.Text = "正在读取用户输入";
Gateway.SendMessageStream(question,"qwen3-235b-a22b",defaultGdbPath,NewMessage_Recall); Gateway.SendMessageStream(question,"qwen3-235b-a22b",defaultGdbPath,NewMessage_Recall);
} }
@ -133,6 +134,10 @@ namespace LinkToolAddin.ui.dockpane
//不存在该消息需添加到ListView中 //不存在该消息需添加到ListView中
if (msg.content == "") if (msg.content == "")
{ {
if (msg.type == MessageType.END_TAG)
{
StatusTextBlock.Text = "";
}
return; return;
} }
idList.Add(msgId); idList.Add(msgId);
@ -167,9 +172,6 @@ namespace LinkToolAddin.ui.dockpane
borderItemsDict[msgId] = border; borderItemsDict[msgId] = border;
ChatHistoryStackPanel.Children.Add(border); ChatHistoryStackPanel.Children.Add(border);
StatusTextBlock.Text = "回答生成中"; 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); borderItemsDict.TryRemove(msgId, out Border border);
messageDict.TryRemove(msgId, out MessageListItem tempMsg); messageDict.TryRemove(msgId, out MessageListItem tempMsg);
idList.Remove(msgId); idList.Remove(msgId);
if (msg.type == MessageType.END_TAG)
{
StatusTextBlock.Text = "";
}
} }
if (msg.role == "user") if (msg.role == "user")
{ {
@ -218,9 +224,6 @@ namespace LinkToolAddin.ui.dockpane
TextBox textBox = grid.Children[1] as TextBox; TextBox textBox = grid.Children[1] as TextBox;
textBox.Text = msg.content; textBox.Text = msg.content;
StatusTextBlock.Text = "回答生成中"; StatusTextBlock.Text = "回答生成中";
}else if (msg.type == MessageType.END_TAG)
{
StatusTextBlock.Text = "";
} }
} }
} }