XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension

【DLL】XFE各类拓展是一个C#的DLL库,旨在优化C#代码中常用语句的使用,并提供更简洁的访问方式,同时提供Xunit测试框架,快速搭建服务器/客户端,免费ChatGPTAPI接口,免费通讯服务器,XFE下载器,新增格式等

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Net.WebSockets;
using System.Text;
using XFEExtension.NetCore.Exceptions;
using XFEExtension.NetCore.XFEChatGPT.ChatGPTInnerClass.DefaultClass;
using XFEExtension.NetCore.XFEChatGPT.ChatGPTInnerClass.HelperClass;
using XFEExtension.NetCore.XFEChatGPT.OtherInnerClass;
using XFEExtension.NetCore.XFETransform;
using XFEExtension.NetCore.XFETransform.Json;

namespace XFEExtension.NetCore.XFEChatGPT;

/// <summary>
/// 基于gpt.api.xfegzs.com开放接口的ChatGPT问答类(记忆模式)
/// </summary>
public class MemorableXFEChatGPT : XFEChatGPTBase
{
    private readonly XFEGPTMemoryDialog _xFEGPTMemoryDialog;
    /// <summary>
    /// 获取或设置对话记录
    /// </summary>
    public XFEGPTMemoryDialog MemoryDialog
    {
        get
        {
            return _xFEGPTMemoryDialog;
        }
    }
    #region 公共方法
    #region 创建对话
    /// <summary>
    /// 创建一个新的对话,使用默认通信协议(快速响应通讯协议)
    /// </summary>
    /// <param name="dialogId">对话的ID</param>
    /// <param name="system">系统消息</param>
    public void CreateDialog(string dialogId, string system)
    {
        _xFEGPTMemoryDialog.Add(dialogId, new XFEGPTMessageCollection([new XFEGPTMessage(dialogId, new GPTMessage("system", system))], false, ChatGPTModel.gpt3point5turbo, XFEComProtocol.XFEFAST, false, 0.7));
    }
    /// <summary>
    /// 创建一个新的对话,使用默认通信协议(快速响应通讯协议)
    /// </summary>
    /// <param name="dialogId">对话的ID</param>
    /// <param name="system">系统消息</param>
    /// <param name="hasMemory">是否记录对话信息</param>
    public void CreateDialog(string dialogId, string system, bool hasMemory)
    {
        _xFEGPTMemoryDialog.Add(dialogId, new XFEGPTMessageCollection([new XFEGPTMessage(dialogId, new GPTMessage("system", system))], false, ChatGPTModel.gpt3point5turbo, XFEComProtocol.XFEFAST, hasMemory, 0.7));
    }
    /// <summary>
    /// 创建一个新的对话,使用默认通信协议(快速响应通讯协议)
    /// </summary>
    /// <param name="dialogId">对话的ID</param>
    /// <param name="system">系统消息</param>
    /// <param name="hasMemory">是否记录对话信息</param>
    /// <param name="streamMode">是否为流式输出</param>
    public void CreateDialog(string dialogId, string system, bool hasMemory, bool streamMode)
    {
        _xFEGPTMemoryDialog.Add(dialogId, new XFEGPTMessageCollection([new XFEGPTMessage(dialogId, new GPTMessage("system", system))], hasMemory, ChatGPTModel.gpt3point5turbo, XFEComProtocol.XFEFAST, streamMode, 0.7));
    }
    /// <summary>
    /// 创建一个新的对话,使用默认通信协议(快速响应通讯协议)
    /// </summary>
    /// <param name="dialogId">对话的ID</param>
    /// <param name="system">系统消息</param>
    /// <param name="hasMemory">是否记录对话信息</param>
    /// <param name="streamMode">是否为流式输出</param>
    /// <param name="chatGPTModel">所用的ChatGPT模型</param>
    public void CreateDialog(string dialogId, string system, bool hasMemory, bool streamMode, ChatGPTModel chatGPTModel)
    {
        _xFEGPTMemoryDialog.Add(dialogId, new XFEGPTMessageCollection([new XFEGPTMessage(dialogId, new GPTMessage("system", system))], hasMemory, chatGPTModel, XFEComProtocol.XFEFAST, streamMode, 0.7));
    }
    /// <summary>
    /// 创建一个新的对话,使用默认通信协议(快速响应通讯协议)
    /// </summary>
    /// <param name="dialogId">对话的ID</param>
    /// <param name="system">系统消息</param>
    /// <param name="hasMemory">是否记录对话信息</param>
    /// <param name="streamMode">是否为流式输出</param>
    /// <param name="chatGPTModel">所用的ChatGPT模型</param>
    /// <param name="temperature">系统的Temperature</param>
    public void CreateDialog(string dialogId, string system, bool hasMemory, bool streamMode, ChatGPTModel chatGPTModel, double temperature)
    {
        _xFEGPTMemoryDialog.Add(dialogId, new XFEGPTMessageCollection([new XFEGPTMessage(dialogId, new GPTMessage("system", system))], hasMemory, chatGPTModel, XFEComProtocol.XFEFAST, streamMode, temperature));
    }
    /// <summary>
    /// 创建一个新的对话,自定义通讯协议
    /// </summary>
    /// <param name="dialogId">对话的ID</param>
    /// <param name="system">系统消息</param>
    /// <param name="hasMemory">是否记录对话信息</param>
    /// <param name="streamMode">是否为流式输出</param>
    /// <param name="chatGPTModel">所用的ChatGPT模型</param>
    /// <param name="comProtocol">通信协议</param>
    public void CreateDialog(string dialogId, string system, bool hasMemory, bool streamMode, ChatGPTModel chatGPTModel, XFEComProtocol comProtocol)
    {
        _xFEGPTMemoryDialog.Add(dialogId, new XFEGPTMessageCollection([new XFEGPTMessage(dialogId, new GPTMessage("system", system))], hasMemory, chatGPTModel, comProtocol, streamMode, 0.7));
    }
    /// <summary>
    /// 创建一个新的对话,自定义通讯协议
    /// </summary>
    /// <param name="dialogId">对话的ID</param>
    /// <param name="system">系统消息</param>
    /// <param name="hasMemory">是否记录对话信息</param>
    /// <param name="streamMode">是否为流式输出</param>
    /// <param name="chatGPTModel">所用的ChatGPT模型</param>
    /// <param name="temperature">系统的Temperature</param>
    /// <param name="comProtocol">通信协议</param>
    public void CreateDialog(string dialogId, string system, bool hasMemory, bool streamMode, ChatGPTModel chatGPTModel, double temperature, XFEComProtocol comProtocol)
    {
        _xFEGPTMemoryDialog.Add(dialogId, new XFEGPTMessageCollection([new XFEGPTMessage(dialogId, new GPTMessage("system", system))], hasMemory, chatGPTModel, comProtocol, streamMode, temperature));
    }
    #endregion
    #region 插入对话
    /// <summary>
    /// 插入对话
    /// </summary>
    /// <param name="dialogId">要插入的对话ID</param>
    /// <param name="userMessage">用户对话内容</param>
    /// <param name="assistantMessage">AI对话的内容</param>
    /// <returns>插入的消息ID</returns>
    public string InsertDialog(string dialogId, string userMessage, string assistantMessage)
    {
        var messageId = Guid.NewGuid().ToString();
        _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId, new GPTMessage("user", userMessage)));
        _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId + "_Assistant", new GPTMessage("assistant", assistantMessage)));
        return messageId;
    }
    /// <summary>
    /// 插入对话
    /// </summary>
    /// <param name="dialogId">要插入的对话ID</param>
    /// <param name="messageId">插入的消息ID</param>
    /// <param name="userMessage">用户对话内容</param>
    /// <param name="assistantMessage">AI对话的内容</param>
    public void InsertDialog(string dialogId, string messageId, string userMessage, string assistantMessage)
    {
        _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId, new GPTMessage("user", userMessage)));
        _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId + "_Assistant", new GPTMessage("assistant", assistantMessage)));
    }
    /// <summary>
    /// 插入对话
    /// </summary>
    /// <param name="dialogId">要插入的对话ID</param>
    /// <param name="dialogMessage">对话,以二维数组的形式</param>
    /// <returns></returns>
    public string[] InsertDialog(string dialogId, string[,] dialogMessage)
    {
        try
        {
            if (dialogMessage.GetLength(1) != 2)
            {
                throw new XFEChatGPTException("dialogMessage的格式不正确!应为string[任意数量,2]");
            }

            if (dialogMessage.Length % 2 == 1)
            {
                throw new XFEChatGPTException("dialogMessage不合法!只能成对添加user和assistant");
            }

            var messageId = new string[dialogMessage.Length];
            for (var i = 0; i < dialogMessage.Length; i += 2)
            {
                messageId[i] = Guid.NewGuid().ToString();
                messageId[i + 1] = messageId[i] + "_Assistant";
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i], new GPTMessage("user", dialogMessage[i == 0 ? 0 : i / 2, 0])));
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i + 1], new GPTMessage("assistant", dialogMessage[i == 0 ? 0 : i / 2, 1])));
            }
            return messageId;
        }
        catch (IndexOutOfRangeException ex)
        {
            throw new XFEChatGPTException("dialogMessage的格式不正确!应为string[任意数量,2]", ex);
        }
    }
    /// <summary>
    /// 插入对话
    /// </summary>
    /// <param name="dialogId">要插入的对话ID</param>
    /// <param name="dialogMessage">对话</param>
    /// <returns></returns>
    /// <exception cref="XFEChatGPTException"></exception>
    public string[] InsertDialog(string dialogId, params string[] dialogMessage)
    {
        try
        {
            if (dialogMessage.Length % 2 == 1)
            {
                throw new XFEChatGPTException("dialogMessage不合法!只能成对添加user和assistant");
            }

            var messageId = new string[dialogMessage.Length];
            for (var i = 0; i < dialogMessage.Length; i += 2)
            {
                messageId[i] = Guid.NewGuid().ToString();
                messageId[i + 1] = messageId[i] + "_Assistant";
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i], new GPTMessage("user", dialogMessage[i])));
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i + 1], new GPTMessage("assistant", dialogMessage[i + 1])));
            }
            return messageId;
        }
        catch (IndexOutOfRangeException ex)
        {
            throw new XFEChatGPTException("dialogMessage的格式不正确!应为string[任意数量,2]", ex);
        }
    }
    /// <summary>
    /// 插入对话
    /// </summary>
    /// <param name="dialogId">要插入的对话ID</param>
    /// <param name="messageId">对话的消息ID,以数组的形式</param>
    /// <param name="dialogMessage">对话,以二维数组的形式</param>
    /// <exception cref="XFEChatGPTException"></exception>
    public void InsertDialog(string dialogId, string[] messageId, string[,] dialogMessage)
    {
        try
        {
            if (messageId.Length != dialogMessage.Length)
            {
                throw new XFEChatGPTException("messageId与dialogMessage数量不对应");
            }

            if (dialogMessage.GetLength(1) != 2)
            {
                throw new XFEChatGPTException("dialogMessage的格式不正确!应为string[任意数量,2]");
            }

            if (dialogMessage.Length % 2 == 1)
            {
                throw new XFEChatGPTException("dialogMessage不合法!只能成对添加user和assistant");
            }

            for (var i = 0; i < dialogMessage.Length; i += 2)
            {
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i], new GPTMessage("user", dialogMessage[i == 0 ? 0 : i / 2, 0])));
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i + 1], new GPTMessage("assistant", dialogMessage[i == 0 ? 0 : i / 2, 1])));
            }
        }
        catch (IndexOutOfRangeException ex)
        {
            throw new Exception("dialogMessage的格式不正确!应为string[任意数量,2]", ex);
        }
    }
    /// <summary>
    /// 插入对话
    /// </summary>
    /// <param name="dialogId">要插入的对话ID</param>
    /// <param name="messageId">对话的消息ID,以数组的形式</param>
    /// <param name="dialogMessage">对话,以一维数组的形式</param>
    /// <exception cref="XFEChatGPTException"></exception>
    public void InsertDialog(string dialogId, string[] messageId, string[] dialogMessage)
    {
        try
        {
            if (messageId.Length != dialogMessage.Length)
            {
                throw new XFEChatGPTException("messageId与dialogMessage数量不对应");
            }

            if (dialogMessage.Length % 2 == 1)
            {
                throw new XFEChatGPTException("dialogMessage不合法!只能成对添加user和assistant");
            }

            for (var i = 0; i < dialogMessage.Length; i += 2)
            {
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i], new GPTMessage("user", dialogMessage[i])));
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i + 1], new GPTMessage("assistant", dialogMessage[i + 1])));
            }
        }
        catch (IndexOutOfRangeException ex)
        {
            throw new XFEChatGPTException("dialogMessage的格式不正确!应为string[任意数量,2]", ex);
        }
    }
    /// <summary>
    /// 插入对话,自动补全对话
    /// </summary>
    /// <param name="dialogId">要插入的对话ID</param>
    /// <param name="dialogMessage">对话</param>
    /// <returns></returns>
    /// <exception cref="XFEChatGPTException"></exception>
    public string[] InsertDialogAutoComplete(string dialogId, params string[] dialogMessage)
    {
        try
        {
            var messageId = dialogMessage.Length % 2 == 0 ? new string[dialogMessage.Length] : new string[dialogMessage.Length + 1];
            for (var i = 0; i < dialogMessage.Length; i += 2)
            {
                messageId[i] = Guid.NewGuid().ToString();
                messageId[i + 1] = messageId[i] + "_Assistant";
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i], new GPTMessage("user", dialogMessage[i])));
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId[i + 1], new GPTMessage("assistant", dialogMessage.Length > i + 1 ? dialogMessage[i + 1] : "该条问题未回复")));
            }
            return messageId;
        }
        catch (IndexOutOfRangeException ex)
        {
            throw new XFEChatGPTException("dialogMessage的格式不正确!", ex);
        }
    }
    #endregion
    #region 其余操作
    /// <summary>
    /// 获取对话
    /// </summary>
    /// <param name="dialogId">对话ID</param>
    /// <returns></returns>
    public GPTMessage[] GetDialog(string dialogId)
    {
        return _xFEGPTMemoryDialog[dialogId].GetGPTMessages();
    }
    /// <summary>
    /// 以字符串数组的形式获取对话
    /// </summary>
    /// <param name="dialogId"></param>
    /// <returns></returns>
    public string[] GetDialogStrings(string dialogId)
    {
        return _xFEGPTMemoryDialog[dialogId].GetGPTMessageStrings();
    }
    #endregion
    #region 开始对话
    /// <summary>
    /// 开始对话
    /// </summary>
    /// <param name="dialogId">对话ID</param>
    /// <param name="messageId">本消息ID</param>
    /// <param name="askMessage">询问的内容</param>
    public void AskChatGPT(string dialogId, string messageId, string askMessage)
    {
        if (_xFEGPTMemoryDialog[dialogId].GetGPTMessages().CheckLegal())
        {
            //判断如果最后一条消息是用户消息,则在添加新的用户消息前添加一条助手消息然后再添加用户消息,否则直接添加用户消息
            if (_xFEGPTMemoryDialog[dialogId].GetLastRole() == "user")
            {
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId + "_Assistant", new GPTMessage("assistant", "正在思考中...")));
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId, new GPTMessage("user", askMessage)));
            }
            else
            {
                _xFEGPTMemoryDialog[dialogId].Add(new XFEGPTMessage(messageId, new GPTMessage("user", askMessage)));
            }
            var nowThread = new Thread(StartGetGPTMessage);
            nowThread.Start(new MessageIdDialogIdAndThread(messageId, dialogId, nowThread));
        }
        else
        {
            throw new XFEChatGPTException("对话信息不合法");
        }
    }
    #endregion
    #region 停止对话

    //TODO:
    /// <summary>
    /// 停止对话(仅在流式输出模式下有效,非流式输出模式下调用该方法将不会有任何效果)
    /// </summary>
    public static void StopChat()
    {

    }
    #endregion
    #endregion
    #region 线程方法
    private async void StartGetGPTMessage(object? sender)
    {
        var messageIdAndThread = (MessageIdDialogIdAndThread)sender!;
        var dialogId = messageIdAndThread.DialogId;
        var messageId = messageIdAndThread.MessageId;
        var thread = messageIdAndThread.Thread;
        var nowDialog = _xFEGPTMemoryDialog[dialogId];
        if (nowDialog.StreamMode)
        {
            var isStarted = false;
            try
            {
                #region 进行HTTP请求
                ClientWebSocket webSocket = new();
                await webSocket.ConnectAsync(new Uri("ws://gpt.api.xfegzs.com/"), CancellationToken.None);
                if (nowDialog.MemorableMode)
                {
                    var json = XFEJson.Serialize(nowDialog.CreateAskMessage());
                    if (json is not null)
                        await webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(json)), WebSocketMessageType.Text, true, CancellationToken.None);
                }
                else
                {
                    var json = XFEJson.Serialize(new XFEAskGPTMessage(false, nowDialog.StreamMode, nowDialog.ChatGPTModel.GetModelString(), null, nowDialog.XFEComProtocol, nowDialog.System, nowDialog[^1].GPTMessage.Content));
                    if (json is not null)
                        await webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(json)), WebSocketMessageType.Text, true, CancellationToken.None);
                }
                #endregion
                while (true)
                {
                    #region 读取消息
                    var receiveBuffer = new byte[1024];
                    var receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
                    var bufferList = new List<byte>();
                    bufferList.AddRange(receiveBuffer.Take(receiveResult.Count));
                    while (!receiveResult.EndOfMessage)
                    {
                        receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
                        bufferList.AddRange(receiveBuffer.Take(receiveResult.Count));
                    }
                    var receivedBinaryBuffer = bufferList.ToArray();
                    var nowReceivedMessage = Encoding.UTF8.GetString(receivedBinaryBuffer);
                    #endregion
                    if (nowDialog.XFEComProtocol == XFEComProtocol.XFEFAST)
                    {
                        if (nowReceivedMessage == "[DONE]")
                        {
                            XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs("[XFEDONE]", messageId, GenerateState.End, dialogId));
                            break;
                        }

                        if (nowReceivedMessage.Contains("[XFERemoteAPIError]"))
                        {
                            if (!isStarted)
                            {
                                XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs("[XFESTART]", messageId, GenerateState.Start, dialogId));
                                _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", "该回复发生了一个错误,可能需要重新回复", true);
                            }
                            else
                            {
                                _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", "该回复发生了一个错误,可能需要重新回复", false);
                            }
                            XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs(nowReceivedMessage.Replace("[XFERemoteAPIError]", string.Empty), messageId, GenerateState.Error, dialogId));
                        }
                        else if (nowReceivedMessage == "[XFE]")
                        {
                            XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs("[XFESTART]", messageId, GenerateState.Start, dialogId));
                            isStarted = true;
                            _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", string.Empty, true);
                        }
                        else
                        {
                            _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", nowReceivedMessage, false);
                            XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs(nowReceivedMessage, messageId, GenerateState.Continue, dialogId));
                        }
                    }
                    else
                    {
                        if (nowReceivedMessage == "[DONE]")
                        {
                            XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs("[XFEDONE]", messageId, GenerateState.End, dialogId));
                            break;
                        }

                        if (nowReceivedMessage.Contains("[XFERemoteAPIError]"))
                        {
                            if (!isStarted)
                            {
                                XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs("[XFESTART]", messageId, GenerateState.Start, dialogId));
                                _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", "该回复发生了一个错误,可能需要重新回复", true);
                            }
                            else
                            {
                                _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", "该回复发生了一个错误,可能需要重新回复", false);
                            }
                            XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs(nowReceivedMessage.Replace("[XFERemoteAPIError]", string.Empty), messageId, GenerateState.Error, dialogId));
                        }
                        else if (nowReceivedMessage == "[XFE]")
                        {
                            XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs("[XFESTART]", messageId, GenerateState.Start, dialogId));
                            isStarted = true;
                            _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", string.Empty, true);
                        }
                        else
                        {
                            if (nowReceivedMessage.Contains("[XFE]"))
                            {
                                nowReceivedMessage = nowReceivedMessage.Replace("[XFE]", string.Empty);
                                _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", nowReceivedMessage, false);
                                XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs(nowReceivedMessage, messageId, GenerateState.Continue, dialogId));
                            }
                            else
                            {
                                if (!isStarted)
                                {
                                    XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs("[XFESTART]", messageId, GenerateState.Start, dialogId));
                                    _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", "该回复发生了一个错误,可能需要重新回复", true);
                                }
                                else
                                {
                                    _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", "该回复发生了一个错误,可能需要重新回复", false);
                                }
                            }
                        }
                    }
                }
                await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Connection closed.", CancellationToken.None);
            }
            catch (Exception ex) when (ex is not XFEChatGPTException)
            {
                if (!isStarted)
                {
                    XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs("[XFESTART]", messageId, GenerateState.Start, dialogId));
                    _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", "该回复发生了一个错误,可能需要重新回复", true);
                }
                else
                {
                    _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", "该回复发生了一个错误,可能需要重新回复", false);
                }
                XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs(ex.ToString(), messageId, GenerateState.Error, dialogId));
                Console.WriteLine(ex.ToString());
            }
        }
        else
        {
            try
            {
                #region 进行HTTP请求
                ClientWebSocket webSocket = new();
                await webSocket.ConnectAsync(new Uri("ws://gpt.api.xfegzs.com/"), CancellationToken.None);
                if (nowDialog.MemorableMode)
                {
                    var json = XFEJson.Serialize(nowDialog.CreateAskMessage());
                    if (json is not null)
                        await webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(json)), WebSocketMessageType.Text, true, CancellationToken.None);
                }
                else
                {
                    var json = XFEJson.Serialize(new XFEAskGPTMessage(false, nowDialog.StreamMode, nowDialog.ChatGPTModel.GetModelString(), null, nowDialog.XFEComProtocol, nowDialog.System, nowDialog[^1].GPTMessage.Content));
                    if (json is not null)
                        await webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(json)), WebSocketMessageType.Text, true, CancellationToken.None);
                }
                #endregion
                #region 读取消息
                var receiveBuffer = new byte[1024];
                var receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
                var bufferList = new List<byte>();
                bufferList.AddRange(receiveBuffer.Take(receiveResult.Count));
                while (!receiveResult.EndOfMessage)
                {
                    receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
                    bufferList.AddRange(receiveBuffer.Take(receiveResult.Count));
                }
                var receivedBinaryBuffer = bufferList.ToArray();
                var nowReceivedMessage = Encoding.UTF8.GetString(receivedBinaryBuffer);
                #endregion
                if (nowReceivedMessage.Contains("[XFE]"))
                {
                    nowReceivedMessage = nowReceivedMessage.Replace("[XFE]", string.Empty);
                    _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", nowReceivedMessage, true);
                    XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs(nowReceivedMessage, messageId, GenerateState.Start, dialogId));
                }
                else
                {
                    _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", nowReceivedMessage, true);
                    XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs(nowReceivedMessage.Replace("[XFERemoteAPIError]", string.Empty), messageId, GenerateState.Error, dialogId));
                }
                await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Connection closed.", CancellationToken.None);
            }
            catch (Exception ex)
            {
                _xFEGPTMemoryDialog.InstanceUpdate(dialogId, messageId + "_Assistant", ex.ToString(), true);
                XFEChatGPTMessageReceived?.Invoke(this, new PrivateMemorableGPTMessageReceivedEventArgs(ex.ToString(), messageId, GenerateState.Error, dialogId));
                Console.WriteLine(ex.ToString());
            }
        }
        ThreadList.Remove(thread);
    }
    #endregion
    #region 公有事件
    /// <summary>
    /// 当收到ChatGPT的消息时触发
    /// </summary>
    public event EventHandler<MemorableGPTMessageReceivedEventArgs>? XFEChatGPTMessageReceived;
    #endregion
    #region 构造方法
    /// <summary>
    /// 创建一个有记忆功能的XFEChatGPT对象
    /// </summary>
    public MemorableXFEChatGPT() => _xFEGPTMemoryDialog = new PrivateXFEGPTMemoryDialog();
    #endregion
}