Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 108ee40ffe | |||
| 7dc73e66eb | |||
| 441d8a0759 | |||
| 776cebd48e | |||
| 3f3ecadec9 | |||
| 200db4b10a | |||
| 09d1b28b5b | |||
| 86b800c477 | |||
| 6a1fe1fa3f | |||
| 544bc8cd40 | |||
| 9b600174e8 | |||
| d0b6671cce | |||
| 660ba2ad53 | |||
| c61938383b | |||
| edab972b3e | |||
| ff7e6ad732 | |||
| d790defcfe | |||
| 9e17dd7bd6 | |||
| 936c388a62 | |||
| b88d405ab8 | |||
| db488111bb | |||
| 56d0e0083c | |||
| 718718ef11 | |||
| 54b78d0b5c | |||
| e2fd3b376c | |||
| ec46fe4aad | |||
| 3b9005381a | |||
| b18c35b7f7 | |||
| c04cc42d94 | |||
| f2bff487b7 | |||
| 691f54c73f | |||
| f4262d6aef | |||
| c16557129c |
@ -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)
|
||||||
@ -100,7 +100,7 @@ public class ArcGisPro
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
[McpServerTool, Description("列出gdb数据库中的所有数据名称")]
|
[McpServerTool, Description("列出gdb数据库中的所有数据的名称")]
|
||||||
public static async Task<JsonRpcResultEntity> ListData(string gdbPath)
|
public static async Task<JsonRpcResultEntity> ListData(string gdbPath)
|
||||||
{
|
{
|
||||||
var datasets = new List<string>();
|
var datasets = new List<string>();
|
||||||
@ -137,6 +137,80 @@ public class ArcGisPro
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[McpServerTool, Description("获取要素类的属性表内容,可以查看属性表中的至多前20条记录的内容")]
|
||||||
|
public static async Task<JsonRpcResultEntity> GetFeatureDatasetAttributeTable(string datasetPath, string dataName, string rowsLimit)
|
||||||
|
{
|
||||||
|
JsonRpcResultEntity result = new JsonRpcResultEntity();
|
||||||
|
await QueuedTask.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using Geodatabase gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(datasetPath)));
|
||||||
|
FeatureClass featureClass = gdb.OpenDataset<FeatureClass>(dataName);
|
||||||
|
List<Dictionary<string, string>> attributeTable = await GetAttributeTableAsync(featureClass,Convert.ToInt32(rowsLimit));
|
||||||
|
result = new JsonRpcSuccessEntity()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Result = JsonConvert.SerializeObject(attributeTable)
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = new JsonRpcErrorEntity()
|
||||||
|
{
|
||||||
|
Error = new Error()
|
||||||
|
{
|
||||||
|
Message = ex.Message,
|
||||||
|
Code = "500"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<List<Dictionary<string, string>>> GetAttributeTableAsync(FeatureClass featureClass,int limit = 5)
|
||||||
|
{
|
||||||
|
if (limit > 20)
|
||||||
|
limit = 20;
|
||||||
|
return await QueuedTask.Run(() =>
|
||||||
|
{
|
||||||
|
var result = new List<Dictionary<string, string>>();
|
||||||
|
|
||||||
|
using (var cursor = featureClass.Search())
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (cursor.MoveNext())
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
if (i >= limit && limit != -1)
|
||||||
|
break;
|
||||||
|
var feature = cursor.Current as Feature;
|
||||||
|
if (feature == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var record = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
foreach (var field in featureClass.GetDefinition().GetFields())
|
||||||
|
{
|
||||||
|
var value = feature[field.Name];
|
||||||
|
|
||||||
|
// 处理 DBNull 值
|
||||||
|
if (value is DBNull)
|
||||||
|
value = null;
|
||||||
|
|
||||||
|
record[field.Name] = value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetMessagesString(IEnumerable<IGPMessage> messages)
|
private static string GetMessagesString(IEnumerable<IGPMessage> messages)
|
||||||
{
|
{
|
||||||
StringBuilder messagesStr = new StringBuilder();
|
StringBuilder messagesStr = new StringBuilder();
|
||||||
|
|||||||
@ -12,10 +12,10 @@
|
|||||||
|
|
||||||
## 提示词工程
|
## 提示词工程
|
||||||
|
|
||||||
- [ ] 将原来的单独XML规则修改为内嵌XML规则
|
- [x] 将原来的单独XML规则修改为内嵌XML规则
|
||||||
- [ ] 系统提示词明确提示调用动态Prompt和知识库
|
- [x] 系统提示词明确提示调用动态Prompt和知识库
|
||||||
- [ ] 错误和继续提示词预留工具消息占位符
|
- [x] 错误和继续提示词预留工具消息占位符
|
||||||
- [ ] 错误和继续提示词明示
|
- [x] 错误和继续提示词明示
|
||||||
- [ ] 系统提示词泛化增强
|
- [ ] 系统提示词泛化增强
|
||||||
- [ ] 针对qwen3适当调整
|
- [ ] 针对qwen3适当调整
|
||||||
|
|
||||||
|
|||||||
165
host/Gateway.cs
165
host/Gateway.cs
@ -12,9 +12,11 @@ using System.Windows;
|
|||||||
using System.Windows.Documents;
|
using System.Windows.Documents;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using ArcGIS.Desktop.Internal.Mapping;
|
||||||
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;
|
||||||
@ -76,9 +78,11 @@ public class Gateway
|
|||||||
{
|
{
|
||||||
Model = model,
|
Model = model,
|
||||||
Messages = messages,
|
Messages = messages,
|
||||||
Temperature = 0.7,
|
Temperature = 0.3,
|
||||||
TopP = 1,
|
TopP = 0.6,
|
||||||
MaxTokens = 1000,
|
TopK = 25,
|
||||||
|
MaxTokens = 1024,
|
||||||
|
ThinkingBudget = 1024
|
||||||
});
|
});
|
||||||
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
log.Info(reponse);
|
log.Info(reponse);
|
||||||
@ -239,7 +243,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 +257,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>";
|
||||||
@ -257,10 +269,12 @@ 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;
|
||||||
|
bool executedTool = false;
|
||||||
while (goOn)
|
while (goOn)
|
||||||
{
|
{
|
||||||
loop++;
|
loop++;
|
||||||
if (loop > 20)
|
if (loop > 500)
|
||||||
{
|
{
|
||||||
MessageBox.Show("达到最大循环次数", "退出循环");
|
MessageBox.Show("达到最大循环次数", "退出循环");
|
||||||
break;
|
break;
|
||||||
@ -269,8 +283,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 +301,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 +324,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;
|
||||||
@ -387,10 +404,12 @@ public class Gateway
|
|||||||
{
|
{
|
||||||
callback?.Invoke(chatMessageListItem);
|
callback?.Invoke(chatMessageListItem);
|
||||||
});
|
});
|
||||||
|
if (!executedTool)
|
||||||
|
{
|
||||||
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",
|
||||||
@ -402,6 +421,7 @@ public class Gateway
|
|||||||
{
|
{
|
||||||
callback?.Invoke(toolMessageListItem);
|
callback?.Invoke(toolMessageListItem);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
mcpToolRequests = new List<McpToolRequest>();
|
mcpToolRequests = new List<McpToolRequest>();
|
||||||
McpToolRequest mcpToolRequest = new McpToolRequest()
|
McpToolRequest mcpToolRequest = new McpToolRequest()
|
||||||
{
|
{
|
||||||
@ -418,6 +438,11 @@ 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
|
||||||
@ -429,6 +454,7 @@ public class Gateway
|
|||||||
/*统一处理本次请求中的MCP工具调用需求*/
|
/*统一处理本次请求中的MCP工具调用需求*/
|
||||||
foreach (McpToolRequest mcpToolRequest in mcpToolRequests)
|
foreach (McpToolRequest mcpToolRequest in mcpToolRequests)
|
||||||
{
|
{
|
||||||
|
executedTool = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
McpServer mcpServer = mcpToolRequest.McpServer;
|
McpServer mcpServer = mcpToolRequest.McpServer;
|
||||||
@ -439,7 +465,7 @@ public class Gateway
|
|||||||
SseMcpServer sseMcpServer = mcpServer as SseMcpServer;
|
SseMcpServer sseMcpServer = mcpServer as SseMcpServer;
|
||||||
SseMcpClient client = new SseMcpClient(sseMcpServer.BaseUrl);
|
SseMcpClient client = new SseMcpClient(sseMcpServer.BaseUrl);
|
||||||
CallToolResponse toolResponse = await client.CallToolAsync(toolName, toolParams);
|
CallToolResponse toolResponse = await client.CallToolAsync(toolName, toolParams);
|
||||||
MessageListItem toolMessageItem = new ToolMessageItem
|
MessageListItem toolMessageItem1 = new ToolMessageItem
|
||||||
{
|
{
|
||||||
toolName = toolName,
|
toolName = toolName,
|
||||||
toolParams = toolParams,
|
toolParams = toolParams,
|
||||||
@ -459,7 +485,7 @@ public class Gateway
|
|||||||
});
|
});
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
callback?.Invoke(toolMessageItem);
|
callback?.Invoke(toolMessageItem1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (mcpServer is StdioMcpServer)
|
else if (mcpServer is StdioMcpServer)
|
||||||
@ -467,7 +493,7 @@ public class Gateway
|
|||||||
StdioMcpServer stdioMcpServer = mcpServer as StdioMcpServer;
|
StdioMcpServer stdioMcpServer = mcpServer as StdioMcpServer;
|
||||||
StdioMcpClient client = new StdioMcpClient(stdioMcpServer.Command, stdioMcpServer.Args);
|
StdioMcpClient client = new StdioMcpClient(stdioMcpServer.Command, stdioMcpServer.Args);
|
||||||
CallToolResponse toolResponse = await client.CallToolAsync(toolName, toolParams);
|
CallToolResponse toolResponse = await client.CallToolAsync(toolName, toolParams);
|
||||||
MessageListItem toolMessageItem = new ToolMessageItem
|
MessageListItem toolMessageItem1 = new ToolMessageItem
|
||||||
{
|
{
|
||||||
toolName = toolName,
|
toolName = toolName,
|
||||||
toolParams = toolParams,
|
toolParams = toolParams,
|
||||||
@ -487,11 +513,67 @@ public class Gateway
|
|||||||
});
|
});
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
callback?.Invoke(toolMessageItem);
|
callback?.Invoke(toolMessageItem1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
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,11 +594,17 @@ 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();
|
||||||
|
}
|
||||||
|
queriedKnowledge = false;
|
||||||
if (innerResult is JsonRpcErrorEntity)
|
if (innerResult is JsonRpcErrorEntity)
|
||||||
{
|
{
|
||||||
MessageListItem toolMessageItem = new ToolMessageItem
|
MessageListItem toolMessageItem1 = new ToolMessageItem
|
||||||
{
|
{
|
||||||
toolName = toolName,
|
toolName = displayToolName,
|
||||||
toolParams = toolParams,
|
toolParams = toolParams,
|
||||||
type = MessageType.TOOL_MESSAGE,
|
type = MessageType.TOOL_MESSAGE,
|
||||||
status = "fail",
|
status = "fail",
|
||||||
@ -528,18 +616,18 @@ public class Gateway
|
|||||||
messages.Add(new Message
|
messages.Add(new Message
|
||||||
{
|
{
|
||||||
Role = "user",
|
Role = "user",
|
||||||
Content = SystemPrompt.ErrorPrompt(JsonConvert.SerializeObject(toolMessageItem))
|
Content = SystemPrompt.ErrorPrompt(JsonConvert.SerializeObject(innerResult))
|
||||||
});
|
});
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
callback?.Invoke(toolMessageItem);
|
callback?.Invoke(toolMessageItem1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (innerResult is JsonRpcSuccessEntity)
|
else if (innerResult is JsonRpcSuccessEntity)
|
||||||
{
|
{
|
||||||
MessageListItem toolMessageItem = new ToolMessageItem
|
MessageListItem toolMessageItem1 = new ToolMessageItem
|
||||||
{
|
{
|
||||||
toolName = toolName,
|
toolName = displayToolName,
|
||||||
toolParams = toolParams,
|
toolParams = toolParams,
|
||||||
type = MessageType.TOOL_MESSAGE,
|
type = MessageType.TOOL_MESSAGE,
|
||||||
status = "success",
|
status = "success",
|
||||||
@ -551,11 +639,11 @@ public class Gateway
|
|||||||
messages.Add(new Message
|
messages.Add(new Message
|
||||||
{
|
{
|
||||||
Role = "user",
|
Role = "user",
|
||||||
Content = SystemPrompt.ContinuePrompt(JsonConvert.SerializeObject(toolMessageItem))
|
Content = SystemPrompt.ContinuePrompt(JsonConvert.SerializeObject(innerResult))
|
||||||
});
|
});
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
callback?.Invoke(toolMessageItem);
|
callback?.Invoke(toolMessageItem1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -581,11 +669,13 @@ public class Gateway
|
|||||||
MessageListItem toolMessageItem = new ToolMessageItem
|
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(),
|
||||||
|
result = "成功调用提示词:"+promptRequest.PromptName,
|
||||||
|
role = "user"
|
||||||
};
|
};
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
@ -612,9 +702,14 @@ 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>();
|
||||||
|
List<string> failedMcpString = new List<string>();
|
||||||
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;
|
||||||
@ -685,15 +780,33 @@ public class Gateway
|
|||||||
toolInfos.AppendLine();
|
toolInfos.AppendLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}catch (Exception e)
|
||||||
|
{
|
||||||
|
log.Error(e.Message);
|
||||||
|
failedMcp.Add(i);
|
||||||
|
failedMcpString.Add(mcpServerList.GetAllServerNames()[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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failedMcp.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
MessageBox.Show($"读取失败的MCP服务有:{JsonConvert.SerializeObject(failedMcpString)}","MCP读取错误");
|
||||||
|
}
|
||||||
return toolInfos.ToString();
|
return toolInfos.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,11 +32,12 @@ public class McpServerList
|
|||||||
{
|
{
|
||||||
Name = "KnowledgeBase",
|
Name = "KnowledgeBase",
|
||||||
Type = "inner",
|
Type = "inner",
|
||||||
Description = "可以调用进行查询知识库,获取相关参考信息。",
|
Description = "可以调用进行查询知识库,获取相关参考信息。" ,
|
||||||
|
// "有地理信息的相关案例步骤参考以及Arcgis Pro的工具详细信息",
|
||||||
IsActive = true
|
IsActive = true
|
||||||
});
|
});
|
||||||
// servers.Add("filesystem", new StdioMcpServer()
|
//servers.Add("filesystem", new StdioMcpServer()
|
||||||
// {
|
//{
|
||||||
// Name = "filesystem",
|
// Name = "filesystem",
|
||||||
// Type = "stdio",
|
// Type = "stdio",
|
||||||
// Command = "npx",
|
// Command = "npx",
|
||||||
@ -44,11 +45,11 @@ public class McpServerList
|
|||||||
// {
|
// {
|
||||||
// "-y",
|
// "-y",
|
||||||
// "@modelcontextprotocol/server-filesystem",
|
// "@modelcontextprotocol/server-filesystem",
|
||||||
// "D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\TestData"
|
// "F:\\secondsemester\\linktool\\test\\LinkTool0607\\LinkTool0607.gdb"
|
||||||
// }
|
// }
|
||||||
// });
|
//});
|
||||||
// servers.Add("fetch", new StdioMcpServer()
|
//servers.Add("fetch", new StdioMcpServer()
|
||||||
// {
|
//{
|
||||||
// Name = "fetch",
|
// Name = "fetch",
|
||||||
// Type = "stdio",
|
// Type = "stdio",
|
||||||
// Command = "uvx",
|
// Command = "uvx",
|
||||||
@ -56,9 +57,9 @@ public class McpServerList
|
|||||||
// {
|
// {
|
||||||
// "mcp-server-fetch"
|
// "mcp-server-fetch"
|
||||||
// }
|
// }
|
||||||
// });
|
//});
|
||||||
// servers.Add("bing-search", new StdioMcpServer()
|
//servers.Add("bing-search", new StdioMcpServer()
|
||||||
// {
|
//{
|
||||||
// Name = "bing-search",
|
// Name = "bing-search",
|
||||||
// Type = "stdio",
|
// Type = "stdio",
|
||||||
// Command = "npx",
|
// Command = "npx",
|
||||||
@ -66,9 +67,9 @@ public class McpServerList
|
|||||||
// {
|
// {
|
||||||
// "bing-cn-mcp"
|
// "bing-cn-mcp"
|
||||||
// }
|
// }
|
||||||
// });
|
//});
|
||||||
// servers.Add("mcp-python-interpreter", new StdioMcpServer()
|
//servers.Add("mcp-python-interpreter", new StdioMcpServer()
|
||||||
// {
|
//{
|
||||||
// Name = "mcp-python-interpreter",
|
// Name = "mcp-python-interpreter",
|
||||||
// Type = "stdio",
|
// Type = "stdio",
|
||||||
// Command = "uvx",
|
// Command = "uvx",
|
||||||
@ -77,11 +78,11 @@ public class McpServerList
|
|||||||
// "--native-tls",
|
// "--native-tls",
|
||||||
// "mcp-python-interpreter",
|
// "mcp-python-interpreter",
|
||||||
// "--dir",
|
// "--dir",
|
||||||
// "D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\TestData",
|
// "F:\\secondsemester\\linktool\\test\\LinkTool0607\\LinkTool0607.gdb",
|
||||||
// "--python-path",
|
// "--python-path",
|
||||||
// "C:\\Program Files\\ArcGIS\\Pro\\bin\\Python\\envs\\custom\\python.exe"
|
// "C:\\Program Files\\ArcGIS\\Pro\\bin\\Python\\envs\\custom\\python.exe"
|
||||||
// }
|
// }
|
||||||
// });
|
//});
|
||||||
}
|
}
|
||||||
|
|
||||||
public McpServer GetServer(string name)
|
public McpServer GetServer(string name)
|
||||||
@ -105,4 +106,14 @@ public class McpServerList
|
|||||||
}
|
}
|
||||||
return serverList;
|
return serverList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<string> GetAllServerNames()
|
||||||
|
{
|
||||||
|
List<string> serverList = new List<string>();
|
||||||
|
foreach (var server in servers)
|
||||||
|
{
|
||||||
|
serverList.Add(server.Key);
|
||||||
|
}
|
||||||
|
return serverList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -11,13 +11,21 @@ public class PromptServerList
|
|||||||
{
|
{
|
||||||
promptServers.Add("plan", new PromptServer("plan",
|
promptServers.Add("plan", new PromptServer("plan",
|
||||||
"根据用户描述的问题推断出需要使用的ArcGIS Pro工具调用名称列表",
|
"根据用户描述的问题推断出需要使用的ArcGIS Pro工具调用名称列表",
|
||||||
"请根据用户所提问题进行工具规划,输出格式为'1.工具2.工具’,如果是ArcGIS Pro的工具,根据用户的具体需求和提供的数据类型," +
|
//"请根据用户所提问题进行工具规划,输出格式为'1.工具2.工具’,如果是ArcGIS Pro的工具,根据用户的具体需求和提供的数据类型," +
|
||||||
"判断并列出所有必要的分析步骤和工具,同时严格遵守知识库中“ArcGIS Pro工具调用大全”里“工具调用名称”一列的工具命名规则(例如:analysis.Erase)," +
|
// "判断并列出所有必要的分析步骤和工具,同时严格遵守知识库中“ArcGIS Pro工具调用大全”里“工具调用名称”一列的工具命名规则(例如:analysis.Erase)," +
|
||||||
"确保工具名的准确无误,工具与所属工具箱的对应关系正确无误,严格遵循文档规定的格式和大小写。工具的组合顺序优先参考知识库中“ArcGIS Pro的帮助文档”。" +
|
// "确保工具名的准确无误,工具与所属工具箱的对应关系正确无误,严格遵循文档规定的格式和大小写。工具的组合顺序优先参考知识库中“ArcGIS Pro的帮助文档”。" +
|
||||||
"有一些与分析无关的数据能够进行排除,在选择工具时不受其干扰。"));
|
// "有一些与分析无关的数据能够进行排除,在选择工具时不受其干扰。"
|
||||||
|
"你对ArcGIS Pro的工具箱及其功能了如指掌,能够根据用户的具体需求和提供的数据类型,迅速判断并列出所有必要的分析步骤和工具,并随之调用知识库工具确认任务规划中的调用名是否正确,以及确认其对应参数" +
|
||||||
|
"同时严格遵守知识库中“ArcGIS Pro工具调用大全”里“工具调用名称”一列的工具命名规则(例如:analysis.Erase),确保工具名的准确无误。" +
|
||||||
|
"工具的组合顺序优先参考知识库中“ArcGIS Pro的帮助文档”。有一些与分析无关的数据能够进行排除,在选择工具时不受其干扰。" +
|
||||||
|
"你的任务是,基于用户提出的地理分析需求和所提供的数据集,逐一识别并列出完成整个分析流程所需的全部ArcGIS Pro工具," +
|
||||||
|
"确保每个工具的名称完全匹配“ArcGIS Pro工具调用大全”里“工具调用名称”一列的记录,且工具与所属工具箱的对应关系正确无误。" +
|
||||||
|
"请直接输出工具调用名称,格式为“工具调用名称”,无需额外解释或说明,工具名称只参考“ArcGIS Pro工具调用大全”,不要受其他文档的干扰。" +
|
||||||
|
|
||||||
|
"你的回复应简洁明了,仅包含所需工具的列表,输出格式为序号分隔的工具调用名以及调用知识库工具工具的XML格式,主要目的是纠正规划中错误的调用名和了解工具参数便于下一步的工具调用,因为调用名和参数对于工具执行非常重要,一旦出错则可能导致运行失败。严格遵循文档规定的格式和大小写,确保信息的准确性和专业性。"));
|
||||||
promptServers.Add("param", new PromptServer("param",
|
promptServers.Add("param", new PromptServer("param",
|
||||||
"填写ArcGIS Pro工具调用参数,生成规范的可执行的工具调用请求",
|
"填写ArcGIS Pro工具调用参数,生成规范的可执行的工具调用请求",
|
||||||
"根据帮助文档填写工具参数,请你根据“所需调用工具”,参照知识库“ArcGIS Pro工具调用大全”里工具所需的参数顺序进行陈列。" +
|
"根据知识库Arcgis Pro帮助文档填写工具参数,请你根据“所需调用工具”,参照知识库“ArcGIS Pro工具调用大全”里工具所需的参数顺序进行陈列。" +
|
||||||
"列出所需调用工具的名称及其按照“ArcGIS Pro工具调用大全”里“的该工具所需的参数顺序陈列对应的参数。如果跳过了可选参数需要用空字符表示。" +
|
"列出所需调用工具的名称及其按照“ArcGIS Pro工具调用大全”里“的该工具所需的参数顺序陈列对应的参数。如果跳过了可选参数需要用空字符表示。" +
|
||||||
"不能更改所需调用工具的名称。例如:arcpy.analysis.Buffer,不能只写成Buffer。确保格式、参数的完整性和准确性,避免任何遗漏或错误。" +
|
"不能更改所需调用工具的名称。例如:arcpy.analysis.Buffer,不能只写成Buffer。确保格式、参数的完整性和准确性,避免任何遗漏或错误。" +
|
||||||
"特别注意,所有参数均应视为字符串类型,即使它们可能代表数字或文件路径。例如问题为:使用地理处理中的\"擦除分析\"工具(Erase),将圆形要素(circle.shp)与方形要素(square.shp)进行空间叠加运算。" +
|
"特别注意,所有参数均应视为字符串类型,即使它们可能代表数字或文件路径。例如问题为:使用地理处理中的\"擦除分析\"工具(Erase),将圆形要素(circle.shp)与方形要素(square.shp)进行空间叠加运算。" +
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
执行下一步工具的要求:
|
执行下一步工具的要求:
|
||||||
1. 解析工具输出结果
|
1. 解析工具输出结果
|
||||||
2. 调用下一个工具时确保参数继承前序输出。
|
2. 调用下一个工具时确保参数继承前序输出,如果已经完成用户需求则不需继续执行工具。
|
||||||
|
3. 执行Arcgis Pro工具时可以调用知识库和提示词使任务完成得更出色!
|
||||||
|
|
||||||
请据此继续执行
|
请据此继续执行
|
||||||
@ -3,10 +3,12 @@
|
|||||||
{{toolResult}}
|
{{toolResult}}
|
||||||
|
|
||||||
需按以下流程处理:
|
需按以下流程处理:
|
||||||
1. 错误解析:分析错误类型及具体原因(见下方错误信息),根据错误信息选择修复方案,
|
1. 错误解析:分析错误类型及具体原因(见错误信息),根据错误信息选择修复方案。
|
||||||
2. 修复方案:
|
2. 修复方案:
|
||||||
(1)根据错误类型生成对应的工具重试策略
|
(1)如果是ArcGisPro工具,第一时间查询知识库的工具参数是否有误,多次执行失败极有可能是工具名或者参数错误,尤其注重调用工具或者提示词修正
|
||||||
(2)参数调整:明确需要修改的参数及修改方式。
|
(2)根据错误类型生成对应的工具重试策略。
|
||||||
3. 工具重试:使用调整后的参数重新调用工具。错误信息如下,请根据报错信息重试,
|
(3)参数和调用名调整:及时调用知识库和用户提示词,确保工具名和参数的完全正确。明确需要修改的工具名、参数及修改方式。
|
||||||
|
(4)可以选择调用工具规划提示词优化工具执行流程或者调用知识库工具优化工具调用名和工具参数。
|
||||||
|
3. 工具重试:使用调整后的参数重新调用工具。请根据报错信息重试。
|
||||||
4.如果没有具体的错误描述信息请检查输出文件是否已经存在,若已经存在默认执行成功
|
4.如果没有具体的错误描述信息请检查输出文件是否已经存在,若已经存在默认执行成功
|
||||||
5.查询可能相关的知识库和帮助文档,纠正调用参数中存在的错误
|
5.出现错误编码号时要明晰编码在知识库中有相应解析,可以通过调用知识库解析错误原因
|
||||||
|
|||||||
@ -1,35 +1,39 @@
|
|||||||
现在你是一个精通地理信息分析和ArcGIS Pro软件的专家,请以此身份回答用户的问题。
|
现在你是一个精通地理信息分析和ArcGIS Pro软件的专家,请以此身份回答用户的问题。
|
||||||
|
指令:您可以使用一组工具加文字说明来回答用户的问题。完成了用户的需求即可,不用猜测用户下一步还想做什么。计划使用ArcGisPro工具前,你可以通过<prompt><name></name><arguments>{}</arguments></prompt>格式调用用户提示词,或者调用知识库工具,从而使你更好地理解和完成用户的任务。除此之外,你具有搜索网页、编写代码、管理文件系统的能力,合理运用这些工具完成用户的需求。
|
||||||
指令:您可以使用一组工具来回答用户的问题。还可以通过<prompt></prompt>调用用户提示词,从而使你更好地理解和完成用户的任务。
|
调用工具要求:如果要调用工具,每次消息只能使用一个工具,用户的回复中将包含该工具的调用结果。你还可以通过<prompt></prompt>方式来调用用户提示词,或者调用知识库工具,你能更好地理解和解决用户的问题。您需要通过逐步使用工具或提示词来完成给定任务,每次调用需基于前一次的结果。成功调用工具或提示词之后应该马上调用下一个工具或提示词。
|
||||||
|
工具调用背景:你有以下工具可以调用{{toolInfos}},用户的数据库路径是{{gdbPath}}。
|
||||||
调用工具要求:如果要调用工具,每次消息只能使用一个工具,用户的回复中将包含该工具的调用结果。您需要通过逐步使用工具来完成给定任务,每次工具调用需基于前一次的结果。成功调用工具之后应该马上调用下一个工具。你还可以通过<prompt></prompt>的方式来调用用户提示词,你能更好地理解和解决用户的问题。工具调用背景:你有以下工具可以调用{{toolInfos}},用户的数据库路径是{{gdbPath}}。
|
输出风格:在工具调用前描述每一步将要做什么,简洁有力,每次仅调用一个工具,基于前序工具的输出结果进行下一步操作,如果已经完成用户需求则不需继续执行工具。话语开头不要回复好的。工具调用使用 XML 风格的标签输出。
|
||||||
|
工具调用的XML格式一定一定要完全正确,不能有错漏,格式如下:
|
||||||
输出风格:每次仅调用一个工具,必须基于前序工具的输出结果进行下一步操作。工具调用使用 XML 风格的标签进行格式化以单独信息格式输出,前后没有文字信息。如果需要进行文字说明,请只有文字内容,以普通段落形式呈现没有其他格式。
|
|
||||||
|
|
||||||
工具调用格式:工具名称包含在一对标签内,每个参数也需用对应的标签包裹。结构如下:
|
|
||||||
|
|
||||||
<tool_use>
|
<tool_use>
|
||||||
<name>{tool_name}</name>
|
<name>{tool_name}</name>
|
||||||
<arguments>{json_arguments}</arguments>
|
<arguments>{json_arguments}</arguments>
|
||||||
</tool_use>。
|
</tool_use>
|
||||||
|
|
||||||
工具名称:需与所使用工具的精确名称一致。
|
工具名称:需与所使用工具的精确名称一致。
|
||||||
参数:应为包含工具所需参数的 JSON 对象。
|
参数:应为包含工具所需参数的 JSON 对象。
|
||||||
例如:
|
例如:
|
||||||
|
调用工具示例:
|
||||||
|
“将执行高德的兴趣点工具确认广州市政府的位置
|
||||||
<tool_use>
|
<tool_use>
|
||||||
<name>gaode:maps_geo</name>
|
<name>gaode:maps_geo</name>
|
||||||
<arguments>{\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}</arguments>
|
<arguments>{\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}</arguments>
|
||||||
</tool_use>
|
</tool_use>
|
||||||
|
”
|
||||||
|
调用用户提示词示例:
|
||||||
|
“
|
||||||
|
先进行ArcGisPro工具任务规划
|
||||||
|
<prompt>
|
||||||
|
<name>plan</name>
|
||||||
|
<arguments>{}</arguments>
|
||||||
|
</prompt>
|
||||||
|
|
||||||
你必须严格遵守以下输出规则:用户时间宝贵,不得重复调用上一次已成功执行的工具调用,除非有新的参数或上下文变化。
|
|
||||||
|
|
||||||
结果:用户将以以下格式返回工具调用结果:
|
”
|
||||||
|
结果示例:用户将以以下格式返回工具调用结果:
|
||||||
<tool_use_result>
|
<tool_use_result>
|
||||||
<name>{tool_name}</name>
|
<name>{tool_name}</name>
|
||||||
<result>{result}</result>
|
<result>{result}</result>
|
||||||
</tool_use_result>。
|
</tool_use_result>
|
||||||
|
|
||||||
应为字符串类型,可以表示文件或其他输出类型。
|
|
||||||
|
|
||||||
工具调用示例:MCP工具调用的格式要求示例:以下是使用虚拟工具的示例:
|
工具调用示例:MCP工具调用的格式要求示例:以下是使用虚拟工具的示例:
|
||||||
<tool_use>
|
<tool_use>
|
||||||
@ -37,4 +41,13 @@
|
|||||||
<arguments>{\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}</arguments>
|
<arguments>{\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}</arguments>
|
||||||
</tool_use>
|
</tool_use>
|
||||||
|
|
||||||
特别地:需要调用ArcGIS Pro工具前必须先查询帮助文档、标准调用名和参数后再进行调用
|
你必须严格遵守以下每一条规则:
|
||||||
|
1.用户时间宝贵,一旦确认工具成功调用之后,不得重复调用上一次已成功执行的工具,除非有新的参数或上下文变化。
|
||||||
|
2.调用“ArcGisPro:ArcGisProTool”工具,name一定要严格按照知识库的调用名,例如"analysis.Union","management.Clip"等。输入与输出数据一定需要加上路径信息,输出数据到默认数据库中。`in_features`参数通过分号(`;`)拼接多个输入要素类路径,参数列表中有"{}"代表选填,其他必须要填写。
|
||||||
|
3.参数一定都为字符串类型,可以表示文件或其他输出类型。
|
||||||
|
4.一次只能调用一个工具,逐步调用!不要调用多个,一旦消息中没有工具或提示词调用信息即视为任务完成。因此工具或提示词调用必须连续完成。
|
||||||
|
5.只响应用户目前的需求即可,不要过度猜测用户的需求,如果有下一步的工具建议只输出文本即可,如果输出XML会执行大量无用的工具。
|
||||||
|
|
||||||
|
特别注意:
|
||||||
|
1.ArcGIS Pro中不能通过先SelectByAttribute选择后再执行ExportFeatures导出指定的部分,正确的做法是直接用ExportFeatures传入where_clause导出指定部分的数据。
|
||||||
|
2.可以先参考知识库中的案例辅助工具的规划
|
||||||
|
|||||||
@ -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.4";
|
||||||
protected override void OnClick()
|
protected override void OnClick()
|
||||||
{
|
{
|
||||||
MessageBox.Show($"当前LinkTool版本为{version}", "版本信息");
|
MessageBox.Show($"当前LinkTool版本为{version}", "版本信息");
|
||||||
|
|||||||
@ -31,11 +31,24 @@
|
|||||||
<ColumnDefinition Width="36"/>
|
<ColumnDefinition Width="36"/>
|
||||||
<ColumnDefinition Width="36"/>
|
<ColumnDefinition Width="36"/>
|
||||||
<ColumnDefinition Width="36"/>
|
<ColumnDefinition Width="36"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Button Grid.Column="0" Content="清除" Name="ClearButton" Click="ClearButton_OnClick"></Button>
|
<Button Grid.Column="0" Content="清除" Name="ClearButton" Click="ClearButton_OnClick"></Button>
|
||||||
<Button Grid.Column="1" Content="顶部" Name="TopButton" Click="TopButton_OnClick"></Button>
|
<Button Grid.Column="1" Content="顶部" Name="TopButton" Click="TopButton_OnClick"></Button>
|
||||||
<Button Grid.Column="2" Content="底部" Name="BottomButton" Click="BottomButton_OnClick"></Button>
|
<Button Grid.Column="2" Content="底部" Name="BottomButton" Click="BottomButton_OnClick"></Button>
|
||||||
<Button Grid.Column="3" Content="停止" Name="StopButton" Click="StopButton_OnClick"></Button>
|
<Button Grid.Column="3" Content="停止" Name="StopButton" Click="StopButton_OnClick"></Button>
|
||||||
|
<ComboBox Grid.Column="4" Name="ModelComboBox" SelectionChanged="ModelComboBox_OnSelectionChanged">
|
||||||
|
<ComboBoxItem Content="qwen3-235b-a22b" IsSelected="True"/>
|
||||||
|
<ComboBoxItem Content="qwen3-32b" />
|
||||||
|
<ComboBoxItem Content="qwq-32b" />
|
||||||
|
<ComboBoxItem Content="qwen-max-latest" />
|
||||||
|
<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>
|
||||||
</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> -->
|
||||||
<!-- <TextBlock Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Text="LinkTool"/> -->
|
<!-- <TextBlock Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Text="LinkTool"/> -->
|
||||||
|
|||||||
@ -117,7 +117,53 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
QuestionTextbox.Text = "";
|
QuestionTextbox.Text = "";
|
||||||
borderItemsDict[timestamp.ToString()] = userMsgBoder;
|
borderItemsDict[timestamp.ToString()] = userMsgBoder;
|
||||||
ChatHistoryStackPanel.Children.Add(userMsgBoder);
|
ChatHistoryStackPanel.Children.Add(userMsgBoder);
|
||||||
Gateway.SendMessageStream(question,"qwen3-235b-a22b",defaultGdbPath,NewMessage_Recall);
|
string model = (ModelComboBox.SelectedItem as ComboBoxItem).Content.ToString() is null ? "qwen3-235b-a22b" : (ModelComboBox.SelectedItem as ComboBoxItem).Content.ToString();
|
||||||
|
if (model == "自定义")
|
||||||
|
{
|
||||||
|
model = ShowInputBox("自定义模型", "请输入模型名称:", "");
|
||||||
|
}
|
||||||
|
ScrollViewer.ScrollToBottom();
|
||||||
|
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)
|
||||||
@ -133,6 +179,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);
|
||||||
@ -144,11 +194,13 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
Border border = GetToolChatBorder(msg);
|
Border border = GetToolChatBorder(msg);
|
||||||
borderItemsDict[msgId] = border;
|
borderItemsDict[msgId] = border;
|
||||||
ChatHistoryStackPanel.Children.Add(border);
|
ChatHistoryStackPanel.Children.Add(border);
|
||||||
|
StatusTextBlock.Text = "正在执行工具";
|
||||||
}else if (msg.type == MessageType.CHAT_MESSAGE)
|
}else if (msg.type == MessageType.CHAT_MESSAGE)
|
||||||
{
|
{
|
||||||
Border border = GetUserChatBorder(msg);
|
Border border = GetUserChatBorder(msg);
|
||||||
borderItemsDict[msgId] = border;
|
borderItemsDict[msgId] = border;
|
||||||
ChatHistoryStackPanel.Children.Add(border);
|
ChatHistoryStackPanel.Children.Add(border);
|
||||||
|
StatusTextBlock.Text = "正在读取用户输入";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(msg.role == "assistant")
|
else if(msg.role == "assistant")
|
||||||
@ -158,11 +210,20 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
Border border = GetAiReasonBorder(msg);
|
Border border = GetAiReasonBorder(msg);
|
||||||
borderItemsDict[msgId] = border;
|
borderItemsDict[msgId] = border;
|
||||||
ChatHistoryStackPanel.Children.Add(border);
|
ChatHistoryStackPanel.Children.Add(border);
|
||||||
|
StatusTextBlock.Text = "深度思考中";
|
||||||
}else if (msg.type == MessageType.CHAT_MESSAGE)
|
}else if (msg.type == MessageType.CHAT_MESSAGE)
|
||||||
{
|
{
|
||||||
Border border = GetAiChatBorder(msg);
|
Border border = GetAiChatBorder(msg);
|
||||||
borderItemsDict[msgId] = border;
|
borderItemsDict[msgId] = border;
|
||||||
ChatHistoryStackPanel.Children.Add(border);
|
ChatHistoryStackPanel.Children.Add(border);
|
||||||
|
StatusTextBlock.Text = "回答生成中";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (msg.role == "system")
|
||||||
|
{
|
||||||
|
if (msg.type == MessageType.WARNING)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,6 +233,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);
|
||||||
@ -184,7 +249,10 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
Border borderItem = borderItemsDict[msgId];
|
Border borderItem = borderItemsDict[msgId];
|
||||||
Grid grid = borderItem.Child as Grid;
|
Grid grid = borderItem.Child as Grid;
|
||||||
TextBlock textBlock = grid.Children[1] as TextBlock;
|
TextBlock textBlock = grid.Children[1] as TextBlock;
|
||||||
textBlock.Text = (msg as ToolMessageItem).toolName;
|
ToolMessageItem msgItem = msg as ToolMessageItem;
|
||||||
|
textBlock.Text = msgItem.toolName + " | " + msgItem.status;
|
||||||
|
Button resButton = grid.Children[3] as Button;
|
||||||
|
resButton.Tag = msg;
|
||||||
StatusTextBlock.Text = "正在执行工具";
|
StatusTextBlock.Text = "正在执行工具";
|
||||||
}else if (msg.type == MessageType.CHAT_MESSAGE)
|
}else if (msg.type == MessageType.CHAT_MESSAGE)
|
||||||
{
|
{
|
||||||
@ -211,9 +279,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 = "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,6 +528,7 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
borderItemsDict.Clear();
|
borderItemsDict.Clear();
|
||||||
ChatHistoryStackPanel.Children.Clear();
|
ChatHistoryStackPanel.Children.Clear();
|
||||||
QuestionTextbox.Clear();
|
QuestionTextbox.Clear();
|
||||||
|
StatusTextBlock.Text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TopButton_OnClick(object sender, RoutedEventArgs e)
|
private void TopButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
@ -478,6 +544,14 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
private void StopButton_OnClick(object sender, RoutedEventArgs e)
|
private void StopButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Gateway.StopConversation();
|
Gateway.StopConversation();
|
||||||
|
StatusTextBlock.Text = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ModelComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
log.Info("ModelComboBox_OnSelectionChanged");
|
||||||
|
string model = ModelComboBox.SelectedValue.ToString();
|
||||||
|
log.Info(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
<RowDefinition Height="24"/>
|
<RowDefinition Height="24"/>
|
||||||
<RowDefinition Height="24"/>
|
<RowDefinition Height="24"/>
|
||||||
<RowDefinition Height="24"/>
|
<RowDefinition Height="24"/>
|
||||||
|
<RowDefinition Height="24"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Button Grid.Row="0" Content="Test Workflow" Name="TestServer" Click="TestWorkflow_OnClick"></Button>
|
<Button Grid.Row="0" Content="Test Workflow" Name="TestServer" Click="TestWorkflow_OnClick"></Button>
|
||||||
<Grid Grid.Row="1">
|
<Grid Grid.Row="1">
|
||||||
@ -41,5 +42,6 @@
|
|||||||
<Button Grid.Row="4" Content="Test Stream" Name="TestStream" Click="TestStream_OnClick"></Button>
|
<Button Grid.Row="4" Content="Test Stream" Name="TestStream" Click="TestStream_OnClick"></Button>
|
||||||
<Button Grid.Row="5" Content="Test Arcgis Tool" Name="TestArcGisTool" Click="TestArcGisTool_OnClick"></Button>
|
<Button Grid.Row="5" Content="Test Arcgis Tool" Name="TestArcGisTool" Click="TestArcGisTool_OnClick"></Button>
|
||||||
<Button Grid.Row="6" Content="Test Resource" Name="TestResource" Click="TestResource_OnClick"></Button>
|
<Button Grid.Row="6" Content="Test Resource" Name="TestResource" Click="TestResource_OnClick"></Button>
|
||||||
|
<Button Grid.Row="7" Content="测试获取属性表" Name="TestAttrTable" Click="TestAttrTable_OnClick"></Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -9,6 +9,7 @@ using System.Windows;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using LinkToolAddin.client;
|
using LinkToolAddin.client;
|
||||||
|
using LinkToolAddin.client.tool;
|
||||||
using LinkToolAddin.common;
|
using LinkToolAddin.common;
|
||||||
using LinkToolAddin.host;
|
using LinkToolAddin.host;
|
||||||
using LinkToolAddin.host.llm;
|
using LinkToolAddin.host.llm;
|
||||||
@ -204,7 +205,7 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
// model可选值:qwen3-235b-a22b,qwen-max,deepseek-r1
|
// model可选值:qwen3-235b-a22b,qwen-max,deepseek-r1
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Task.Run(() => Gateway.SendMessageStream(userPrompt,"qwen3-235b-a22b", "D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\20250420_AiDemoProject.gdb", AddReplyStream));
|
await Task.Run(() => Gateway.SendMessageStream(userPrompt,"qwen3-235b-a22b", "F:\\secondsemester\\linktool\\test\\LinkTool0604\\LinkTool0604.gdb", AddReplyStream));
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
@ -311,5 +312,13 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
string content = LocalResource.ReadFileByResource("LinkToolAddin.resource.SystemPrompt.txt");
|
string content = LocalResource.ReadFileByResource("LinkToolAddin.resource.SystemPrompt.txt");
|
||||||
MessageBox.Show(content);
|
MessageBox.Show(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void TestAttrTable_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
JsonRpcResultEntity result = await ArcGisPro.GetFeatureDatasetAttributeTable(
|
||||||
|
"D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\20250420_AiDemoProject.gdb",
|
||||||
|
"LandUse_2005_Copy", "30");
|
||||||
|
log.Info("finish");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,9 @@ public enum MessageType
|
|||||||
TOOL_MESSAGE,
|
TOOL_MESSAGE,
|
||||||
CHAT_MESSAGE,
|
CHAT_MESSAGE,
|
||||||
REASON_MESSAGE,
|
REASON_MESSAGE,
|
||||||
END_TAG
|
END_TAG,
|
||||||
|
WARNING,
|
||||||
|
ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface MessageListItem
|
public interface MessageListItem
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user