diff --git a/src/Infrastructure/BotSharp.Abstraction/Translation/Models/TranslationRequestModel.cs b/src/Infrastructure/BotSharp.Abstraction/Translation/Models/TranslationRequestModel.cs index 588dedfc..d3d6a453 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Translation/Models/TranslationRequestModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Translation/Models/TranslationRequestModel.cs @@ -1,5 +1,3 @@ -using BotSharp.Abstraction.Infrastructures.Enums; - namespace BotSharp.OpenAPI.ViewModels.Translations; public class TranslationRequestModel @@ -7,3 +5,15 @@ public class TranslationRequestModel public string Text { get; set; } = null!; public string ToLang { get; set; } = LanguageType.CHINESE; } + +public class TranslationScriptTimestamp +{ + public string Text { set; get; } = null!; + public string Timestamp { get; set; } = null!; +} + +public class TranslationLongTextRequestModel +{ + public TranslationScriptTimestamp[] Texts { get; set; } = null!; + public string ToLang { get; set; } = LanguageType.CHINESE; +} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/TranslationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/TranslationController.cs index ac7686a1..17e9ff53 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/TranslationController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/TranslationController.cs @@ -1,4 +1,4 @@ -using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Options; using BotSharp.Abstraction.Translation; using BotSharp.OpenAPI.ViewModels.Translations; @@ -9,10 +9,13 @@ namespace BotSharp.OpenAPI.Controllers; public class TranslationController : ControllerBase { private readonly IServiceProvider _services; + private readonly JsonSerializerOptions _jsonOptions; - public TranslationController(IServiceProvider services) + public TranslationController(IServiceProvider services, + BotSharpOptions options) { _services = services; + _jsonOptions = InitJsonOptions(options); } [HttpPost("/translate")] @@ -27,4 +30,71 @@ public class TranslationController : ControllerBase Text = text }; } + + [HttpPost("/translate/long-text")] + public async Task SendMessageSse([FromBody] TranslationLongTextRequestModel model) + { + var agentService = _services.GetRequiredService(); + var agent = await agentService.LoadAgent(BuiltInAgentId.AIAssistant); + var translator = _services.GetRequiredService(); + + Response.StatusCode = 200; + Response.Headers.Append(Microsoft.Net.Http.Headers.HeaderNames.ContentType, "text/event-stream"); + Response.Headers.Append(Microsoft.Net.Http.Headers.HeaderNames.CacheControl, "no-cache"); + Response.Headers.Append(Microsoft.Net.Http.Headers.HeaderNames.Connection, "keep-alive"); + + foreach (var script in model.Texts) + { + var translatedText = await translator.Translate(agent, Guid.NewGuid().ToString(), script.Text, language: model.ToLang); + + var json = JsonSerializer.Serialize(new TranslationScriptTimestamp + { + Text = translatedText, + Timestamp = script.Timestamp + }, _jsonOptions); + + await OnChunkReceived(Response, json); + } + + await OnEventCompleted(Response); + } + + private async Task OnChunkReceived(HttpResponse response, string text) + { + var buffer = Encoding.UTF8.GetBytes($"data:{text}\n"); + await response.Body.WriteAsync(buffer, 0, buffer.Length); + await Task.Delay(10); + + buffer = Encoding.UTF8.GetBytes("\n"); + await response.Body.WriteAsync(buffer, 0, buffer.Length); + } + + private async Task OnEventCompleted(HttpResponse response) + { + var buffer = Encoding.UTF8.GetBytes("data:[DONE]\n"); + await response.Body.WriteAsync(buffer, 0, buffer.Length); + + buffer = Encoding.UTF8.GetBytes("\n"); + await response.Body.WriteAsync(buffer, 0, buffer.Length); + } + + private JsonSerializerOptions InitJsonOptions(BotSharpOptions options) + { + var jsonOption = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + AllowTrailingCommas = true + }; + + if (options?.JsonSerializerOptions != null) + { + foreach (var option in options.JsonSerializerOptions.Converters) + { + jsonOption.Converters.Add(option); + } + } + + return jsonOption; + } }