Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 108ee40ffe |
@ -26,7 +26,6 @@
|
|||||||
<button refID="DialogDockpane_ShowButton" size="large" />
|
<button refID="DialogDockpane_ShowButton" size="large" />
|
||||||
<button refID="Version_Button" size="large" />
|
<button refID="Version_Button" size="large" />
|
||||||
<button refID="LinkToolAddin_ui_dockpane_TestDockpane_ShowButton" size="large" />
|
<button refID="LinkToolAddin_ui_dockpane_TestDockpane_ShowButton" size="large" />
|
||||||
<button refID="LinkToolAddin_ui_mcp_McpConfigWindow" size="large" />
|
|
||||||
</group>
|
</group>
|
||||||
<group id="PreferenceGroup" caption="设置项" appearsOnAddInTab="false">
|
<group id="PreferenceGroup" caption="设置项" appearsOnAddInTab="false">
|
||||||
<button refID="Preference_Button" size="large" />
|
<button refID="Preference_Button" size="large" />
|
||||||
@ -45,9 +44,6 @@
|
|||||||
<button id="LinkToolAddin_ui_dockpane_TestDockpane_ShowButton" caption="测试面板" className="LinkToolAddin.ui.dockpane.TestDockpane_ShowButton" loadOnClick="true" smallImage="GenericButtonPurple16" largeImage="GenericButtonPurple32">
|
<button id="LinkToolAddin_ui_dockpane_TestDockpane_ShowButton" caption="测试面板" className="LinkToolAddin.ui.dockpane.TestDockpane_ShowButton" loadOnClick="true" smallImage="GenericButtonPurple16" largeImage="GenericButtonPurple32">
|
||||||
<tooltip heading="测试面板">打开测试面板<disabledText /></tooltip>
|
<tooltip heading="测试面板">打开测试面板<disabledText /></tooltip>
|
||||||
</button>
|
</button>
|
||||||
<button id="LinkToolAddin_ui_mcp_McpConfigWindow" caption="McpConfigWindow" className="LinkToolAddin.ui.mcp.ShowMcpConfigWindow" loadOnClick="true" smallImage="GenericButtonPurple16" largeImage="GenericButtonPurple32">
|
|
||||||
<tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
|
|
||||||
</button>
|
|
||||||
</controls>
|
</controls>
|
||||||
<dockPanes>
|
<dockPanes>
|
||||||
<dockPane id="DialogDockpane" caption="LinkTool" className="LinkToolAddin.ui.dockpane.DialogDockpaneViewModel" dock="group" dockWith="esri_core_projectDockPane">
|
<dockPane id="DialogDockpane" caption="LinkTool" className="LinkToolAddin.ui.dockpane.DialogDockpaneViewModel" dock="group" dockWith="esri_core_projectDockPane">
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"profiles": {
|
"profiles": {
|
||||||
"LinkToolAddin": {
|
"LinkToolAddin": {
|
||||||
"commandName": "Executable",
|
"commandName": "Executable",
|
||||||
"executablePath": "C:\\Program Files\\ArcGIS\\Pro\\bin\\ArcGISPro.exe",
|
"executablePath": "C:\\Users\\86158\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\ArcGISPro.exe",
|
||||||
"applicationUrl": "https://localhost:5001",
|
"applicationUrl": "https://localhost:5001",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
|||||||
@ -1,250 +0,0 @@
|
|||||||
using ArcGIS.Core.CIM;
|
|
||||||
using ArcGIS.Core.Data;
|
|
||||||
using ArcGIS.Desktop.Core;
|
|
||||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
|
||||||
using ArcGIS.Desktop.Mapping;
|
|
||||||
using LinkToolAddin.server;
|
|
||||||
using ModelContextProtocol.Server;
|
|
||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
|
|
||||||
namespace LinkToolAddin.client.tool
|
|
||||||
{
|
|
||||||
public class ArcGisProSymbology
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 将 System.Drawing.Color 转换为 CIMColor(支持 RGB 和透明度)
|
|
||||||
/// </summary>
|
|
||||||
private static CIMColor ColorToCIMColor(int r, int g, int b, double alpha =0)
|
|
||||||
{
|
|
||||||
return ColorFactory.Instance.CreateRGBColor(r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造点符号引用(封装 SymbolFactory 调用)
|
|
||||||
/// </summary>
|
|
||||||
private static CIMSymbolReference GetPointSymbolRef(int r, int g, int b, float size)
|
|
||||||
{
|
|
||||||
CIMColor color = ColorToCIMColor(r, g, b);
|
|
||||||
CIMPointSymbol symbol = SymbolFactory.Instance.ConstructPointSymbol(color, size);
|
|
||||||
return symbol.MakeSymbolReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造线符号引用
|
|
||||||
/// </summary>
|
|
||||||
private static CIMSymbolReference GetLineSymbolRef(int r, int g, int b, float width)
|
|
||||||
{
|
|
||||||
CIMColor color = ColorToCIMColor(r, g, b);
|
|
||||||
|
|
||||||
// 手动创建线符号图层
|
|
||||||
CIMSolidStroke stroke = new CIMSolidStroke
|
|
||||||
{
|
|
||||||
Color = color,
|
|
||||||
Width = width,
|
|
||||||
CapStyle = LineCapStyle.Round, // 端点样式:圆头
|
|
||||||
JoinStyle = LineJoinStyle.Round, // 连接处样式:圆角
|
|
||||||
Enable = true // 必须启用!
|
|
||||||
};
|
|
||||||
|
|
||||||
// 创建线符号并设置图层
|
|
||||||
CIMLineSymbol symbol = new CIMLineSymbol
|
|
||||||
{
|
|
||||||
SymbolLayers = new CIMSymbolLayer[] { stroke }
|
|
||||||
};
|
|
||||||
|
|
||||||
return symbol.MakeSymbolReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造面符号引用(填充 + 轮廓)
|
|
||||||
/// </summary>
|
|
||||||
private static CIMSymbolReference GetPolygonSymbolRef(
|
|
||||||
int fillR, int fillG, int fillB,
|
|
||||||
int outlineR, int outlineG, int outlineB,
|
|
||||||
float outlineWidth)
|
|
||||||
{
|
|
||||||
// 填充图层
|
|
||||||
CIMSolidFill fillLayer = new CIMSolidFill
|
|
||||||
{
|
|
||||||
Color = ColorToCIMColor(fillR, fillG, fillB)
|
|
||||||
};
|
|
||||||
|
|
||||||
// 轮廓图层
|
|
||||||
CIMSolidStroke outlineLayer = new CIMSolidStroke
|
|
||||||
{
|
|
||||||
Color = ColorToCIMColor(outlineR, outlineG, outlineB),
|
|
||||||
Width = outlineWidth,
|
|
||||||
JoinStyle = LineJoinStyle.Round//圆角
|
|
||||||
};
|
|
||||||
|
|
||||||
CIMPolygonSymbol polygonSymbol = new CIMPolygonSymbol
|
|
||||||
{
|
|
||||||
SymbolLayers = new CIMSymbolLayer[] { fillLayer, outlineLayer }
|
|
||||||
};
|
|
||||||
|
|
||||||
return polygonSymbol.MakeSymbolReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 工具方法 ====================
|
|
||||||
|
|
||||||
[McpServerTool, Description("可以通过调用 ArcGIS Pro 的符号系统,设置点图层的符号颜色和大小。" +
|
|
||||||
"此工具将分析要素数据特征与当前地图布局,智能生成符合视觉美学原则的点状符号。" +
|
|
||||||
"传入参数必须包括红(R)、绿(G)、蓝(B)三种颜色分量(0-255)、符号尺寸(单位:点)以及目标图层名称。" +
|
|
||||||
"系统在设置过程中综合考虑颜色对比度、符号可辨性、形状匹配度及整体地图协调性等因素," +
|
|
||||||
"动态调整或创建新的符号配置,避免视觉拥挤或信息弱化问题。" +
|
|
||||||
"最终输出一个优化后的点符号系统配置,可直接应用于指定的点要素图层,显著提升地图的视觉层次感与信息传达效率。" +
|
|
||||||
"适用于城市位置、监测站点、兴趣点(POI)等点状地理要素的可视化表达场景。")]
|
|
||||||
public static async Task<JsonRpcResultEntity> SetPointColor(string r, string g, string b, string layerName, string size)
|
|
||||||
{
|
|
||||||
return await SetSymbolAsync(layerName, esriGeometryType.esriGeometryPoint, () =>
|
|
||||||
{
|
|
||||||
return GetPointSymbolRef(int.Parse(r), int.Parse(g), int.Parse(b), float.Parse(size));
|
|
||||||
}, "点符号");
|
|
||||||
}
|
|
||||||
|
|
||||||
[McpServerTool, Description("可以通过调用 ArcGIS Pro 的符号系统,设置线图层的符号颜色和宽度。" +
|
|
||||||
"此工具将分析要素数据和当前地图布局,智能选择或生成符合视觉美学原则的线符号。" +
|
|
||||||
"传入参数必须包括 RGB 三种颜色分量、线符号宽度以及目标图层名称。" +
|
|
||||||
"系统会综合考虑颜色对比度、线型协调性、地图整体可读性等因素,动态调整或创建新的符号配置。" +
|
|
||||||
"最终输出一个优化后的线符号系统,可直接应用于指定的线要素图层,显著提升地图的视觉表达效果与信息传达清晰度。" +
|
|
||||||
"适用于道路、河流、边界等线状要素的符号化场景。")]
|
|
||||||
public static async Task<JsonRpcResultEntity> SetLineColor(string r, string g, string b, string layerName, string width)
|
|
||||||
{
|
|
||||||
|
|
||||||
return await SetSymbolAsync(layerName, esriGeometryType.esriGeometryPolyline, () =>
|
|
||||||
{
|
|
||||||
return GetLineSymbolRef(int.Parse(r), int.Parse(g), int.Parse(b), float.Parse(width));
|
|
||||||
}, "线符号");
|
|
||||||
}
|
|
||||||
|
|
||||||
[McpServerTool, Description("设置面图层的填充颜色、轮廓颜色和轮廓宽度。" +
|
|
||||||
"此工具将调用 ArcGIS Pro 符号系统,智能生成符合视觉美学的面符号。" +
|
|
||||||
"传入参数包括:填充颜色的RGB值、轮廓颜色的RGB值、轮廓宽度、图层名称。" +
|
|
||||||
"最终将优化后的符号应用于指定的面要素图层,提升地图可视化效果。")]
|
|
||||||
public static async Task<JsonRpcResultEntity> SetPolygonColor(string fillR, string fillG, string fillB,
|
|
||||||
string outlineR, string outlineG, string outlineB, string outlineWidth, string layerName)
|
|
||||||
{
|
|
||||||
return await SetSymbolAsync(layerName, esriGeometryType.esriGeometryPolygon, () =>
|
|
||||||
{
|
|
||||||
return GetPolygonSymbolRef(int.Parse(fillR), int.Parse(fillG), int.Parse(fillB), int.Parse(outlineR), int.Parse(outlineG), int.Parse(outlineB), float.Parse(outlineWidth));
|
|
||||||
}, "面符号");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 通用符号设置逻辑(封装重复代码)
|
|
||||||
/// </summary>
|
|
||||||
private async static Task<JsonRpcResultEntity> SetSymbolAsync(
|
|
||||||
string layerName,
|
|
||||||
esriGeometryType expectedType,
|
|
||||||
Func<CIMSymbolReference> symbolFactory,
|
|
||||||
string symbolTypeName)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Map map = MapView.Active?.Map;
|
|
||||||
if (map == null)
|
|
||||||
{
|
|
||||||
return new JsonRpcErrorEntity
|
|
||||||
{
|
|
||||||
Error = new Error
|
|
||||||
{
|
|
||||||
Code = "404",
|
|
||||||
Message = "当前没有激活的地图"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
FeatureLayer featureLayer = map.GetLayersAsFlattenedList()
|
|
||||||
.OfType<FeatureLayer>()
|
|
||||||
.FirstOrDefault(l => l.Name == layerName);
|
|
||||||
|
|
||||||
if (featureLayer == null)
|
|
||||||
{
|
|
||||||
return(new JsonRpcErrorEntity
|
|
||||||
{
|
|
||||||
Error = new Error
|
|
||||||
{
|
|
||||||
Code = "404",
|
|
||||||
Message = $"找不到名为 '{layerName}' 的图层"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (featureLayer.ShapeType != expectedType)
|
|
||||||
{
|
|
||||||
return(new JsonRpcErrorEntity
|
|
||||||
{
|
|
||||||
Error = new Error
|
|
||||||
{
|
|
||||||
Code = "400",
|
|
||||||
Message = $"指定图层 '{layerName}' 不是{symbolTypeName}图层"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
CIMRenderer renderer = null;
|
|
||||||
|
|
||||||
await QueuedTask.Run(async () =>
|
|
||||||
{
|
|
||||||
renderer = featureLayer.GetRenderer();
|
|
||||||
});
|
|
||||||
CIMSimpleRenderer simpleRenderer = renderer as CIMSimpleRenderer;
|
|
||||||
if (simpleRenderer == null)
|
|
||||||
{
|
|
||||||
return(new JsonRpcErrorEntity
|
|
||||||
{
|
|
||||||
Error = new Error
|
|
||||||
{
|
|
||||||
Code = "400",
|
|
||||||
Message = $"图层 '{layerName}' 的渲染器不是简单渲染器,无法设置"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await QueuedTask.Run(async () =>
|
|
||||||
{
|
|
||||||
CIMSymbolReference symbolRef = symbolFactory();
|
|
||||||
simpleRenderer.Symbol = symbolRef;
|
|
||||||
featureLayer.SetRenderer(renderer);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (new JsonRpcSuccessEntity
|
|
||||||
{
|
|
||||||
Result = $"{symbolTypeName}设置成功",
|
|
||||||
Id = GetIdForType(expectedType)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
// 捕获 QueuedTask 外层异常(如线程中断等)
|
|
||||||
return new JsonRpcErrorEntity
|
|
||||||
{
|
|
||||||
Error = new Error
|
|
||||||
{
|
|
||||||
Code = "500",
|
|
||||||
Message = $"任务执行失败: {ex.Message}"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据几何类型返回对应的 ID(用于兼容原逻辑)
|
|
||||||
/// </summary>
|
|
||||||
private static int GetIdForType(esriGeometryType type)
|
|
||||||
{
|
|
||||||
return type switch
|
|
||||||
{
|
|
||||||
esriGeometryType.esriGeometryPoint => 1,
|
|
||||||
esriGeometryType.esriGeometryPolyline => 2,
|
|
||||||
esriGeometryType.esriGeometryPolygon => 3,
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
117
host/Gateway.cs
117
host/Gateway.cs
@ -56,7 +56,7 @@ 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(),callback);
|
string toolInfos = await GetToolInfos(new McpServerList());
|
||||||
log.Info(SystemPrompt.SysPrompt(gdbPath, toolInfos));
|
log.Info(SystemPrompt.SysPrompt(gdbPath, toolInfos));
|
||||||
messages.Add(new Message
|
messages.Add(new Message
|
||||||
{
|
{
|
||||||
@ -238,48 +238,15 @@ public class Gateway
|
|||||||
|
|
||||||
public static async void SendMessageStream(string message, string model, string gdbPath, Action<MessageListItem> callback)
|
public static async void SendMessageStream(string message, string model, string gdbPath, Action<MessageListItem> callback)
|
||||||
{
|
{
|
||||||
Llm modelObj = new Bailian();
|
Llm bailian = new Bailian
|
||||||
List<string> bailianModels = ["Moonshot-Kimi-K2-Instruct","deepseek-r1","deepseek-v3","qwen3-235b-a22b","qwen3-32b","qwen-plus","qwen-turbo","abab6.5s-chat"];
|
|
||||||
List<string> dmxModels = ["grok-3-mini","o4-mini","claude-3-5-haiku-20241022","claude-sonnet-4-20250514-thinking","claude-3-7-sonnet-20250219-thinking","grok-4-ssvip","gemini-2.5-pro-ssvip","gemini-2.5-flash-ssvip","o3-pro","gpt-4.1","gpt-4o"];
|
|
||||||
if (bailianModels.Contains(model))
|
|
||||||
{
|
|
||||||
modelObj = new Bailian
|
|
||||||
{
|
{
|
||||||
api_key = "sk-db177155677e438f832860e7f4da6afc"
|
api_key = "sk-db177155677e438f832860e7f4da6afc"
|
||||||
};
|
};
|
||||||
}else if (dmxModels.Contains(model))
|
|
||||||
{
|
|
||||||
modelObj = new DmxApi
|
|
||||||
{
|
|
||||||
api_key = "sk-VQeuLUmhO1LL8H97tFj5kuWOqGFD4CFRmAsdqhxkmkYxUUlP"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MessageListItem endMessageListItem2 = new ChatMessageItem
|
|
||||||
{
|
|
||||||
type = MessageType.ERROR,
|
|
||||||
content = $"目前暂未支持{model}模型,请选择其他模型。",
|
|
||||||
id = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(),
|
|
||||||
role = "system"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem2);
|
|
||||||
MessageListItem endMessageListItem1 = new ChatMessageItem
|
|
||||||
{
|
|
||||||
type = MessageType.END_TAG,
|
|
||||||
content = "",
|
|
||||||
id = (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + 3).ToString(),
|
|
||||||
role = "assistant"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Message> messages = new List<Message>();
|
List<Message> messages = new List<Message>();
|
||||||
string toolInfos = "";
|
string toolInfos = "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
toolInfos = await GetToolInfos(new McpServerList(),callback);
|
toolInfos = await GetToolInfos(new McpServerList());
|
||||||
messages.Add(new Message
|
messages.Add(new Message
|
||||||
{
|
{
|
||||||
Role = "system",
|
Role = "system",
|
||||||
@ -293,26 +260,9 @@ public class Gateway
|
|||||||
}catch (Exception ex)
|
}catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.Error(ex);
|
log.Error(ex);
|
||||||
MessageListItem endMessageListItem2 = new ChatMessageItem
|
MessageBox.Show(ex.Message,"获取MCP列表失败");
|
||||||
{
|
|
||||||
type = MessageType.WARNING,
|
|
||||||
content = $"MCP列表读取失败{ex.Message}",
|
|
||||||
id = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(),
|
|
||||||
role = "system"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem2);
|
|
||||||
MessageListItem endMessageListItem1 = new ChatMessageItem
|
|
||||||
{
|
|
||||||
type = MessageType.END_TAG,
|
|
||||||
content = "",
|
|
||||||
id = (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + 3).ToString(),
|
|
||||||
role = "assistant"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem1);
|
|
||||||
// MessageBox.Show(ex.Message,"获取MCP列表失败");
|
|
||||||
}
|
}
|
||||||
goOn = true;
|
goOn = true;
|
||||||
long accTokens = 0;
|
|
||||||
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>";
|
||||||
McpServerList mcpServerList = new McpServerList();
|
McpServerList mcpServerList = new McpServerList();
|
||||||
@ -323,27 +273,10 @@ public class Gateway
|
|||||||
bool executedTool = false;
|
bool executedTool = false;
|
||||||
while (goOn)
|
while (goOn)
|
||||||
{
|
{
|
||||||
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
||||||
loop++;
|
loop++;
|
||||||
if (loop > 500)
|
if (loop > 500)
|
||||||
{
|
{
|
||||||
MessageListItem endMessageListItem2 = new ChatMessageItem
|
MessageBox.Show("达到最大循环次数", "退出循环");
|
||||||
{
|
|
||||||
type = MessageType.ERROR,
|
|
||||||
content = "达到最大循环次数,已退出循环。",
|
|
||||||
id = timestamp.ToString(),
|
|
||||||
role = "system"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem2);
|
|
||||||
MessageListItem endMessageListItem1 = new ChatMessageItem
|
|
||||||
{
|
|
||||||
type = MessageType.END_TAG,
|
|
||||||
content = "",
|
|
||||||
id = (timestamp + 3).ToString(),
|
|
||||||
role = "assistant"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem1);
|
|
||||||
// MessageBox.Show("达到最大循环次数", "退出循环");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LlmJsonContent jsonContent = new LlmJsonContent()
|
LlmJsonContent jsonContent = new LlmJsonContent()
|
||||||
@ -352,8 +285,10 @@ public class Gateway
|
|||||||
Messages = messages,
|
Messages = messages,
|
||||||
Temperature = 0.3,
|
Temperature = 0.3,
|
||||||
TopP = 0.4,
|
TopP = 0.4,
|
||||||
|
TopK = 7,
|
||||||
MaxTokens = 1000,
|
MaxTokens = 1000,
|
||||||
};
|
};
|
||||||
|
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
List<McpToolRequest> mcpToolRequests = new List<McpToolRequest>();
|
List<McpToolRequest> mcpToolRequests = new List<McpToolRequest>();
|
||||||
List<PromptRequest> promptRequests = new List<PromptRequest>();
|
List<PromptRequest> promptRequests = new List<PromptRequest>();
|
||||||
var (toolMatched, toolRemaining) = ExtractMatchedPart(messageContent, toolPattern);
|
var (toolMatched, toolRemaining) = ExtractMatchedPart(messageContent, toolPattern);
|
||||||
@ -375,7 +310,7 @@ public class Gateway
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await foreach(LlmStreamChat llmStreamChat in modelObj.SendChatStreamAsync(jsonContent))
|
await foreach(LlmStreamChat llmStreamChat in bailian.SendChatStreamAsync(jsonContent))
|
||||||
{
|
{
|
||||||
if (!goOn)
|
if (!goOn)
|
||||||
{
|
{
|
||||||
@ -506,24 +441,7 @@ public class Gateway
|
|||||||
}catch (Exception e)
|
}catch (Exception e)
|
||||||
{
|
{
|
||||||
log.Error(e.Message);
|
log.Error(e.Message);
|
||||||
MessageListItem endMessageListItem2 = new ChatMessageItem
|
MessageBox.Show(e.Message, "请求大模型出错");
|
||||||
{
|
|
||||||
type = MessageType.ERROR,
|
|
||||||
content = $"请求大模型出错:{e.Message}",
|
|
||||||
id = timestamp.ToString(),
|
|
||||||
role = "system"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem2);
|
|
||||||
MessageListItem endMessageListItem1 = new ChatMessageItem
|
|
||||||
{
|
|
||||||
type = MessageType.END_TAG,
|
|
||||||
content = "",
|
|
||||||
id = (timestamp + 3).ToString(),
|
|
||||||
role = "assistant"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem1);
|
|
||||||
// MessageBox.Show(e.Message, "请求大模型出错");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (messageContent != "")
|
if (messageContent != "")
|
||||||
{
|
{
|
||||||
@ -779,13 +697,10 @@ public class Gateway
|
|||||||
};
|
};
|
||||||
callback?.Invoke(endMessageListItem);
|
callback?.Invoke(endMessageListItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageBox.Show("本轮回复完成", "结束提示");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> GetToolInfos(McpServerList mcpServerList,Action<MessageListItem> callback)
|
private static async Task<string> GetToolInfos(McpServerList mcpServerList)
|
||||||
{
|
{
|
||||||
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
||||||
StringBuilder toolInfos = new StringBuilder();
|
StringBuilder toolInfos = new StringBuilder();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
List<int> failedMcp = new List<int>();
|
List<int> failedMcp = new List<int>();
|
||||||
@ -869,7 +784,7 @@ public class Gateway
|
|||||||
{
|
{
|
||||||
log.Error(e.Message);
|
log.Error(e.Message);
|
||||||
failedMcp.Add(i);
|
failedMcp.Add(i);
|
||||||
failedMcpString.Add(mcpServerList.GetAllServerNames()[i-1]);
|
failedMcpString.Add(mcpServerList.GetAllServerNames()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,15 +805,7 @@ public class Gateway
|
|||||||
|
|
||||||
if (!failedMcp.IsNullOrEmpty())
|
if (!failedMcp.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
MessageListItem endMessageListItem2 = new ChatMessageItem
|
MessageBox.Show($"读取失败的MCP服务有:{JsonConvert.SerializeObject(failedMcpString)}","MCP读取错误");
|
||||||
{
|
|
||||||
type = MessageType.WARNING,
|
|
||||||
content = $"读取失败的MCP服务有:{JsonConvert.SerializeObject(failedMcpString)}",
|
|
||||||
id = timestamp.ToString(),
|
|
||||||
role = "system"
|
|
||||||
};
|
|
||||||
callback?.Invoke(endMessageListItem2);
|
|
||||||
// MessageBox.Show($"读取失败的MCP服务有:{JsonConvert.SerializeObject(failedMcpString)}","MCP读取错误");
|
|
||||||
}
|
}
|
||||||
return toolInfos.ToString();
|
return toolInfos.ToString();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using LinkToolAddin.host.mcp;
|
using LinkToolAddin.host.mcp;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace LinkToolAddin.host;
|
namespace LinkToolAddin.host;
|
||||||
|
|
||||||
@ -29,13 +28,6 @@ public class McpServerList
|
|||||||
Description = "可以调用arcgis的地理处理工具或执行python代码等",
|
Description = "可以调用arcgis的地理处理工具或执行python代码等",
|
||||||
IsActive = true
|
IsActive = true
|
||||||
});
|
});
|
||||||
servers.Add("ArcGisProSymbology", new InnerMcpServer
|
|
||||||
{
|
|
||||||
Name = "ArcGisProSymbology",
|
|
||||||
Type = "inner",
|
|
||||||
Description = "可以调用arcgis的符号系统进行简单符号设置",
|
|
||||||
IsActive = true
|
|
||||||
});
|
|
||||||
servers.Add("KnowledgeBase", new InnerMcpServer
|
servers.Add("KnowledgeBase", new InnerMcpServer
|
||||||
{
|
{
|
||||||
Name = "KnowledgeBase",
|
Name = "KnowledgeBase",
|
||||||
@ -93,11 +85,6 @@ public class McpServerList
|
|||||||
//});
|
//});
|
||||||
}
|
}
|
||||||
|
|
||||||
public McpServerList(string json)
|
|
||||||
{
|
|
||||||
servers = JsonConvert.DeserializeObject<Dictionary<string, McpServer>>(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
public McpServer GetServer(string name)
|
public McpServer GetServer(string name)
|
||||||
{
|
{
|
||||||
if (servers.ContainsKey(name))
|
if (servers.ContainsKey(name))
|
||||||
|
|||||||
@ -1,52 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using LinkToolAddin.common;
|
|
||||||
using LinkToolAddin.host.llm.entity;
|
|
||||||
using LinkToolAddin.host.llm.entity.stream;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace LinkToolAddin.host.llm;
|
|
||||||
|
|
||||||
public class DmxApi : Llm
|
|
||||||
{
|
|
||||||
public string model { get; set; } = "gpt-4o";
|
|
||||||
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 async IAsyncEnumerable<LlmStreamChat> SendChatStreamAsync(LlmJsonContent jsonContent)
|
|
||||||
{
|
|
||||||
jsonContent.Stream = true;
|
|
||||||
StringBuilder contentBuilder = new StringBuilder();
|
|
||||||
StringBuilder reasonBuilder = new StringBuilder();
|
|
||||||
await foreach (LlmStreamChat chunk in HttpRequest.PostWithStreamingResponseAsync(
|
|
||||||
"https://www.dmxapi.cn/v1/chat/completions",
|
|
||||||
JsonConvert.SerializeObject(jsonContent),
|
|
||||||
api_key))
|
|
||||||
{
|
|
||||||
contentBuilder.Append(chunk.Choices[0].Delta.Content);
|
|
||||||
reasonBuilder.Append(chunk.Choices[0].Delta.ResoningContent);
|
|
||||||
LlmStreamChat fullChunk = chunk;
|
|
||||||
fullChunk.Choices[0].Delta.Content = contentBuilder.ToString();
|
|
||||||
fullChunk.Choices[0].Delta.ResoningContent = reasonBuilder.ToString();
|
|
||||||
yield return fullChunk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IAsyncEnumerable<string> SendApplicationStreamAsync(string message)
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<string> SendChatAsync(LlmJsonContent jsonContent)
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<string> SendApplicationAsync(CommonInput commonInput)
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -24,7 +24,7 @@ namespace LinkToolAddin.host.llm.entity
|
|||||||
public int MaxTokens { get; set; } = 2048;
|
public int MaxTokens { get; set; } = 2048;
|
||||||
|
|
||||||
[JsonProperty("top_k")]
|
[JsonProperty("top_k")]
|
||||||
public int TopK { get; set; }
|
public int TopK { get; set; } = 40;
|
||||||
|
|
||||||
[JsonProperty("enable_thinking")]
|
[JsonProperty("enable_thinking")]
|
||||||
public bool EnableThinking { get; set; } = true;
|
public bool EnableThinking { get; set; } = true;
|
||||||
|
|||||||
@ -40,15 +40,13 @@
|
|||||||
<ComboBox Grid.Column="4" Name="ModelComboBox" SelectionChanged="ModelComboBox_OnSelectionChanged">
|
<ComboBox Grid.Column="4" Name="ModelComboBox" SelectionChanged="ModelComboBox_OnSelectionChanged">
|
||||||
<ComboBoxItem Content="qwen3-235b-a22b" IsSelected="True"/>
|
<ComboBoxItem Content="qwen3-235b-a22b" IsSelected="True"/>
|
||||||
<ComboBoxItem Content="qwen3-32b" />
|
<ComboBoxItem Content="qwen3-32b" />
|
||||||
|
<ComboBoxItem Content="qwq-32b" />
|
||||||
|
<ComboBoxItem Content="qwen-max-latest" />
|
||||||
<ComboBoxItem Content="deepseek-r1" />
|
<ComboBoxItem Content="deepseek-r1" />
|
||||||
|
<ComboBoxItem Content="deepseek-r1-0528" />
|
||||||
|
<ComboBoxItem Content="deepseek-r1-distill-qwen-32b" />
|
||||||
|
<ComboBoxItem Content="deepseek-r1-distill-llama-70b" />
|
||||||
<ComboBoxItem Content="deepseek-v3" />
|
<ComboBoxItem Content="deepseek-v3" />
|
||||||
<ComboBoxItem Content="Moonshot-Kimi-K2-Instruct" />
|
|
||||||
<Separator></Separator>
|
|
||||||
<ComboBoxItem Content="grok-3-mini" />
|
|
||||||
<ComboBoxItem Content="o4-mini" />
|
|
||||||
<ComboBoxItem Content="claude-3-5-haiku-20241022" />
|
|
||||||
<ComboBoxItem Content="gemini-2.5-flash-ssvip" />
|
|
||||||
<Separator></Separator>
|
|
||||||
<ComboBoxItem Content="自定义" />
|
<ComboBoxItem Content="自定义" />
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -63,7 +61,7 @@
|
|||||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||||
<ColumnDefinition Width="48"></ColumnDefinition>
|
<ColumnDefinition Width="48"></ColumnDefinition>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBox Grid.Column="0" Name="QuestionTextbox" Text="" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" PreviewKeyDown="QuestionTextbox_OnPreviewKeyDown"></TextBox>
|
<TextBox Grid.Column="0" Name="QuestionTextbox" Text="这是用户的问题" TextWrapping="Wrap"></TextBox>
|
||||||
<Button Grid.Column="1" Name="SendButton" Content="发送" Click="SendButton_OnClick"></Button>
|
<Button Grid.Column="1" Name="SendButton" Content="发送" Click="SendButton_OnClick"></Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@ -2,10 +2,8 @@ using System;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
@ -16,7 +14,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows.Documents;
|
using System.Windows.Documents;
|
||||||
using System.Windows.Input;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using ArcGIS.Desktop.Core;
|
using ArcGIS.Desktop.Core;
|
||||||
using ArcGIS.Desktop.Core.Geoprocessing;
|
using ArcGIS.Desktop.Core.Geoprocessing;
|
||||||
@ -36,7 +33,6 @@ using ModelContextProtocol.Client;
|
|||||||
using ModelContextProtocol.Protocol.Types;
|
using ModelContextProtocol.Protocol.Types;
|
||||||
using ModelContextProtocol.Server;
|
using ModelContextProtocol.Server;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace LinkToolAddin.ui.dockpane
|
namespace LinkToolAddin.ui.dockpane
|
||||||
{
|
{
|
||||||
@ -104,7 +100,6 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
|
|
||||||
private void SendButton_OnClick(object sender, RoutedEventArgs e)
|
private void SendButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
StatusTextBlock.Text = "正在读取用户输入和工具列表";
|
|
||||||
string question = QuestionTextbox.Text;
|
string question = QuestionTextbox.Text;
|
||||||
string defaultGdbPath = Project.Current.DefaultGeodatabasePath;
|
string defaultGdbPath = Project.Current.DefaultGeodatabasePath;
|
||||||
string gdbPath = @"";
|
string gdbPath = @"";
|
||||||
@ -228,16 +223,7 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
{
|
{
|
||||||
if (msg.type == MessageType.WARNING)
|
if (msg.type == MessageType.WARNING)
|
||||||
{
|
{
|
||||||
Border border = GetWarningChatBorder(msg);
|
|
||||||
borderItemsDict[msgId] = border;
|
|
||||||
ChatHistoryStackPanel.Children.Add(border);
|
|
||||||
StatusTextBlock.Text = "出现警告信息";
|
|
||||||
}else if (msg.type == MessageType.ERROR)
|
|
||||||
{
|
|
||||||
Border border = GetErrorChatBorder(msg);
|
|
||||||
borderItemsDict[msgId] = border;
|
|
||||||
ChatHistoryStackPanel.Children.Add(border);
|
|
||||||
StatusTextBlock.Text = "出现错误信息";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,7 +263,7 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
StatusTextBlock.Text = "正在读取用户输入";
|
StatusTextBlock.Text = "正在读取用户输入";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(msg.role == "assistant")
|
else
|
||||||
{
|
{
|
||||||
if (msg.type == MessageType.REASON_MESSAGE)
|
if (msg.type == MessageType.REASON_MESSAGE)
|
||||||
{
|
{
|
||||||
@ -294,22 +280,6 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
textBox.Text = msg.content;
|
textBox.Text = msg.content;
|
||||||
StatusTextBlock.Text = "回答生成中";
|
StatusTextBlock.Text = "回答生成中";
|
||||||
}
|
}
|
||||||
}else if (msg.role == "system")
|
|
||||||
{
|
|
||||||
if (msg.type == MessageType.WARNING)
|
|
||||||
{
|
|
||||||
Border borderItem = borderItemsDict[msgId];
|
|
||||||
Grid grid = borderItem.Child as Grid;
|
|
||||||
TextBox textBox = grid.Children[1] as TextBox;
|
|
||||||
textBox.Text = msg.content;
|
|
||||||
StatusTextBlock.Text = "出现警告信息";
|
|
||||||
}else if (msg.type == MessageType.ERROR)
|
|
||||||
{
|
|
||||||
Border borderItem = borderItemsDict[msgId];
|
|
||||||
Grid grid = borderItem.Child as Grid;
|
|
||||||
TextBox textBox = grid.Children[1] as TextBox;
|
|
||||||
textBox.Text = msg.content;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Math.Abs(verticalOffset + viewportHeight - contentHeight) < tolerance)
|
if (Math.Abs(verticalOffset + viewportHeight - contentHeight) < tolerance)
|
||||||
@ -476,66 +446,6 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
return border;
|
return border;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Border GetWarningChatBorder(MessageListItem msg)
|
|
||||||
{
|
|
||||||
Border border = new Border();
|
|
||||||
border.Margin = new Thickness(24);
|
|
||||||
border.Padding = new Thickness(8);
|
|
||||||
border.BorderThickness = new Thickness(1);
|
|
||||||
border.BorderBrush = Brushes.DarkGoldenrod;
|
|
||||||
border.CornerRadius = new CornerRadius(3);
|
|
||||||
border.Background = Brushes.Moccasin;
|
|
||||||
Grid grid = new Grid();
|
|
||||||
// Image icon = new Image()
|
|
||||||
// {
|
|
||||||
// Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.tool.png"),
|
|
||||||
// Stretch = Stretch.Fill,
|
|
||||||
// HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center
|
|
||||||
// };
|
|
||||||
// icon.Margin = new Thickness(0, 0, 8, 0);
|
|
||||||
// grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)});
|
|
||||||
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)});
|
|
||||||
TextBlock textBlock = new TextBlock();
|
|
||||||
textBlock.Text = (msg as ChatMessageItem).content;
|
|
||||||
textBlock.TextWrapping = TextWrapping.Wrap;
|
|
||||||
// grid.Children.Add(icon);
|
|
||||||
grid.Children.Add(textBlock);
|
|
||||||
// Grid.SetColumn(icon, 0);
|
|
||||||
Grid.SetColumn(textBlock, 1);
|
|
||||||
border.Child = grid;
|
|
||||||
return border;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Border GetErrorChatBorder(MessageListItem msg)
|
|
||||||
{
|
|
||||||
Border border = new Border();
|
|
||||||
border.Margin = new Thickness(24);
|
|
||||||
border.Padding = new Thickness(8);
|
|
||||||
border.BorderThickness = new Thickness(1);
|
|
||||||
border.BorderBrush = Brushes.Crimson;
|
|
||||||
border.CornerRadius = new CornerRadius(3);
|
|
||||||
border.Background = Brushes.LightPink;
|
|
||||||
Grid grid = new Grid();
|
|
||||||
// Image icon = new Image()
|
|
||||||
// {
|
|
||||||
// Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.tool.png"),
|
|
||||||
// Stretch = Stretch.Fill,
|
|
||||||
// HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center
|
|
||||||
// };
|
|
||||||
// icon.Margin = new Thickness(0, 0, 8, 0);
|
|
||||||
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)});
|
|
||||||
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)});
|
|
||||||
TextBlock textBlock = new TextBlock();
|
|
||||||
textBlock.Text = (msg as ChatMessageItem).content;
|
|
||||||
textBlock.TextWrapping = TextWrapping.Wrap;
|
|
||||||
// grid.Children.Add(icon);
|
|
||||||
grid.Children.Add(textBlock);
|
|
||||||
// Grid.SetColumn(icon, 0);
|
|
||||||
Grid.SetColumn(textBlock, 1);
|
|
||||||
border.Child = grid;
|
|
||||||
return border;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Border GetToolChatBorder(MessageListItem msg)
|
private Border GetToolChatBorder(MessageListItem msg)
|
||||||
{
|
{
|
||||||
Border border = new Border();
|
Border border = new Border();
|
||||||
@ -569,47 +479,18 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
argsButton.Content = "参数";
|
argsButton.Content = "参数";
|
||||||
argsButton.Tag = msg as ToolMessageItem;
|
argsButton.Tag = msg as ToolMessageItem;
|
||||||
argsButton.Click += ToolArgsButton_OnClick;
|
argsButton.Click += ToolArgsButton_OnClick;
|
||||||
|
border.Child = grid;
|
||||||
Button resButton = new Button();
|
Button resButton = new Button();
|
||||||
resButton.Content = "结果";
|
resButton.Content = "结果";
|
||||||
resButton.Tag = msg as ToolMessageItem;
|
resButton.Tag = msg as ToolMessageItem;
|
||||||
resButton.Click += ToolResButton_OnClick;
|
resButton.Click += ToolResButton_OnClick;
|
||||||
|
|
||||||
grid.Children.Add(argsButton);
|
grid.Children.Add(argsButton);
|
||||||
Grid.SetColumn(argsButton, 2);
|
Grid.SetColumn(argsButton, 2);
|
||||||
grid.Children.Add(resButton);
|
grid.Children.Add(resButton);
|
||||||
Grid.SetColumn(resButton, 3);
|
Grid.SetColumn(resButton, 3);
|
||||||
|
|
||||||
if (toolMsg.toolParams.ContainsKey("toolName"))
|
|
||||||
{
|
|
||||||
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(36, GridUnitType.Pixel)});
|
|
||||||
Button checkButton = new Button();
|
|
||||||
checkButton.Content = "检查";
|
|
||||||
checkButton.Tag = toolMsg;
|
|
||||||
checkButton.Click += ToolCheckButton_OnClick;
|
|
||||||
grid.Children.Add(checkButton);
|
|
||||||
Grid.SetColumn(checkButton, 4);
|
|
||||||
}
|
|
||||||
border.Child = grid;
|
|
||||||
return border;
|
return border;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToolCheckButton_OnClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Button button = sender as Button;
|
|
||||||
ToolMessageItem toolItem = button.Tag as ToolMessageItem;
|
|
||||||
string gisToolName = toolItem.toolParams["toolName"] as string;
|
|
||||||
JArray gisToolParams = toolItem.toolParams["toolParams"] as JArray;
|
|
||||||
List<string> gitToolParamsList = (gisToolParams as JArray).Select(token => token.ToString()).ToList();
|
|
||||||
Geoprocessing.OpenToolDialog(gisToolName,gitToolParamsList);
|
|
||||||
}catch (Exception ex)
|
|
||||||
{
|
|
||||||
log.Error(ex);
|
|
||||||
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(ex.Message,"打开工具失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ToolArgsButton_OnClick(object sender, RoutedEventArgs e)
|
private void ToolArgsButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Button button = sender as Button;
|
Button button = sender as Button;
|
||||||
@ -672,43 +553,5 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
string model = ModelComboBox.SelectedValue.ToString();
|
string model = ModelComboBox.SelectedValue.ToString();
|
||||||
log.Info(model);
|
log.Info(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void QuestionTextbox_OnKeyDown(object sender, KeyEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Key == Key.Enter)
|
|
||||||
{
|
|
||||||
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
|
|
||||||
{
|
|
||||||
// Shift + Enter: 插入换行
|
|
||||||
QuestionTextbox.SelectedText = Environment.NewLine;
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Enter: 触发发送
|
|
||||||
e.Handled = true;
|
|
||||||
SendButton_OnClick(sender, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void QuestionTextbox_OnPreviewKeyDown(object sender, KeyEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Key == Key.Enter)
|
|
||||||
{
|
|
||||||
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
|
|
||||||
{
|
|
||||||
// Shift + Enter: 插入换行
|
|
||||||
QuestionTextbox.SelectedText = Environment.NewLine;
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Enter: 触发发送
|
|
||||||
e.Handled = true;
|
|
||||||
SendButton_OnClick(sender, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
<RowDefinition Height="24"/>
|
<RowDefinition Height="24"/>
|
||||||
<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>
|
||||||
@ -44,6 +43,5 @@
|
|||||||
<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>
|
<Button Grid.Row="7" Content="测试获取属性表" Name="TestAttrTable" Click="TestAttrTable_OnClick"></Button>
|
||||||
<Button Grid.Row="8" Content="测试符号系统" Name="TestSymbology" Click="TestSymbology_Click"></Button>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -320,12 +320,5 @@ namespace LinkToolAddin.ui.dockpane
|
|||||||
"LandUse_2005_Copy", "30");
|
"LandUse_2005_Copy", "30");
|
||||||
log.Info("finish");
|
log.Info("finish");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void TestSymbology_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
//await ArcGisProSymbology.SetPointColor(115, 174, 82, "population_XYTableToPoint", 10);
|
|
||||||
//await ArcGisProSymbology.SetLineColor(29,141,213,"testline",50);
|
|
||||||
//await ArcGisProSymbology.SetPolygonColor(149, 2, 8, 255, 153, 0, 30, "county111_popul");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
<controls:ProWindow x:Class="LinkToolAddin.ui.mcp.McpConfigWindow"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:controls="clr-namespace:ArcGIS.Desktop.Framework.Controls;assembly=ArcGIS.Desktop.Framework"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:extensions="clr-namespace:ArcGIS.Desktop.Extensions;assembly=ArcGIS.Desktop.Extensions"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
Title="MCP服务器配置" Height="450" Width="500"
|
|
||||||
WindowStartupLocation="CenterOwner"
|
|
||||||
>
|
|
||||||
<controls:ProWindow.Resources>
|
|
||||||
<ResourceDictionary>
|
|
||||||
<ResourceDictionary.MergedDictionaries>
|
|
||||||
<extensions:DesignOnlyResourceDictionary Source="pack://application:,,,/ArcGIS.Desktop.Framework;component\Themes\Default.xaml"/>
|
|
||||||
</ResourceDictionary.MergedDictionaries>
|
|
||||||
</ResourceDictionary>
|
|
||||||
</controls:ProWindow.Resources>
|
|
||||||
<Grid>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="*"></RowDefinition>
|
|
||||||
<RowDefinition Height="Auto"></RowDefinition>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<TextBox Grid.Row="0" Name="McpJsonTextBox" AcceptsReturn="True"></TextBox>
|
|
||||||
<Button Grid.Row="1" Name="McpJsonButton">保存</Button>
|
|
||||||
</Grid>
|
|
||||||
</controls:ProWindow>
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Data;
|
|
||||||
using System.Windows.Documents;
|
|
||||||
using System.Windows.Input;
|
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
using System.Windows.Navigation;
|
|
||||||
using System.Windows.Shapes;
|
|
||||||
using LinkToolAddin.host;
|
|
||||||
using LinkToolAddin.host.mcp;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Path = System.IO.Path;
|
|
||||||
|
|
||||||
namespace LinkToolAddin.ui.mcp
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for McpConfigWindow.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class McpConfigWindow : ArcGIS.Desktop.Framework.Controls.ProWindow
|
|
||||||
{
|
|
||||||
private static Dictionary<string,McpServer> servers = new Dictionary<string, McpServer>();
|
|
||||||
public McpConfigWindow()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
string mcpConfigStr = ReadMcpConfig();
|
|
||||||
McpJsonTextBox.Text = mcpConfigStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ReadMcpConfig()
|
|
||||||
{
|
|
||||||
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
|
||||||
string configDirPath = Path.Combine(appDataPath, "LinkTool");
|
|
||||||
string mcpConfigPath = Path.Combine(appDataPath, "LinkTool", "McpConfig.json");
|
|
||||||
Directory.CreateDirectory(configDirPath);
|
|
||||||
if (!File.Exists(mcpConfigPath))
|
|
||||||
{
|
|
||||||
File.Create(mcpConfigPath);
|
|
||||||
McpServerList mcpServerList = new McpServerList();
|
|
||||||
string json = JsonConvert.SerializeObject(mcpServerList.GetAllServers());
|
|
||||||
File.WriteAllText(mcpConfigPath, json);
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string mcpConfigStr = File.ReadAllText(mcpConfigPath);
|
|
||||||
McpServerList mcpServerList = new McpServerList(mcpConfigStr);
|
|
||||||
return JsonConvert.SerializeObject(mcpServerList.GetAllServers());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteMcpConfig(string json)
|
|
||||||
{
|
|
||||||
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
|
||||||
string configDirPath = Path.Combine(appDataPath, "LinkTool");
|
|
||||||
string mcpConfigPath = Path.Combine(appDataPath, "LinkTool", "McpConfig.json");
|
|
||||||
Directory.CreateDirectory(configDirPath);
|
|
||||||
if (!File.Exists(mcpConfigPath))
|
|
||||||
{
|
|
||||||
File.Create(mcpConfigPath);
|
|
||||||
}
|
|
||||||
File.WriteAllText(mcpConfigPath, json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
using ArcGIS.Core.CIM;
|
|
||||||
using ArcGIS.Core.Data;
|
|
||||||
using ArcGIS.Core.Geometry;
|
|
||||||
using ArcGIS.Desktop.Catalog;
|
|
||||||
using ArcGIS.Desktop.Core;
|
|
||||||
using ArcGIS.Desktop.Editing;
|
|
||||||
using ArcGIS.Desktop.Extensions;
|
|
||||||
using ArcGIS.Desktop.Framework;
|
|
||||||
using ArcGIS.Desktop.Framework.Contracts;
|
|
||||||
using ArcGIS.Desktop.Framework.Dialogs;
|
|
||||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
|
||||||
using ArcGIS.Desktop.KnowledgeGraph;
|
|
||||||
using ArcGIS.Desktop.Layouts;
|
|
||||||
using ArcGIS.Desktop.Mapping;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace LinkToolAddin.ui.mcp
|
|
||||||
{
|
|
||||||
internal class ShowMcpConfigWindow : Button
|
|
||||||
{
|
|
||||||
|
|
||||||
private McpConfigWindow _mcpconfigwindow = null;
|
|
||||||
|
|
||||||
protected override void OnClick()
|
|
||||||
{
|
|
||||||
//already open?
|
|
||||||
if (_mcpconfigwindow != null)
|
|
||||||
return;
|
|
||||||
_mcpconfigwindow = new McpConfigWindow();
|
|
||||||
_mcpconfigwindow.Owner = FrameworkApplication.Current.MainWindow;
|
|
||||||
_mcpconfigwindow.Closed += (o, e) => { _mcpconfigwindow = null; };
|
|
||||||
_mcpconfigwindow.Show();
|
|
||||||
//uncomment for modal
|
|
||||||
//_mcpconfigwindow.ShowDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -6,6 +6,4 @@ public class ChatMessageItem : MessageListItem
|
|||||||
public string role { get; set; }
|
public string role { get; set; }
|
||||||
public string content { get; set; }
|
public string content { get; set; }
|
||||||
public MessageType type { get; set; }
|
public MessageType type { get; set; }
|
||||||
|
|
||||||
public long accumulateTokens { get; set; }
|
|
||||||
}
|
}
|
||||||
@ -16,5 +16,4 @@ public interface MessageListItem
|
|||||||
string role { get; set; }
|
string role { get; set; }
|
||||||
string content { get; set; }
|
string content { get; set; }
|
||||||
MessageType type { get; set; }
|
MessageType type { get; set; }
|
||||||
long accumulateTokens { get; set; }
|
|
||||||
}
|
}
|
||||||
@ -12,6 +12,4 @@ public class ToolMessageItem : MessageListItem
|
|||||||
public MessageType type { get; set; }
|
public MessageType type { get; set; }
|
||||||
public string status { get; set; }
|
public string status { get; set; }
|
||||||
public string result { get; set; }
|
public string result { get; set; }
|
||||||
|
|
||||||
public long accumulateTokens { get; set; }
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user