diff options
Diffstat (limited to 'lib/public/TaskProcessing')
8 files changed, 494 insertions, 5 deletions
diff --git a/lib/public/TaskProcessing/EShapeType.php b/lib/public/TaskProcessing/EShapeType.php index cd8d6d837da..f6cfab6b38f 100644 --- a/lib/public/TaskProcessing/EShapeType.php +++ b/lib/public/TaskProcessing/EShapeType.php @@ -154,19 +154,19 @@ enum EShapeType: int { 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_string($value)) { + 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_string($value)) { + 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_string($value)) { + 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)) { 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 68825e82533..723eca8f615 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 */ @@ -47,11 +48,13 @@ interface IManager { /** * @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(bool $showDisabled = false): array; + public function getAvailableTaskTypes(bool $showDisabled = false, ?string $userId = null): array; /** * @param Task $task The task to run 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/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 index 937c13bbba5..cd08d6f4e3d 100644 --- a/lib/public/TaskProcessing/TaskTypes/ContextAgentInteraction.php +++ b/lib/public/TaskProcessing/TaskTypes/ContextAgentInteraction.php @@ -39,7 +39,7 @@ class ContextAgentInteraction implements ITaskType { * @since 31.0.0 */ public function getName(): string { - return $this->l->t('ContextAgent'); + return 'ContextAgent'; // We do not translate this } /** 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 + ), + ]; + } +} |