Skip to content

feat(ai): add file translation methods support#367

Open
innomaxx wants to merge 2 commits intomainfrom
feature/issue-360_add-ai-file-translation-methods
Open

feat(ai): add file translation methods support#367
innomaxx wants to merge 2 commits intomainfrom
feature/issue-360_add-ai-file-translation-methods

Conversation

@innomaxx
Copy link
Copy Markdown
Collaborator

Closes #360

@innomaxx innomaxx requested a review from andrii-bodnar March 22, 2026 18:29
@innomaxx innomaxx changed the title Feature/issue 360 add ai file translation methods feat(ai): add file translation methods support Mar 22, 2026
@andrii-bodnar andrii-bodnar requested a review from Copilot March 23, 2026 07:57
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Crowdin AI File Translation endpoint support to the AI executor layer, along with unit tests and test resources, enabling SDK consumers to start/cancel file translation jobs and download results.

Changes:

  • Introduces request/response models for AI file translation jobs (AiFileTranslationsRequest, AiFileTranslationsStatus, AiFileTranslationsStage).
  • Extends IAiApiExecutor / AiApiExecutor with methods to start a job, fetch status, cancel, and download translated artifacts.
  • Adds unit tests plus new .resx fixtures and a shared download-link assertion helper.

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/Crowdin.Api.UnitTesting/Tests/AI/AiFileTranslationsTests.cs Adds unit tests covering AI file translation start/status/cancel/download APIs.
tests/Crowdin.Api.UnitTesting/Resources/Common.resx Adds shared download link JSON fixture.
tests/Crowdin.Api.UnitTesting/Resources/Common.Designer.cs Strongly-typed accessor for Common.resx.
tests/Crowdin.Api.UnitTesting/Resources/AI_FileTranslations.resx Adds request/response JSON fixtures for AI file translation endpoints.
tests/Crowdin.Api.UnitTesting/Resources/AI_FileTranslations.Designer.cs Strongly-typed accessor for AI_FileTranslations.resx.
tests/Crowdin.Api.UnitTesting/Crowdin.Api.UnitTesting.csproj Wires new .resx files and designers into the test project.
tests/Crowdin.Api.UnitTesting/CommonResponsesAssertUtils.cs Adds shared assertions for DownloadLink responses.
src/Crowdin.Api/AI/IAiApiExecutor.cs Adds new public executor methods for AI file translation workflows.
src/Crowdin.Api/AI/AiFileTranslationsStatus.cs Adds response model for file translation job status.
src/Crowdin.Api/AI/AiFileTranslationsStage.cs Adds enum for job stage values.
src/Crowdin.Api/AI/AiFileTranslationsRequest.cs Adds request model for starting AI file translations.
src/Crowdin.Api/AI/AiApiExecutor.cs Implements the new AI file translation endpoints.
Files not reviewed (2)
  • tests/Crowdin.Api.UnitTesting/Resources/AI_FileTranslations.Designer.cs: Language not supported
  • tests/Crowdin.Api.UnitTesting/Resources/Common.Designer.cs: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

/// <a href="https://support.crowdin.com/developer/api/v2/#tag/AI/operation/api.users.ai.file-translations.download">Crowdin File Based API</a>
/// <a href="https://support.crowdin.com/developer/api/v2/string-based/#tag/AI/operation/api.users.ai.file-translations.download">Crowdin String Based API</a>
/// <a href="https://support.crowdin.com/developer/enterprise/api/v2/#tag/AI/operation/api.ai.file-translations.download">Crowdin Enterprise API</a>
/// </summary>
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

DownloadTranslatedFile is missing the [PublicAPI] attribute, while other public methods in this executor are consistently annotated. For consistency (and to match the other AI endpoints), add [PublicAPI] to this method as well.

Suggested change
/// </summary>
/// </summary>
[PublicAPI]

Copilot uses AI. Check for mistakes.
Comment on lines +113 to +120
/// <summary>
/// AI File Translations. Documentation:
/// <a href="https://support.crowdin.com/developer/api/v2/#tag/AI/operation/api.users.ai.file-translations.post">Crowdin File Based API</a>
/// <a href="https://support.crowdin.com/developer/api/v2/string-based/#tag/AI/operation/api.users.ai.file-translations.post">Crowdin String Based API</a>
/// <a href="https://support.crowdin.com/developer/enterprise/api/v2/#tag/AI/operation/api.ai.file-translations.post">Crowdin Enterprise API</a>
/// </summary>
Task<AiFileTranslationsStatus> AiFileTranslations(long? userId, AiFileTranslationsRequest request);

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

Method name AiFileTranslations(...) reads like a noun/resource name rather than an action, which is inconsistent with the rest of IAiApiExecutor (e.g., GenerateAiReport, TranslateStrings, DownloadAiReport). Consider renaming this to a verb-based name (e.g., StartFileTranslation / TranslateFile) so the public API is clearer and more consistent.

Copilot uses AI. Check for mistakes.
Comment on lines +484 to +490
public async Task<AiFileTranslationsStatus> AiFileTranslations(long? userId, AiFileTranslationsRequest request)
{
string url = AddUserIdIfAvailable(userId, "/ai/file-translations");
CrowdinApiResult result = await _apiClient.SendPostRequest(url, request);
return _jsonParser.ParseResponseObject<AiFileTranslationsStatus>(result.JsonObject);
}

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

Implementation method name AiFileTranslations(...) is noun-like and inconsistent with the executor's other verb-based method names. If you rename the interface method for consistency/clarity, update this implementation accordingly to keep the public API self-explanatory.

Suggested change
public async Task<AiFileTranslationsStatus> AiFileTranslations(long? userId, AiFileTranslationsRequest request)
{
string url = AddUserIdIfAvailable(userId, "/ai/file-translations");
CrowdinApiResult result = await _apiClient.SendPostRequest(url, request);
return _jsonParser.ParseResponseObject<AiFileTranslationsStatus>(result.JsonObject);
}
public async Task<AiFileTranslationsStatus> StartFileTranslations(long? userId, AiFileTranslationsRequest request)
{
string url = AddUserIdIfAvailable(userId, "/ai/file-translations");
CrowdinApiResult result = await _apiClient.SendPostRequest(url, request);
return _jsonParser.ParseResponseObject<AiFileTranslationsStatus>(result.JsonObject);
}
Task<AiFileTranslationsStatus> IAiApiExecutor.AiFileTranslations(long? userId, AiFileTranslationsRequest request)
{
return StartFileTranslations(userId, request);
}

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +14
public static void Assert_DownloadLink(DownloadLink? expectedDownloadLink)
{
ArgumentNullException.ThrowIfNull(expectedDownloadLink);

Assert.Equal("https://test.com", expectedDownloadLink.Url);
Assert.Equal(DateTimeOffset.Parse("2019-09-20T10:31:21+00:00"), expectedDownloadLink.ExpireIn);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

Assert_DownloadLink parameter name expectedDownloadLink is misleading because the method asserts against the actual response value passed in by callers. Rename it to something like downloadLink/actualDownloadLink to make intent clearer.

Suggested change
public static void Assert_DownloadLink(DownloadLink? expectedDownloadLink)
{
ArgumentNullException.ThrowIfNull(expectedDownloadLink);
Assert.Equal("https://test.com", expectedDownloadLink.Url);
Assert.Equal(DateTimeOffset.Parse("2019-09-20T10:31:21+00:00"), expectedDownloadLink.ExpireIn);
public static void Assert_DownloadLink(DownloadLink? downloadLink)
{
ArgumentNullException.ThrowIfNull(downloadLink);
Assert.Equal("https://test.com", downloadLink.Url);
Assert.Equal(DateTimeOffset.Parse("2019-09-20T10:31:21+00:00"), downloadLink.ExpireIn);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for AI File Translation methods

2 participants