接入高德MCP
This commit is contained in:
parent
f341ac9aac
commit
5107fc2f1d
@ -104,6 +104,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
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.Threading.Tasks;
|
||||
using LinkToolAddin.host.llm.entity;
|
||||
|
||||
namespace LinkToolAddin.host.llm;
|
||||
|
||||
@ -11,4 +13,6 @@ public interface Llm
|
||||
|
||||
public IAsyncEnumerable<string> SendChatStreamAsync(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="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<DockPanel Grid.Row="0" LastChildFill="true" KeyboardNavigation.TabNavigation="Local" Height="30">
|
||||
<TextBlock Text="{Binding Heading}" Style="{DynamicResource Esri_TextBlockDockPaneHeader}">
|
||||
<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>
|
||||
<Button Content="Test Server" Name="TestServer" Click="TestServer_OnClick"></Button>
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -1,9 +1,27 @@
|
||||
using System;
|
||||
using System;
|
||||
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.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
|
||||
{
|
||||
@ -12,76 +30,94 @@ namespace LinkToolAddin.ui.dockpane
|
||||
/// </summary>
|
||||
public partial class DialogDockpaneView : UserControl
|
||||
{
|
||||
private static ILog log = LogManager.GetLogger(typeof(DialogDockpaneView));
|
||||
|
||||
public DialogDockpaneView()
|
||||
{
|
||||
InitLogger();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void TestButton_OnClick(object sender, RoutedEventArgs e)
|
||||
public void CallBack(string str,object obj)
|
||||
{
|
||||
string originalJson = @"{
|
||||
""name"": ""Alice"",
|
||||
""age"": 30,
|
||||
""isStudent"": false,
|
||||
""hobbies"": [
|
||||
""reading"",
|
||||
""swimming"",
|
||||
""hiking""
|
||||
],
|
||||
""address"": {
|
||||
""street"": ""123 Main St"",
|
||||
""city"": ""Anytown"",
|
||||
""postalCode"": ""12345""
|
||||
log.Info($"CallBack {str}");
|
||||
}
|
||||
}";
|
||||
|
||||
try
|
||||
private async void TestServer_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 反序列化 JSON 到对象
|
||||
Person? person = JsonSerializer.Deserialize<Person>(originalJson);
|
||||
log.Info("TestServer Clicked");
|
||||
string res = await SseMcpClient.testGaodeMcp();
|
||||
log.Info(res);
|
||||
}
|
||||
|
||||
if (person != null)
|
||||
private async void Retrieve_Test()
|
||||
{
|
||||
// 序列化对象回 JSON 字符串
|
||||
string serializedJson = JsonSerializer.Serialize(person, new JsonSerializerOptions
|
||||
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()
|
||||
{
|
||||
WriteIndented = true // 格式化输出
|
||||
Llm bailian = new Bailian
|
||||
{
|
||||
api_key = "sk-db177155677e438f832860e7f4da6afc",
|
||||
app_id = "6a77c5a68de64f469b79fcdcde9d5001",
|
||||
};
|
||||
string reponse = await bailian.SendChatAsync(new LlmJsonContent()
|
||||
{
|
||||
Model = "qwen-max",
|
||||
Messages = new List<Message>()
|
||||
{
|
||||
new Message()
|
||||
{
|
||||
Role = "user",
|
||||
Content = "你是谁"
|
||||
}
|
||||
},
|
||||
Temperature = 0.7,
|
||||
TopP = 1,
|
||||
MaxTokens = 1000,
|
||||
});
|
||||
|
||||
Console.WriteLine("序列化后的 JSON:");
|
||||
Console.WriteLine(serializedJson);
|
||||
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(serializedJson);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("反序列化失败,对象为 null。");
|
||||
}
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
Console.WriteLine($"JSON 处理错误: {ex.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"发生错误: {ex.Message}");
|
||||
}
|
||||
}
|
||||
log.Info(reponse);
|
||||
}
|
||||
|
||||
// 定义数据模型类
|
||||
public class Person
|
||||
protected void InitLogger()
|
||||
{
|
||||
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; }
|
||||
}
|
||||
// 1. 创建控制台输出器(Appender)
|
||||
var consoleAppender = new ConsoleAppender
|
||||
{
|
||||
Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"),
|
||||
Threshold = log4net.Core.Level.Info // 仅输出 Info 及以上级别
|
||||
};
|
||||
consoleAppender.ActivateOptions(); // 激活配置
|
||||
|
||||
public class Address
|
||||
// 2. 创建文件滚动输出器(按大小滚动)
|
||||
var fileAppender = new RollingFileAppender
|
||||
{
|
||||
public string? Street { get; set; }
|
||||
public string? City { get; set; }
|
||||
public string? PostalCode { get; set; }
|
||||
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 日志(严重问题)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -17,6 +17,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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
|
||||
{
|
||||
@ -56,6 +60,7 @@ namespace LinkToolAddin.ui.dockpane
|
||||
{
|
||||
protected override void OnClick()
|
||||
{
|
||||
|
||||
DialogDockpaneViewModel.Show();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user