diff options
author | Marcel Klehr <mklehr@gmx.net> | 2024-04-29 16:21:07 +0200 |
---|---|---|
committer | Marcel Klehr <mklehr@gmx.net> | 2024-05-14 11:38:39 +0200 |
commit | 00894e24208e4e6ae78609b8828ba32544e88ee8 (patch) | |
tree | e3cb1c6026c9a8a7688b2df5220bfee9f64e7b13 /lib/public | |
parent | e3f341fecb8a63b88f897d22af185cb2886ebe56 (diff) | |
download | nextcloud-server-00894e24208e4e6ae78609b8828ba32544e88ee8.tar.gz nextcloud-server-00894e24208e4e6ae78609b8828ba32544e88ee8.zip |
feat: first pass at TaskProcessing API
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Diffstat (limited to 'lib/public')
21 files changed, 1430 insertions, 0 deletions
diff --git a/lib/public/Files/SimpleFS/ISimpleFile.php b/lib/public/Files/SimpleFS/ISimpleFile.php index 8afc3108836..cf848d33724 100644 --- a/lib/public/Files/SimpleFS/ISimpleFile.php +++ b/lib/public/Files/SimpleFS/ISimpleFile.php @@ -121,4 +121,12 @@ interface ISimpleFile { * @since 14.0.0 */ public function write(); + + /** + * Returns the file id + * + * @return int + * @since 30.0.0 + */ + public function getId(): int; } diff --git a/lib/public/TaskProcessing/EShapeType.php b/lib/public/TaskProcessing/EShapeType.php new file mode 100644 index 00000000000..514451da068 --- /dev/null +++ b/lib/public/TaskProcessing/EShapeType.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace OCP\TaskProcessing; + +enum EShapeType: int { + case Number = 0; + case Text = 1; + case Image = 2; + case Audio = 3; + case Video = 4; + case File = 5; + case ListOfNumbers = 10; + case ListOfTexts = 11; + case ListOfImages = 12; + case ListOfAudio = 13; + case ListOfVideo = 14; + case ListOfFiles = 15; +} + diff --git a/lib/public/TaskProcessing/Events/AbstractTextProcessingEvent.php b/lib/public/TaskProcessing/Events/AbstractTextProcessingEvent.php new file mode 100644 index 00000000000..0d8f6ddb2e0 --- /dev/null +++ b/lib/public/TaskProcessing/Events/AbstractTextProcessingEvent.php @@ -0,0 +1,51 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCP\TaskProcessing\Events; + +use OCP\EventDispatcher\Event; +use OCP\TaskProcessing\Task; + +/** + * @since 30.0.0 + */ +abstract class AbstractTextProcessingEvent extends Event { + /** + * @since 30.0.0 + */ + public function __construct( + private readonly Task $task + ) { + parent::__construct(); + } + + /** + * @return Task + * @since 30.0.0 + */ + public function getTask(): Task { + return $this->task; + } +} diff --git a/lib/public/TaskProcessing/Events/TaskFailedEvent.php b/lib/public/TaskProcessing/Events/TaskFailedEvent.php new file mode 100644 index 00000000000..7b118c08b8c --- /dev/null +++ b/lib/public/TaskProcessing/Events/TaskFailedEvent.php @@ -0,0 +1,30 @@ +<?php + +namespace OCP\TaskProcessing\Events; + +use OCP\TaskProcessing\Task; + +/** + * @since 30.0.0 + */ +class TaskFailedEvent extends AbstractTextProcessingEvent { + /** + * @param Task $task + * @param string $errorMessage + * @since 30.0.0 + */ + public function __construct( + Task $task, + private readonly string $errorMessage, + ) { + parent::__construct($task); + } + + /** + * @return string + * @since 30.0.0 + */ + public function getErrorMessage(): string { + return $this->errorMessage; + } +} diff --git a/lib/public/TaskProcessing/Events/TaskSuccessfulEvent.php b/lib/public/TaskProcessing/Events/TaskSuccessfulEvent.php new file mode 100644 index 00000000000..88214a451aa --- /dev/null +++ b/lib/public/TaskProcessing/Events/TaskSuccessfulEvent.php @@ -0,0 +1,9 @@ +<?php + +namespace OCP\TaskProcessing\Events; + +/** + * @since 30.0.0 + */ +class TaskSuccessfulEvent extends AbstractTextProcessingEvent { +} diff --git a/lib/public/TaskProcessing/Exception/Exception.php b/lib/public/TaskProcessing/Exception/Exception.php new file mode 100644 index 00000000000..5b6a9f88b80 --- /dev/null +++ b/lib/public/TaskProcessing/Exception/Exception.php @@ -0,0 +1,34 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +namespace OCP\TaskProcessing\Exception; + +/** + * TaskProcessing Exception + * @since 30.0.0 + */ +class Exception extends \Exception { +} diff --git a/lib/public/TaskProcessing/Exception/NotFoundException.php b/lib/public/TaskProcessing/Exception/NotFoundException.php new file mode 100644 index 00000000000..ef3eee9009c --- /dev/null +++ b/lib/public/TaskProcessing/Exception/NotFoundException.php @@ -0,0 +1,7 @@ +<?php + +namespace OCP\TaskProcessing\Exception; + +class NotFoundException extends Exception { + +} diff --git a/lib/public/TaskProcessing/Exception/ProcessingException.php b/lib/public/TaskProcessing/Exception/ProcessingException.php new file mode 100644 index 00000000000..528876acb24 --- /dev/null +++ b/lib/public/TaskProcessing/Exception/ProcessingException.php @@ -0,0 +1,35 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +namespace OCP\TaskProcessing\Exception; + +/** + * Exception thrown during processing of a task + * by a synchronous provider + * @since 30.0.0 + */ +class ProcessingException extends \RuntimeException { +} diff --git a/lib/public/TaskProcessing/Exception/ValidationException.php b/lib/public/TaskProcessing/Exception/ValidationException.php new file mode 100644 index 00000000000..82de81226b4 --- /dev/null +++ b/lib/public/TaskProcessing/Exception/ValidationException.php @@ -0,0 +1,7 @@ +<?php + +namespace OCP\TaskProcessing\Exception; + +class ValidationException extends Exception { + +} diff --git a/lib/public/TaskProcessing/IManager.php b/lib/public/TaskProcessing/IManager.php new file mode 100644 index 00000000000..73e4c85701e --- /dev/null +++ b/lib/public/TaskProcessing/IManager.php @@ -0,0 +1,157 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +namespace OCP\TaskProcessing; + +use OCP\Files\GenericFileException; +use OCP\Files\NotPermittedException; +use OCP\Lock\LockedException; +use OCP\PreConditionNotMetException; +use OCP\TaskProcessing\Exception\Exception; +use OCP\TaskProcessing\Exception\NotFoundException; +use OCP\TaskProcessing\Exception\ValidationException; + +/** + * API surface for apps interacting with and making use of LanguageModel providers + * without known which providers are installed + * @since 30.0.0 + */ +interface IManager { + /** + * @since 30.0.0 + */ + public function hasProviders(): bool; + + /** + * @return IProvider[] + * @since 30.0.0 + */ + public function getProviders(): array; + + /** + * @return array<string,array{name: string, description: string, inputShape: array<string, ShapeDescriptor>, optionalInputShape: array<string, ShapeDescriptor>, outputShape: array<string, ShapeDescriptor>, optionalOutputShape: array<string, ShapeDescriptor>}> + * @since 30.0.0 + */ + public function getAvailableTaskTypes(): array; + + /** + * @param Task $task The task to run + * @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 + * @since 30.0.0 + */ + public function scheduleTask(Task $task): void; + + /** + * Delete a task that has been scheduled before + * + * @param Task $task The task to delete + * @throws Exception if deleting the task in the database failed + * @since 30.0.0 + */ + public function deleteTask(Task $task): void; + + /** + * @param int $id The id of the task + * @return Task + * @throws Exception If the query failed + * @throws NotFoundException If the task could not be found + * @since 30.0.0 + */ + public function getTask(int $id): Task; + + /** + * @param int $id The id of the task + * @throws Exception If the query failed + * @throws NotFoundException If the task could not be found + * @since 30.0.0 + */ + public function cancelTask(int $id): void; + + /** + * @param int $id The id of the task + * @param string|null $error + * @param array|null $result + * @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; + + /** + * @param int $id + * @param float $progress + * @return bool `true` if the task should still be running; `false` if the task has been cancelled in the meantime + * @throws ValidationException + * @throws Exception + * @throws NotFoundException + */ + public function setTaskProgress(int $id, float $progress): bool; + + /** + * @param string|null $taskTypeId + * @return Task + * @throws Exception If the query failed + * @throws NotFoundException If no task could not be found + * @since 30.0.0 + */ + public function getNextScheduledTask(?string $taskTypeId = null): Task; + + /** + * @param int $id The id of the task + * @param string|null $userId The user id that scheduled the task + * @return Task + * @throws Exception If the query failed + * @throws NotFoundException If the task could not be found + * @since 30.0.0 + */ + public function getUserTask(int $id, ?string $userId): Task; + + /** + * @param string|null $userId + * @param string $appId + * @param string|null $identifier + * @return list<Task> + * @throws Exception If the query failed + * @throws NotFoundException If the task could not be found + * @since 30.0.0 + */ + public function getUserTasksByApp(?string $userId, string $appId, ?string $identifier = null): array; + + /** + * Prepare the task's input data, so it can be processed by the provider + * ie. this replaces file ids with base64 data + * + * @param Task $task + * @return array<string, mixed> + * @throws NotPermittedException + * @throws GenericFileException + * @throws LockedException + * @throws ValidationException + */ + public function prepareInputData(Task $task): array; +} diff --git a/lib/public/TaskProcessing/IProvider.php b/lib/public/TaskProcessing/IProvider.php new file mode 100644 index 00000000000..be6aa33d125 --- /dev/null +++ b/lib/public/TaskProcessing/IProvider.php @@ -0,0 +1,80 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +namespace OCP\TaskProcessing; + +use OCP\TextProcessing\ITaskType; +use RuntimeException; + +/** + * This is the interface that is implemented by apps that + * implement a task processing provider + * @since 30.0.0 + */ +interface IProvider { + /** + * The unique id of this provider + * @since 30.0.0 + */ + public function getId(): string; + + /** + * The localized name of this provider + * @since 30.0.0 + */ + public function getName(): string; + + /** + * Returns the task type id of the task type, that this + * provider handles + * + * @since 30.0.0 + * @return string + */ + public function getTaskType(): string; + + /** + * @return int The expected average runtime of a task in seconds + * @since 30.0.0 + */ + public function getExpectedRuntime(): int; + + /** + * Returns the shape of optional input parameters + * + * @since 30.0.0 + * @psalm-return array{string, ShapeDescriptor} + */ + public function getOptionalInputShape(): array; + + /** + * Returns the shape of optional output parameters + * + * @since 30.0.0 + * @psalm-return array{string, ShapeDescriptor} + */ + public function getOptionalOutputShape(): array; +} diff --git a/lib/public/TaskProcessing/ISynchronousProvider.php b/lib/public/TaskProcessing/ISynchronousProvider.php new file mode 100644 index 00000000000..e4fc0b1ea7f --- /dev/null +++ b/lib/public/TaskProcessing/ISynchronousProvider.php @@ -0,0 +1,48 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +namespace OCP\TaskProcessing; + +use OCP\TaskProcessing\Exception\ProcessingException; + +/** + * This is the interface that is implemented by apps that + * implement a task processing provider + * @since 30.0.0 + */ +interface ISynchronousProvider extends IProvider { + + /** + * Returns the shape of optional output parameters + * + * @since 30.0.0 + * @param null|string $userId The user that created the current task + * @param array<string, string> $input The task input + * @psalm-return array<string, string> + * @throws ProcessingException + */ + public function process(?string $userId, array $input): array; +} diff --git a/lib/public/TaskProcessing/ITaskType.php b/lib/public/TaskProcessing/ITaskType.php new file mode 100644 index 00000000000..bdac1ec397e --- /dev/null +++ b/lib/public/TaskProcessing/ITaskType.php @@ -0,0 +1,73 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace OCP\TaskProcessing; + +/** + * This is a task type interface that is implemented by task processing + * task types + * @since 30.0.0 + */ +interface ITaskType { + /** + * Returns the unique id of this task type + * + * @since 30.0.0 + * @return string + */ + public function getId(): string; + + /** + * Returns the localized name of this task type + * + * @since 30.0.0 + * @return string + */ + public function getName(): string; + + /** + * Returns the localized description of this task type + * + * @since 30.0.0 + * @return string + */ + public function getDescription(): string; + + /** + * Returns the shape of the input array + * + * @since 30.0.0 + * @psalm-return array{string, ShapeDescriptor} + */ + public function getInputShape(): array; + + /** + * Returns the shape of the output array + * + * @since 30.0.0 + * @psalm-return array{string, ShapeDescriptor} + */ + public function getOutputShape(): array; +} diff --git a/lib/public/TaskProcessing/ShapeDescriptor.php b/lib/public/TaskProcessing/ShapeDescriptor.php new file mode 100644 index 00000000000..0c770b7d07e --- /dev/null +++ b/lib/public/TaskProcessing/ShapeDescriptor.php @@ -0,0 +1,24 @@ +<?php + +namespace OCP\TaskProcessing; + +class ShapeDescriptor { + public function __construct( + private string $name, + private string $description, + private EShapeType $shapeType, + ) { + } + + public function getName(): string { + return $this->name; + } + + public function getDescription(): string { + return $this->description; + } + + public function getShapeType(): EShapeType { + return $this->shapeType; + } +} diff --git a/lib/public/TaskProcessing/Task.php b/lib/public/TaskProcessing/Task.php new file mode 100644 index 00000000000..a467c0d57d0 --- /dev/null +++ b/lib/public/TaskProcessing/Task.php @@ -0,0 +1,263 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace OCP\TaskProcessing; + +use DateTime; +use OCP\Files\AppData\IAppDataFactory; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; +use OCP\IImage; +use OCP\Image; +use OCP\TaskProcessing\Exception\ValidationException; + +/** + * This is a task processing task + * + * @since 30.0.0 + */ +final class Task implements \JsonSerializable { + protected ?int $id = null; + + protected ?DateTime $completionExpectedAt = null; + + protected ?array $output = null; + + protected ?string $errorMessage = null; + + protected ?float $progress = null; + + /** + * @since 30.0.0 + */ + public const STATUS_CANCELLED = 5; + /** + * @since 30.0.0 + */ + public const STATUS_FAILED = 4; + /** + * @since 30.0.0 + */ + public const STATUS_SUCCESSFUL = 3; + /** + * @since 30.0.0 + */ + public const STATUS_RUNNING = 2; + /** + * @since 30.0.0 + */ + public const STATUS_SCHEDULED = 1; + /** + * @since 30.0.0 + */ + public const STATUS_UNKNOWN = 0; + + /** + * @psalm-var self::STATUS_* + */ + protected int $status = self::STATUS_UNKNOWN; + + /** + * @param array<string,mixed> $input + * @param string $appId + * @param string|null $userId + * @param null|string $identifier An arbitrary identifier for this task. max length: 255 chars + * @since 30.0.0 + */ + final public function __construct( + protected readonly string $taskType, + protected array $input, + protected readonly string $appId, + protected readonly ?string $userId, + protected readonly ?string $identifier = '', + ) { + } + + /** + * @since 30.0.0 + */ + final public function getTaskType(): string { + return $this->taskType; + } + + /** + * @psalm-return self::STATUS_* + * @since 30.0.0 + */ + final public function getStatus(): int { + return $this->status; + } + + /** + * @psalm-param self::STATUS_* $status + * @since 30.0.0 + */ + final public function setStatus(int $status): void { + $this->status = $status; + } + + /** + * @param ?DateTime $at + * @since 30.0.0 + */ + final public function setCompletionExpectedAt(?DateTime $at): void { + $this->completionExpectedAt = $at; + } + + /** + * @return ?DateTime + * @since 30.0.0 + */ + final public function getCompletionExpectedAt(): ?DateTime { + return $this->completionExpectedAt; + } + + /** + * @return int|null + * @since 30.0.0 + */ + final public function getId(): ?int { + return $this->id; + } + + /** + * @param int|null $id + * @since 30.0.0 + */ + final public function setId(?int $id): void { + $this->id = $id; + } + + /** + * @since 30.0.0 + */ + final public function setOutput(?array $output): void { + $this->output = $output; + } + + /** + * @since 30.0.0 + */ + final public function getOutput(): ?array { + return $this->output; + } + + /** + * @return string + * @since 30.0.0 + */ + final public function getInput(): array { + return $this->input; + } + + /** + * @return string + * @since 30.0.0 + */ + final public function getAppId(): string { + return $this->appId; + } + + /** + * @return null|string + * @since 30.0.0 + */ + final public function getIdentifier(): ?string { + return $this->identifier; + } + + /** + * @return string|null + * @since 30.0.0 + */ + final public function getUserId(): ?string { + return $this->userId; + } + + /** + * @psalm-return array{id: ?int, status: self::STATUS_*, userId: ?string, appId: string, input: ?array, output: ?array, identifier: ?string, completionExpectedAt: ?int, progress: ?float} + * @since 30.0.0 + */ + public function jsonSerialize(): array { + return [ + 'id' => $this->getId(), + 'status' => $this->getStatus(), + 'userId' => $this->getUserId(), + 'appId' => $this->getAppId(), + 'input' => $this->getInput(), + 'output' => $this->getOutput(), + 'identifier' => $this->getIdentifier(), + 'completionExpectedAt' => $this->getCompletionExpectedAt()->getTimestamp(), + 'progress' => $this->getProgress(), + ]; + } + + /** + * @param string|null $error + * @return void + * @since 30.0.0 + */ + public function setErrorMessage(?string $error) { + $this->errorMessage = $error; + } + + /** + * @return string|null + * @since 30.0.0 + */ + public function getErrorMessage(): ?string { + return $this->errorMessage; + } + + /** + * @param array $input + * @return void + * @since 30.0.0 + */ + public function setInput(array $input): void { + $this->input = $input; + } + + /** + * @param float|null $progress + * @return void + * @throws ValidationException + * @since 30.0.0 + */ + public function setProgress(?float $progress): void { + if ($progress < 0 || $progress > 1.0) { + throw new ValidationException('Progress must be between 0.0 and 1.0 inclusively; ' . $progress . ' given'); + } + $this->progress = $progress; + } + + /** + * @return float|null + * @since 30.0.0 + */ + public function getProgress(): ?float { + return $this->progress; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/AudioToText.php b/lib/public/TaskProcessing/TaskTypes/AudioToText.php new file mode 100644 index 00000000000..c074c154341 --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/AudioToText.php @@ -0,0 +1,93 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +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 transcription + * @since 30.0.0 + */ +class AudioToText implements ITaskType { + const ID = 'core:audio2text'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 30.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('core'); + } + + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getName(): string { + return $this->l->t('Transcribe audio'); + } + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getDescription(): string { + return $this->l->t('Transcribe the things said in an audio'); + } + + public function getId(): string { + return self::ID; + } + + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Audio input'), + $this->l->t('The audio to transcribe'), + EShapeType::Audio + ), + ]; + } + + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Transcription'), + $this->l->t('The transcribed text'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/TextToImage.php b/lib/public/TaskProcessing/TaskTypes/TextToImage.php new file mode 100644 index 00000000000..264238afee5 --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToImage.php @@ -0,0 +1,98 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +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 image generation + * @since 30.0.0 + */ +class TextToImage implements ITaskType { + const ID = 'core:text2image'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 30.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('core'); + } + + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getName(): string { + return $this->l->t('Generate image'); + } + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getDescription(): string { + return $this->l->t('Generate an image from a text prompt'); + } + + public function getId(): string { + return self::ID; + } + + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Prompt'), + $this->l->t('Describe the image you want to generate'), + EShapeType::Text + ), + 'numberOfImages' => new ShapeDescriptor( + $this->l->t('Number of images'), + $this->l->t('How many images to generate'), + EShapeType::Number + ), + ]; + } + + public function getOutputShape(): array { + return [ + 'images' => new ShapeDescriptor( + $this->l->t('Output images'), + $this->l->t('The generated images'), + EShapeType::ListOfImages + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/TextToText.php b/lib/public/TaskProcessing/TaskTypes/TextToText.php new file mode 100644 index 00000000000..436c47aa8ee --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToText.php @@ -0,0 +1,93 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +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 TextToText implements ITaskType { + const ID = 'core:text2text'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 30.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('core'); + } + + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getName(): string { + return $this->l->t('Free text to text prompt'); + } + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getDescription(): string { + return $this->l->t('Runs an arbitrary prompt through a language model that retuns a reply'); + } + + public function getId(): string { + return self::ID; + } + + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Prompt'), + $this->l->t('Describe a task that you want the assistant to do or ask a question'), + EShapeType::Text + ), + ]; + } + + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Generated reply'), + $this->l->t('The generated text from the assistant'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextHeadline.php b/lib/public/TaskProcessing/TaskTypes/TextToTextHeadline.php new file mode 100644 index 00000000000..e524c83fe55 --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextHeadline.php @@ -0,0 +1,93 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +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 creating headline + * @since 30.0.0 + */ +class TextToTextHeadline implements ITaskType { + const ID = 'core:text2text:headline'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 30.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('core'); + } + + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getName(): string { + return $this->l->t('Generate a headline'); + } + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getDescription(): string { + return $this->l->t('Generates a possible headline for a text.'); + } + + public function getId(): string { + return self::ID; + } + + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Original text'), + $this->l->t('The original text to generate a headline for'), + EShapeType::Text + ), + ]; + } + + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Headline'), + $this->l->t('The generated headline'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextSummary.php b/lib/public/TaskProcessing/TaskTypes/TextToTextSummary.php new file mode 100644 index 00000000000..4db13b24a24 --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextSummary.php @@ -0,0 +1,92 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +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 summaries + * @since 30.0.0 + */ +class TextToTextSummary implements ITaskType { + const ID = 'core:text2text:summary'; + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 30.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('core'); + } + + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getName(): string { + return $this->l->t('Summarize'); + } + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getDescription(): string { + return $this->l->t('Summarizes a text'); + } + + public function getId(): string { + return self::ID; + } + + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Original text'), + $this->l->t('The original text to summarize'), + EShapeType::Text + ), + ]; + } + + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Summary'), + $this->l->t('The generated summary'), + EShapeType::Text + ), + ]; + } +} diff --git a/lib/public/TaskProcessing/TaskTypes/TextToTextTopics.php b/lib/public/TaskProcessing/TaskTypes/TextToTextTopics.php new file mode 100644 index 00000000000..f2f0c5c1b7d --- /dev/null +++ b/lib/public/TaskProcessing/TaskTypes/TextToTextTopics.php @@ -0,0 +1,93 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Marcel Klehr <mklehr@gmx.net> + * + * @author Marcel Klehr <mklehr@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +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 topics extraction + * @since 30.0.0 + */ +class TextToTextTopics implements ITaskType { + const ID = 'core:text2text:topics'; + + private IL10N $l; + + /** + * @param IFactory $l10nFactory + * @since 30.0.0 + */ + public function __construct( + IFactory $l10nFactory, + ) { + $this->l = $l10nFactory->get('core'); + } + + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getName(): string { + return $this->l->t('Extract topics'); + } + + /** + * @inheritDoc + * @since 30.0.0 + */ + public function getDescription(): string { + return $this->l->t('Extracts topics from a text and outputs them separated by commas'); + } + + public function getId(): string { + return self::ID; + } + + public function getInputShape(): array { + return [ + 'input' => new ShapeDescriptor( + $this->l->t('Original text'), + $this->l->t('The original text to extract topics from'), + EShapeType::Text + ), + ]; + } + + public function getOutputShape(): array { + return [ + 'output' => new ShapeDescriptor( + $this->l->t('Topics'), + $this->l->t('The list of extracted topics'), + EShapeType::Text + ), + ]; + } +} |