合并后提交

This commit is contained in:
zengmq 2025-06-08 17:10:31 +08:00
commit 200db4b10a
8 changed files with 289 additions and 191 deletions

View File

@ -6,6 +6,13 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<NoWarn>CA1416</NoWarn> <NoWarn>CA1416</NoWarn>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<Version>0.1.3</Version>
<Title>LinkToolAddin</Title>
<Authors>LinkTool团队</Authors>
<Description>LinkTool以大模型赋能让您只需一两句话便能完成复杂的空间分析与时空大数据处理任务。</Description>
<Copyright>华南农业大学</Copyright>
<PackageReleaseNotes>校AI大赛提交版本</PackageReleaseNotes>
<Company>华南农业大学</Company>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Remove="Config.daml" /> <None Remove="Config.daml" />

View File

@ -24,7 +24,7 @@ public class ArcGisPro
[McpServerTool, Description("可以通过调用ArcGIS Pro的地理处理工具实现一些数据处理功能传入参数必须严格遵循ArcGIS Pro调用工具的标准调用名和参数要求知识库。")] [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)
{ {
IGPResult results = await Geoprocessing.ExecuteToolAsync(toolName, toolParams); IGPResult results = await Geoprocessing.ExecuteToolAsync(toolName, toolParams,null,null,null,GPExecuteToolFlags.InheritGPOptions|GPExecuteToolFlags.GPThread);
JsonRpcResultEntity jsonRpcResultEntity; JsonRpcResultEntity jsonRpcResultEntity;
if (results.IsFailed) if (results.IsFailed)
{ {
@ -33,8 +33,8 @@ public class ArcGisPro
{ {
Error = new Error() Error = new Error()
{ {
Code = results.ErrorCode, Code = results.ErrorCode.ToString(),
Message = GetMessagesString(results.ErrorMessages) Message = GetMessagesString(results.ErrorMessages)+"\n"+GetMessagesString(results.Messages)
} }
}; };
}else if(results.HasWarnings) }else if(results.HasWarnings)

View File

@ -239,7 +239,10 @@ public class Gateway
api_key = "sk-db177155677e438f832860e7f4da6afc" api_key = "sk-db177155677e438f832860e7f4da6afc"
}; };
List<Message> messages = new List<Message>(); List<Message> messages = new List<Message>();
string toolInfos = await GetToolInfos(new McpServerList()); string toolInfos = "";
try
{
toolInfos = await GetToolInfos(new McpServerList());
messages.Add(new Message messages.Add(new Message
{ {
Role = "system", Role = "system",
@ -250,6 +253,11 @@ public class Gateway
Role = "user", Role = "user",
Content = message Content = message
}); });
}catch (Exception ex)
{
log.Error(ex);
MessageBox.Show(ex.Message,"获取MCP列表失败");
}
goOn = true; goOn = true;
string toolPattern = "<tool_use>([\\s\\S]*?)<name>([\\s\\S]*?)<\\/name>([\\s\\S]*?)<arguments>([\\s\\S]*?)<\\/arguments>([\\s\\S]*?)<\\/tool_use>"; string toolPattern = "<tool_use>([\\s\\S]*?)<name>([\\s\\S]*?)<\\/name>([\\s\\S]*?)<arguments>([\\s\\S]*?)<\\/arguments>([\\s\\S]*?)<\\/tool_use>";
string promptPattern = "<prompt>([\\s\\S]*?)<name>([\\s\\S]*?)<\\/name>([\\s\\S]*?)<arguments>([\\s\\S]*?)<\\/arguments>([\\s\\S]*?)<\\/prompt>"; string promptPattern = "<prompt>([\\s\\S]*?)<name>([\\s\\S]*?)<\\/name>([\\s\\S]*?)<arguments>([\\s\\S]*?)<\\/arguments>([\\s\\S]*?)<\\/prompt>";
@ -260,7 +268,7 @@ public class Gateway
while (goOn) while (goOn)
{ {
loop++; loop++;
if (loop > 20) if (loop > 500)
{ {
MessageBox.Show("达到最大循环次数", "退出循环"); MessageBox.Show("达到最大循环次数", "退出循环");
break; break;
@ -269,8 +277,9 @@ public class Gateway
{ {
Model = model, Model = model,
Messages = messages, Messages = messages,
Temperature = 0.7, Temperature = 0.3,
TopP = 1, TopP = 0.4,
TopK = 7,
MaxTokens = 1000, MaxTokens = 1000,
}; };
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
@ -286,12 +295,15 @@ public class Gateway
{ {
type = MessageType.END_TAG, type = MessageType.END_TAG,
content = "", content = "",
id = (timestamp+3).ToString(), id = (timestamp + 3).ToString(),
role = "assistant" role = "assistant"
}; };
callback?.Invoke(endMessageListItem1); callback?.Invoke(endMessageListItem1);
break; break;
} }
try
{
await foreach(LlmStreamChat llmStreamChat in bailian.SendChatStreamAsync(jsonContent)) await foreach(LlmStreamChat llmStreamChat in bailian.SendChatStreamAsync(jsonContent))
{ {
if (!goOn) if (!goOn)
@ -306,7 +318,6 @@ public class Gateway
callback?.Invoke(endMessageListItem2); callback?.Invoke(endMessageListItem2);
break; break;
} }
try try
{ {
string chunk = llmStreamChat.Choices[0].Delta.Content; string chunk = llmStreamChat.Choices[0].Delta.Content;
@ -418,6 +429,12 @@ public class Gateway
log.Error(e.Message); log.Error(e.Message);
} }
} }
}catch (Exception e)
{
log.Error(e.Message);
MessageBox.Show(e.Message, "请求大模型出错");
}
if (messageContent != "") if (messageContent != "")
{ {
messages.Add(new Message messages.Add(new Message
@ -512,11 +529,16 @@ 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;
string displayToolName = toolName;
if (displayToolName == "ArcGisProTool")
{
displayToolName = "【GP】"+toolParams["toolName"].ToString();
}
if (innerResult is JsonRpcErrorEntity) if (innerResult is JsonRpcErrorEntity)
{ {
MessageListItem toolMessageItem = new ToolMessageItem MessageListItem toolMessageItem = new ToolMessageItem
{ {
toolName = toolName, toolName = displayToolName,
toolParams = toolParams, toolParams = toolParams,
type = MessageType.TOOL_MESSAGE, type = MessageType.TOOL_MESSAGE,
status = "fail", status = "fail",
@ -539,7 +561,7 @@ public class Gateway
{ {
MessageListItem toolMessageItem = new ToolMessageItem MessageListItem toolMessageItem = new ToolMessageItem
{ {
toolName = toolName, toolName = displayToolName,
toolParams = toolParams, toolParams = toolParams,
type = MessageType.TOOL_MESSAGE, type = MessageType.TOOL_MESSAGE,
status = "success", status = "success",
@ -586,7 +608,8 @@ public class Gateway
status = "success", status = "success",
content = "成功调用提示词:"+promptRequest.PromptName, content = "成功调用提示词:"+promptRequest.PromptName,
id = (timestamp+1).ToString(), id = (timestamp+1).ToString(),
result = "成功调用提示词:"+promptRequest.PromptName result = "成功调用提示词:"+promptRequest.PromptName,
role = "user"
}; };
Application.Current.Dispatcher.Invoke(() => Application.Current.Dispatcher.Invoke(() =>
{ {
@ -613,9 +636,13 @@ public class Gateway
private static async Task<string> GetToolInfos(McpServerList mcpServerList) private static async Task<string> GetToolInfos(McpServerList mcpServerList)
{ {
StringBuilder toolInfos = new StringBuilder(); StringBuilder toolInfos = new StringBuilder();
int i = 0;
List<int> failedMcp = new List<int>();
foreach (McpServer mcpServer in mcpServerList.GetAllServers()) foreach (McpServer mcpServer in mcpServerList.GetAllServers())
{ {
log.Info($"正在列出{mcpServer.Name}中的工具"); i++;
try
{
if (mcpServer is InnerMcpServer) if (mcpServer is InnerMcpServer)
{ {
InnerMcpServer innerMcpServer = (InnerMcpServer)mcpServer; InnerMcpServer innerMcpServer = (InnerMcpServer)mcpServer;
@ -686,15 +713,28 @@ public class Gateway
toolInfos.AppendLine(); toolInfos.AppendLine();
} }
} }
}catch (Exception e)
{
log.Error(e.Message);
failedMcp.Add(i);
}
} }
List<UserPrompt> prompts = DynamicPrompt.GetAllPrompts(); List<UserPrompt> prompts = DynamicPrompt.GetAllPrompts();
foreach (UserPrompt userPrompt in prompts) foreach (UserPrompt userPrompt in prompts)
{
try
{ {
XNode node = JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(new PromptDefinition(){UserPrompt = userPrompt})); XNode node = JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(new PromptDefinition(){UserPrompt = userPrompt}));
toolInfos.AppendLine(node.ToString()); toolInfos.AppendLine(node.ToString());
toolInfos.AppendLine(); toolInfos.AppendLine();
} }
catch (Exception e)
{
log.Error(e.Message);
}
}
MessageBox.Show($"读取失败的MCP序号{JsonConvert.SerializeObject(failedMcp)}","MCP读取错误");
return toolInfos.ToString(); return toolInfos.ToString();
} }

View File

@ -22,7 +22,7 @@ public class CallArcGISPro
{ {
Error = new Error() Error = new Error()
{ {
Code = results.ErrorCode, Code = results.ErrorCode.ToString(),
Message = JsonConvert.SerializeObject(results.ErrorMessages) Message = JsonConvert.SerializeObject(results.ErrorMessages)
} }
}; };

View File

@ -17,7 +17,7 @@ namespace LinkToolAddin.server
public partial class Error public partial class Error
{ {
[JsonProperty("code")] [JsonProperty("code")]
public long Code { get; set; } public string Code { get; set; }
[JsonProperty("message")] [JsonProperty("message")]
public string Message { get; set; } public string Message { get; set; }

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.3";
protected override void OnClick() protected override void OnClick()
{ {
MessageBox.Show($"当前LinkTool版本为{version}", "版本信息"); MessageBox.Show($"当前LinkTool版本为{version}", "版本信息");

View File

@ -43,6 +43,11 @@
<ComboBoxItem Content="qwq-32b" /> <ComboBoxItem Content="qwq-32b" />
<ComboBoxItem Content="qwen-max-latest" /> <ComboBoxItem Content="qwen-max-latest" />
<ComboBoxItem Content="deepseek-r1" /> <ComboBoxItem Content="deepseek-r1" />
<ComboBoxItem Content="deepseek-r1-0528" />
<ComboBoxItem Content="deepseek-r1-distill-qwen-32b" />
<ComboBoxItem Content="deepseek-r1-distill-llama-70b" />
<ComboBoxItem Content="deepseek-v3" />
<ComboBoxItem Content="自定义" />
</ComboBox> </ComboBox>
</Grid> </Grid>
<!-- <Button Grid.Row="0" Content="Test" Name="TestButton" Click="TestButton_OnClick"></Button> --> <!-- <Button Grid.Row="0" Content="Test" Name="TestButton" Click="TestButton_OnClick"></Button> -->

View File

@ -118,9 +118,53 @@ namespace LinkToolAddin.ui.dockpane
borderItemsDict[timestamp.ToString()] = userMsgBoder; borderItemsDict[timestamp.ToString()] = userMsgBoder;
ChatHistoryStackPanel.Children.Add(userMsgBoder); ChatHistoryStackPanel.Children.Add(userMsgBoder);
string model = (ModelComboBox.SelectedItem as ComboBoxItem).Content.ToString() is null ? "qwen3-235b-a22b" : (ModelComboBox.SelectedItem as ComboBoxItem).Content.ToString(); string model = (ModelComboBox.SelectedItem as ComboBoxItem).Content.ToString() is null ? "qwen3-235b-a22b" : (ModelComboBox.SelectedItem as ComboBoxItem).Content.ToString();
if (model == "自定义")
{
model = ShowInputBox("自定义模型", "请输入模型名称:", "");
}
Gateway.SendMessageStream(question,model,defaultGdbPath,NewMessage_Recall); Gateway.SendMessageStream(question,model,defaultGdbPath,NewMessage_Recall);
} }
private string ShowInputBox(string title, string message, string defaultValue = "")
{
// 创建一个自定义的输入对话框
var dialog = new System.Windows.Window
{
Title = title,
Width = 300,
Height = 150,
WindowStyle = WindowStyle.ToolWindow,
ResizeMode = ResizeMode.NoResize,
Topmost = true,
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
// 设置对话框内容
var stackPanel = new StackPanel { Margin = new Thickness(10) };
stackPanel.Children.Add(new TextBlock { Text = message, Margin = new Thickness(0, 0, 0, 5) });
var textBox = new TextBox { Text = defaultValue, Margin = new Thickness(0, 0, 0, 10) };
stackPanel.Children.Add(textBox);
var buttonPanel = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right };
var okButton = new Button { Content = "确定", Width = 75, Margin = new Thickness(0, 0, 5, 0) };
okButton.Click += (sender, e) => dialog.Close();
var cancelButton = new Button { Content = "取消", Width = 75 };
cancelButton.Click += (sender, e) => { textBox.Text = null; dialog.Close(); };
buttonPanel.Children.Add(okButton);
buttonPanel.Children.Add(cancelButton);
stackPanel.Children.Add(buttonPanel);
dialog.Content = stackPanel;
// 显示对话框并获取结果
dialog.ShowDialog();
return textBox.Text;
}
public void NewMessage_Recall(MessageListItem msg) public void NewMessage_Recall(MessageListItem msg)
{ {
string msgId = msg.id; string msgId = msg.id;
@ -134,6 +178,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);
@ -168,9 +216,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 = "";
} }
} }
} }
@ -180,6 +225,10 @@ namespace LinkToolAddin.ui.dockpane
messageDict[msgId] = msg; messageDict[msgId] = msg;
if (msg.content == "") if (msg.content == "")
{ {
if (msg.type == MessageType.END_TAG)
{
StatusTextBlock.Text = "";
}
ChatHistoryStackPanel.Children.Remove(borderItemsDict[msgId]); ChatHistoryStackPanel.Children.Remove(borderItemsDict[msgId]);
borderItemsDict.TryRemove(msgId, out Border border); borderItemsDict.TryRemove(msgId, out Border border);
messageDict.TryRemove(msgId, out MessageListItem tempMsg); messageDict.TryRemove(msgId, out MessageListItem tempMsg);
@ -219,9 +268,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 = "";
} }
} }
} }