v0.1.4版本 #2
@ -104,6 +104,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Esri.ArcGISPro.Extensions30" Version="3.4.1.55405" />
|
<PackageReference Include="Esri.ArcGISPro.Extensions30" Version="3.4.1.55405" />
|
||||||
|
<PackageReference Include="log4net" Version="3.1.0" />
|
||||||
|
<PackageReference Include="ModelContextProtocol" Version="0.1.0-preview.13" />
|
||||||
|
<PackageReference Include="ModelContextProtocol.AspNetCore" Version="0.1.0-preview.13" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="C:\Program Files\ArcGIS\Pro\bin\Esri.ProApp.SDK.Desktop.targets" Condition="Exists('C:\Program Files\ArcGIS\Pro\bin\Esri.ProApp.SDK.Desktop.targets') AND !Exists('Esri.ArcGISPro.Extensions.targets')" />
|
<Import Project="C:\Program Files\ArcGIS\Pro\bin\Esri.ProApp.SDK.Desktop.targets" Condition="Exists('C:\Program Files\ArcGIS\Pro\bin\Esri.ProApp.SDK.Desktop.targets') AND !Exists('Esri.ArcGISPro.Extensions.targets')" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
18
client/CallArcGISPro.cs
Normal file
18
client/CallArcGISPro.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LinkToolAddin.server;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace LinkToolAddin.client;
|
||||||
|
|
||||||
|
public class CallArcGISPro
|
||||||
|
{
|
||||||
|
public async static Task<string> CallArcGISProTool(Dictionary<string,string> parameters)
|
||||||
|
{
|
||||||
|
// Call the ArcGIS Pro method and get the result
|
||||||
|
var result = await server.CallArcGISPro.CallArcGISProTool(parameters["toolName"], JsonConvert.DeserializeObject<List<string>>(parameters["toolParams"]));
|
||||||
|
|
||||||
|
// Serialize the result back to a JSON string
|
||||||
|
return JsonConvert.SerializeObject(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
client/PythonMcpClient.cs
Normal file
6
client/PythonMcpClient.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace LinkToolAddin.client;
|
||||||
|
|
||||||
|
public class PythonMcpClient
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
56
client/SseMcpClient.cs
Normal file
56
client/SseMcpClient.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ModelContextProtocol.Client;
|
||||||
|
using ModelContextProtocol.Protocol.Transport;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace LinkToolAddin.client;
|
||||||
|
|
||||||
|
public class SseMcpClient
|
||||||
|
{
|
||||||
|
public static async Task<string> testGaodeMcp()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Connecting to 高德 MCP Server via SSE...");
|
||||||
|
|
||||||
|
// 创建 MCP Server 配置
|
||||||
|
SseClientTransportOptions options = new SseClientTransportOptions
|
||||||
|
{
|
||||||
|
Endpoint = new Uri("https://mcp.amap.com/sse?key=ed418512c94ade8f83d42c37b77d2bb2"),
|
||||||
|
};
|
||||||
|
|
||||||
|
IClientTransport transport = new SseClientTransport(options);;
|
||||||
|
|
||||||
|
// 创建 MCP Client
|
||||||
|
var client = await McpClientFactory.CreateAsync(transport);
|
||||||
|
Console.WriteLine("Connected to 高德 MCP Server");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 获取可用工具列表
|
||||||
|
var tools = await client.ListToolsAsync();
|
||||||
|
Console.WriteLine("\nAvailable Tools:");
|
||||||
|
foreach (var tool in tools)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"- {tool.Name}: {tool.Description}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 示例调用:获取当前定位
|
||||||
|
var result = await client.CallToolAsync("amap.maps_weather", new Dictionary<string, object>{{"city","北京"}});
|
||||||
|
Console.WriteLine("\n[amap.get_location] Result:");
|
||||||
|
Console.WriteLine(result);
|
||||||
|
return JsonConvert.SerializeObject(result);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error occurred: {ex.Message}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await client.DisposeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Client closed.");
|
||||||
|
return "failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
21
common/HttpRequest.cs
Normal file
21
common/HttpRequest.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LinkToolAddin.host.llm.entity;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace LinkToolAddin.common;
|
||||||
|
|
||||||
|
public class HttpRequest
|
||||||
|
{
|
||||||
|
public static async Task<string> SendPostRequestAsync(string url, string jsonContent, string apiKey)
|
||||||
|
{
|
||||||
|
using var httpClient = new HttpClient();
|
||||||
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
|
||||||
|
var response = await httpClient.PostAsync(url, new StringContent(jsonContent, Encoding.UTF8, "application/json"));
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
var responseBody = await response.Content.ReadAsStringAsync();
|
||||||
|
return responseBody;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
host/CallMcp.cs
Normal file
28
host/CallMcp.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LinkToolAddin.server;
|
||||||
|
using log4net;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace LinkToolAddin.host
|
||||||
|
{
|
||||||
|
public class CallMcp
|
||||||
|
{
|
||||||
|
private static readonly ILog log = LogManager.GetLogger(typeof(CallMcp));
|
||||||
|
public static async Task<string> CallInnerMcpTool(string jsonRpcString)
|
||||||
|
{
|
||||||
|
log.Info("通过反射调用内部MCP工具");
|
||||||
|
var jsonRpcEntity = JsonConvert.DeserializeObject<JsonRpcEntity>(jsonRpcString);
|
||||||
|
|
||||||
|
Type type = Type.GetType("LinkToolAddin.client."+jsonRpcEntity.Method.Split('.')[0]);
|
||||||
|
MethodInfo method = type.GetMethod(jsonRpcEntity.Method.Split('.')[1],BindingFlags.Public | BindingFlags.Static);
|
||||||
|
var task = method.Invoke(null, new object[] { jsonRpcEntity.Params }) as Task<JsonRpcResultEntity>;
|
||||||
|
JsonRpcResultEntity result = await task;
|
||||||
|
return JsonConvert.SerializeObject(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
host/llm/Bailian.cs
Normal file
45
host/llm/Bailian.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LinkToolAddin.common;
|
||||||
|
using LinkToolAddin.host.llm.entity;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace LinkToolAddin.host.llm;
|
||||||
|
|
||||||
|
public class Bailian : Llm
|
||||||
|
{
|
||||||
|
public string model { get; set; } = "qwen-max";
|
||||||
|
public string temperature { get; set; }
|
||||||
|
public string top_p { get; set; }
|
||||||
|
public string max_tokens { get; set; }
|
||||||
|
public string app_id { get; set; }
|
||||||
|
public string api_key { get; set; }
|
||||||
|
public IAsyncEnumerable<string> SendChatStreamAsync(string message)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<string> SendApplicationStreamAsync(string message)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> SendChatAsync(LlmJsonContent jsonContent)
|
||||||
|
{
|
||||||
|
string url = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions";
|
||||||
|
string responseBody = await HttpRequest.SendPostRequestAsync(url, JsonConvert.SerializeObject(jsonContent), api_key);
|
||||||
|
LlmChat result = JsonConvert.DeserializeObject<LlmChat>(responseBody);
|
||||||
|
return result.Choices[0].Message.Content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> SendApplicationAsync(CommonInput commonInput)
|
||||||
|
{
|
||||||
|
string url = $"https://dashscope.aliyuncs.com/api/v1/apps/{app_id}/completion";
|
||||||
|
string responseBody = await HttpRequest.SendPostRequestAsync(url, JsonConvert.SerializeObject(commonInput), api_key);
|
||||||
|
ApplicationOutput result = JsonConvert.DeserializeObject<ApplicationOutput>(responseBody);
|
||||||
|
return responseBody;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LinkToolAddin.host.llm.entity;
|
||||||
|
|
||||||
namespace LinkToolAddin.host.llm;
|
namespace LinkToolAddin.host.llm;
|
||||||
|
|
||||||
@ -11,4 +13,6 @@ public interface Llm
|
|||||||
|
|
||||||
public IAsyncEnumerable<string> SendChatStreamAsync(string message);
|
public IAsyncEnumerable<string> SendChatStreamAsync(string message);
|
||||||
public IAsyncEnumerable<string> SendApplicationStreamAsync(string message);
|
public IAsyncEnumerable<string> SendApplicationStreamAsync(string message);
|
||||||
|
public Task<string> SendChatAsync(LlmJsonContent jsonContent);
|
||||||
|
public Task<string> SendApplicationAsync(CommonInput commonInput);
|
||||||
}
|
}
|
||||||
51
host/llm/entity/ApplicationOutput.cs
Normal file
51
host/llm/entity/ApplicationOutput.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
namespace LinkToolAddin.host.llm.entity
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
|
public partial class ApplicationOutput
|
||||||
|
{
|
||||||
|
[JsonProperty("output")]
|
||||||
|
public Output Output { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("usage")]
|
||||||
|
public Usage Usage { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("request_id")]
|
||||||
|
public Guid RequestId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Output
|
||||||
|
{
|
||||||
|
[JsonProperty("finish_reason")]
|
||||||
|
public string FinishReason { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("session_id")]
|
||||||
|
public string SessionId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("text")]
|
||||||
|
public string Text { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Usage
|
||||||
|
{
|
||||||
|
[JsonProperty("models")]
|
||||||
|
public List<Model> Models { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Model
|
||||||
|
{
|
||||||
|
[JsonProperty("output_tokens")]
|
||||||
|
public long OutputTokens { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("model_id")]
|
||||||
|
public string ModelId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("input_tokens")]
|
||||||
|
public long InputTokens { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
31
host/llm/entity/CommonInput.cs
Normal file
31
host/llm/entity/CommonInput.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
namespace LinkToolAddin.host.llm.entity
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
|
public partial class CommonInput
|
||||||
|
{
|
||||||
|
[JsonProperty("input")]
|
||||||
|
public Input Input { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("parameters")]
|
||||||
|
public Debug Parameters { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("debug")]
|
||||||
|
public Debug Debug { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Debug
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Input
|
||||||
|
{
|
||||||
|
[JsonProperty("prompt")]
|
||||||
|
public string Prompt { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
42
host/llm/entity/KnowldgeResult.cs
Normal file
42
host/llm/entity/KnowldgeResult.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
namespace LinkToolAddin.host.llm.entity
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
|
public partial class KnowledgeResult
|
||||||
|
{
|
||||||
|
[JsonProperty("rewriteQuery")]
|
||||||
|
public string RewriteQuery { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("chunkList")]
|
||||||
|
public List<ChunkList> ChunkList { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class ChunkList
|
||||||
|
{
|
||||||
|
[JsonProperty("score")]
|
||||||
|
public double Score { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("imagesUrl")]
|
||||||
|
public List<object> ImagesUrl { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("documentName")]
|
||||||
|
public string DocumentName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("titcontent", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string Titcontent { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("title", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string Content { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("conten_score_with_weight", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string ContenScoreWithWeight { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
69
host/llm/entity/LlmChat.cs
Normal file
69
host/llm/entity/LlmChat.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
namespace LinkToolAddin.host.llm.entity
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
|
public partial class LlmChat
|
||||||
|
{
|
||||||
|
[JsonProperty("choices")]
|
||||||
|
public List<Choice> Choices { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("object")]
|
||||||
|
public string Object { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("usage")]
|
||||||
|
public Usage Usage { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("created")]
|
||||||
|
public long Created { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("system_fingerprint")]
|
||||||
|
public object SystemFingerprint { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("model")]
|
||||||
|
public string Model { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Choice
|
||||||
|
{
|
||||||
|
[JsonProperty("message")]
|
||||||
|
public Message Message { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("finish_reason")]
|
||||||
|
public string FinishReason { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("index")]
|
||||||
|
public long Index { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("logprobs")]
|
||||||
|
public object Logprobs { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Usage
|
||||||
|
{
|
||||||
|
[JsonProperty("prompt_tokens")]
|
||||||
|
public long PromptTokens { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("completion_tokens")]
|
||||||
|
public long CompletionTokens { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("total_tokens")]
|
||||||
|
public long TotalTokens { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("prompt_tokens_details")]
|
||||||
|
public PromptTokensDetails PromptTokensDetails { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class PromptTokensDetails
|
||||||
|
{
|
||||||
|
[JsonProperty("cached_tokens")]
|
||||||
|
public long CachedTokens { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
38
host/llm/entity/LlmJsonContent.cs
Normal file
38
host/llm/entity/LlmJsonContent.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
namespace LinkToolAddin.host.llm.entity
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
public partial class LlmJsonContent
|
||||||
|
{
|
||||||
|
[JsonProperty("model")]
|
||||||
|
public string Model { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("messages")]
|
||||||
|
public List<Message> Messages { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("stream")]
|
||||||
|
public bool Stream { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty("temperature")]
|
||||||
|
public double Temperature { get; set; } = 0.7;
|
||||||
|
|
||||||
|
[JsonProperty("top_p")]
|
||||||
|
public double TopP { get; set; } = 1.0;
|
||||||
|
|
||||||
|
[JsonProperty("max_tokens")]
|
||||||
|
public int MaxTokens { get; set; } = 2048;
|
||||||
|
|
||||||
|
[JsonProperty("top_k")]
|
||||||
|
public int TopK { get; set; } = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Message
|
||||||
|
{
|
||||||
|
[JsonProperty("role")]
|
||||||
|
public string Role { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("content")]
|
||||||
|
public string Content { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
54
resource/DocDb.cs
Normal file
54
resource/DocDb.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LinkToolAddin.host.llm;
|
||||||
|
using LinkToolAddin.host.llm.entity;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace LinkToolAddin.resource;
|
||||||
|
|
||||||
|
public class DocDb
|
||||||
|
{
|
||||||
|
public string appId {get;set;}
|
||||||
|
public string apiKey {get;set;}
|
||||||
|
|
||||||
|
public DocDb(string apiKey,KnowledgeBase knowledgeBaseEnum)
|
||||||
|
{
|
||||||
|
this.apiKey = apiKey;
|
||||||
|
appId = knowledgeBase[knowledgeBaseEnum];
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum KnowledgeBase
|
||||||
|
{
|
||||||
|
ArcGISProHelpDoc,
|
||||||
|
ArcGISProToolDoc,
|
||||||
|
TaskPlanningDoc,
|
||||||
|
ArcGISProApplicantExample
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<KnowledgeBase, string> knowledgeBase = new Dictionary<KnowledgeBase, string>
|
||||||
|
{
|
||||||
|
{KnowledgeBase.ArcGISProHelpDoc,"6a77c5a68de64f469b79fcdcde9d5001"}
|
||||||
|
};
|
||||||
|
|
||||||
|
public async Task<KnowledgeResult> Retrieve(string query)
|
||||||
|
{
|
||||||
|
Llm bailian = new Bailian
|
||||||
|
{
|
||||||
|
api_key = apiKey,
|
||||||
|
app_id = appId,
|
||||||
|
};
|
||||||
|
var commonInput = new CommonInput
|
||||||
|
{
|
||||||
|
Input = new Input
|
||||||
|
{
|
||||||
|
Prompt = query
|
||||||
|
},
|
||||||
|
Parameters = new Debug(),
|
||||||
|
Debug = new Debug()
|
||||||
|
};
|
||||||
|
string responseBody = await bailian.SendApplicationAsync(commonInput);
|
||||||
|
ApplicationOutput result = JsonConvert.DeserializeObject<ApplicationOutput>(responseBody);
|
||||||
|
KnowledgeResult knowledgeResult = JsonConvert.DeserializeObject<KnowledgeResult>(result.Output.Text);
|
||||||
|
return knowledgeResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
resource/GpToolDb.cs
Normal file
9
resource/GpToolDb.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace LinkToolAddin.resource;
|
||||||
|
|
||||||
|
public class GpToolDb
|
||||||
|
{
|
||||||
|
public string toolName { get; set; }
|
||||||
|
public string toolDescription { get; set; }
|
||||||
|
public string exeName { get; set; }
|
||||||
|
public string toolParma { get; set; }
|
||||||
|
}
|
||||||
8
resource/PromptDb.cs
Normal file
8
resource/PromptDb.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace LinkToolAddin.resource;
|
||||||
|
|
||||||
|
public class PromptDb
|
||||||
|
{
|
||||||
|
public string promptName { get; set; }
|
||||||
|
public string promptDescription { get; set; }
|
||||||
|
public string promptContent { get; set; }
|
||||||
|
}
|
||||||
23
server/CallArcGISPro.cs
Normal file
23
server/CallArcGISPro.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ArcGIS.Desktop.Core.Geoprocessing;
|
||||||
|
using ArcGIS.Desktop.Framework.Dialogs;
|
||||||
|
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LinkToolAddin.server;
|
||||||
|
|
||||||
|
public class CallArcGISPro
|
||||||
|
{
|
||||||
|
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(CallArcGISPro));
|
||||||
|
public async static Task<JsonRpcResultEntity> CallArcGISProTool(string toolName, List<string> toolParams)
|
||||||
|
{
|
||||||
|
var results = await Geoprocessing.ExecuteToolAsync(toolName, toolParams);
|
||||||
|
log.Info($"CallArcGISProTool: {toolName} | {toolParams}");
|
||||||
|
return new JsonRpcSuccessEntity()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Result = results.ToString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
25
server/JsonRpcEntity.cs
Normal file
25
server/JsonRpcEntity.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace LinkToolAddin.server
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
public partial class JsonRpcEntity
|
||||||
|
{
|
||||||
|
[JsonProperty("jsonrpc")]
|
||||||
|
public string Jsonrpc { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("method")]
|
||||||
|
public string Method { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("params")]
|
||||||
|
public Dictionary<string,string> Params { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public long Id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
25
server/JsonRpcErrorEntity.cs
Normal file
25
server/JsonRpcErrorEntity.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
namespace LinkToolAddin.server
|
||||||
|
{
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
public partial class JsonRpcErrorEntity
|
||||||
|
{
|
||||||
|
[JsonProperty("jsonrpc")]
|
||||||
|
public string Jsonrpc { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("error")]
|
||||||
|
public Error Error { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public long Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Error
|
||||||
|
{
|
||||||
|
[JsonProperty("code")]
|
||||||
|
public long Code { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("message")]
|
||||||
|
public string Message { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
15
server/JsonRpcResultEntity.cs
Normal file
15
server/JsonRpcResultEntity.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace LinkToolAddin.server
|
||||||
|
{
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
public partial class JsonRpcResultEntity
|
||||||
|
{
|
||||||
|
[JsonProperty("jsonrpc")]
|
||||||
|
public string Jsonrpc { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public long Id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
16
server/JsonRpcSuccessEntity.cs
Normal file
16
server/JsonRpcSuccessEntity.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace LinkToolAddin.server
|
||||||
|
{
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
public partial class JsonRpcSuccessEntity : JsonRpcResultEntity
|
||||||
|
{
|
||||||
|
[JsonProperty("jsonrpc")]
|
||||||
|
public string Jsonrpc { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("result")]
|
||||||
|
public string Result { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public long Id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,14 +22,7 @@
|
|||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<DockPanel Grid.Row="0" LastChildFill="true" KeyboardNavigation.TabNavigation="Local" Height="30">
|
<DockPanel Grid.Row="0" LastChildFill="true" KeyboardNavigation.TabNavigation="Local" Height="30">
|
||||||
<TextBlock Text="{Binding Heading}" Style="{DynamicResource Esri_TextBlockDockPaneHeader}">
|
<Button Content="Test Server" Name="TestServer" Click="TestServer_OnClick"></Button>
|
||||||
<TextBlock.ToolTip>
|
|
||||||
<WrapPanel Orientation="Vertical" MaxWidth="300">
|
|
||||||
<TextBlock Text="{Binding Heading}" TextWrapping="Wrap"/>
|
|
||||||
</WrapPanel>
|
|
||||||
</TextBlock.ToolTip>
|
|
||||||
</TextBlock>
|
|
||||||
<Button Content="Test Server" Name="TestButton" Click="TestButton_OnClick" ></Button>
|
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,9 +1,27 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json;
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading;
|
||||||
|
using ArcGIS.Desktop.Core.Geoprocessing;
|
||||||
|
using LinkToolAddin.client;
|
||||||
|
using LinkToolAddin.host.llm;
|
||||||
|
using LinkToolAddin.host.llm.entity;
|
||||||
|
using LinkToolAddin.resource;
|
||||||
|
using log4net;
|
||||||
|
using log4net.Appender;
|
||||||
|
using log4net.Config;
|
||||||
|
using log4net.Layout;
|
||||||
|
using ModelContextProtocol.Server;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace LinkToolAddin.ui.dockpane
|
namespace LinkToolAddin.ui.dockpane
|
||||||
{
|
{
|
||||||
@ -12,76 +30,94 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class DialogDockpaneView : UserControl
|
public partial class DialogDockpaneView : UserControl
|
||||||
{
|
{
|
||||||
|
private static ILog log = LogManager.GetLogger(typeof(DialogDockpaneView));
|
||||||
|
|
||||||
public DialogDockpaneView()
|
public DialogDockpaneView()
|
||||||
{
|
{
|
||||||
|
InitLogger();
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TestButton_OnClick(object sender, RoutedEventArgs e)
|
public void CallBack(string str,object obj)
|
||||||
{
|
{
|
||||||
string originalJson = @"{
|
log.Info($"CallBack {str}");
|
||||||
""name"": ""Alice"",
|
}
|
||||||
""age"": 30,
|
|
||||||
""isStudent"": false,
|
|
||||||
""hobbies"": [
|
|
||||||
""reading"",
|
|
||||||
""swimming"",
|
|
||||||
""hiking""
|
|
||||||
],
|
|
||||||
""address"": {
|
|
||||||
""street"": ""123 Main St"",
|
|
||||||
""city"": ""Anytown"",
|
|
||||||
""postalCode"": ""12345""
|
|
||||||
}
|
|
||||||
}";
|
|
||||||
|
|
||||||
try
|
private async void TestServer_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
log.Info("TestServer Clicked");
|
||||||
|
string res = await SseMcpClient.testGaodeMcp();
|
||||||
|
log.Info(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void Retrieve_Test()
|
||||||
|
{
|
||||||
|
log.Info("TestServer Clicked");
|
||||||
|
// string jsonRpcString = @"{""jsonrpc"":""2.0"",""method"":""CallArcGISPro.CallArcGISProTool"",""params"":{""toolName"":""analysis.Buffer"",""toolParams"":""[\""D:/01_Development/02_ArcGIS_Pro_Project/20250319_GisAi/Test.gdb/河流\"",\""D:/01_Development/02_ArcGIS_Pro_Project/20250319_GisAi/Test.gdb/河流buffer\"",\""100\""]""},""id"":1}";
|
||||||
|
DocDb docDb = new DocDb("sk-db177155677e438f832860e7f4da6afc", DocDb.KnowledgeBase.ArcGISProHelpDoc);
|
||||||
|
string query = "缓冲区";
|
||||||
|
KnowledgeResult knowledgeResult = await docDb.Retrieve(query);
|
||||||
|
log.Info(JsonConvert.SerializeObject(knowledgeResult.ChunkList));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void Request_Bailian_Test()
|
||||||
|
{
|
||||||
|
Llm bailian = new Bailian
|
||||||
{
|
{
|
||||||
// 反序列化 JSON 到对象
|
api_key = "sk-db177155677e438f832860e7f4da6afc",
|
||||||
Person? person = JsonSerializer.Deserialize<Person>(originalJson);
|
app_id = "6a77c5a68de64f469b79fcdcde9d5001",
|
||||||
|
};
|
||||||
if (person != null)
|
string reponse = await bailian.SendChatAsync(new LlmJsonContent()
|
||||||
|
{
|
||||||
|
Model = "qwen-max",
|
||||||
|
Messages = new List<Message>()
|
||||||
{
|
{
|
||||||
// 序列化对象回 JSON 字符串
|
new Message()
|
||||||
string serializedJson = JsonSerializer.Serialize(person, new JsonSerializerOptions
|
|
||||||
{
|
{
|
||||||
WriteIndented = true // 格式化输出
|
Role = "user",
|
||||||
});
|
Content = "你是谁"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Temperature = 0.7,
|
||||||
|
TopP = 1,
|
||||||
|
MaxTokens = 1000,
|
||||||
|
});
|
||||||
|
log.Info(reponse);
|
||||||
|
}
|
||||||
|
|
||||||
Console.WriteLine("序列化后的 JSON:");
|
protected void InitLogger()
|
||||||
Console.WriteLine(serializedJson);
|
{
|
||||||
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(serializedJson);
|
// 1. 创建控制台输出器(Appender)
|
||||||
}
|
var consoleAppender = new ConsoleAppender
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("反序列化失败,对象为 null。");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (JsonException ex)
|
|
||||||
{
|
{
|
||||||
Console.WriteLine($"JSON 处理错误: {ex.Message}");
|
Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"),
|
||||||
}
|
Threshold = log4net.Core.Level.Info // 仅输出 Info 及以上级别
|
||||||
catch (Exception ex)
|
};
|
||||||
|
consoleAppender.ActivateOptions(); // 激活配置
|
||||||
|
|
||||||
|
// 2. 创建文件滚动输出器(按大小滚动)
|
||||||
|
var fileAppender = new RollingFileAppender
|
||||||
{
|
{
|
||||||
Console.WriteLine($"发生错误: {ex.Message}");
|
File = Path.Combine("Logs", "linktool_app.log"), // 日志文件路径
|
||||||
}
|
AppendToFile = true, // 追加模式
|
||||||
|
RollingStyle = RollingFileAppender.RollingMode.Size, // 按文件大小滚动
|
||||||
|
MaxSizeRollBackups = 10, // 保留 10 个历史文件
|
||||||
|
MaximumFileSize = "1MB", // 单个文件最大 1MB
|
||||||
|
StaticLogFileName = true, // 固定文件名(否则自动追加序号)
|
||||||
|
Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"),
|
||||||
|
Threshold = log4net.Core.Level.Info // 仅输出 Info 及以上级别
|
||||||
|
};
|
||||||
|
fileAppender.ActivateOptions(); // 激活配置
|
||||||
|
|
||||||
|
// 3. 直接通过 BasicConfigurator 注册 Appender
|
||||||
|
BasicConfigurator.Configure(consoleAppender, fileAppender);
|
||||||
|
|
||||||
|
log = LogManager.GetLogger(typeof(DialogDockpaneView));
|
||||||
|
|
||||||
|
// 测试日志输出
|
||||||
|
log.Debug("Debug 日志(控制台可见)");
|
||||||
|
log.Info("Info 日志(控制台和文件可见)");
|
||||||
|
log.Error("Error 日志(严重问题)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定义数据模型类
|
|
||||||
public class Person
|
|
||||||
{
|
|
||||||
public string? Name { get; set; }
|
|
||||||
public int Age { get; set; }
|
|
||||||
public bool IsStudent { get; set; }
|
|
||||||
public List<string>? Hobbies { get; set; }
|
|
||||||
public Address? Address { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Address
|
|
||||||
{
|
|
||||||
public string? Street { get; set; }
|
|
||||||
public string? City { get; set; }
|
|
||||||
public string? PostalCode { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -17,6 +17,10 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Logging.Console;
|
||||||
|
|
||||||
namespace LinkToolAddin.ui.dockpane
|
namespace LinkToolAddin.ui.dockpane
|
||||||
{
|
{
|
||||||
@ -56,6 +60,7 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
{
|
{
|
||||||
protected override void OnClick()
|
protected override void OnClick()
|
||||||
{
|
{
|
||||||
|
|
||||||
DialogDockpaneViewModel.Show();
|
DialogDockpaneViewModel.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user