Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

обновление gptchat, добавление ттс для фигурок #939

Merged
merged 2 commits into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
<Control HorizontalExpand="True" MinWidth="5" />
<Button Visible="True" Name="PopOut" Access="Public" Text="{Loc 'admin-logs-pop-out'}" StyleClasses="OpenBoth" HorizontalAlignment="Left" />
<Control HorizontalExpand="True" />
<Button Visible="False" Name="GptChat" Text="{Loc 'admin-player-actions-gpt'}" StyleClasses="OpenRight" /> <!-- backmen: gpt -->

<Button Visible="False" Name="GptChat" Text="{Loc 'admin-player-actions-gpt'}" StyleClasses="OpenRight"></Button> <!-- backmen: gpt -->
<CheckButton Visible="False" Name="GptChatToggle" Text="{Loc 'admin-player-actions-gpt-auto'}" StyleClasses="OpenRight"></CheckButton> <!-- backmen: gpt -->
Comment on lines +15 to +16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Локализация присутствует, но требует улучшения

Ключи локализации определены в обоих языковых файлах (en-US и ru-RU), однако значения для русской локализации не переведены и остались на английском языке:

  • admin-player-actions-gpt = GptChat - требуется перевод
  • admin-player-actions-gpt-auto = Auto - требуется перевод
🔗 Analysis chain

Проверьте локализацию новых строк

Убедитесь, что ключи локализации admin-player-actions-gpt и admin-player-actions-gpt-auto определены во всех поддерживаемых языках.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Проверка наличия ключей локализации

# Поиск ключей локализации в файлах ресурсов
rg -l "admin-player-actions-gpt|admin-player-actions-gpt-auto" Resources/Locale/

Length of output: 188


Script:

#!/bin/bash
# Проверим содержимое файлов локализации, чтобы убедиться, что ключи действительно определены
echo "=== Содержимое en-US/administration/ui/actions.ftl ==="
rg "admin-player-actions-gpt" Resources/Locale/en-US/administration/ui/actions.ftl -A 1
echo -e "\n=== Содержимое ru-RU/administration/ui/actions.ftl ==="
rg "admin-player-actions-gpt" Resources/Locale/ru-RU/administration/ui/actions.ftl -A 1

Length of output: 638


<Control HorizontalExpand="True" />
<Button Visible="False" Name="Bans" Text="{Loc 'admin-player-actions-bans'}" StyleClasses="OpenBoth" />
<Button Visible="False" Name="Notes" Text="{Loc 'admin-player-actions-notes'}" StyleClasses="OpenBoth" />
<Button Visible="False" Name="Kick" Text="{Loc 'admin-player-actions-kick'}" StyleClasses="OpenBoth" />
Expand Down
15 changes: 15 additions & 0 deletions Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ public BwoinkControl()
if (info.OverallPlaytime <= TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.NewPlayerThreshold)))
sb.Append(new Rune(0x23F2)); // ⏲

// start-backmen: gpt
if(info.AutoGpt)
sb.Append(new Rune(0x2607)); // ☇
// end-backmen: gpt

sb.AppendFormat("\"{0}\"", text);

return sb.ToString();
Expand Down Expand Up @@ -151,6 +156,13 @@ public BwoinkControl()
};

// start-backmen: gpt
GptChatToggle.OnPressed += _ =>
{
if (_currentPlayer is not null)
_console.ExecuteCommand($"ahelp_gpt_toggle \"{_currentPlayer.Username}\"");

GptChatToggle.Pressed = !GptChatToggle.Pressed;
};
Comment on lines +159 to +165
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Возможная проблема синхронизации состояния кнопки

Текущая реализация меняет состояние кнопки немедленно после отправки команды, не дожидаясь подтверждения выполнения.

Предлагаемое исправление:

 GptChatToggle.OnPressed += _ =>
 {
     if (_currentPlayer is not null)
-        _console.ExecuteCommand($"ahelp_gpt_toggle \"{_currentPlayer.Username}\"");
-
-    GptChatToggle.Pressed = !GptChatToggle.Pressed;
+    {
+        _console.ExecuteCommand($"ahelp_gpt_toggle \"{_currentPlayer.Username}\"");
+        // Состояние кнопки обновится через UpdateButtons когда придет ответ от сервера
+    }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
GptChatToggle.OnPressed += _ =>
{
if (_currentPlayer is not null)
_console.ExecuteCommand($"ahelp_gpt_toggle \"{_currentPlayer.Username}\"");
GptChatToggle.Pressed = !GptChatToggle.Pressed;
};
GptChatToggle.OnPressed += _ =>
{
if (_currentPlayer is not null)
{
_console.ExecuteCommand($"ahelp_gpt_toggle \"{_currentPlayer.Username}\"");
// Состояние кнопки обновится через UpdateButtons когда придет ответ от сервера
}
};

Rxup marked this conversation as resolved.
Show resolved Hide resolved
GptChat.OnPressed += _ =>
{
if (_currentPlayer is not null)
Expand Down Expand Up @@ -224,6 +236,9 @@ public void UpdateButtons()
// start-backmen: gpt
GptChat.Visible = _adminManager.CanCommand("ahelp_gpt");
GptChat.Disabled = !GptChat.Visible || disabled;
GptChatToggle.Visible = _adminManager.CanCommand("ahelp_gpt_toggle");
GptChatToggle.Disabled = !GptChatToggle.Visible || disabled;
GptChatToggle.Pressed = _currentPlayer?.AutoGpt ?? false;
// end-backmen: gpt

Bans.Visible = _adminManager.HasFlag(AdminFlags.Ban);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:cc="clr-namespace:Content.Client.Administration.UI.Bwoink"
SetSize="900 500"
SetSize="1000 500"
HeaderClass="windowHeaderAlert"
TitleClass="windowTitleAlert"
Title="{Loc 'bwoink-user-title'}" >
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ public override void Initialize()
_sawmill = _logMan.GetSawmill("rules");
_netManager.RegisterNetMessage<RulesAcceptedMessage>();
_netManager.RegisterNetMessage<SendRulesInformationMessage>(OnRulesInformationMessage);

#if DEBUG
_consoleHost.RegisterCommand("fuckrules",
"",
"",
(_, _, _) =>
{
OnAcceptPressed();
});
#endif
Comment on lines +36 to +44
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Необходимо переработать отладочную команду

Текущая реализация отладочной команды вызывает следующие опасения:

  1. Команда позволяет обойти важный процесс принятия правил без какого-либо логирования
  2. Используется неприемлемое название команды
  3. Отсутствует документация (пустые строки описания)

Предлагаю следующие изменения:

#if DEBUG
-        _consoleHost.RegisterCommand("fuckrules",
-            "",
-            "",
-            (_, _, _) =>
-        {
-            OnAcceptPressed();
-        });
+        _consoleHost.RegisterCommand("debug-accept-rules",
+            "Debug command to bypass rules acceptance",
+            "debug-accept-rules",
+            (_, _, _) =>
+        {
+            _sawmill.Debug("Rules acceptance bypassed using debug command");
+            OnAcceptPressed();
+        });
#endif
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#if DEBUG
_consoleHost.RegisterCommand("fuckrules",
"",
"",
(_, _, _) =>
{
OnAcceptPressed();
});
#endif
#if DEBUG
_consoleHost.RegisterCommand("debug-accept-rules",
"Debug command to bypass rules acceptance",
"debug-accept-rules",
(_, _, _) =>
{
_sawmill.Debug("Rules acceptance bypassed using debug command");
OnAcceptPressed();
});
#endif

Comment on lines +36 to +44
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Potential issue

Подтверждено: необходима замена отладочной команды

Проверка кодовой базы показала, что команда fuckrules используется только в одном файле InfoUIController.cs в блоке DEBUG. Предложенные изменения необходимо реализовать:

  • Заменить название команды на профессиональное debug_skip_rules
  • Добавить документацию на русском языке
  • Добавить логирование через _sawmill

Это улучшит качество кода и сделает отладочную функциональность более профессиональной и безопасной.

🔗 Analysis chain

Необходимо переработать отладочную команду

Текущая реализация отладочной команды имеет несколько проблем:

  1. Использование некорректного наименования команды
  2. Отсутствие документации и описания
  3. Отсутствие логирования выполнения команды

Предлагаю следующие изменения:

#if DEBUG
-        _consoleHost.RegisterCommand("fuckrules",
-            "",
-            "",
-            (_, _, _) =>
-        {
-            OnAcceptPressed();
-        });
+        _consoleHost.RegisterCommand("debug_skip_rules",
+            "Пропустить принятие правил (только для отладки)",
+            "debug_skip_rules - автоматически принять правила без показа диалога",
+            (_, _, _) =>
+        {
+            _sawmill.Warning("Выполнена отладочная команда пропуска правил");
+            OnAcceptPressed();
+        });
#endif
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Проверка использования команды в продакшн коде
rg -l "fuckrules" --type cs

Length of output: 89


Script:

#!/bin/bash
# Check if the command is used in any other files and get more context
rg "fuckrules" -C 3 --type cs

# Check for any similar debug commands pattern
ast-grep --pattern 'RegisterCommand($_, $_, $_, $_)'

Length of output: 795

}

private void OnRulesInformationMessage(SendRulesInformationMessage message)
Expand Down
16 changes: 13 additions & 3 deletions Content.Server/Administration/Systems/AdminSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public sealed class AdminSystem : EntitySystem
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly StationRecordsSystem _stationRecords = default!;
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly Backmen.Administration.Bwoink.Gpt.GptAhelpSystem _gpt = default!;

private readonly Dictionary<NetUserId, PlayerInfo> _playerList = new();

Expand Down Expand Up @@ -256,9 +257,18 @@ private PlayerInfo GetPlayerInfo(SessionData data, ICommonSession? session)
{
overallPlaytime = playTime;
}

return new PlayerInfo(name, entityName, identityName, startingRole, antag, GetNetEntity(session?.AttachedEntity), data.UserId,
connected, _roundActivePlayers.Contains(data.UserId), overallPlaytime
return new PlayerInfo(
name,
entityName,
identityName,
startingRole,
antag,
GetNetEntity(session?.AttachedEntity),
data.UserId,
connected,
_roundActivePlayers.Contains(data.UserId),
overallPlaytime,
_gpt.HasAutoReplay(data.UserId) // backmen: gpt
);
}

Expand Down
12 changes: 10 additions & 2 deletions Content.Server/Administration/Systems/BwoinkSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public sealed partial class BwoinkSystem : SharedBwoinkSystem
[Dependency] private readonly IAfkManager _afkManager = default!;
[Dependency] private readonly IServerDbManager _dbManager = default!;
[Dependency] private readonly PlayerRateLimitManager _rateLimit = default!;
[Dependency] private readonly GptAhelpSystem _gpt = default!;

[GeneratedRegex(@"^https://discord\.com/api/webhooks/(\d+)/((?!.*/).*)$")]
private static partial Regex DiscordRegex();
Expand Down Expand Up @@ -738,6 +739,8 @@ protected override void OnBwoinkTextMessage(BwoinkTextMessage message, EntitySes
}
}

var nonAfkAdmins = GetNonAfkAdmins();

var sendsWebhook = _webhookUrl != string.Empty;
if (sendsWebhook)
{
Expand All @@ -752,7 +755,7 @@ protected override void OnBwoinkTextMessage(BwoinkTextMessage message, EntitySes
str = str[..(DescriptionMax - _maxAdditionalChars - unameLength)];
}

var nonAfkAdmins = GetNonAfkAdmins();

var messageParams = new AHelpMessageParams(
senderSession.Name,
str,
Expand All @@ -765,7 +768,12 @@ protected override void OnBwoinkTextMessage(BwoinkTextMessage message, EntitySes
_messageQueues[msg.UserId].Enqueue(GenerateAHelpMessage(messageParams));
}

EntityManager.SystemOrNull<GptAhelpSystem>()?.AddUserMessage(message.UserId, personalChannel, escapedText); // backmen: gpt
// start-backmen: gpt
_gpt.AddUserMessage(message.UserId, personalChannel, escapedText);

Comment on lines +772 to +773
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Добавьте обработку возможных исключений при вызове _gpt.AddUserMessage

Рекомендуется обернуть вызов _gpt.AddUserMessage в блок try-catch, чтобы обеспечить корректную обработку возможных исключений и предотвратить потенциальные сбои системы.

if(personalChannel && ((nonAfkAdmins.Count == 0 && _gpt.EnabledNoAdminAutoResponse) || _gpt.HasAutoReplay(senderSession.UserId)))
_gpt.DoAutoReplay(senderSession);
// end-backmen: gpt

if (admins.Count != 0 || sendsWebhook)
return;
Expand Down
113 changes: 108 additions & 5 deletions Content.Server/Backmen/Administration/Bwoink/Gpt/GptAhelpSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
using System.Threading.Tasks;
using Content.Server.Administration;
using Content.Server.Administration.Managers;
using Content.Server.Administration.Systems;
using Content.Server.Backmen.Administration.Bwoink.Gpt.Models;
using Content.Shared.Administration;
using Content.Shared.GameTicking;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Utility;

namespace Content.Server.Backmen.Administration.Bwoink.Gpt;
Expand All @@ -25,6 +27,7 @@ public sealed class GptAhelpSystem : EntitySystem
[Dependency] private readonly IConsoleHost _console = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly AdminSystem _adminSystem = default!;
private readonly HttpClient _httpClient = new(
/*
new SocketsHttpHandler()
Expand All @@ -48,6 +51,8 @@ public sealed class GptAhelpSystem : EntitySystem

private const string BotName = "GptChat";

public bool EnabledNoAdminAutoResponse { get; private set; } = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Рассмотрите использование потокобезопасной коллекции для _autoReplayUsers

HashSet<NetUserId> не является потокобезопасным. При одновременном доступе из разных потоков возможны состояния гонки.

Предлагаю следующие изменения:

-private HashSet<NetUserId> _autoReplayUsers = new();
+private readonly ConcurrentHashSet<NetUserId> _autoReplayUsers = new();

Also applies to: 72-85


private List<object> _gptFunctions = new();
public override void Initialize()
{
Expand All @@ -58,8 +63,30 @@ public override void Initialize()
_cfg.OnValueChanged(Shared.Backmen.CCVar.CCVars.GptApiToken, GptTokenCVarChanged, true);
_cfg.OnValueChanged(Shared.Backmen.CCVar.CCVars.GptModel, GptModelCVarChanged, true);
_cfg.OnValueChanged(Shared.Backmen.CCVar.CCVars.GptApiGigaToken, GptGigaTokenCVarChanged, true);
_cfg.OnValueChanged(Shared.Backmen.CCVar.CCVars.GptApiNoAdminAuto, v => { EnabledNoAdminAutoResponse = v; }, true);

_console.RegisterCommand("ahelp_gpt", GptCommand, GptCommandCompletion);
_console.RegisterCommand("ahelp_gpt_toggle", GptToggleCommand, GptToggleCommandCompletion);
}

private HashSet<NetUserId> _autoReplayUsers = new();

public bool HasAutoReplay(NetUserId userId) => _autoReplayUsers.Contains(userId);
public void AddAutoReplayUser(ICommonSession user)
{
_autoReplayUsers.Add(user.UserId);
_adminSystem.UpdatePlayerList(user);
}

public void RemAutoReplayUser(ICommonSession user)
{
_autoReplayUsers.Remove(user.UserId);
_adminSystem.UpdatePlayerList(user);
}

public void DoAutoReplay(ICommonSession user)
{
_console.ExecuteCommand($"ahelp_gpt {user.Name}");
Rxup marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Обеспечьте корректность передачи имени пользователя в консольную команду

При выполнении команды _console.ExecuteCommand($"ahelp_gpt {user.Name}"); возможны проблемы, если user.Name содержит пробелы или специальные символы. Рекомендуется обернуть имя пользователя в кавычки или использовать метод, который правильно экранирует аргументы.

Предлагаем изменить код следующим образом:

-_console.ExecuteCommand($"ahelp_gpt {user.Name}");
+_console.ExecuteCommand($"ahelp_gpt \"{user.Name}\"");

Это гарантирует, что имя пользователя будет правильно передано даже при наличии пробелов или специальных символов.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_console.ExecuteCommand($"ahelp_gpt {user.Name}");
_console.ExecuteCommand($"ahelp_gpt \"{user.Name}\"");

}

#region GigaChat
Expand Down Expand Up @@ -131,11 +158,13 @@ private void SetTyping(NetUserId channel, bool enable)
}
}

private async Task<(GptResponseApi? responseApi, string? err)> SendApiRequest(GptUserInfo history)
private async Task<(GptResponseApi? responseApi, string? err)> SendApiRequest(GptUserInfo history, NetUserId userId)
{
var payload = new GptApiPacket(_apiModel, history.GetMessagesForApi(), _gptFunctions,0.8f);
var postData = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
postData.Headers.Add("X-Session-ID", userId.ToString());
var request = await _httpClient.PostAsync($"{_apiUrl + (_apiUrl.EndsWith("/")?"":"/")}chat/completions",
new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"));
postData);
Comment on lines +161 to +167
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Добавьте обработку ошибок для HTTP-запросов

Необходимо добавить обработку сетевых исключений и таймаутов при выполнении HTTP-запросов.

Предлагаю следующие изменения:

 private async Task<(GptResponseApi? responseApi, string? err)> SendApiRequest(GptUserInfo history, NetUserId userId)
 {
+    try {
         var payload = new GptApiPacket(_apiModel, history.GetMessagesForApi(), _gptFunctions,0.8f);
         var postData = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
         postData.Headers.Add("X-Session-ID", userId.ToString());
         var request = await _httpClient.PostAsync($"{_apiUrl + (_apiUrl.EndsWith("/")?"":"/")}chat/completions",
             postData);
+    } catch (HttpRequestException ex) {
+        Log.Error($"Ошибка сети при отправке запроса: {ex.Message}");
+        return (null, "Ошибка сети при отправке запроса");
+    } catch (TaskCanceledException) {
+        Log.Error("Таймаут при отправке запроса");
+        return (null, "Превышено время ожидания ответа");
+    }

Committable suggestion skipped: line range outside the PR's diff.


var response = await request.Content.ReadAsStringAsync();

Expand All @@ -152,6 +181,63 @@ private void SetTyping(NetUserId channel, bool enable)
return (info, null);
}

[AdminCommand(AdminFlags.Fun)]
private async void GptToggleCommand(IConsoleShell shell, string argstr, string[] args)
{
if (!_enabled)
{
shell.WriteError("disabled!");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Используйте локализацию для сообщений об ошибках

Сообщение об ошибке "disabled!" не локализовано. Рекомендуется использовать Loc.GetString для поддержки многоязычности.

Предлагаем заменить строку:

-shell.WriteError("disabled!");
+shell.WriteError(Loc.GetString("gpt-command-disabled"));

И добавить соответствующую строку локализации.

Committable suggestion skipped: line range outside the PR's diff.

return;
}

if (args.Length != 1)
{
shell.WriteError(Loc.GetString("shell-need-exactly-one-argument"));
return;
}

if (!_playerManager.TryGetSessionByUsername(args[0], out var player))
{
shell.WriteError(Loc.GetString("parse-session-fail", ("username", args[0])));
return;
}

var userId = player.UserId;
if (HasAutoReplay(userId))
{
RemAutoReplayUser(player);
shell.WriteLine("Убран!");
}
else
{
AddAutoReplayUser(player);
shell.WriteLine("Добавлен!");
}

var bwoinkText = $"[color=lightblue]{BotName}[/color]: " +
$"АДМИН {shell.Player?.Name ?? "Console"} " +
$"{(HasAutoReplay(userId) ? "[color=green]включил[/color]" : "[color=red]выключил[/color]")} " +
$"авто ответ";
Rxup marked this conversation as resolved.
Show resolved Hide resolved

var msg = new SharedBwoinkSystem.BwoinkTextMessage(userId, SharedBwoinkSystem.SystemUserId, bwoinkText);

var admins = GetTargetAdmins();

// Notify all admins
foreach (var channel in admins)
{
RaiseNetworkEvent(msg, channel);
}
}

private CompletionResult GptToggleCommandCompletion(IConsoleShell shell, string[] args)
{
if (args.Length != 1)
return CompletionResult.Empty;

return CompletionResult.FromHintOptions(CompletionHelper.SessionNames(), "Пользователь");
}

[AdminCommand(AdminFlags.Adminhelp)]
private async void GptCommand(IConsoleShell shell, string argstr, string[] args)
{
Expand Down Expand Up @@ -213,7 +299,7 @@ private async void GptCommand(IConsoleShell shell, string argstr, string[] args)

private async Task ProcessRequest(IConsoleShell shell, NetUserId userId, GptUserInfo history)
{
var (info, err) = await SendApiRequest(history);
var (info, err) = await SendApiRequest(history, userId);
if (!string.IsNullOrEmpty(err))
{
shell.WriteError(err);
Expand Down Expand Up @@ -266,10 +352,26 @@ private async Task ProcessFunctionCall(IConsoleShell shell, NetUserId userId, Gp
var ev = new EventGptFunctionCall(shell,userId,history,msg);
RaiseLocalEvent(ev);

if (!ev.Handled)
if (ev is { Handled: false, HandlerTask: null })
{
history.Add(new GptMessageFunction(fnName));
}
else if (ev.HandlerTask != null)
{
try
{
await ev.HandlerTask;
}
catch (Exception e)
{
Log.Error(e.Message);
history.Add(new GptMessageFunction(fnName));
Rxup marked this conversation as resolved.
Show resolved Hide resolved
}
if (!ev.Handled)
{
history.Add(new GptMessageFunction(fnName));
}
}

await ProcessRequest(shell, userId, history);
}
Expand Down Expand Up @@ -370,14 +472,15 @@ public void AddUserMessage(NetUserId messageUserId, bool personalChannel, string
return;
}

_history.TryAdd(messageUserId, new GptUserInfo());
_history.TryAdd(messageUserId, new GptUserInfo(messageUserId, _playerManager, _cfg));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Обеспечьте потокобезопасный доступ к _history

Использование TryAdd без синхронизации может привести к состоянию гонки при одновременном доступе.

Рекомендуется использовать ConcurrentDictionary:

-private Dictionary<NetUserId, GptUserInfo> _history = new();
+private readonly ConcurrentDictionary<NetUserId, GptUserInfo> _history = new();

Committable suggestion skipped: line range outside the PR's diff.


_history[messageUserId].Add(new GptMessageChat(personalChannel ? GptUserDirection.user : GptUserDirection.assistant, escapedText));
}
}

public sealed class EventGptFunctionCall : HandledEntityEventArgs
{
public Task? HandlerTask { get; set; }
public IConsoleShell Shell { get; }
public NetUserId UserId { get; }
public GptUserInfo History { get; }
Expand Down
Loading
Loading