diff --git a/developer_manual/digging_deeper/text_processing.rst b/developer_manual/digging_deeper/text_processing.rst index 88ea9b2f30a..3530d2b9dbd 100644 --- a/developer_manual/digging_deeper/text_processing.rst +++ b/developer_manual/digging_deeper/text_processing.rst @@ -19,6 +19,10 @@ To consume the Language Model API, you will need to :ref:`inject` @@ -37,9 +41,8 @@ To create a task we use the ``\OCP\TextProcessing\Task`` class. Its constructor .. code-block:: php - if (in_array(SummaryTaskType::class, $languageModelManager->getAvailableTaskTypes()) { + if (in_array(SummaryTaskType::class, $textprocessingManager->getAvailableTaskTypes()) { $summaryTask = new Task(SummaryTaskType::class, $emailText, "my_app", $userId, (string) $emailId); - $languageModelManager->scheduleTask($summaryTask); } else { // cannot use summarization } @@ -55,6 +58,59 @@ The task class objects have the following methods available: * ``getIdentifier()`` This returns the original scheduler-defined identifier for the task * ``getUserId()`` This returns the originating user ID of the task. +You could now run the task directly as follows. However, this will block the current PHP process until the task is done, which can sometimes take dozens of minutes, depending on which provider is used. + +.. code-block:: php + + try { + $textprocessingManager->runTask($summaryTask); + } catch (\OCP\PreConditionNotMetException|\OCP\TextProcessing\Exception\TaskFailureException $e) { + // task failed + // return error + } + // task was successful + +The wiser choice, when you are in the context of a HTTP controller, is to schedule the task for execution in a background job, as follows: + +.. code-block:: php + + try { + $textprocessingManager->scheduleTask($summaryTask); + } catch (\OCP\PreConditionNotMetException|\OCP\DB\Exception $e) { + // scheduling task failed + } + // task was scheduled successfully + +Conditional scheduling of tasks +############################### + +.. versionadded:: 28.0.0 + +Of course, you might want to schedule the task in a background job **only** if it takes longer than the request timeout. This is what ``runOrScheduleTask`` does. + +.. code-block:: php + + try { + $textprocessingManager->runOrScheduleTask($summaryTask); + } catch (\OCP\PreConditionNotMetException|\OCP\DB\Exception $e) { + // scheduling task failed + // return error + } catch (\OCP\TextProcessing\Exception\TaskFailureException $e) { + // task was run but failed + // status will be STATUS_FAILED + // return error + } + + switch ($summaryTask->getStatus()) { + case \OCP\TextProcessing\Task::STATUS_SUCCESSFUL: + // task was run directly and was successful + case \OCP\TextProcessing\Task::STATUS_RUNNING: + case \OCP\TextProcessing\Task::STATUS_SCHEDULED: + // task was deferred to background job + default: + // something went wrong + } + Task statuses ^^^^^^^^^^^^^ @@ -164,6 +220,102 @@ The method ``process`` implements the text processing step, e.g. it passes the p The class would typically be saved into a file in ``lib/TextProcessing`` of your app but you are free to put it elsewhere as long as it's loadable by Nextcloud's :ref:`dependency injection container`. +Processing tasks in the context of a user +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionadded:: 28.0.0 + +Sometimes the processing of a text processing task may depend upon which user requested the task. You can now obtain this information in your provider by additionally implementing the ``OCP\TextProcessing\IProviderWithUserId`` interface: + +.. code-block:: php + :emphasize-lines: 10,14,16,31,32,33 + + l->t('My awesome text processing provider'); + } + + public function getTaskType(): string { + return SummaryTaskType::class; + } + + public function setUserId(?string $userId): void { + $this->userId = $userId; + } + + public function process(string $input): string { + // Return the output here, making use of $this->userId + } + } + +Streamlining processing for fast providers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionadded:: 28.0.0 + +Downstream consumers of the TextProcessing API can optimize execution of tasks if they know how long a task will run with your provider. To allow this kind of optimization you can provide an estimate of how much time your provider typically takes. To do this you simply implement the additional ``OCP\TextProcessing\IProviderWithExpectedRuntime`` interface + +.. code-block:: php + :emphasize-lines: 10,14,29,30,31 + + l->t('My awesome text processing provider'); + } + + public function getTaskType(): string { + return SummaryTaskType::class; + } + + public function getExpectedRuntime(): int { + return 10; // expected runtime of a task is 10s + } + + public function process(string $input): string { + // Return the output here + } + } + Providing more task types ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -227,4 +379,4 @@ The provider class is registered via the :ref:`bootstrap mechanism