Skip to content

Commit

Permalink
Исправлена работа библиотеки, теперь языковая модель отвечает корретн…
Browse files Browse the repository at this point in the history
…о на запросы продолжения ответа.
  • Loading branch information
WutADude committed Nov 23, 2023
1 parent ddc9877 commit 8735182
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 21 deletions.
71 changes: 55 additions & 16 deletions JObjects/EventObjects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,43 @@ internal EventObjects(string workingLanguage, string? appVersion)
_ActualAppVersion = string.IsNullOrWhiteSpace(appVersion) ? _ActualAppVersion : appVersion;
}

/// <summary>
/// Объект, который создаётся и отправляется в языковую модель для "авторизации", хотя она таковой и не является, но без неё нельзя получать продолжения ответов.
/// </summary>
internal JsonObject AuthEvent
{
get
{
JsonObject auth = new JsonObject()
{
["event"] = new JsonObject()
{
["header"] = new JsonObject()
{
["namespace"] = "System",
["name"] = "SynchronizeState",
["messageId"] = Randomizer.GetRandomId,
["seqNumber"] = _SeqNumber
},
["payload"] = new JsonObject()
{
["auth_token"] = Randomizer.GetRandomId,
["uuid"] = _UUID,
["vins"] = new JsonObject()
{
["application"] = new JsonObject()
{
["app_id"] = "ru.yandex.webdesktop",
["platform"] = "windows"
}
}
}
}
};
return auth;
}
}

/// <summary>
/// Объект, который создаётся и отправляется при отправке вопроса в языковую модель, на который нужно получить ответ.
/// </summary>
Expand Down Expand Up @@ -63,27 +100,28 @@ internal JsonObject TextInputEvent(string? message)
},
["header"] = new JsonObject()
{
["prev_req_id"] = null,
["prev_req_id"] = Randomizer.GetRandomId,
["sequence_number"] = null,
["request_id"] = _LastRequestId = Randomizer.GetRandomId,
["dialog_id"] = _DialogSkillId
["dialog_id"] = _DialogSkillId,
["dialog_type"] = 1
},
["request"] = new JsonObject()
{
["event"] = new JsonObject()
{
["type"] = "suggested_input",
["type"] = "text_input",
["text"] = message
},
["voice_session"] = false,
["experiments"] = new JsonArray() { "set_symbols_per_second=200", "stroka_yabro", "search_use_cloud_ui", "weather_use_cloud_ui", "enable_open_link_and_cloud_ui", "hw_onboarding_enable_greetings", "remove_feedback_suggests", "shopping_list", "enable_external_skills_for_webdesktop_and_webtouch", "send_show_view_directive_on_supports_show_view_layer_content_interface", "use_app_host_pure_Dialogovo_scenario" },
["experiments"] = new JsonArray() { "set_symbols_per_second=200", "stroka_yabro", "search_use_cloud_ui", "weather_use_cloud_ui", "enable_open_link_and_cloud_ui", "hw_onboarding_enable_greetings", "remove_feedback_suggests", "shopping_list", "enable_external_skills_for_webdesktop_and_webtouch", "send_show_view_directive_on_supports_show_view_layer_content_interface", "use_app_host_pure_Dialogovo_scenario", "div2cards_in_external_skills_for_web_standalone" },
["additional_options"] = new JsonObject()
{
["bass_options"] = new JsonObject()
{
["screen_scale_factor"] = 1
},
["supported_features"] = new JsonArray() { "open_link", "server_action", "cloud_ui", "cloud_first_screen_div", "cloud_ui_filling", "show_promo", "show_view_layer_content", "reminders_and_todos", "div2_cards", "print_text_in_message_view", "supports_print_text_in_message_view", "player_pause_directive" },
["supported_features"] = new JsonArray() { "open_link", "server_action", "cloud_ui", "cloud_first_screen_div", "cloud_ui_filling", "show_promo", "show_view_layer_content", "reminders_and_todos", "div2_cards", "print_text_in_message_view", "supports_print_text_in_message_view", "player_pause_directive", "supports_rich_json_cards_in_fullscreen_mode_in_skills" },
["unsupported_features"] = new JsonArray()
}
},
Expand All @@ -100,9 +138,9 @@ internal JsonObject TextInputEvent(string? message)
/// <summary>
/// Объект, который создаётся и отправляется в случае запроса продолжения ответа, если языковая модель не подтвердила окончание ответа.
/// </summary>
/// <param name="firstContinuationRequestId">ID сообщения с первым запросом продолжения, для получения продолжения ответа.</param>
/// <param name="parrentRequestId">ID сообщения с первым запросом продолжения, для получения продолжения ответа.</param>
/// <returns>Возвращает JsonObject для дальнейшей сериализации и отправки в формате строки.</returns>
internal JsonObject ContinuationEvent(ref string? firstContinuationRequestId)
internal JsonObject ContinuationEvent(ref string? parrentRequestId)
{
string currRequestId = string.Empty;
JsonObject continuation = new JsonObject()
Expand All @@ -121,7 +159,7 @@ internal JsonObject ContinuationEvent(ref string? firstContinuationRequestId)
["application"] = new JsonObject()
{
["app_id"] = "ru.yandex.webdesktop",
["app_version"] = "1.0.279-home-static/alice-web/10.2",
["app_version"] = _ActualAppVersion,
["platform"] = "windows",
["os_version"] = "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/116.0.0.0 safari/537.36 opr/102.0.0.0",
["uuid"] = _UUID,
Expand All @@ -130,15 +168,14 @@ internal JsonObject ContinuationEvent(ref string? firstContinuationRequestId)
["timezone"] = "Europe/Moscow",
["timestamp"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()
},
["format"] = "audio/ogg;codecs=opus",
["header"] = new JsonObject()
{
["prev_req_id"] = _LastRequestId,
["sequence_number"] = null,
["request_id"] = currRequestId = Randomizer.GetRandomId,
["dialog_id"] = _DialogSkillId
["dialog_id"] = _DialogSkillId,
["dialog_type"] = 1
},
["mime"] = "audio/webm;codecs=opus",
["request"] = new JsonObject()
{
["additional_options"] = new JsonObject()
Expand All @@ -147,25 +184,27 @@ internal JsonObject ContinuationEvent(ref string? firstContinuationRequestId)
{
["screen_scale_factor"] = 1
},
["supported_features"] = new JsonArray() { "open_link", "server_action", "cloud_ui", "cloud_first_screen_div", "cloud_ui_filling", "show_promo", "show_view_layer_content", "reminders_and_todos", "div2_cards", "print_text_in_message_view", "supports_print_text_in_message_view", "player_pause_directive" },
["supported_features"] = new JsonArray() { "open_link", "server_action", "cloud_ui", "cloud_first_screen_div", "cloud_ui_filling", "show_promo", "show_view_layer_content", "reminders_and_todos", "div2_cards", "print_text_in_message_view", "supports_print_text_in_message_view", "player_pause_directive", "supports_rich_json_cards_in_fullscreen_mode_in_skills" },
["unsupported_features"] = new JsonArray()
},
["event"] = new JsonObject()
{
["type"] = "server_action",
["name"] = "@@mm_stack_engine_get_next",
["payload"] = new JsonObject()
{
["@recovery_params"] = new JsonObject(),
["@request_id"] = _LastRequestId,
["stack_session_id"] = firstContinuationRequestId ??= _LastRequestId,
["stack_session_id"] = parrentRequestId ??= _LastRequestId,
["@scenario_name"] = "Dialogovo",
["stack_product_scenario_name"] = "dialogovo"
},
["type"] = "server_action"
}
},
["experiments"] = new JsonArray() { "set_symbols_per_second=200", "stroka_yabro", "search_use_cloud_ui", "weather_use_cloud_ui", "enable_open_link_and_cloud_ui", "hw_onboarding_enable_greetings", "remove_feedback_suggests", "shopping_list", "enable_external_skills_for_webdesktop_and_webtouch", "send_show_view_directive_on_supports_show_view_layer_content_interface", "use_app_host_pure_Dialogovo_scenario" },
["experiments"] = new JsonArray() { "set_symbols_per_second=200", "stroka_yabro", "search_use_cloud_ui", "weather_use_cloud_ui", "enable_open_link_and_cloud_ui", "hw_onboarding_enable_greetings", "remove_feedback_suggests", "shopping_list", "enable_external_skills_for_webdesktop_and_webtouch", "send_show_view_directive_on_supports_show_view_layer_content_interface", "use_app_host_pure_Dialogovo_scenario", "div2cards_in_external_skills_for_web_standalone" },
["voice_session"] = false
},
["format"] = "audio/ogg;codecs=opus",
["mime"] = "audio/webm;codecs=opus",
["topic"] = "desktopgeneral"
}
}
Expand Down
5 changes: 4 additions & 1 deletion Networking/WSocket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@ public WSocket(CancellationToken? cancelationToken = null)
/// </summary>
/// <param name="message">Текст сообщения сериализованный в Json объект.</param>
/// <param name="endMessage">Необязательный параметр отвечающий за то, является ли сообщение - окончанием, по стандарту = true.</param>
/// <param name="waitResponse">Необязательный параметр отвечающий за то, нужно-ли нам ожидать ответа от языковой модели или нет, по стандарту = true.</param>
/// <returns>Возвращает сериализованный ответ языковой модели в формате строки для последующей десериализации.</returns>
protected async Task<string> SendTextAsync(string message, bool endMessage = true)
protected async Task<string> SendEventAsync(string message, bool endMessage = true, bool waitResponse = true)
{
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
await _WebSocket.SendAsync(new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, endMessage, _CancelationToken ?? CancellationToken.None);
if (!waitResponse)
return string.Empty;
byte[] incomingData = new byte[65536]; // Размер ответа всегда разный, выделенный буфер - это буфер с запасом.
WebSocketReceiveResult receivedData = await _WebSocket.ReceiveAsync(new ArraySegment<byte>(incomingData), _CancelationToken ?? CancellationToken.None);
if (receivedData.CloseStatus.HasValue)
Expand Down
5 changes: 3 additions & 2 deletions YaGPT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class YaGPT : WSocket, IDisposable
public YaGPT(string language = Language.Russian, CancellationToken? cancelationToken = null) : base(cancelationToken)
{
_EventObjects = new EventObjects(language, Task.Run(async () => RegexManager.GetActualAppVersion(await Requests.GetHtmlDocument())).Result);
Task.Run(async () => await SendEventAsync(JsonManager.GetSerializedJson(_EventObjects.AuthEvent), waitResponse: false)).Wait();
}

/// <summary>
Expand All @@ -32,14 +33,14 @@ public async Task<string> SendMessageAsync(string message)
StringBuilder answerString = new StringBuilder();
try
{
var responseData = JsonManager.GetResponseData(await SendTextAsync(JsonManager.GetSerializedJson(_EventObjects.TextInputEvent(message))));
var responseData = JsonManager.GetResponseData(await SendEventAsync(JsonManager.GetSerializedJson(_EventObjects.TextInputEvent(message))));
answerString.Append(responseData.messageText);
string? firstContinuationRequestId = null;
while (!responseData.isEnd)
{
if (responseData.prefetchTime > 0)
await Task.Delay(responseData.prefetchTime, _CancelationToken ?? CancellationToken.None);
responseData = JsonManager.GetResponseData(await SendTextAsync(JsonManager.GetSerializedJson(_EventObjects.ContinuationEvent(ref firstContinuationRequestId))));
responseData = JsonManager.GetResponseData(await SendEventAsync(JsonManager.GetSerializedJson(_EventObjects.ContinuationEvent(ref firstContinuationRequestId))));
answerString.Append(responseData.messageText);
}
return answerString.ToString();
Expand Down
15 changes: 13 additions & 2 deletions YandexGPTWrapper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,20 @@
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Company>WutADude</Company>
<Authors>$(AssemblyName)</Authors>
<Company>wDude</Company>
<Authors>WutADude</Authors>
<Description>Библиотека для работы с языковой моделью YandexGPT</Description>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<Version>1.0.17</Version>
<Copyright>WutADude</Copyright>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<GenerateAssemblyInfo>True</GenerateAssemblyInfo>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<GenerateAssemblyInfo>True</GenerateAssemblyInfo>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 8735182

Please sign in to comment.