合并后提交
This commit is contained in:
commit
200db4b10a
@ -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" />
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
398
host/Gateway.cs
398
host/Gateway.cs
@ -239,17 +239,25 @@ 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 = "";
|
||||||
messages.Add(new Message
|
try
|
||||||
{
|
{
|
||||||
Role = "system",
|
toolInfos = await GetToolInfos(new McpServerList());
|
||||||
Content = SystemPrompt.SysPrompt(gdbPath, toolInfos)
|
messages.Add(new Message
|
||||||
});
|
{
|
||||||
messages.Add(new Message
|
Role = "system",
|
||||||
|
Content = SystemPrompt.SysPrompt(gdbPath, toolInfos)
|
||||||
|
});
|
||||||
|
messages.Add(new Message
|
||||||
|
{
|
||||||
|
Role = "user",
|
||||||
|
Content = message
|
||||||
|
});
|
||||||
|
}catch (Exception ex)
|
||||||
{
|
{
|
||||||
Role = "user",
|
log.Error(ex);
|
||||||
Content = message
|
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();
|
||||||
@ -282,56 +291,105 @@ public class Gateway
|
|||||||
{
|
{
|
||||||
//如果本次回复不包含任何工具的调用或提示词的调用,则不再请求
|
//如果本次回复不包含任何工具的调用或提示词的调用,则不再请求
|
||||||
goOn = false;
|
goOn = false;
|
||||||
MessageListItem endMessageListItem1 = new ChatMessageItem
|
MessageListItem endMessageListItem1 = new ChatMessageItem
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
await foreach(LlmStreamChat llmStreamChat in bailian.SendChatStreamAsync(jsonContent))
|
|
||||||
{
|
|
||||||
if (!goOn)
|
|
||||||
{
|
|
||||||
MessageListItem endMessageListItem2 = new ChatMessageItem
|
|
||||||
{
|
|
||||||
type = MessageType.END_TAG,
|
|
||||||
content = "",
|
|
||||||
id = (timestamp+3).ToString(),
|
|
||||||
role = "assistant"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
await foreach(LlmStreamChat llmStreamChat in bailian.SendChatStreamAsync(jsonContent))
|
||||||
{
|
{
|
||||||
string chunk = llmStreamChat.Choices[0].Delta.Content;
|
if (!goOn)
|
||||||
MessageListItem reasonMessageListItem = new ChatMessageItem()
|
|
||||||
{
|
{
|
||||||
content = llmStreamChat.Choices[0].Delta.ResoningContent,
|
MessageListItem endMessageListItem2 = new ChatMessageItem
|
||||||
role = "assistant",
|
|
||||||
type = MessageType.REASON_MESSAGE,
|
|
||||||
id = (timestamp+2).ToString()
|
|
||||||
};
|
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
|
||||||
{
|
|
||||||
callback?.Invoke(reasonMessageListItem);
|
|
||||||
});
|
|
||||||
messageContent = chunk;
|
|
||||||
var (matched, remaining) = ExtractMatchedPart(chunk, toolPattern);
|
|
||||||
if (matched == "")
|
|
||||||
{
|
|
||||||
var (matchedPrompt, remainingPrompt) = ExtractMatchedPart(chunk, promptPattern);
|
|
||||||
if (matchedPrompt == "")
|
|
||||||
{
|
{
|
||||||
//普通消息文本
|
type = MessageType.END_TAG,
|
||||||
|
content = "",
|
||||||
|
id = (timestamp+3).ToString(),
|
||||||
|
role = "assistant"
|
||||||
|
};
|
||||||
|
callback?.Invoke(endMessageListItem2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string chunk = llmStreamChat.Choices[0].Delta.Content;
|
||||||
|
MessageListItem reasonMessageListItem = new ChatMessageItem()
|
||||||
|
{
|
||||||
|
content = llmStreamChat.Choices[0].Delta.ResoningContent,
|
||||||
|
role = "assistant",
|
||||||
|
type = MessageType.REASON_MESSAGE,
|
||||||
|
id = (timestamp+2).ToString()
|
||||||
|
};
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
callback?.Invoke(reasonMessageListItem);
|
||||||
|
});
|
||||||
|
messageContent = chunk;
|
||||||
|
var (matched, remaining) = ExtractMatchedPart(chunk, toolPattern);
|
||||||
|
if (matched == "")
|
||||||
|
{
|
||||||
|
var (matchedPrompt, remainingPrompt) = ExtractMatchedPart(chunk, promptPattern);
|
||||||
|
if (matchedPrompt == "")
|
||||||
|
{
|
||||||
|
//普通消息文本
|
||||||
|
MessageListItem chatMessageListItem = new ChatMessageItem()
|
||||||
|
{
|
||||||
|
content = remainingPrompt,
|
||||||
|
role = "assistant",
|
||||||
|
type = MessageType.CHAT_MESSAGE,
|
||||||
|
id = timestamp.ToString()
|
||||||
|
};
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
callback?.Invoke(chatMessageListItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//包含Prompt调用请求的消息
|
||||||
|
MessageListItem chatMessageListItem = new ChatMessageItem()
|
||||||
|
{
|
||||||
|
content = remainingPrompt,
|
||||||
|
role = "assistant",
|
||||||
|
type = MessageType.CHAT_MESSAGE,
|
||||||
|
id = timestamp.ToString()
|
||||||
|
};
|
||||||
|
callback?.Invoke(chatMessageListItem);
|
||||||
|
XElement promptUse = XElement.Parse(matchedPrompt);
|
||||||
|
string promptKey = promptUse.Element("name")?.Value;
|
||||||
|
string promptArgs = promptUse.Element("arguments")?.Value;
|
||||||
|
Dictionary<string, string> promptParams = JsonConvert.DeserializeObject<Dictionary<string, string>>(promptArgs);
|
||||||
|
promptRequests = new List<PromptRequest>();
|
||||||
|
promptRequests.Add(new PromptRequest()
|
||||||
|
{
|
||||||
|
PromptName = promptKey,
|
||||||
|
PromptArgs = promptParams,
|
||||||
|
PromptServer = promptServerList.GetPromptServer(promptKey)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//包含工具调用请求的消息
|
||||||
|
XElement toolUse = XElement.Parse(matched);
|
||||||
|
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;
|
||||||
|
McpServer mcpServer = mcpServerList.GetServer(serverName);
|
||||||
|
//将工具调用请求添加至列表中待一次回答完整后再统一进行调用
|
||||||
MessageListItem chatMessageListItem = new ChatMessageItem()
|
MessageListItem chatMessageListItem = new ChatMessageItem()
|
||||||
{
|
{
|
||||||
content = remainingPrompt,
|
content = remaining,
|
||||||
role = "assistant",
|
role = "assistant",
|
||||||
type = MessageType.CHAT_MESSAGE,
|
type = MessageType.CHAT_MESSAGE,
|
||||||
id = timestamp.ToString()
|
id = timestamp.ToString()
|
||||||
@ -340,84 +398,43 @@ public class Gateway
|
|||||||
{
|
{
|
||||||
callback?.Invoke(chatMessageListItem);
|
callback?.Invoke(chatMessageListItem);
|
||||||
});
|
});
|
||||||
}
|
MessageListItem toolMessageListItem = new ToolMessageItem()
|
||||||
else
|
|
||||||
{
|
|
||||||
//包含Prompt调用请求的消息
|
|
||||||
MessageListItem chatMessageListItem = new ChatMessageItem()
|
|
||||||
{
|
{
|
||||||
content = remainingPrompt,
|
content = "",
|
||||||
role = "assistant",
|
result = "",
|
||||||
type = MessageType.CHAT_MESSAGE,
|
toolName = toolName,
|
||||||
id = timestamp.ToString()
|
toolParams = toolParams,
|
||||||
|
role = "user",
|
||||||
|
type = MessageType.TOOL_MESSAGE,
|
||||||
|
id = (timestamp+1).ToString(),
|
||||||
|
status = "loading"
|
||||||
};
|
};
|
||||||
callback?.Invoke(chatMessageListItem);
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
XElement promptUse = XElement.Parse(matchedPrompt);
|
|
||||||
string promptKey = promptUse.Element("name")?.Value;
|
|
||||||
string promptArgs = promptUse.Element("arguments")?.Value;
|
|
||||||
Dictionary<string, string> promptParams = JsonConvert.DeserializeObject<Dictionary<string, string>>(promptArgs);
|
|
||||||
promptRequests = new List<PromptRequest>();
|
|
||||||
promptRequests.Add(new PromptRequest()
|
|
||||||
{
|
{
|
||||||
PromptName = promptKey,
|
callback?.Invoke(toolMessageListItem);
|
||||||
PromptArgs = promptParams,
|
|
||||||
PromptServer = promptServerList.GetPromptServer(promptKey)
|
|
||||||
});
|
});
|
||||||
|
mcpToolRequests = new List<McpToolRequest>();
|
||||||
|
McpToolRequest mcpToolRequest = new McpToolRequest()
|
||||||
|
{
|
||||||
|
McpServer = mcpServer,
|
||||||
|
ToolName = toolName,
|
||||||
|
ToolArgs = toolParams,
|
||||||
|
};
|
||||||
|
mcpToolRequests.Add(mcpToolRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
//包含工具调用请求的消息
|
Console.WriteLine(e);
|
||||||
XElement toolUse = XElement.Parse(matched);
|
log.Error(e.Message);
|
||||||
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;
|
|
||||||
McpServer mcpServer = mcpServerList.GetServer(serverName);
|
|
||||||
//将工具调用请求添加至列表中待一次回答完整后再统一进行调用
|
|
||||||
MessageListItem chatMessageListItem = new ChatMessageItem()
|
|
||||||
{
|
|
||||||
content = remaining,
|
|
||||||
role = "assistant",
|
|
||||||
type = MessageType.CHAT_MESSAGE,
|
|
||||||
id = timestamp.ToString()
|
|
||||||
};
|
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
|
||||||
{
|
|
||||||
callback?.Invoke(chatMessageListItem);
|
|
||||||
});
|
|
||||||
MessageListItem toolMessageListItem = new ToolMessageItem()
|
|
||||||
{
|
|
||||||
content = "",
|
|
||||||
result = "",
|
|
||||||
toolName = toolName,
|
|
||||||
toolParams = toolParams,
|
|
||||||
role = "user",
|
|
||||||
type = MessageType.TOOL_MESSAGE,
|
|
||||||
id = (timestamp+1).ToString(),
|
|
||||||
status = "loading"
|
|
||||||
};
|
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
|
||||||
{
|
|
||||||
callback?.Invoke(toolMessageListItem);
|
|
||||||
});
|
|
||||||
mcpToolRequests = new List<McpToolRequest>();
|
|
||||||
McpToolRequest mcpToolRequest = new McpToolRequest()
|
|
||||||
{
|
|
||||||
McpServer = mcpServer,
|
|
||||||
ToolName = toolName,
|
|
||||||
ToolArgs = toolParams,
|
|
||||||
};
|
|
||||||
mcpToolRequests.Add(mcpToolRequest);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
}catch (Exception e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
log.Error(e.Message);
|
||||||
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,88 +636,105 @@ 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++;
|
||||||
if (mcpServer is InnerMcpServer)
|
try
|
||||||
{
|
{
|
||||||
InnerMcpServer innerMcpServer = (InnerMcpServer)mcpServer;
|
if (mcpServer is InnerMcpServer)
|
||||||
Type type = Type.GetType("LinkToolAddin.client.tool." + innerMcpServer.Name);
|
|
||||||
MethodInfo[] methods = type.GetMethods();
|
|
||||||
foreach (MethodInfo method in methods)
|
|
||||||
{
|
{
|
||||||
if (method.IsPublic && method.IsStatic)
|
InnerMcpServer innerMcpServer = (InnerMcpServer)mcpServer;
|
||||||
|
Type type = Type.GetType("LinkToolAddin.client.tool." + innerMcpServer.Name);
|
||||||
|
MethodInfo[] methods = type.GetMethods();
|
||||||
|
foreach (MethodInfo method in methods)
|
||||||
{
|
{
|
||||||
string methodName = method.Name;
|
if (method.IsPublic && method.IsStatic)
|
||||||
string methodDescription = method.GetCustomAttribute<DescriptionAttribute>()?.Description;
|
{
|
||||||
string methodParamSchema = LinkToolAddin.common.JsonSchemaGenerator.GenerateJsonSchema(method);
|
string methodName = method.Name;
|
||||||
|
string methodDescription = method.GetCustomAttribute<DescriptionAttribute>()?.Description;
|
||||||
|
string methodParamSchema = LinkToolAddin.common.JsonSchemaGenerator.GenerateJsonSchema(method);
|
||||||
|
McpToolDefinition toolDefinition = new McpToolDefinition
|
||||||
|
{
|
||||||
|
Tool = new Tool
|
||||||
|
{
|
||||||
|
Name = innerMcpServer.Name + ":" + methodName,
|
||||||
|
Description = methodDescription,
|
||||||
|
Arguments = methodParamSchema
|
||||||
|
}
|
||||||
|
};
|
||||||
|
XNode node = JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition));
|
||||||
|
toolInfos.AppendLine(node.ToString());
|
||||||
|
toolInfos.AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(mcpServer is SseMcpServer)
|
||||||
|
{
|
||||||
|
SseMcpClient client = new SseMcpClient((mcpServer as SseMcpServer).BaseUrl);
|
||||||
|
IList<McpClientTool> tools = await client.GetToolListAsync();
|
||||||
|
foreach (McpClientTool tool in tools)
|
||||||
|
{
|
||||||
|
string toolName = (mcpServer as SseMcpServer).Name + ":" + tool.Name;
|
||||||
|
string toolDescription = tool.Description;
|
||||||
|
string toolParamSchema = tool.JsonSchema.ToString();
|
||||||
McpToolDefinition toolDefinition = new McpToolDefinition
|
McpToolDefinition toolDefinition = new McpToolDefinition
|
||||||
{
|
{
|
||||||
Tool = new Tool
|
Tool = new Tool
|
||||||
{
|
{
|
||||||
Name = innerMcpServer.Name + ":" + methodName,
|
Name = toolName,
|
||||||
Description = methodDescription,
|
Description = toolDescription,
|
||||||
Arguments = methodParamSchema
|
Arguments = toolParamSchema
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
XNode node = JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition));
|
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
|
||||||
toolInfos.AppendLine(node.ToString());
|
toolInfos.AppendLine();
|
||||||
|
}
|
||||||
|
}else if (mcpServer is StdioMcpServer)
|
||||||
|
{
|
||||||
|
StdioMcpClient client = new StdioMcpClient((mcpServer as StdioMcpServer).Command, (mcpServer as StdioMcpServer).Args);
|
||||||
|
IList<McpClientTool> tools = await client.GetToolListAsync();
|
||||||
|
foreach (McpClientTool tool in tools)
|
||||||
|
{
|
||||||
|
string toolName = (mcpServer as StdioMcpServer).Name + ":" + tool.Name;;
|
||||||
|
string toolDescription = tool.Description;
|
||||||
|
string toolParamSchema = tool.JsonSchema.ToString();
|
||||||
|
McpToolDefinition toolDefinition = new McpToolDefinition
|
||||||
|
{
|
||||||
|
Tool = new Tool
|
||||||
|
{
|
||||||
|
Name = toolName,
|
||||||
|
Description = toolDescription,
|
||||||
|
Arguments = CompressJson(toolParamSchema)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
|
||||||
toolInfos.AppendLine();
|
toolInfos.AppendLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}catch (Exception e)
|
||||||
else if(mcpServer is SseMcpServer)
|
|
||||||
{
|
{
|
||||||
SseMcpClient client = new SseMcpClient((mcpServer as SseMcpServer).BaseUrl);
|
log.Error(e.Message);
|
||||||
IList<McpClientTool> tools = await client.GetToolListAsync();
|
failedMcp.Add(i);
|
||||||
foreach (McpClientTool tool in tools)
|
|
||||||
{
|
|
||||||
string toolName = (mcpServer as SseMcpServer).Name + ":" + tool.Name;
|
|
||||||
string toolDescription = tool.Description;
|
|
||||||
string toolParamSchema = tool.JsonSchema.ToString();
|
|
||||||
McpToolDefinition toolDefinition = new McpToolDefinition
|
|
||||||
{
|
|
||||||
Tool = new Tool
|
|
||||||
{
|
|
||||||
Name = toolName,
|
|
||||||
Description = toolDescription,
|
|
||||||
Arguments = toolParamSchema
|
|
||||||
}
|
|
||||||
};
|
|
||||||
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
|
|
||||||
toolInfos.AppendLine();
|
|
||||||
}
|
|
||||||
}else if (mcpServer is StdioMcpServer)
|
|
||||||
{
|
|
||||||
StdioMcpClient client = new StdioMcpClient((mcpServer as StdioMcpServer).Command, (mcpServer as StdioMcpServer).Args);
|
|
||||||
IList<McpClientTool> tools = await client.GetToolListAsync();
|
|
||||||
foreach (McpClientTool tool in tools)
|
|
||||||
{
|
|
||||||
string toolName = (mcpServer as StdioMcpServer).Name + ":" + tool.Name;;
|
|
||||||
string toolDescription = tool.Description;
|
|
||||||
string toolParamSchema = tool.JsonSchema.ToString();
|
|
||||||
McpToolDefinition toolDefinition = new McpToolDefinition
|
|
||||||
{
|
|
||||||
Tool = new Tool
|
|
||||||
{
|
|
||||||
Name = toolName,
|
|
||||||
Description = toolDescription,
|
|
||||||
Arguments = CompressJson(toolParamSchema)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
toolInfos.AppendLine(JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(toolDefinition)).ToString());
|
|
||||||
toolInfos.AppendLine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<UserPrompt> prompts = DynamicPrompt.GetAllPrompts();
|
List<UserPrompt> prompts = DynamicPrompt.GetAllPrompts();
|
||||||
foreach (UserPrompt userPrompt in prompts)
|
foreach (UserPrompt userPrompt in prompts)
|
||||||
{
|
{
|
||||||
XNode node = JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(new PromptDefinition(){UserPrompt = userPrompt}));
|
try
|
||||||
toolInfos.AppendLine(node.ToString());
|
{
|
||||||
toolInfos.AppendLine();
|
XNode node = JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(new PromptDefinition(){UserPrompt = userPrompt}));
|
||||||
|
toolInfos.AppendLine(node.ToString());
|
||||||
|
toolInfos.AppendLine();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.Error(e.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
MessageBox.Show($"读取失败的MCP序号:{JsonConvert.SerializeObject(failedMcp)}","MCP读取错误");
|
||||||
return toolInfos.ToString();
|
return toolInfos.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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; }
|
||||||
|
|||||||
@ -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}", "版本信息");
|
||||||
|
|||||||
@ -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> -->
|
||||||
|
|||||||
@ -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 = "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user