From 0f21dcf68d47258da651c56f7e22b7881e559dc3 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 3 Jan 2025 11:44:06 +0100 Subject: [PATCH] feat(translations): Expose task-processing translation options Signed-off-by: Joas Schilling --- docs/capabilities.md | 1 + lib/Capabilities.php | 6 ++++++ lib/ResponseDefinitions.php | 3 ++- openapi-administration.json | 4 ++++ openapi-backend-recording.json | 4 ++++ openapi-backend-signaling.json | 4 ++++ openapi-backend-sipbridge.json | 4 ++++ openapi-bots.json | 4 ++++ openapi-federation.json | 4 ++++ openapi-full.json | 4 ++++ openapi.json | 4 ++++ src/types/openapi/openapi-administration.ts | 1 + src/types/openapi/openapi-backend-recording.ts | 1 + src/types/openapi/openapi-backend-signaling.ts | 1 + src/types/openapi/openapi-backend-sipbridge.ts | 1 + src/types/openapi/openapi-bots.ts | 1 + src/types/openapi/openapi-federation.ts | 1 + src/types/openapi/openapi-full.ts | 1 + src/types/openapi/openapi.ts | 1 + tests/php/CapabilitiesTest.php | 13 +++++++++++++ 20 files changed, 62 insertions(+), 1 deletion(-) diff --git a/docs/capabilities.md b/docs/capabilities.md index 87802a453c7..9b484dbe286 100644 --- a/docs/capabilities.md +++ b/docs/capabilities.md @@ -171,3 +171,4 @@ * `config => conversations => force-passwords` - Whether passwords are enforced for public rooms * `conversation-creation-password` - Whether the endpoints for creating public conversations or making a conversation public support setting a password * `call-notification-state-api` (local) - Whether the endpoints exists for checking if a call notification should be dismissed +* `config => chat => has-translation-task-providers` (local) - When true, translations can be done using the [OCS TaskProcessing API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-taskprocessing-api.html). diff --git a/lib/Capabilities.php b/lib/Capabilities.php index b8817a629f2..96d56fba280 100644 --- a/lib/Capabilities.php +++ b/lib/Capabilities.php @@ -20,6 +20,7 @@ use OCP\IUserSession; use OCP\TaskProcessing\IManager as ITaskProcessingManager; use OCP\TaskProcessing\TaskTypes\TextToTextSummary; +use OCP\TaskProcessing\TaskTypes\TextToTextTranslate; use OCP\Translation\ITranslationManager; use OCP\Util; @@ -148,6 +149,7 @@ class Capabilities implements IPublicCapability { 'chat' => [ 'read-privacy', 'has-translation-providers', + 'has-translation-task-providers', 'typing-privacy', 'summary-threshold', ], @@ -223,6 +225,7 @@ public function getCapabilities(): array { 'max-length' => ChatManager::MAX_CHAT_LENGTH, 'read-privacy' => Participant::PRIVACY_PUBLIC, 'has-translation-providers' => $this->translationManager->hasProviders(), + 'has-translation-task-providers' => false, 'typing-privacy' => Participant::PRIVACY_PUBLIC, 'summary-threshold' => 100, ], @@ -324,6 +327,9 @@ public function getCapabilities(): array { if (isset($supportedTaskTypes[TextToTextSummary::ID])) { $capabilities['features'][] = 'chat-summary-api'; } + if (isset($supportedTaskTypes[TextToTextTranslate::ID])) { + $capabilities['config']['chat']['has-translation-task-providers'] = true; + } return [ 'spreed' => $capabilities, diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index f3e04023de3..72ef598c863 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -352,12 +352,13 @@ * max-length: int, * read-privacy: int, * has-translation-providers: bool, + * has-translation-task-providers: bool, * typing-privacy: int, * summary-threshold: positive-int, * }, * conversations: array{ * can-create: bool, - * force-passwords: bool, + * force-passwords: bool, * }, * federation: array{ * enabled: bool, diff --git a/openapi-administration.json b/openapi-administration.json index 82336b43982..5b78166d6de 100644 --- a/openapi-administration.json +++ b/openapi-administration.json @@ -208,6 +208,7 @@ "max-length", "read-privacy", "has-translation-providers", + "has-translation-task-providers", "typing-privacy", "summary-threshold" ], @@ -223,6 +224,9 @@ "has-translation-providers": { "type": "boolean" }, + "has-translation-task-providers": { + "type": "boolean" + }, "typing-privacy": { "type": "integer", "format": "int64" diff --git a/openapi-backend-recording.json b/openapi-backend-recording.json index d89ba139d1c..216bbf0c33a 100644 --- a/openapi-backend-recording.json +++ b/openapi-backend-recording.json @@ -141,6 +141,7 @@ "max-length", "read-privacy", "has-translation-providers", + "has-translation-task-providers", "typing-privacy", "summary-threshold" ], @@ -156,6 +157,9 @@ "has-translation-providers": { "type": "boolean" }, + "has-translation-task-providers": { + "type": "boolean" + }, "typing-privacy": { "type": "integer", "format": "int64" diff --git a/openapi-backend-signaling.json b/openapi-backend-signaling.json index 80d66c8f466..65f96abcf66 100644 --- a/openapi-backend-signaling.json +++ b/openapi-backend-signaling.json @@ -141,6 +141,7 @@ "max-length", "read-privacy", "has-translation-providers", + "has-translation-task-providers", "typing-privacy", "summary-threshold" ], @@ -156,6 +157,9 @@ "has-translation-providers": { "type": "boolean" }, + "has-translation-task-providers": { + "type": "boolean" + }, "typing-privacy": { "type": "integer", "format": "int64" diff --git a/openapi-backend-sipbridge.json b/openapi-backend-sipbridge.json index 317475a72b4..5bdb40d2711 100644 --- a/openapi-backend-sipbridge.json +++ b/openapi-backend-sipbridge.json @@ -184,6 +184,7 @@ "max-length", "read-privacy", "has-translation-providers", + "has-translation-task-providers", "typing-privacy", "summary-threshold" ], @@ -199,6 +200,9 @@ "has-translation-providers": { "type": "boolean" }, + "has-translation-task-providers": { + "type": "boolean" + }, "typing-privacy": { "type": "integer", "format": "int64" diff --git a/openapi-bots.json b/openapi-bots.json index 2989979159d..6191015e49c 100644 --- a/openapi-bots.json +++ b/openapi-bots.json @@ -141,6 +141,7 @@ "max-length", "read-privacy", "has-translation-providers", + "has-translation-task-providers", "typing-privacy", "summary-threshold" ], @@ -156,6 +157,9 @@ "has-translation-providers": { "type": "boolean" }, + "has-translation-task-providers": { + "type": "boolean" + }, "typing-privacy": { "type": "integer", "format": "int64" diff --git a/openapi-federation.json b/openapi-federation.json index 97f1f2ec13c..a7c190cff9b 100644 --- a/openapi-federation.json +++ b/openapi-federation.json @@ -184,6 +184,7 @@ "max-length", "read-privacy", "has-translation-providers", + "has-translation-task-providers", "typing-privacy", "summary-threshold" ], @@ -199,6 +200,9 @@ "has-translation-providers": { "type": "boolean" }, + "has-translation-task-providers": { + "type": "boolean" + }, "typing-privacy": { "type": "integer", "format": "int64" diff --git a/openapi-full.json b/openapi-full.json index b609e45f551..2170ff1ce7c 100644 --- a/openapi-full.json +++ b/openapi-full.json @@ -342,6 +342,7 @@ "max-length", "read-privacy", "has-translation-providers", + "has-translation-task-providers", "typing-privacy", "summary-threshold" ], @@ -357,6 +358,9 @@ "has-translation-providers": { "type": "boolean" }, + "has-translation-task-providers": { + "type": "boolean" + }, "typing-privacy": { "type": "integer", "format": "int64" diff --git a/openapi.json b/openapi.json index e00793473bf..1626dcab966 100644 --- a/openapi.json +++ b/openapi.json @@ -301,6 +301,7 @@ "max-length", "read-privacy", "has-translation-providers", + "has-translation-task-providers", "typing-privacy", "summary-threshold" ], @@ -316,6 +317,9 @@ "has-translation-providers": { "type": "boolean" }, + "has-translation-task-providers": { + "type": "boolean" + }, "typing-privacy": { "type": "integer", "format": "int64" diff --git a/src/types/openapi/openapi-administration.ts b/src/types/openapi/openapi-administration.ts index 679689cb062..2a4049aa9f3 100644 --- a/src/types/openapi/openapi-administration.ts +++ b/src/types/openapi/openapi-administration.ts @@ -239,6 +239,7 @@ export type components = { /** Format: int64 */ "read-privacy": number; "has-translation-providers": boolean; + "has-translation-task-providers": boolean; /** Format: int64 */ "typing-privacy": number; /** Format: int64 */ diff --git a/src/types/openapi/openapi-backend-recording.ts b/src/types/openapi/openapi-backend-recording.ts index 4ca4a529557..c34d7441dbe 100644 --- a/src/types/openapi/openapi-backend-recording.ts +++ b/src/types/openapi/openapi-backend-recording.ts @@ -73,6 +73,7 @@ export type components = { /** Format: int64 */ "read-privacy": number; "has-translation-providers": boolean; + "has-translation-task-providers": boolean; /** Format: int64 */ "typing-privacy": number; /** Format: int64 */ diff --git a/src/types/openapi/openapi-backend-signaling.ts b/src/types/openapi/openapi-backend-signaling.ts index a7bd86951ca..f344fd8f709 100644 --- a/src/types/openapi/openapi-backend-signaling.ts +++ b/src/types/openapi/openapi-backend-signaling.ts @@ -59,6 +59,7 @@ export type components = { /** Format: int64 */ "read-privacy": number; "has-translation-providers": boolean; + "has-translation-task-providers": boolean; /** Format: int64 */ "typing-privacy": number; /** Format: int64 */ diff --git a/src/types/openapi/openapi-backend-sipbridge.ts b/src/types/openapi/openapi-backend-sipbridge.ts index e85a92d06d5..d94e13eca8d 100644 --- a/src/types/openapi/openapi-backend-sipbridge.ts +++ b/src/types/openapi/openapi-backend-sipbridge.ts @@ -154,6 +154,7 @@ export type components = { /** Format: int64 */ "read-privacy": number; "has-translation-providers": boolean; + "has-translation-task-providers": boolean; /** Format: int64 */ "typing-privacy": number; /** Format: int64 */ diff --git a/src/types/openapi/openapi-bots.ts b/src/types/openapi/openapi-bots.ts index 389f124c257..35a8d291d00 100644 --- a/src/types/openapi/openapi-bots.ts +++ b/src/types/openapi/openapi-bots.ts @@ -77,6 +77,7 @@ export type components = { /** Format: int64 */ "read-privacy": number; "has-translation-providers": boolean; + "has-translation-task-providers": boolean; /** Format: int64 */ "typing-privacy": number; /** Format: int64 */ diff --git a/src/types/openapi/openapi-federation.ts b/src/types/openapi/openapi-federation.ts index ad4031ec8ce..469be07a639 100644 --- a/src/types/openapi/openapi-federation.ts +++ b/src/types/openapi/openapi-federation.ts @@ -185,6 +185,7 @@ export type components = { /** Format: int64 */ "read-privacy": number; "has-translation-providers": boolean; + "has-translation-task-providers": boolean; /** Format: int64 */ "typing-privacy": number; /** Format: int64 */ diff --git a/src/types/openapi/openapi-full.ts b/src/types/openapi/openapi-full.ts index f4e658a405c..efa8174dadf 100644 --- a/src/types/openapi/openapi-full.ts +++ b/src/types/openapi/openapi-full.ts @@ -2002,6 +2002,7 @@ export type components = { /** Format: int64 */ "read-privacy": number; "has-translation-providers": boolean; + "has-translation-task-providers": boolean; /** Format: int64 */ "typing-privacy": number; /** Format: int64 */ diff --git a/src/types/openapi/openapi.ts b/src/types/openapi/openapi.ts index 6a208fd0f90..6e51763dd66 100644 --- a/src/types/openapi/openapi.ts +++ b/src/types/openapi/openapi.ts @@ -1502,6 +1502,7 @@ export type components = { /** Format: int64 */ "read-privacy": number; "has-translation-providers": boolean; + "has-translation-task-providers": boolean; /** Format: int64 */ "typing-privacy": number; /** Format: int64 */ diff --git a/tests/php/CapabilitiesTest.php b/tests/php/CapabilitiesTest.php index 2669e433e88..ba1d0d57d21 100644 --- a/tests/php/CapabilitiesTest.php +++ b/tests/php/CapabilitiesTest.php @@ -24,6 +24,7 @@ use OCP\TaskProcessing\IManager as ITaskProcessingManager; use OCP\TaskProcessing\TaskTypes\TextToTextFormalization; use OCP\TaskProcessing\TaskTypes\TextToTextSummary; +use OCP\TaskProcessing\TaskTypes\TextToTextTranslate; use OCP\Translation\ITranslationManager; use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; @@ -147,6 +148,7 @@ public function testGetCapabilitiesGuest(): void { 'max-length' => 32000, 'read-privacy' => 0, 'has-translation-providers' => false, + 'has-translation-task-providers' => false, 'typing-privacy' => 0, 'summary-threshold' => 100, ], @@ -280,6 +282,7 @@ public function testGetCapabilitiesUserAllowed(bool $isNotAllowed, bool $canCrea 'max-length' => 32000, 'read-privacy' => $readPrivacy, 'has-translation-providers' => false, + 'has-translation-task-providers' => false, 'typing-privacy' => 0, 'summary-threshold' => 100, ], @@ -404,6 +407,16 @@ public function testCapabilitiesTranslations(): void { $this->assertEquals(true, $data['spreed']['config']['chat']['has-translation-providers']); } + public function testCapabilitiesTranslationsTaskProviders(): void { + $capabilities = $this->getCapabilities(); + + $this->taskProcessingManager->method('getAvailableTaskTypes') + ->willReturn([TextToTextTranslate::ID => true]); + + $data = json_decode(json_encode($capabilities->getCapabilities(), JSON_THROW_ON_ERROR), true); + $this->assertEquals(true, $data['spreed']['config']['chat']['has-translation-task-providers']); + } + public function testSummaryTaskProviders(): void { $capabilities = $this->getCapabilities();