diff options
Diffstat (limited to 'lib/public/TaskProcessing')
30 files changed, 1361 insertions, 27 deletions
diff --git a/lib/public/TaskProcessing/EShapeType.php b/lib/public/TaskProcessing/EShapeType.php index d66de6e01a8..f6cfab6b38f 100644 --- a/lib/public/TaskProcessing/EShapeType.php +++ b/lib/public/TaskProcessing/EShapeType.php @@ -23,6 +23,7 @@ enum EShapeType: int { case Audio = 3; case Video = 4; case File = 5; + case Enum = 6; case ListOfNumbers = 10; case ListOfTexts = 11; case ListOfImages = 12; @@ -32,11 +33,33 @@ enum EShapeType: int { /** * @param mixed $value + * @param ShapeEnumValue[] $enumValues + * @return void + * @throws ValidationException + * @since 30.0.0 + */ + public function validateEnum(mixed $value, array $enumValues): void { + if ($this !== EShapeType::Enum) { + throw new ValidationException('Provider provided enum values for non-enum slot'); + } + foreach ($enumValues as $enumValue) { + if ($value === $enumValue->getValue()) { + return; + } + } + throw new ValidationException('Wrong value given for Enum slot. Got "' . $value . '", but expected one of the provided enum values: "' . implode('", "', array_map(fn ($enumValue) => $enumValue->getValue(), $enumValues)) . '"'); + } + + /** + * @param mixed $value * @return void * @throws ValidationException * @since 30.0.0 */ private function validateNonFileType(mixed $value): void { + if ($this === EShapeType::Enum && !is_string($value)) { + throw new ValidationException('Non-text item provided for Enum slot'); + } if ($this === EShapeType::Text && !is_string($value)) { throw new ValidationException('Non-text item provided for Text slot'); } @@ -89,7 +112,7 @@ enum EShapeType: int { * @throws ValidationException * @since 30.0.0 */ - public function validateOutput(mixed $value) { + public function validateOutputWithFileData(mixed $value): void { $this->validateNonFileType($value); if ($this === EShapeType::Image && !is_string($value)) { throw new ValidationException('Non-image item provided for Image slot'); @@ -118,6 +141,40 @@ enum EShapeType: int { } /** + * @param mixed $value + * @return void + * @throws ValidationException + * @since 30.0.0 + */ + public function validateOutputWithFileIds(mixed $value): void { + $this->validateNonFileType($value); + if ($this === EShapeType::Image && !is_numeric($value)) { + throw new ValidationException('Non-image item provided for Image slot'); + } + if ($this === EShapeType::ListOfImages && (!is_array($value) || count(array_filter($value, fn ($item) => !is_numeric($item))) > 0)) { + throw new ValidationException('Non-image list item provided for ListOfImages slot'); + } + if ($this === EShapeType::Audio && !is_numeric($value)) { + throw new ValidationException('Non-audio item provided for Audio slot'); + } + if ($this === EShapeType::ListOfAudios && (!is_array($value) || count(array_filter($value, fn ($item) => !is_numeric($item))) > 0)) { + throw new ValidationException('Non-audio list item provided for ListOfAudio slot'); + } + if ($this === EShapeType::Video && !is_numeric($value)) { + throw new ValidationException('Non-video item provided for Video slot'); + } + if ($this === EShapeType::ListOfVideos && (!is_array($value) || count(array_filter($value, fn ($item) => !is_numeric($item))) > 0)) { + throw new ValidationException('Non-video list item provided for ListOfTexts slot'); + } + if ($this === EShapeType::File && !is_numeric($value)) { + throw new ValidationException('Non-file item provided for File slot'); + } + if ($this === EShapeType::ListOfFiles && (!is_array($value) || count(array_filter($value, fn ($item) => !is_numeric($item))) > 0)) { + throw new ValidationException('Non-audio list item provided for ListOfFiles slot'); + } + } + + /** * @param EShapeType $type * @return EShapeType * @since 30.0.0 @@ -125,4 +182,13 @@ enum EShapeType: int { public static function getScalarType(EShapeType $type): EShapeType { return EShapeType::from($type->value % 10); } + + /** + * @param EShapeType $type + * @return bool + * @since 30.0.0 + */ + public static function isFileType(EShapeType $type): bool { + return in_array(EShapeType::getScalarType($type), [EShapeType::File, EShapeType::Image, EShapeType::Audio, EShapeType::Video], true); + } } diff --git a/lib/public/TaskProcessing/Events/AbstractTaskProcessingEvent.php b/lib/public/TaskProcessing/Events/AbstractTaskProcessingEvent.php index 84dbb8915f8..55f33327e9f 100644 --- a/lib/public/TaskProcessing/Events/AbstractTaskProcessingEvent.php +++ b/lib/public/TaskProcessing/Events/AbstractTaskProcessingEvent.php @@ -19,7 +19,7 @@ abstract class AbstractTaskProcessingEvent extends Event { * @since 30.0.0 */ public function __construct( - private readonly Task $task + private readonly Task $task, ) { parent::__construct(); } diff --git a/lib/public/TaskProcessing/Events/GetTaskProcessingProvidersEvent.php b/lib/public/TaskProcessing/Events/GetTaskProcessingProvidersEvent.php new file mode 100644 index 00000000000..10c94d20406 --- /dev/null +++ b/lib/public/TaskProcessing/Events/GetTaskProcessingProvidersEvent.php @@ -0,0 +1,68 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCP\TaskProcessing\Events; + +use OCP\EventDispatcher\Event; +use OCP\TaskProcessing\IProvider; +use OCP\TaskProcessing\ITaskType; + +/** + * Event dispatched by the server to collect Task Processing Providers + * and custom Task Types from listeners (like AppAPI). + * + * Listeners should add their providers and task types using the + * addProvider() and addTaskType() methods. + * + * @since 32.0.0 + */ +class GetTaskProcessingProvidersEvent extends Event { + /** @var IProvider[] */ + private array $providers = []; + + /** @var ITaskType[] */ + private array $taskTypes = []; + + /** + * Add a Task Processing Provider. + * + * @param IProvider $provider The provider instance to add. + * @since 32.0.0 + */ + public function addProvider(IProvider $provider): void { + $this->providers[] = $provider; + } + + /** + * Get all collected Task Processing Providers. + * + * @return IProvider[] + * @since 32.0.0 + */ + public function getProviders(): array { + return $this->providers; + } + + /** + * Add a custom Task Processing Task Type. + * + * @param ITaskType $taskType The task type instance to add. + * @since 32.0.0 + */ + public function addTaskType(ITaskType $taskType): void { + $this->taskTypes[] = $taskType; + } + + /** + * Get all collected custom Task Processing Task Types. + * + * @return ITaskType[] + * @since 32.0.0 + */ + public function getTaskTypes(): array { + return $this->taskTypes; + } +} diff --git a/lib/public/TaskProcessing/IManager.php b/lib/public/TaskProcessing/IManager.php index 599bd244d8a..731250d7aa1 100644 --- a/lib/public/TaskProcessing/IManager.php +++ b/lib/public/TaskProcessing/IManager.php @@ -26,6 +26,7 @@ use OCP\TaskProcessing\Exception\ValidationException; * @since 30.0.0 */ interface IManager { + /** * @since 30.0.0 */ @@ -38,18 +39,22 @@ interface IManager { public function getProviders(): array; /** - * @param string $taskType + * @param string $taskTypeId * @return IProvider * @throws Exception * @since 30.0.0 */ - public function getPreferredProvider(string $taskType); + public function getPreferredProvider(string $taskTypeId); /** - * @return array<string,array{name: string, description: string, inputShape: ShapeDescriptor[], optionalInputShape: ShapeDescriptor[], outputShape: ShapeDescriptor[], optionalOutputShape: ShapeDescriptor[]}> + * @param bool $showDisabled if false, disabled task types will be filtered + * @param ?string $userId to check if the user is a guest. Will be obtained from session if left to default + * @return array<string, array{name: string, description: string, inputShape: ShapeDescriptor[], inputShapeEnumValues: ShapeEnumValue[][], inputShapeDefaults: array<array-key, numeric|string>, optionalInputShape: ShapeDescriptor[], optionalInputShapeEnumValues: ShapeEnumValue[][], optionalInputShapeDefaults: array<array-key, numeric|string>, outputShape: ShapeDescriptor[], outputShapeEnumValues: ShapeEnumValue[][], optionalOutputShape: ShapeDescriptor[], optionalOutputShapeEnumValues: ShapeEnumValue[][]}> * @since 30.0.0 + * @since 31.0.0 Added the `showDisabled` argument. + * @since 31.0.7 Added the `userId` argument */ - public function getAvailableTaskTypes(): array; + public function getAvailableTaskTypes(bool $showDisabled = false, ?string $userId = null): array; /** * @param Task $task The task to run @@ -62,6 +67,33 @@ interface IManager { public function scheduleTask(Task $task): void; /** + * Run the task and return the finished task + * + * @param Task $task The task to run + * @return Task The result task + * @throws PreConditionNotMetException If no or not the requested provider was registered but this method was still called + * @throws ValidationException the given task input didn't pass validation against the task type's input shape and/or the providers optional input shape specs + * @throws Exception storing the task in the database failed + * @throws UnauthorizedException the user scheduling the task does not have access to the files used in the input + * @since 30.0.0 + */ + public function runTask(Task $task): Task; + + /** + * Process task with a synchronous provider + * + * Prepare task input data and run the process method of the provider + * This should only be used by OC\TaskProcessing\SynchronousBackgroundJob::run() and OCP\TaskProcessing\IManager::runTask() + * + * @param Task $task + * @param ISynchronousProvider $provider + * @return bool True if the task has run successfully + * @throws Exception + * @since 30.0.0 + */ + public function processTask(Task $task, ISynchronousProvider $provider): bool; + + /** * Delete a task that has been scheduled before * * @param Task $task The task to delete @@ -91,11 +123,12 @@ interface IManager { * @param int $id The id of the task * @param string|null $error * @param array|null $result + * @param bool $isUsingFileIds * @throws Exception If the query failed * @throws NotFoundException If the task could not be found * @since 30.0.0 */ - public function setTaskResult(int $id, ?string $error, ?array $result): void; + public function setTaskResult(int $id, ?string $error, ?array $result, bool $isUsingFileIds = false): void; /** * @param int $id @@ -140,6 +173,24 @@ interface IManager { public function getUserTasks(?string $userId, ?string $taskTypeId = null, ?string $customId = null): array; /** + * @param string|null $userId The user id that scheduled the task + * @param string|null $taskTypeId The task type id to filter by + * @param string|null $appId The app ID of the app that submitted the task + * @param string|null $customId The custom task ID + * @param int|null $status The task status + * @param int|null $scheduleAfter Minimum schedule time filter + * @param int|null $endedBefore Maximum ending time filter + * @return list<Task> + * @throws Exception If the query failed + * @throws NotFoundException If the task could not be found + * @since 30.0.0 + */ + public function getTasks( + ?string $userId, ?string $taskTypeId = null, ?string $appId = null, ?string $customId = null, + ?int $status = null, ?int $scheduleAfter = null, ?int $endedBefore = null, + ): array; + + /** * @param string|null $userId * @param string $appId * @param string|null $customId @@ -152,7 +203,7 @@ interface IManager { /** * Prepare the task's input data, so it can be processed by the provider - * ie. this replaces file ids with base64 data + * ie. this replaces file ids with File objects * * @param Task $task * @return array<array-key, list<numeric|string|File>|numeric|string|File> @@ -160,6 +211,7 @@ interface IManager { * @throws GenericFileException * @throws LockedException * @throws ValidationException + * @throws UnauthorizedException * @since 30.0.0 */ public function prepareInputData(Task $task): array; @@ -182,4 +234,14 @@ interface IManager { * @since 30.0.0 */ public function setTaskStatus(Task $task, int $status): void; + + /** + * Extract all input and output file IDs from a task + * + * @param Task $task + * @return list<int> + * @throws NotFoundException + * @since 32.0.0 + */ + public function extractFileIdsFromTask(Task $task): array; } diff --git a/lib/public/TaskProcessing/IProvider.php b/lib/public/TaskProcessing/IProvider.php index 68a708ca834..a4e752216c7 100644 --- a/lib/public/TaskProcessing/IProvider.php +++ b/lib/public/TaskProcessing/IProvider.php @@ -58,4 +58,52 @@ interface IProvider { * @psalm-return ShapeDescriptor[] */ public function getOptionalOutputShape(): array; + + /** + * Returns the option list for each input shape ENUM slot + * + * @since 30.0.0 + * @psalm-return ShapeEnumValue[][] + */ + public function getInputShapeEnumValues(): array; + + /** + * Returns the default values for input shape slots + * + * @since 30.0.0 + * @psalm-return array<array-key, string|numeric> + */ + public function getInputShapeDefaults(): array; + + /** + * Returns the option list for each optional input shape ENUM slot + * + * @since 30.0.0 + * @psalm-return ShapeEnumValue[][] + */ + public function getOptionalInputShapeEnumValues(): array; + + /** + * Returns the default values for optional input shape slots + * + * @since 30.0.0 + * @psalm-return array<array-key, string|numeric> + */ + public function getOptionalInputShapeDefaults(): array; + + /** + * Returns the option list for each output shape ENUM slot + * + * @since 30.0.0 + * @psalm-return ShapeEnumValue[][] + */ + public function getOutputShapeEnumValues(): array; + + /** + * Returns the option list for each optional output shape ENUM slot + * + * @since 30.0.0 + * @psalm-return ShapeEnumValue[][] + */ + public function getOptionalOutputShapeEnumValues(): array; } diff --git a/lib/public/TaskProcessing/ISynchronousProvider.php b/lib/public/TaskProcessing/ISynchronousProvider.php index 8cd504af189..d7e42684df5 100644 --- a/lib/public/TaskProcessing/ISynchronousProvider.php +++ b/lib/public/TaskProcessing/ISynchronousProvider.php @@ -28,7 +28,7 @@ interface ISynchronousProvider extends IProvider { * @param callable(float):bool $reportProgress Report the task progress. If this returns false, that means the task was cancelled and processing should be stopped. * @psalm-return array<string, list<numeric|string>|numeric|string> * @throws ProcessingException - *@since 30.0.0 + * @since 30.0.0 */ public function process(?string $userId, array $input, callable $reportProgress): array; } diff --git a/lib/public/TaskProcessing/ShapeDescriptor.php b/lib/public/TaskProcessing/ShapeDescriptor.php index 5759b260865..19e57c8a91d 100644 --- a/lib/public/TaskProcessing/ShapeDescriptor.php +++ b/lib/public/TaskProcessing/ShapeDescriptor.php @@ -49,11 +49,11 @@ class ShapeDescriptor implements \JsonSerializable { } /** - * @return array{name: string, description: string, type: "Number"|"Text"|"Audio"|"Image"|"Video"|"File"|"ListOfNumbers"|"ListOfTexts"|"ListOfImages"|"ListOfAudios"|"ListOfVideos"|"ListOfFiles"} + * @return array{name: string, description: string, type: "Number"|"Text"|"Audio"|"Image"|"Video"|"File"|"Enum"|"ListOfNumbers"|"ListOfTexts"|"ListOfImages"|"ListOfAudios"|"ListOfVideos"|"ListOfFiles"} * @since 30.0.0 */ public function jsonSerialize(): array { - /** @var "Number"|"Text"|"Audio"|"Image"|"Video"|"File"|"ListOfNumbers"|"ListOfTexts"|"ListOfImages"|"ListOfAudios"|"ListOfVideos"|"ListOfFiles" $type */ + /** @var "Number"|"Text"|"Audio"|"Image"|"Video"|"File"|"Enum"|"ListOfNumbers"|"ListOfTexts"|"ListOfImages"|"ListOfAudios"|"ListOfVideos"|"ListOfFiles" $type */ $type = $this->getShapeType()->name; return [ 'name' => $this->getName(), diff --git a/lib/public/TaskProcessing/ShapeEnumValue.php b/lib/public/TaskProcessing/ShapeEnumValue.php new file mode 100644 index 00000000000..bc500524304 --- /dev/null +++ b/lib/public/TaskProcessing/ShapeEnumValue.php @@ -0,0 +1,51 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCP\TaskProcessing; + +/** + * Data object for input output shape enum slot value + * @since 30.0.0 + */ +class ShapeEnumValue implements \JsonSerializable { + /** + * @param string $name + * @param string $value + * @since 30.0.0 + */ + public function __construct( + private string $name, + private string $value, + ) { + } + + /** + * @return string + * @since 30.0.0 + */ + public function getName(): string { + return $this->name; + } + + /** + * @return string + * @since 30.0.0 + */ + public function getValue(): string { + return $this->value; + } + + /** + * @return array{name: string, value: string} + * @since 30.0.0 + */ + public function jsonSerialize(): array { + return [ + 'name' => $this->getName(), + 'value' => $this->getValue(), + ]; + } +} diff --git a/lib/public/TaskProcessing/Task.php b/lib/public/TaskProcessing/Task.php index 2ec367e4a0a..06dc84d59ff 100644 --- a/lib/public/TaskProcessing/Task.php +++ b/lib/public/TaskProcessing/Task.php @@ -30,6 +30,9 @@ final class Task implements \JsonSerializable { protected int $lastUpdated; + protected ?string $webhookUri = null; + protected ?string $webhookMethod = null; + /** * @since 30.0.0 */ @@ -60,6 +63,11 @@ final class Task implements \JsonSerializable { */ protected int $status = self::STATUS_UNKNOWN; + protected ?int $scheduledAt = null; + protected ?int $startedAt = null; + protected ?int $endedAt = null; + protected bool $allowCleanup = true; + /** * @param string $taskTypeId * @param array<string,list<numeric|string>|numeric|string> $input @@ -198,12 +206,76 @@ final class Task implements \JsonSerializable { } /** - * @psalm-return array{id: ?int, lastUpdated: int, type: string, status: 'STATUS_CANCELLED'|'STATUS_FAILED'|'STATUS_SUCCESSFUL'|'STATUS_RUNNING'|'STATUS_SCHEDULED'|'STATUS_UNKNOWN', userId: ?string, appId: string, input: array<array-key, list<numeric|string>|numeric|string>, output: ?array<array-key, list<numeric|string>|numeric|string>, customId: ?string, completionExpectedAt: ?int, progress: ?float} + * @return int|null + * @since 30.0.0 + */ + final public function getScheduledAt(): ?int { + return $this->scheduledAt; + } + + /** + * @param int|null $scheduledAt + * @since 30.0.0 + */ + final public function setScheduledAt(?int $scheduledAt): void { + $this->scheduledAt = $scheduledAt; + } + + /** + * @return int|null + * @since 30.0.0 + */ + final public function getStartedAt(): ?int { + return $this->startedAt; + } + + /** + * @param int|null $startedAt + * @since 30.0.0 + */ + final public function setStartedAt(?int $startedAt): void { + $this->startedAt = $startedAt; + } + + /** + * @return int|null + * @since 30.0.0 + */ + final public function getEndedAt(): ?int { + return $this->endedAt; + } + + /** + * @param int|null $endedAt + * @since 30.0.0 + */ + final public function setEndedAt(?int $endedAt): void { + $this->endedAt = $endedAt; + } + + /** + * @return bool + * @since 32.0.0 + */ + final public function getAllowCleanup(): bool { + return $this->allowCleanup; + } + + /** + * @param bool $allowCleanup + * @since 32.0.0 + */ + final public function setAllowCleanup(bool $allowCleanup): void { + $this->allowCleanup = $allowCleanup; + } + + /** + * @psalm-return array{id: int, lastUpdated: int, type: string, status: 'STATUS_CANCELLED'|'STATUS_FAILED'|'STATUS_SUCCESSFUL'|'STATUS_RUNNING'|'STATUS_SCHEDULED'|'STATUS_UNKNOWN', userId: ?string, appId: string, input: array<string, list<numeric|string>|numeric|string>, output: ?array<string, list<numeric|string>|numeric|string>, customId: ?string, completionExpectedAt: ?int, progress: ?float, scheduledAt: ?int, startedAt: ?int, endedAt: ?int, allowCleanup: bool} * @since 30.0.0 */ final public function jsonSerialize(): array { return [ - 'id' => $this->getId(), + 'id' => (int)$this->getId(), 'type' => $this->getTaskTypeId(), 'lastUpdated' => $this->getLastUpdated(), 'status' => self::statusToString($this->getStatus()), @@ -214,6 +286,10 @@ final class Task implements \JsonSerializable { 'customId' => $this->getCustomId(), 'completionExpectedAt' => $this->getCompletionExpectedAt()?->getTimestamp(), 'progress' => $this->getProgress(), + 'scheduledAt' => $this->getScheduledAt(), + 'startedAt' => $this->getStartedAt(), + 'endedAt' => $this->getEndedAt(), + 'allowCleanup' => $this->getAllowCleanup(), ]; } @@ -265,6 +341,40 @@ final class Task implements \JsonSerializable { } /** + * @return null|string + * @since 30.0.0 + */ + final public function getWebhookUri(): ?string { + return $this->webhookUri; + } + + /** + * @param string|null $webhookUri + * @return void + * @since 30.0.0 + */ + final public function setWebhookUri(?string $webhookUri): void { + $this->webhookUri = $webhookUri; + } + + /** + * @return null|string + * @since 30.0.0 + */ + final public function getWebhookMethod(): ?string { + return $this->webhookMethod; + } + + /** + * @param string|null $webhookMethod + * @return void + * @since 30.0.0 + */ + final public function setWebhookMethod(?string $webhookMethod): void { + $this->webhookMethod = $webhookMethod; + } + + /** * @param int $status * @return 'STATUS_CANCELLED'|'STATUS_FAILED'|'STATUS_SUCCESSFUL'|'STATUS_RUNNING'|'STATUS_SCHEDULED'|'STATUS_UNKNOWN' * @since 30.0.0 diff --git a/lib/public/TaskProcessing/TaskTypes/AnalyzeImages.php b/lib/public/TaskProcessing/TaskTypes/AnalyzeImages.php new file mode 100644 index 00000000000..462016c5c19 --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/AnalyzeImages.php @@ -0,0 +1,96 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\TaskProcessing\TaskTypes; + +use OCP\IL10N; +use OCP\L10N\IFactory; +use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\ITaskType; +use OCP\TaskProcessing\ShapeDescriptor; + +/** + * This is the task processing task type to ask a question about the images + * @since 32.0.0 + */ +class AnalyzeImages implements ITaskType { + /** + * @since 32.0.0 + */ + public const ID = 'core:analyze-images'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 32.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('lib'); + } + + /** + * @inheritDoc + * @since 32.0.0 + */ + public function getName(): string { + return $this->l->t('Analyze images'); + } + + /** + * @inheritDoc + * @since 32.0.0 + */ + public function getDescription(): string { + return $this->l->t('Ask a question about the given images.'); + } + + /** + * @return string + * @since 32.0.0 + */ + public function getId(): string { + return self::ID; + } + + /** + * @return ShapeDescriptor[] + * @since 32.0.0 + */ + public function getInputShape(): array { + return [ + 'images' => new ShapeDescriptor( + $this->l->t('Images'), + $this->l->t('Images to ask a question about'), + EShapeType::ListOfImages, + ), + 'input' => new ShapeDescriptor( + $this->l->t('Question'), + $this->l->t('What to ask about the images.'), + EShapeType::Text, + ), + ]; + } + + /** + * @return ShapeDescriptor[] + * @since 32.0.0 + */ + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Generated response'), + $this->l->t('The answer to the question'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/AudioToAudioChat.php b/lib/public/TaskProcessing/TaskTypes/AudioToAudioChat.php new file mode 100644 index 00000000000..c862437e86b --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/AudioToAudioChat.php @@ -0,0 +1,112 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\TaskProcessing\TaskTypes; + +use OCP\IL10N; +use OCP\L10N\IFactory; +use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\ITaskType; +use OCP\TaskProcessing\ShapeDescriptor; + +/** + * This is the task processing task type for audio chat + * @since 32.0.0 + */ +class AudioToAudioChat implements ITaskType { + /** + * @since 32.0.0 + */ + public const ID = 'core:audio2audio:chat'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 32.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('lib'); + } + + + /** + * @inheritDoc + * @since 32.0.0 + */ + public function getName(): string { + return $this->l->t('Audio chat'); + } + + /** + * @inheritDoc + * @since 32.0.0 + */ + public function getDescription(): string { + return $this->l->t('Voice chat with the assistant'); + } + + /** + * @return string + * @since 32.0.0 + */ + public function getId(): string { + return self::ID; + } + + /** + * @return ShapeDescriptor[] + * @since 32.0.0 + */ + public function getInputShape(): array { + return [ + 'system_prompt' => new ShapeDescriptor( + $this->l->t('System prompt'), + $this->l->t('Define rules and assumptions that the assistant should follow during the conversation.'), + EShapeType::Text + ), + 'input' => new ShapeDescriptor( + $this->l->t('Chat voice message'), + $this->l->t('Describe a task that you want the assistant to do or ask a question.'), + EShapeType::Audio + ), + 'history' => new ShapeDescriptor( + $this->l->t('Chat history'), + $this->l->t('The history of chat messages before the current message, starting with a message by the user.'), + EShapeType::ListOfTexts + ) + ]; + } + + /** + * @return ShapeDescriptor[] + * @since 32.0.0 + */ + public function getOutputShape(): array { + return [ + 'input_transcript' => new ShapeDescriptor( + $this->l->t('Input transcript'), + $this->l->t('Transcription of the audio input'), + EShapeType::Text, + ), + 'output' => new ShapeDescriptor( + $this->l->t('Response voice message'), + $this->l->t('The generated voice response as part of the conversation'), + EShapeType::Audio + ), + 'output_transcript' => new ShapeDescriptor( + $this->l->t('Output transcript'), + $this->l->t('Transcription of the audio output'), + EShapeType::Text, + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/AudioToText.php b/lib/public/TaskProcessing/TaskTypes/AudioToText.php index 3f23d00d41b..1982d4c9d28 100644 --- a/lib/public/TaskProcessing/TaskTypes/AudioToText.php +++ b/lib/public/TaskProcessing/TaskTypes/AudioToText.php @@ -34,7 +34,7 @@ class AudioToText implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/ContextAgentAudioInteraction.php b/lib/public/TaskProcessing/TaskTypes/ContextAgentAudioInteraction.php new file mode 100644 index 00000000000..6cd358040b7 --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/ContextAgentAudioInteraction.php @@ -0,0 +1,118 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\TaskProcessing\TaskTypes; + +use OCP\IL10N; +use OCP\L10N\IFactory; +use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\ITaskType; +use OCP\TaskProcessing\ShapeDescriptor; + +/** + * This is the task processing task type for Context Agent interaction + * @since 32.0.0 + */ +class ContextAgentAudioInteraction implements ITaskType { + public const ID = 'core:contextagent:audio-interaction'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 32.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('lib'); + } + + /** + * @inheritDoc + * @since 32.0.0 + */ + public function getName(): string { + return 'ContextAgent audio'; // We do not translate this + } + + /** + * @inheritDoc + * @since 32.0.0 + */ + public function getDescription(): string { + return $this->l->t('Chat by voice with an agent'); + } + + /** + * @return string + * @since 32.0.0 + */ + public function getId(): string { + return self::ID; + } + + /** + * @return ShapeDescriptor[] + * @since 32.0.0 + */ + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Chat voice message'), + $this->l->t('Describe a task that you want the agent to do or ask a question.'), + EShapeType::Audio + ), + 'confirmation' => new ShapeDescriptor( + $this->l->t('Confirmation'), + $this->l->t('Whether to confirm previously requested actions: 0 for denial and 1 for confirmation.'), + EShapeType::Number + ), + 'conversation_token' => new ShapeDescriptor( + $this->l->t('Conversation token'), + $this->l->t('A token representing the conversation.'), + EShapeType::Text + ), + ]; + } + + /** + * @return ShapeDescriptor[] + * @since 32.0.0 + */ + public function getOutputShape(): array { + return [ + 'input_transcript' => new ShapeDescriptor( + $this->l->t('Input transcript'), + $this->l->t('Transcription of the audio input'), + EShapeType::Text, + ), + 'output' => new ShapeDescriptor( + $this->l->t('Response voice message'), + $this->l->t('The generated voice response as part of the conversation'), + EShapeType::Audio + ), + 'output_transcript' => new ShapeDescriptor( + $this->l->t('Output transcript'), + $this->l->t('Transcription of the audio output'), + EShapeType::Text, + ), + 'conversation_token' => new ShapeDescriptor( + $this->l->t('The new conversation token'), + $this->l->t('Send this along with the next interaction.'), + EShapeType::Text + ), + 'actions' => new ShapeDescriptor( + $this->l->t('Requested actions by the agent'), + $this->l->t('Actions that the agent would like to carry out in JSON format.'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/ContextAgentInteraction.php b/lib/public/TaskProcessing/TaskTypes/ContextAgentInteraction.php new file mode 100644 index 00000000000..cd08d6f4e3d --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/ContextAgentInteraction.php @@ -0,0 +1,108 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\TaskProcessing\TaskTypes; + +use OCP\IL10N; +use OCP\L10N\IFactory; +use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\ITaskType; +use OCP\TaskProcessing\ShapeDescriptor; + +/** + * This is the task processing task type for Context Agent interaction + * @since 31.0.0 + */ +class ContextAgentInteraction implements ITaskType { + public const ID = 'core:contextagent:interaction'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 31.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('lib'); + } + + /** + * @inheritDoc + * @since 31.0.0 + */ + public function getName(): string { + return 'ContextAgent'; // We do not translate this + } + + /** + * @inheritDoc + * @since 31.0.0 + */ + public function getDescription(): string { + return $this->l->t('Chat with an agent'); + } + + /** + * @return string + * @since 31.0.0 + */ + public function getId(): string { + return self::ID; + } + + /** + * @return ShapeDescriptor[] + * @since 31.0.0 + */ + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Chat message'), + $this->l->t('A chat message to send to the agent.'), + EShapeType::Text + ), + 'confirmation' => new ShapeDescriptor( + $this->l->t('Confirmation'), + $this->l->t('Whether to confirm previously requested actions: 0 for denial and 1 for confirmation.'), + EShapeType::Number + ), + 'conversation_token' => new ShapeDescriptor( + $this->l->t('Conversation token'), + $this->l->t('A token representing the conversation.'), + EShapeType::Text + ), + ]; + } + + /** + * @return ShapeDescriptor[] + * @since 31.0.0 + */ + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Generated response'), + $this->l->t('The response from the chat model.'), + EShapeType::Text + ), + 'conversation_token' => new ShapeDescriptor( + $this->l->t('The new conversation token'), + $this->l->t('Send this along with the next interaction.'), + EShapeType::Text + ), + 'actions' => new ShapeDescriptor( + $this->l->t('Requested actions by the agent'), + $this->l->t('Actions that the agent would like to carry out in JSON format.'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/ContextWrite.php b/lib/public/TaskProcessing/TaskTypes/ContextWrite.php index 08a8fc5b301..fd5c6a8f58b 100644 --- a/lib/public/TaskProcessing/TaskTypes/ContextWrite.php +++ b/lib/public/TaskProcessing/TaskTypes/ContextWrite.php @@ -34,7 +34,7 @@ class ContextWrite implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } @@ -43,7 +43,7 @@ class ContextWrite implements ITaskType { * @since 30.0.0 */ public function getName(): string { - return $this->l->t('ContextWrite'); + return $this->l->t('Context write'); } /** diff --git a/lib/public/TaskProcessing/TaskTypes/GenerateEmoji.php b/lib/public/TaskProcessing/TaskTypes/GenerateEmoji.php index 89ddfa58072..2cb22b3b455 100644 --- a/lib/public/TaskProcessing/TaskTypes/GenerateEmoji.php +++ b/lib/public/TaskProcessing/TaskTypes/GenerateEmoji.php @@ -34,7 +34,7 @@ class GenerateEmoji implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/TextToImage.php b/lib/public/TaskProcessing/TaskTypes/TextToImage.php index a4b8070e8bb..ed956d244a1 100644 --- a/lib/public/TaskProcessing/TaskTypes/TextToImage.php +++ b/lib/public/TaskProcessing/TaskTypes/TextToImage.php @@ -34,7 +34,7 @@ class TextToImage implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/TextToSpeech.php b/lib/public/TaskProcessing/TaskTypes/TextToSpeech.php new file mode 100644 index 00000000000..ce35be32a6f --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToSpeech.php @@ -0,0 +1,92 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\TaskProcessing\TaskTypes; + +use OCP\IL10N; +use OCP\L10N\IFactory; +use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\ITaskType; +use OCP\TaskProcessing\ShapeDescriptor; + +/** + * This is the task processing task type for speech generation + * @since 32.0.0 + */ +class TextToSpeech implements ITaskType { + /** + * @since 32.0.0 + */ + public const ID = 'core:text2speech'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 32.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('lib'); + } + + + /** + * @inheritDoc + * @since 32.0.0 + */ + public function getName(): string { + return $this->l->t('Generate speech'); + } + + /** + * @inheritDoc + * @since 32.0.0 + */ + public function getDescription(): string { + return $this->l->t('Generate speech from a transcript'); + } + + /** + * @return string + * @since 32.0.0 + */ + public function getId(): string { + return self::ID; + } + + /** + * @return ShapeDescriptor[] + * @since 32.0.0 + */ + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Prompt'), + $this->l->t('Write transcript that you want the assistant to generate speech from'), + EShapeType::Text + ), + ]; + } + + /** + * @return ShapeDescriptor[] + * @since 32.0.0 + */ + public function getOutputShape(): array { + return [ + 'speech' => new ShapeDescriptor( + $this->l->t('Output speech'), + $this->l->t('The generated speech'), + EShapeType::Audio + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/TextToText.php b/lib/public/TaskProcessing/TaskTypes/TextToText.php index 7ac7f2eca05..c39d435688a 100644 --- a/lib/public/TaskProcessing/TaskTypes/TextToText.php +++ b/lib/public/TaskProcessing/TaskTypes/TextToText.php @@ -34,7 +34,7 @@ class TextToText implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } @@ -51,7 +51,7 @@ class TextToText implements ITaskType { * @since 30.0.0 */ public function getDescription(): string { - return $this->l->t('Runs an arbitrary prompt through a language model that retuns a reply'); + return $this->l->t('Runs an arbitrary prompt through a language model that returns a reply'); } /** diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextChangeTone.php b/lib/public/TaskProcessing/TaskTypes/TextToTextChangeTone.php new file mode 100644 index 00000000000..0ea4575a187 --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextChangeTone.php @@ -0,0 +1,93 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\TaskProcessing\TaskTypes; + +use OCP\IL10N; +use OCP\L10N\IFactory; +use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\ITaskType; +use OCP\TaskProcessing\ShapeDescriptor; + +/** + * This is the task processing task type for text reformulation + * @since 31.0.0 + */ +class TextToTextChangeTone implements ITaskType { + public const ID = 'core:text2text:changetone'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 31.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('lib'); + } + + /** + * @inheritDoc + * @since 31.0.0 + */ + public function getName(): string { + return $this->l->t('Change Tone'); + } + + /** + * @inheritDoc + * @since 31.0.0 + */ + public function getDescription(): string { + return $this->l->t('Change the tone of a piece of text.'); + } + + /** + * @return string + * @since 31.0.0 + */ + public function getId(): string { + return self::ID; + } + + /** + * @return ShapeDescriptor[] + * @since 31.0.0 + */ + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Input text'), + $this->l->t('Write a text that you want the assistant to rewrite in another tone.'), + EShapeType::Text, + ), + 'tone' => new ShapeDescriptor( + $this->l->t('Desired tone'), + $this->l->t('In which tone should your text be rewritten?'), + EShapeType::Enum, + ), + ]; + } + + /** + * @return ShapeDescriptor[] + * @since 31.0.0 + */ + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Generated response'), + $this->l->t('The rewritten text in the desired tone, written by the assistant:'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextChat.php b/lib/public/TaskProcessing/TaskTypes/TextToTextChat.php index e9169f64837..9cf1e7ef3ce 100644 --- a/lib/public/TaskProcessing/TaskTypes/TextToTextChat.php +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextChat.php @@ -34,7 +34,7 @@ class TextToTextChat implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextChatWithTools.php b/lib/public/TaskProcessing/TaskTypes/TextToTextChatWithTools.php new file mode 100644 index 00000000000..ebc660a3af9 --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextChatWithTools.php @@ -0,0 +1,117 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\TaskProcessing\TaskTypes; + +use OCP\IL10N; +use OCP\L10N\IFactory; +use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\ITaskType; +use OCP\TaskProcessing\ShapeDescriptor; + +/** + * This is the task processing task type for invoking Chat-enabled LLMs with tool call support + * @since 31.0.0 + */ +class TextToTextChatWithTools implements ITaskType { + public const ID = 'core:text2text:chatwithtools'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 31.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('lib'); + } + + /** + * @inheritDoc + * @since 31.0.0 + */ + public function getName(): string { + // TRANSLATORS Tool calling, also known as function calling, is a structured way to give LLMs the ability to make requests back to the application that called it. You define the tools you want to make available to the model, and the model will make tool requests to your app as necessary to fulfill the prompts you give it. + return $this->l->t('Chat with tools'); + } + + /** + * @inheritDoc + * @since 31.0.0 + */ + public function getDescription(): string { + // TRANSLATORS Tool calling, also known as function calling, is a structured way to give LLMs the ability to make requests back to the application that called it. You define the tools you want to make available to the model, and the model will make tool requests to your app as necessary to fulfill the prompts you give it. + return $this->l->t('Chat with the language model with tool calling support.'); + } + + /** + * @return string + * @since 31.0.0 + */ + public function getId(): string { + return self::ID; + } + + /** + * @return ShapeDescriptor[] + * @since 31.0.0 + */ + public function getInputShape(): array { + return [ + 'system_prompt' => new ShapeDescriptor( + $this->l->t('System prompt'), + $this->l->t('Define rules and assumptions that the assistant should follow during the conversation.'), + EShapeType::Text + ), + 'input' => new ShapeDescriptor( + $this->l->t('Chat message'), + $this->l->t('Describe a task that you want the assistant to do or ask a question'), + EShapeType::Text + ), + 'tool_message' => new ShapeDescriptor( + $this->l->t('Tool message'), + $this->l->t('The result of tool calls in the last interaction'), + EShapeType::Text + ), + 'history' => new ShapeDescriptor( + $this->l->t('Chat history'), + $this->l->t('The history of chat messages before the current message, starting with a message by the user'), + EShapeType::ListOfTexts + ), + // See https://platform.openai.com/docs/api-reference/chat/create#chat-create-tools for the format + 'tools' => new ShapeDescriptor( + // TRANSLATORS Tool calling, also known as function calling, is a structured way to give LLMs the ability to make requests back to the application that called it. You define the tools you want to make available to the model, and the model will make tool requests to your app as necessary to fulfill the prompts you give it. + $this->l->t('Available tools'), + $this->l->t('The available tools in JSON format'), + EShapeType::Text + ), + ]; + } + + /** + * @return ShapeDescriptor[] + * @since 31.0.0 + */ + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Generated response'), + $this->l->t('The response from the chat model'), + EShapeType::Text + ), + 'tool_calls' => new ShapeDescriptor( + $this->l->t('Tool calls'), + $this->l->t('Tools call instructions from the model in JSON format'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextFormalization.php b/lib/public/TaskProcessing/TaskTypes/TextToTextFormalization.php index 81eff28f3e9..70e38f78c0b 100644 --- a/lib/public/TaskProcessing/TaskTypes/TextToTextFormalization.php +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextFormalization.php @@ -34,7 +34,7 @@ class TextToTextFormalization implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextHeadline.php b/lib/public/TaskProcessing/TaskTypes/TextToTextHeadline.php index 9907a3605b2..dde4ea03042 100644 --- a/lib/public/TaskProcessing/TaskTypes/TextToTextHeadline.php +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextHeadline.php @@ -34,7 +34,7 @@ class TextToTextHeadline implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextProofread.php b/lib/public/TaskProcessing/TaskTypes/TextToTextProofread.php new file mode 100644 index 00000000000..508794490be --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextProofread.php @@ -0,0 +1,91 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\TaskProcessing\TaskTypes; + +use OCP\IL10N; +use OCP\L10N\IFactory; +use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\ITaskType; +use OCP\TaskProcessing\ShapeDescriptor; + +/** + * This is the task processing task type for proofreading + * @since 31.0.0 + */ +class TextToTextProofread implements ITaskType { + /** + * @since 31.0.0 + */ + public const ID = 'core:text2text:proofread'; + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 31.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('lib'); + } + + + /** + * @inheritDoc + * @since 31.0.0 + */ + public function getName(): string { + return $this->l->t('Proofread'); + } + + /** + * @inheritDoc + * @since 31.0.0 + */ + public function getDescription(): string { + return $this->l->t('Proofreads a text and lists corrections'); + } + + /** + * @return string + * @since 31.0.0 + */ + public function getId(): string { + return self::ID; + } + + /** + * @return ShapeDescriptor[] + * @since 31.0.0 + */ + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Text'), + $this->l->t('The text to proofread'), + EShapeType::Text + ), + ]; + } + + /** + * @return ShapeDescriptor[] + * @since 31.0.0 + */ + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Corrections'), + $this->l->t('The corrections that should be made in your text'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextReformulation.php b/lib/public/TaskProcessing/TaskTypes/TextToTextReformulation.php index 44c1fddc73c..120f5316aee 100644 --- a/lib/public/TaskProcessing/TaskTypes/TextToTextReformulation.php +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextReformulation.php @@ -34,7 +34,7 @@ class TextToTextReformulation implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextSimplification.php b/lib/public/TaskProcessing/TaskTypes/TextToTextSimplification.php index 580b9d92755..d107e584e3a 100644 --- a/lib/public/TaskProcessing/TaskTypes/TextToTextSimplification.php +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextSimplification.php @@ -34,7 +34,7 @@ class TextToTextSimplification implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextSummary.php b/lib/public/TaskProcessing/TaskTypes/TextToTextSummary.php index 8b00c64f915..601b478c0bd 100644 --- a/lib/public/TaskProcessing/TaskTypes/TextToTextSummary.php +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextSummary.php @@ -33,7 +33,7 @@ class TextToTextSummary implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextTopics.php b/lib/public/TaskProcessing/TaskTypes/TextToTextTopics.php index a08ec6d2c0f..943cc2e2fd4 100644 --- a/lib/public/TaskProcessing/TaskTypes/TextToTextTopics.php +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextTopics.php @@ -34,7 +34,7 @@ class TextToTextTopics implements ITaskType { public function __construct( IFactory $l10nFactory, ) { - $this->l = $l10nFactory->get('core'); + $this->l = $l10nFactory->get('lib'); } diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextTranslate.php b/lib/public/TaskProcessing/TaskTypes/TextToTextTranslate.php new file mode 100644 index 00000000000..a02550226ee --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextTranslate.php @@ -0,0 +1,102 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\TaskProcessing\TaskTypes; + +use OCP\IL10N; +use OCP\L10N\IFactory; +use OCP\TaskProcessing\EShapeType; +use OCP\TaskProcessing\ITaskType; +use OCP\TaskProcessing\ShapeDescriptor; + +/** + * This is the task processing task type for generic text processing + * @since 30.0.0 + */ +class TextToTextTranslate implements ITaskType { + /** + * @since 30.0.0 + */ + public const ID = 'core:text2text:translate'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 30.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('lib'); + } + + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getName(): string { + return $this->l->t('Translate'); + } + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getDescription(): string { + return $this->l->t('Translate text from one language to another'); + } + + /** + * @return string + * @since 30.0.0 + */ + public function getId(): string { + return self::ID; + } + + /** + * @return ShapeDescriptor[] + * @since 30.0.0 + */ + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Origin text'), + $this->l->t('The text to translate'), + EShapeType::Text + ), + 'origin_language' => new ShapeDescriptor( + $this->l->t('Origin language'), + $this->l->t('The language of the origin text'), + EShapeType::Enum + ), + 'target_language' => new ShapeDescriptor( + $this->l->t('Target language'), + $this->l->t('The desired language to translate the origin text in'), + EShapeType::Enum + ), + ]; + } + + /** + * @return ShapeDescriptor[] + * @since 30.0.0 + */ + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Result'), + $this->l->t('The translated text'), + EShapeType::Text + ), + ]; + } +} |