From 04326d4eb62e10a0c34226927ca07a6bd00cb88f Mon Sep 17 00:00:00 2001 From: RiabushenkoA Date: Wed, 26 Nov 2025 18:03:43 +0200 Subject: [PATCH 1/2] Adustments to PostEditService --- Apps.OpenAI/Apps.OpenAI.csproj | 2 +- Apps.OpenAI/Services/JsonGlossaryService.cs | 3 ++- Apps.OpenAI/Services/PostEditService.cs | 2 +- Tests.OpenAI/TranslationActionsTests.cs | 9 ++++---- Tests.OpenAI/XliffActionTests.cs | 23 ++++++++++++--------- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/Apps.OpenAI/Apps.OpenAI.csproj b/Apps.OpenAI/Apps.OpenAI.csproj index bcb361b..7b718f7 100644 --- a/Apps.OpenAI/Apps.OpenAI.csproj +++ b/Apps.OpenAI/Apps.OpenAI.csproj @@ -4,7 +4,7 @@ net8.0 OpenAI Creating safe artificial general intelligence that benefits all of humanity - 2.8.10 + 2.8.11 Apps.OpenAI diff --git a/Apps.OpenAI/Services/JsonGlossaryService.cs b/Apps.OpenAI/Services/JsonGlossaryService.cs index 9e6ac80..10306e0 100644 --- a/Apps.OpenAI/Services/JsonGlossaryService.cs +++ b/Apps.OpenAI/Services/JsonGlossaryService.cs @@ -34,7 +34,8 @@ private class GlossaryJson } var glossaryStream = await fileManagementClient.DownloadAsync(glossary); - var blackbirdGlossary = await glossaryStream.ConvertFromTbx(); + using var sanitizedGlossaryStream = await glossaryStream.SanitizeTbxXmlAsync(); + var blackbirdGlossary = await sanitizedGlossaryStream.ConvertFromTbx(); var jsonGlossary = new GlossaryJson(); var entriesIncluded = false; diff --git a/Apps.OpenAI/Services/PostEditService.cs b/Apps.OpenAI/Services/PostEditService.cs index dbe9e9e..3fac978 100644 --- a/Apps.OpenAI/Services/PostEditService.cs +++ b/Apps.OpenAI/Services/PostEditService.cs @@ -239,7 +239,7 @@ private async Task ProcessBatchAsync( catch (Exception ex) { result.IsSuccess = false; - result.ErrorMessages.Add($"Unexpected error processing batch: {ex.Message}"); + result.ErrorMessages.Add($"Unexpected error processing batch: {ex.GetType().Name}: {ex.Message}"); return result; } } diff --git a/Tests.OpenAI/TranslationActionsTests.cs b/Tests.OpenAI/TranslationActionsTests.cs index 1cbe217..77171d2 100644 --- a/Tests.OpenAI/TranslationActionsTests.cs +++ b/Tests.OpenAI/TranslationActionsTests.cs @@ -21,12 +21,13 @@ public async Task Translate_html(InvocationContext context) var modelIdentifier = new TextChatModelIdentifier { ModelId = "gpt-5-mini" }; var translateRequest = new TranslateContentRequest { - File = new FileReference { Name = "" }, + File = new FileReference { Name = "Pasted text-en-ko-Tr.mxliff" }, TargetLanguage = "zh-Hans-CN", - OutputFileHandling = "original" + OutputFileHandling = "original", + }; - var reasoningEffortRequest = new ReasoningEffortRequest(); - string systemMessage = ""; + var reasoningEffortRequest = new ReasoningEffortRequest { }; + string systemMessage = "The content is intended to introduce products and services to potential customers. Your task is to ensure the translation is accurate, engaging, and easy to understand by correcting critical errors, while maintaining a formal tone. \r\nCritical errors include tag misplacements, malformed tags, number mismatches, translation omissions, or glossary term violations. Tags appear as combinations of {, }, <, or > with a number (e.g., {1}, <2}, {3>), and these must match the source exactly. Tags define font styles of texts between two tags or represent inserted links and line breaks. \r\nDo not change the existing translation unless a critical error or translation mistake is present. Do not add punctuations which do not exist in the source. \r\n"; var glossaryRequest = new GlossaryRequest { Glossary = new FileReference { Name = "Glossary.tbx" } }; var result = await actions.TranslateContent(modelIdentifier, translateRequest, systemMessage, glossaryRequest, reasoningEffortRequest); diff --git a/Tests.OpenAI/XliffActionTests.cs b/Tests.OpenAI/XliffActionTests.cs index 6a12319..07de5a7 100644 --- a/Tests.OpenAI/XliffActionTests.cs +++ b/Tests.OpenAI/XliffActionTests.cs @@ -6,30 +6,33 @@ using Blackbird.Applications.Sdk.Common.Exceptions; using Blackbird.Applications.Sdk.Common.Files; using Blackbird.Applications.Sdk.Common.Invocation; +using Apps.OpenAI.Constants; namespace Tests.OpenAI; [TestClass] public class XliffActionTests : TestBaseWithContext { - [TestMethod, ContextDataSource] + [TestMethod, ContextDataSource(ConnectionTypes.AzureOpenAi)] public async Task PostEditXLIFF_WithValidXlfFile_ProcessesSuccessfully(InvocationContext context) { // Arrange var actions = new DeprecatedXliffActions(context, FileManagementClient); - var modelIdentifier = new TextChatModelIdentifier { ModelId = "gpt-4.1" }; - var prompt = "You are a Swiss machine translation post-editor. You edit texts from German into Italian. Your task is to post-edit a translation. You need to take the source segment into account when post-editing the translation. Check each target segment and perform the following tasks:\r\n- Replace the character \"'\" with the character \"’\". Example: write \"l’indice\" instead of \"l'indice\".\r\n- Make sure that the quotation marks \"«»\" are used in the target text. Example: write «I prezzi aumentano» instead of \"I prezzi aumentano\".\r\n- Make sure percentages are expressed with the symbol \"%\". Make sure there aren't spaces between the number and the symbol. Example: write \"10%\" instead of “10 per cento”.\r\n- Perform a grammar and punctuation check. Focus on spelling, gender and number. Ensure internal consistency and fluency. Try to use impersonal formulations when possible.\r\n- Perform a terminology check. The attached glossary contains the terms that need to be strictly applied to the translation, ensuring grammatical correctness, gender, inflections and plurals.\r\nReturn the new .xliff file. "; - + var modelIdentifier = new TextChatModelIdentifier { /*ModelId = "gpt-4.1" */}; + var prompt = ""; var editRequest = new PostEditXliffRequest { - DisableTagChecks = true, - File = new FileReference { Name = "contentful.html.xliff" }, - SourceLanguage = "German", - TargetLanguage = "Italian", - + //DisableTagChecks = true, + File = new FileReference { Name = "Pasted text-en-ko-Tr.mxliff" }, + //SourceLanguage = "German", + //TargetLanguage = "Italian", + NeverFail = false, + ModifiedBy= "1441948", + FilterGlossary=true, + PostEditLockedSegments = false }; string? systemMessage = prompt; - var glossaryRequest = new GlossaryRequest { Glossary = new FileReference { Name = "glossary.tbx" } }; + var glossaryRequest = new GlossaryRequest { Glossary = new FileReference { Name = "TermWeb_Safe For AI.tbx" } }; // Act var result = await actions.PostEditXLIFF(modelIdentifier, editRequest, systemMessage, glossaryRequest); From 502a48390d7114914be78ee369ad0fb6b6f3464a Mon Sep 17 00:00:00 2001 From: RiabushenkoA Date: Wed, 26 Nov 2025 18:05:01 +0200 Subject: [PATCH 2/2] Adustments to PostEditService --- Tests.OpenAI/TranslationActionsTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests.OpenAI/TranslationActionsTests.cs b/Tests.OpenAI/TranslationActionsTests.cs index 77171d2..59ad93a 100644 --- a/Tests.OpenAI/TranslationActionsTests.cs +++ b/Tests.OpenAI/TranslationActionsTests.cs @@ -27,8 +27,8 @@ public async Task Translate_html(InvocationContext context) }; var reasoningEffortRequest = new ReasoningEffortRequest { }; - string systemMessage = "The content is intended to introduce products and services to potential customers. Your task is to ensure the translation is accurate, engaging, and easy to understand by correcting critical errors, while maintaining a formal tone. \r\nCritical errors include tag misplacements, malformed tags, number mismatches, translation omissions, or glossary term violations. Tags appear as combinations of {, }, <, or > with a number (e.g., {1}, <2}, {3>), and these must match the source exactly. Tags define font styles of texts between two tags or represent inserted links and line breaks. \r\nDo not change the existing translation unless a critical error or translation mistake is present. Do not add punctuations which do not exist in the source. \r\n"; - var glossaryRequest = new GlossaryRequest { Glossary = new FileReference { Name = "Glossary.tbx" } }; + string systemMessage = ""; + var glossaryRequest = new GlossaryRequest { Glossary = new FileReference { Name = "Glossary.tbx" } }; var result = await actions.TranslateContent(modelIdentifier, translateRequest, systemMessage, glossaryRequest, reasoningEffortRequest); Assert.IsNotNull(result);