v0.1.4版本 #2

Merged
PeterZhong merged 70 commits from host into master 2025-06-15 14:42:58 +00:00
10 changed files with 63 additions and 16 deletions
Showing only changes of commit 23c60b9c34 - Show all commits

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using ArcGIS.Core.Data; using ArcGIS.Core.Data;
using ArcGIS.Core.Data.Raster; using ArcGIS.Core.Data.Raster;
@ -33,7 +34,7 @@ public class ArcGisPro
Error = new Error() Error = new Error()
{ {
Code = results.ErrorCode, Code = results.ErrorCode,
Message = JsonConvert.SerializeObject(results.ErrorMessages) Message = GetMessagesString(results.ErrorMessages)
} }
}; };
}else if(results.HasWarnings) }else if(results.HasWarnings)
@ -41,7 +42,7 @@ public class ArcGisPro
log.Warn(results.Messages); log.Warn(results.Messages);
jsonRpcResultEntity = new JsonRpcSuccessEntity jsonRpcResultEntity = new JsonRpcSuccessEntity
{ {
Result = JsonConvert.SerializeObject(results.Messages) Result = GetMessagesString(results.Messages)
}; };
} }
else else
@ -49,7 +50,7 @@ public class ArcGisPro
log.Info("success gp tool"); log.Info("success gp tool");
jsonRpcResultEntity = new JsonRpcSuccessEntity jsonRpcResultEntity = new JsonRpcSuccessEntity
{ {
Result = JsonConvert.SerializeObject(results.Messages) Result = GetMessagesString(results.Messages)
}; };
} }
return jsonRpcResultEntity; return jsonRpcResultEntity;
@ -135,4 +136,14 @@ public class ArcGisPro
}; };
return result; return result;
} }
private static string GetMessagesString(IEnumerable<IGPMessage> messages)
{
StringBuilder messagesStr = new StringBuilder();
foreach (var gpMessage in messages)
{
messagesStr.AppendLine(gpMessage.Text);
}
return messagesStr.ToString();
}
} }

View File

@ -67,7 +67,7 @@ public class HttpRequest
return null; return null;
} }
public static async IAsyncEnumerable<string> PostWithStreamingResponseAsync( public static async IAsyncEnumerable<LlmStreamChat> PostWithStreamingResponseAsync(
string url, string url,
string body, string body,
string apiKey, string apiKey,
@ -114,7 +114,7 @@ public class HttpRequest
if (dataObj is not null) if (dataObj is not null)
{ {
yield return dataObj.Choices[0].Delta.Content; yield return dataObj;
} }
} }
} }

View File

@ -32,6 +32,7 @@ using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Schema.Generation; using Newtonsoft.Json.Schema.Generation;
using Tool = LinkToolAddin.host.mcp.Tool; using Tool = LinkToolAddin.host.mcp.Tool;
using LinkToolAddin.common; using LinkToolAddin.common;
using LinkToolAddin.host.llm.entity.stream;
namespace LinkToolAddin.host; namespace LinkToolAddin.host;
@ -303,12 +304,22 @@ public class Gateway
goOn = false; goOn = false;
break; break;
} }
await foreach(var chunk in bailian.SendChatStreamAsync(jsonContent)) await foreach(LlmStreamChat llmStreamChat in bailian.SendChatStreamAsync(jsonContent))
{ {
if (!goOn) if (!goOn)
{ {
break; break;
} }
string chunk = llmStreamChat.Choices[0].Delta.Content;
MessageListItem reasonMessageListItem = new ChatMessageItem()
{
content = llmStreamChat.Choices[0].Delta.ResoningContent,
role = "assistant",
type = MessageType.REASON_MESSAGE,
id = (timestamp-1).ToString()
};
callback?.Invoke(reasonMessageListItem);
messageContent = chunk; messageContent = chunk;
var (matched, remaining) = ExtractMatchedPart(chunk, toolPattern); var (matched, remaining) = ExtractMatchedPart(chunk, toolPattern);
if (matched == "") if (matched == "")

View File

@ -6,6 +6,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using LinkToolAddin.common; using LinkToolAddin.common;
using LinkToolAddin.host.llm.entity; using LinkToolAddin.host.llm.entity;
using LinkToolAddin.host.llm.entity.stream;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace LinkToolAddin.host.llm; namespace LinkToolAddin.host.llm;
@ -18,17 +19,22 @@ public class Bailian : Llm
public string max_tokens { get; set; } public string max_tokens { get; set; }
public string app_id { get; set; } public string app_id { get; set; }
public string api_key { get; set; } public string api_key { get; set; }
public async IAsyncEnumerable<string> SendChatStreamAsync(LlmJsonContent jsonContent) public async IAsyncEnumerable<LlmStreamChat> SendChatStreamAsync(LlmJsonContent jsonContent)
{ {
jsonContent.Stream = true; jsonContent.Stream = true;
StringBuilder builder = new StringBuilder(); StringBuilder contentBuilder = new StringBuilder();
await foreach (var chunk in HttpRequest.PostWithStreamingResponseAsync( StringBuilder reasonBuilder = new StringBuilder();
await foreach (LlmStreamChat chunk in HttpRequest.PostWithStreamingResponseAsync(
"https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions", "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
JsonConvert.SerializeObject(jsonContent), JsonConvert.SerializeObject(jsonContent),
api_key)) api_key))
{ {
builder.Append(chunk); contentBuilder.Append(chunk.Choices[0].Delta.Content);
yield return builder.ToString(); 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;
} }
} }

View File

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using LinkToolAddin.host.llm.entity; using LinkToolAddin.host.llm.entity;
using LinkToolAddin.host.llm.entity.stream;
namespace LinkToolAddin.host.llm; namespace LinkToolAddin.host.llm;
@ -11,7 +12,7 @@ public interface Llm
public string top_p { get; set; } public string top_p { get; set; }
public string max_tokens { get; set; } public string max_tokens { get; set; }
public IAsyncEnumerable<string> SendChatStreamAsync(LlmJsonContent jsonContent); public IAsyncEnumerable<LlmStreamChat> SendChatStreamAsync(LlmJsonContent jsonContent);
public IAsyncEnumerable<string> SendApplicationStreamAsync(string message); public IAsyncEnumerable<string> SendApplicationStreamAsync(string message);
public Task<string> SendChatAsync(LlmJsonContent jsonContent); public Task<string> SendChatAsync(LlmJsonContent jsonContent);
public Task<string> SendApplicationAsync(CommonInput commonInput); public Task<string> SendApplicationAsync(CommonInput commonInput);

View File

@ -25,6 +25,15 @@ namespace LinkToolAddin.host.llm.entity
[JsonProperty("top_k")] [JsonProperty("top_k")]
public int TopK { get; set; } = 40; public int TopK { get; set; } = 40;
[JsonProperty("enable_thinking")]
public bool EnableThinking { get; set; } = true;
[JsonProperty("thinking_budget")]
public long ThinkingBudget { get; set; } = 1200;
[JsonProperty("incremental_output")]
public bool IncrementalOutput { get; set; } = true;
} }
public partial class Message public partial class Message

View File

@ -50,5 +50,7 @@
{ {
[JsonProperty("content")] [JsonProperty("content")]
public string Content { get; set; } public string Content { get; set; }
[JsonProperty("reasoning_content")]
public string ResoningContent { get; set; }
} }
} }

View File

@ -7,7 +7,7 @@ namespace LinkToolAddin.server
public partial class JsonRpcResultEntity public partial class JsonRpcResultEntity
{ {
[JsonProperty("jsonrpc")] [JsonProperty("jsonrpc")]
public string Jsonrpc { get; set; } public string Jsonrpc { get; set; } = "2.0";
[JsonProperty("id")] [JsonProperty("id")]
public long Id { get; set; } public long Id { get; set; }

View File

@ -198,8 +198,8 @@ namespace LinkToolAddin.ui.dockpane
private void PromptTestButton_OnClick(object sender, RoutedEventArgs e) private void PromptTestButton_OnClick(object sender, RoutedEventArgs e)
{ {
string userPrompt = PromptTestTextBox.Text; string userPrompt = PromptTestTextBox.Text;
// Gateway.SendMessage(userPrompt,"qwen-max","C:/Project/test.gdb",AddReply); // model可选值qwen3-235b-a22b,qwen-max,deepseek-r1
Gateway.SendMessageStream(userPrompt,"qwen-max", "D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\20250420_AiDemoProject.gdb", AddReplyStream); Gateway.SendMessageStream(userPrompt,"qwen3-235b-a22b", "D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\20250420_AiDemoProject.gdb", AddReplyStream);
} }
public void AddReplyStream(MessageListItem msg) public void AddReplyStream(MessageListItem msg)
@ -219,7 +219,13 @@ namespace LinkToolAddin.ui.dockpane
foreach (KeyValuePair<string,MessageListItem> pair in messageDict) foreach (KeyValuePair<string,MessageListItem> pair in messageDict)
{ {
MessageListItem msgItem = pair.Value; MessageListItem msgItem = pair.Value;
builder.AppendLine(msgItem.content); string content = msgItem.content;
if (msgItem.type == MessageType.REASON_MESSAGE)
{
content = "<think>" + content + "</think>";
}
builder.AppendLine(content);
builder.AppendLine();
ReplyTextBox.Text = builder.ToString(); ReplyTextBox.Text = builder.ToString();
ReplyTextBox.ScrollToEnd(); ReplyTextBox.ScrollToEnd();
} }

View File

@ -4,6 +4,7 @@ public enum MessageType
{ {
TOOL_MESSAGE, TOOL_MESSAGE,
CHAT_MESSAGE, CHAT_MESSAGE,
REASON_MESSAGE,
} }
public interface MessageListItem public interface MessageListItem