From 3392a9c893a8a7849103dc80c408b93a08723277 Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Mon, 12 Feb 2024 17:30:20 +0100 Subject: [PATCH 01/17] start adding task list Signed-off-by: Julien Veyssier --- appinfo/routes.php | 1 + lib/AppInfo/Application.php | 6 + lib/Controller/AssistantController.php | 28 ++++- lib/Controller/SpeechToTextController.php | 2 +- lib/Db/MetaTaskMapper.php | 17 ++- .../SpeechToTextResultListener.php | 4 +- .../AssistantTextProcessingForm.vue | 35 +++++- src/components/TaskList.vue | 88 ++++++++++++++ src/components/TaskListItem.vue | 107 ++++++++++++++++++ 9 files changed, 278 insertions(+), 10 deletions(-) create mode 100644 src/components/TaskList.vue create mode 100644 src/components/TaskListItem.vue diff --git a/appinfo/routes.php b/appinfo/routes.php index 15033ba7..84d19808 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -8,6 +8,7 @@ ['name' => 'assistant#getAssistantTaskResultPage', 'url' => '/task/view/{metaTaskId}', 'verb' => 'GET'], ['name' => 'assistant#getAssistantTask', 'url' => '/task/{metaTaskId}', 'verb' => 'GET'], + ['name' => 'assistant#getUserTasks', 'url' => '/tasks', 'verb' => 'GET'], ['name' => 'assistant#runTextProcessingTask', 'url' => '/task/run', 'verb' => 'POST'], ['name' => 'assistant#scheduleTextProcessingTask', 'url' => '/task/schedule', 'verb' => 'POST'], ['name' => 'assistant#runOrScheduleTextProcessingTask', 'url' => '/task/run-or-schedule', 'verb' => 'POST'], diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 43af1ff6..ab91e9c0 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -45,6 +45,12 @@ class Application extends App implements IBootstrap { public const STT_TASK_SUCCESSFUL = 1; public const STT_TASK_FAILED = -1; + public const STATUS_META_TASK_FAILED = 4; + public const STATUS_META_TASK_SUCCESSFUL = 3; + public const STATUS_META_TASK_RUNNING = 2; + public const STATUS_META_TASK_SCHEDULED = 1; + public const STATUS_META_TASK_UNKNOWN = 0; + public const TASK_CATEGORY_TEXT_GEN = 0; public const TASK_CATEGORY_TEXT_TO_IMAGE = 1; public const TASK_CATEGORY_SPEECH_TO_TEXT = 2; diff --git a/lib/Controller/AssistantController.php b/lib/Controller/AssistantController.php index fcb2fedd..b08e8d24 100644 --- a/lib/Controller/AssistantController.php +++ b/lib/Controller/AssistantController.php @@ -3,6 +3,8 @@ namespace OCA\TpAssistant\Controller; use OCA\TpAssistant\AppInfo\Application; +use OCA\TpAssistant\Db\MetaTask; +use OCA\TpAssistant\Db\MetaTaskMapper; use OCA\TpAssistant\Service\AssistantService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; @@ -11,16 +13,18 @@ use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; +use OCP\DB\Exception; use OCP\IRequest; class AssistantController extends Controller { public function __construct( - string $appName, - IRequest $request, + string $appName, + IRequest $request, private AssistantService $assistantService, - private IInitialState $initialStateService, - private ?string $userId, + private MetaTaskMapper $metaTaskMapper, + private IInitialState $initialStateService, + private ?string $userId, ) { parent::__construct($appName, $request); } @@ -59,6 +63,22 @@ public function getAssistantTask(int $metaTaskId): DataResponse { return new DataResponse('', Http::STATUS_NOT_FOUND); } + #[NoAdminRequired] + public function getUserTasks(?string $taskType = null, ?int $category = null): DataResponse { + if ($this->userId !== null) { + try { + $tasks = $this->metaTaskMapper->getUserMetaTasks($this->userId, $taskType, $category); + $serializedTasks = array_map(static function(MetaTask $task) { + return $task->jsonSerializeCc(); + }, $tasks); + return new DataResponse(['tasks' => $serializedTasks]); + } catch (Exception $e) { + return new DataResponse(['tasks' => []]); + } + } + return new DataResponse('', Http::STATUS_NOT_FOUND); + } + /** * @param array $inputs * @param string $type diff --git a/lib/Controller/SpeechToTextController.php b/lib/Controller/SpeechToTextController.php index ac8be40b..03365162 100644 --- a/lib/Controller/SpeechToTextController.php +++ b/lib/Controller/SpeechToTextController.php @@ -106,7 +106,7 @@ public function getTranscript(int $id): DataResponse { */ private function internalGetTask(int $id): MetaTask { try { - $metaTask = $this->metaTaskMapper->getMetaTaskOfUser($id, $this->userId); + $metaTask = $this->metaTaskMapper->getUserMetaTask($id, $this->userId); if($metaTask->getCategory() !== Application::TASK_CATEGORY_SPEECH_TO_TEXT) { throw new Exception('Task is not a speech to text task.', Http::STATUS_BAD_REQUEST); diff --git a/lib/Db/MetaTaskMapper.php b/lib/Db/MetaTaskMapper.php index d846db57..3ca8a0a6 100644 --- a/lib/Db/MetaTaskMapper.php +++ b/lib/Db/MetaTaskMapper.php @@ -120,7 +120,7 @@ public function getMetaTasksByOcpTaskIdAndCategory(int $ocpTaskId, int $category * @throws Exception * @throws MultipleObjectsReturnedException */ - public function getMetaTaskOfUser(int $id, string $userId): MetaTask { + public function getUserMetaTask(int $id, string $userId): MetaTask { $qb = $this->db->getQueryBuilder(); $qb->select('*') @@ -136,10 +136,12 @@ public function getMetaTaskOfUser(int $id, string $userId): MetaTask { /** * @param string $userId + * @param string|null $taskType + * @param int|null $category * @return array * @throws Exception */ - public function getMetaTasksOfUser(string $userId): array { + public function getUserMetaTasks(string $userId, ?string $taskType = null, ?int $category = null): array { $qb = $this->db->getQueryBuilder(); $qb->select('*') @@ -147,6 +149,17 @@ public function getMetaTasksOfUser(string $userId): array { ->where( $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) ); + if ($taskType !== null) { + $qb->andWhere( + $qb->expr()->eq('task_type', $qb->createNamedParameter($taskType, IQueryBuilder::PARAM_STR)) + ); + } + if ($category !== null) { + $qb->andWhere( + $qb->expr()->eq('category', $qb->createNamedParameter($category, IQueryBuilder::PARAM_INT)) + ); + } + $qb->orderBy('timestamp', 'DESC'); return $this->findEntities($qb); } diff --git a/lib/Listener/SpeechToText/SpeechToTextResultListener.php b/lib/Listener/SpeechToText/SpeechToTextResultListener.php index 8c76e9a5..57ef614b 100644 --- a/lib/Listener/SpeechToText/SpeechToTextResultListener.php +++ b/lib/Listener/SpeechToText/SpeechToTextResultListener.php @@ -72,7 +72,7 @@ public function handle(Event $event): void { // Update the meta task with the output and new status $assistantTask->setOutput($transcript); - $assistantTask->setStatus(Application::STT_TASK_SUCCESSFUL); + $assistantTask->setStatus(Application::STATUS_META_TASK_SUCCESSFUL); $assistantTask = $this->metaTaskMapper->update($assistantTask); try { @@ -104,7 +104,7 @@ public function handle(Event $event): void { } // Update the meta task with the new status - $assistantTask->setStatus(Application::STT_TASK_FAILED); + $assistantTask->setStatus(Application::STATUS_META_TASK_FAILED); $assistantTask = $this->metaTaskMapper->update($assistantTask); try { diff --git a/src/components/AssistantTextProcessingForm.vue b/src/components/AssistantTextProcessingForm.vue index 0996061d..5a25b23a 100644 --- a/src/components/AssistantTextProcessingForm.vue +++ b/src/components/AssistantTextProcessingForm.vue @@ -29,7 +29,7 @@
- {{ formattedOutput }} + {{ formattedOutput }}
@@ -99,6 +99,21 @@ +
+ + + {{ t('assistant', 'Task history') }} + + +
@@ -106,6 +121,8 @@ import ContentCopyIcon from 'vue-material-design-icons/ContentCopy.vue' import ClipboardCheckOutlineIcon from 'vue-material-design-icons/ClipboardCheckOutline.vue' import CreationIcon from 'vue-material-design-icons/Creation.vue' +import ChevronRightIcon from 'vue-material-design-icons/ChevronRight.vue' +import ChevronDownIcon from 'vue-material-design-icons/ChevronDown.vue' import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js' import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' @@ -116,6 +133,7 @@ import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js import TaskTypeSelect from './TaskTypeSelect.vue' import AssistantFormInputs from './AssistantFormInputs.vue' import Text2ImageDisplay from './Text2Image/Text2ImageDisplay.vue' +import TaskList from './TaskList.vue' import axios from '@nextcloud/axios' import { generateOcsUrl, generateUrl } from '@nextcloud/router' @@ -130,6 +148,7 @@ const FREE_PROMPT_TASK_TYPE_ID = 'OCP\\TextProcessing\\FreePromptTaskType' export default { name: 'AssistantTextProcessingForm', components: { + TaskList, Text2ImageDisplay, TaskTypeSelect, NcButton, @@ -139,6 +158,8 @@ export default { CreationIcon, ContentCopyIcon, ClipboardCheckOutlineIcon, + ChevronDownIcon, + ChevronRightIcon, NcNoteCard, AssistantFormInputs, }, @@ -176,6 +197,7 @@ export default { taskTypes: [], mySelectedTaskTypeId: this.selectedTaskTypeId || FREE_PROMPT_TASK_TYPE_ID, copied: false, + showHistory: false, } }, computed: { @@ -387,6 +409,17 @@ export default { } } + .history { + width: 100%; + display: flex; + flex-direction: column; + align-items: end; + + &--list { + width: 100%; + } + } + .success-icon { color: var(--color-success); } diff --git a/src/components/TaskList.vue b/src/components/TaskList.vue new file mode 100644 index 00000000..1b15a159 --- /dev/null +++ b/src/components/TaskList.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/src/components/TaskListItem.vue b/src/components/TaskListItem.vue new file mode 100644 index 00000000..6bbfb117 --- /dev/null +++ b/src/components/TaskListItem.vue @@ -0,0 +1,107 @@ + + + + + From e2526e2d9bc32d0bbecc5a4f32084fc7054edd2f Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Tue, 13 Feb 2024 14:30:59 +0100 Subject: [PATCH 02/17] implement task canceling and deletion Signed-off-by: Julien Veyssier --- appinfo/routes.php | 2 + lib/Controller/AssistantController.php | 36 ++++- .../SpeechToTextResultListener.php | 12 +- lib/Listener/TaskFailedListener.php | 8 +- lib/Listener/TaskSuccessfulListener.php | 6 +- .../Text2Image/Text2ImageResultListener.php | 15 +- lib/Service/AssistantService.php | 134 +++++++----------- lib/Service/NotificationService.php | 88 ++++++++++++ .../SpeechToText/SpeechToTextService.php | 6 +- .../Text2Image/Text2ImageHelperService.php | 22 +-- src/components/TaskList.vue | 35 ++++- src/components/TaskListItem.vue | 57 ++++++-- 12 files changed, 298 insertions(+), 123 deletions(-) create mode 100644 lib/Service/NotificationService.php diff --git a/appinfo/routes.php b/appinfo/routes.php index 84d19808..e11714fe 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -13,6 +13,8 @@ ['name' => 'assistant#scheduleTextProcessingTask', 'url' => '/task/schedule', 'verb' => 'POST'], ['name' => 'assistant#runOrScheduleTextProcessingTask', 'url' => '/task/run-or-schedule', 'verb' => 'POST'], ['name' => 'assistant#parseTextFromFile', 'url' => '/parse-file', 'verb' => 'POST'], + ['name' => 'assistant#deleteTask', 'url' => '/task/{metaTaskId}', 'verb' => 'DELETE'], + ['name' => 'assistant#cancelTask', 'url' => '/task/cancel/{metaTaskId}', 'verb' => 'PUT'], ['name' => 'Text2Image#processPrompt', 'url' => '/i/process_prompt', 'verb' => 'POST'], ['name' => 'Text2Image#getPromptHistory', 'url' => '/i/prompt_history', 'verb' => 'GET'], diff --git a/lib/Controller/AssistantController.php b/lib/Controller/AssistantController.php index b08e8d24..398663cb 100644 --- a/lib/Controller/AssistantController.php +++ b/lib/Controller/AssistantController.php @@ -29,6 +29,40 @@ public function __construct( parent::__construct($appName, $request); } + /** + * @param int $metaTaskId + * @return DataResponse + */ + #[NoAdminRequired] + public function deleteTask(int $metaTaskId): DataResponse { + if ($this->userId !== null) { + try { + $this->assistantService->deleteAssistantTask($this->userId, $metaTaskId); + return new DataResponse(''); + } catch (\Exception $e) { + } + } + + return new DataResponse('', Http::STATUS_NOT_FOUND); + } + + /** + * @param int $metaTaskId + * @return DataResponse + */ + #[NoAdminRequired] + public function cancelTask(int $metaTaskId): DataResponse { + if ($this->userId !== null) { + try { + $this->assistantService->cancelAssistantTask($this->userId, $metaTaskId); + return new DataResponse(''); + } catch (\Exception $e) { + } + } + + return new DataResponse('', Http::STATUS_NOT_FOUND); + } + /** * @param int $metaTaskId * @return TemplateResponse @@ -68,7 +102,7 @@ public function getUserTasks(?string $taskType = null, ?int $category = null): D if ($this->userId !== null) { try { $tasks = $this->metaTaskMapper->getUserMetaTasks($this->userId, $taskType, $category); - $serializedTasks = array_map(static function(MetaTask $task) { + $serializedTasks = array_map(static function (MetaTask $task) { return $task->jsonSerializeCc(); }, $tasks); return new DataResponse(['tasks' => $serializedTasks]); diff --git a/lib/Listener/SpeechToText/SpeechToTextResultListener.php b/lib/Listener/SpeechToText/SpeechToTextResultListener.php index 57ef614b..8b70c146 100644 --- a/lib/Listener/SpeechToText/SpeechToTextResultListener.php +++ b/lib/Listener/SpeechToText/SpeechToTextResultListener.php @@ -24,7 +24,7 @@ use OCA\TpAssistant\AppInfo\Application; use OCA\TpAssistant\Db\MetaTaskMapper; -use OCA\TpAssistant\Service\AssistantService; +use OCA\TpAssistant\Service\NotificationService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\SpeechToText\Events\AbstractTranscriptionEvent; @@ -39,7 +39,7 @@ class SpeechToTextResultListener implements IEventListener { public function __construct( private LoggerInterface $logger, private MetaTaskMapper $metaTaskMapper, - private AssistantService $assistantService, + private NotificationService $notificationService, ) { } @@ -76,13 +76,14 @@ public function handle(Event $event): void { $assistantTask = $this->metaTaskMapper->update($assistantTask); try { - $this->assistantService->sendNotification($assistantTask, null, null, $transcript); + $this->notificationService->sendNotification($assistantTask, null, null, $transcript); } catch (\InvalidArgumentException $e) { $this->logger->error('Failed to dispatch notification for successful transcription: ' . $e->getMessage()); } } if ($event instanceof TranscriptionFailedEvent) { + $file = $event->getFile(); $this->logger->error('Transcript generation failed: ' . $event->getErrorMessage()); $metaTasks = $this->metaTaskMapper->getMetaTasksByOcpTaskIdAndCategory($file->getId(), Application::TASK_CATEGORY_SPEECH_TO_TEXT); @@ -99,16 +100,17 @@ public function handle(Event $event): void { } if ($assistantTask === null) { - $this->logger->error('No assistant task found for speech to text result'); + $this->logger->error('No assistant task found for speech to text result (task id: ' . $file->getId() . ')'); return; } // Update the meta task with the new status $assistantTask->setStatus(Application::STATUS_META_TASK_FAILED); + $assistantTask->setOutput($event->getErrorMessage()); $assistantTask = $this->metaTaskMapper->update($assistantTask); try { - $this->assistantService->sendNotification($assistantTask); + $this->notificationService->sendNotification($assistantTask); } catch (\InvalidArgumentException $e) { $this->logger->error('Failed to dispatch notification for failed transcription: ' . $e->getMessage()); } diff --git a/lib/Listener/TaskFailedListener.php b/lib/Listener/TaskFailedListener.php index 058d76e6..769cc7c6 100644 --- a/lib/Listener/TaskFailedListener.php +++ b/lib/Listener/TaskFailedListener.php @@ -5,7 +5,7 @@ use OCA\TpAssistant\AppInfo\Application; use OCA\TpAssistant\Db\MetaTaskMapper; use OCA\TpAssistant\Event\BeforeAssistantNotificationEvent; -use OCA\TpAssistant\Service\AssistantService; +use OCA\TpAssistant\Service\NotificationService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventDispatcher; @@ -18,7 +18,7 @@ class TaskFailedListener implements IEventListener { public function __construct( - private AssistantService $assistantService, + private NotificationService $notificationService, private IEventDispatcher $eventDispatcher, private MetaTaskMapper $metaTaskMapper, ) { @@ -59,9 +59,9 @@ public function handle(Event $event): void { // Update task status and output: $assistantTask->setStatus($task->getStatus()); - $assistantTask->setOutput($task->getOutput()); + $assistantTask->setOutput($event->getErrorMessage()); $assistantTask = $this->metaTaskMapper->update($assistantTask); - $this->assistantService->sendNotification($assistantTask, $notificationTarget, $notificationActionLabel); + $this->notificationService->sendNotification($assistantTask, $notificationTarget, $notificationActionLabel); } } diff --git a/lib/Listener/TaskSuccessfulListener.php b/lib/Listener/TaskSuccessfulListener.php index 0bf72bc3..3605154b 100644 --- a/lib/Listener/TaskSuccessfulListener.php +++ b/lib/Listener/TaskSuccessfulListener.php @@ -5,7 +5,7 @@ use OCA\TpAssistant\AppInfo\Application; use OCA\TpAssistant\Db\MetaTaskMapper; use OCA\TpAssistant\Event\BeforeAssistantNotificationEvent; -use OCA\TpAssistant\Service\AssistantService; +use OCA\TpAssistant\Service\NotificationService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventDispatcher; @@ -18,7 +18,7 @@ class TaskSuccessfulListener implements IEventListener { public function __construct( - private AssistantService $assistantService, + private NotificationService $notificationService, private IEventDispatcher $eventDispatcher, private MetaTaskMapper $metaTaskMapper, ) { @@ -62,6 +62,6 @@ public function handle(Event $event): void { $assistantTask->setOutput($task->getOutput()); $assistantTask = $this->metaTaskMapper->update($assistantTask); - $this->assistantService->sendNotification($assistantTask, $notificationTarget, $notificationActionLabel); + $this->notificationService->sendNotification($assistantTask, $notificationTarget, $notificationActionLabel); } } diff --git a/lib/Listener/Text2Image/Text2ImageResultListener.php b/lib/Listener/Text2Image/Text2ImageResultListener.php index 2d42f7ab..7c46338a 100644 --- a/lib/Listener/Text2Image/Text2ImageResultListener.php +++ b/lib/Listener/Text2Image/Text2ImageResultListener.php @@ -5,7 +5,7 @@ use OCA\TpAssistant\AppInfo\Application; use OCA\TpAssistant\Db\MetaTaskMapper; use OCA\TpAssistant\Db\Text2Image\ImageGenerationMapper; -use OCA\TpAssistant\Service\AssistantService; +use OCA\TpAssistant\Service\NotificationService; use OCA\TpAssistant\Service\Text2Image\Text2ImageHelperService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; @@ -24,10 +24,10 @@ class Text2ImageResultListener implements IEventListener { public function __construct( private Text2ImageHelperService $text2ImageService, - private ImageGenerationMapper $imageGenerationMapper, - private LoggerInterface $logger, - private AssistantService $assistantService, - private MetaTaskMapper $metaTaskMapper, + private ImageGenerationMapper $imageGenerationMapper, + private LoggerInterface $logger, + private NotificationService $notificationService, + private MetaTaskMapper $metaTaskMapper, ) { } @@ -67,16 +67,17 @@ public function handle(Event $event): void { // Update the assistant meta task status: $assistantTask->setStatus(Task::STATUS_FAILED); + $assistantTask->setOutput($event->getErrorMessage()); $assistantTask = $this->metaTaskMapper->update($assistantTask); - $this->assistantService->sendNotification($assistantTask); + $this->notificationService->sendNotification($assistantTask); } // Only send the notification if the user enabled them for this task: try { $imageGeneration = $this->imageGenerationMapper->getImageGenerationOfImageGenId($imageGenId); if ($imageGeneration->getNotifyReady()) { - $this->assistantService->sendNotification($assistantTask); + $this->notificationService->sendNotification($assistantTask); } } catch (\OCP\Db\Exception | DoesNotExistException | MultipleObjectsReturnedException $e) { $this->logger->warning('Could not notify user of a generation (id:' . $imageGenId . ') being ready: ' . $e->getMessage()); diff --git a/lib/Service/AssistantService.php b/lib/Service/AssistantService.php index 2d524e6d..253b5e7f 100644 --- a/lib/Service/AssistantService.php +++ b/lib/Service/AssistantService.php @@ -4,11 +4,10 @@ require_once __DIR__ . '/../../vendor/autoload.php'; -use DateTime; use OCA\TpAssistant\AppInfo\Application; use OCA\TpAssistant\Db\MetaTask; use OCA\TpAssistant\Db\MetaTaskMapper; -use OCA\TpAssistant\Db\Text2Image\ImageGenerationMapper; +use OCA\TpAssistant\Service\Text2Image\Text2ImageHelperService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\Common\Exception\NotFoundException; @@ -17,14 +16,12 @@ use OCP\Files\GenericFileException; use OCP\Files\IRootFolder; use OCP\Files\NotPermittedException; -use OCP\IURLGenerator; +use OCP\IL10N; use OCP\Lock\LockedException; -use OCP\Notification\IManager as INotificationManager; use OCP\PreConditionNotMetException; use OCP\TextProcessing\FreePromptTaskType; use OCP\TextProcessing\IManager as ITextProcessingManager; use OCP\TextProcessing\Task as TextProcessingTask; -use OCP\TextToImage\Task as TextToImageTask; use Parsedown; use PhpOffice\PhpWord\IOFactory; use Psr\Log\LoggerInterface; @@ -33,84 +30,15 @@ class AssistantService { public function __construct( - private INotificationManager $notificationManager, private ITextProcessingManager $textProcessingManager, - private MetaTaskMapper $metaTaskMapper, - private ImageGenerationMapper $imageGenerationMapper, - private LoggerInterface $logger, - private IRootFolder $storage, - private IURLGenerator $url, + private Text2ImageHelperService $text2ImageHelperService, + private MetaTaskMapper $metaTaskMapper, + private LoggerInterface $logger, + private IRootFolder $storage, + private IL10N $l10n, ) { } - /** - * Send a success or failure task result notification - * - * @param MetaTask $task - * @param string|null $customTarget optional notification link target - * @param string|null $actionLabel optional label for the notification action button - * @param string|null $resultPreview - * @return void - */ - public function sendNotification(MetaTask $task, ?string $customTarget = null, ?string $actionLabel = null, ?string $resultPreview = null): void { - $manager = $this->notificationManager; - $notification = $manager->createNotification(); - - $params = [ - 'appId' => $task->getAppId(), - 'id' => $task->getId(), - 'inputs' => $task->getInputsAsArray(), - 'target' => $customTarget ?? $this->getDefaultTarget($task), - 'actionLabel' => $actionLabel, - 'result' => $resultPreview, - ]; - $params['taskTypeClass'] = $task->getTaskType(); - $params['taskCategory'] = $task->getCategory(); - - switch ($task->getCategory()) { - case Application::TASK_CATEGORY_TEXT_TO_IMAGE: - { - $taskSuccessful = $task->getStatus() === TextToImageTask::STATUS_SUCCESSFUL; - break; - } - case Application::TASK_CATEGORY_TEXT_GEN: - { - $taskSuccessful = $task->getStatus() === TextProcessingTask::STATUS_SUCCESSFUL; - break; - } - case Application::TASK_CATEGORY_SPEECH_TO_TEXT: - { - $taskSuccessful = $task->getStatus() === Application::STT_TASK_SUCCESSFUL; - break; - } - default: - { - $taskSuccessful = false; - break; - } - } - - $subject = $taskSuccessful - ? 'success' - : 'failure'; - - $objectType = $customTarget === null - ? 'task' - : 'task-with-custom-target'; - - $notification->setApp(Application::APP_ID) - ->setUser($task->getUserId()) - ->setDateTime(new DateTime()) - ->setObject($objectType, (string) ($task->getId() ?? 0)) - ->setSubject($subject, $params); - - $manager->notify($notification); - } - - private function getDefaultTarget(MetaTask $task): string { - return $this->url->linkToRouteAbsolute(Application::APP_ID . '.assistant.getAssistantTaskResultPage', ['metaTaskId' => $task->getId()]); - } - /** * @param string $writingStyle * @param string $sourceMaterial @@ -190,6 +118,54 @@ public function getAssistantTask(string $userId, int $metaTaskId): ?MetaTask { return $metaTask; } + /** + * @param string $userId + * @param int $metaTaskId + * @return void + * @throws Exception + */ + public function deleteAssistantTask(string $userId, int $metaTaskId): void { + $metaTask = $this->getAssistantTask($userId, $metaTaskId); + if ($metaTask !== null) { + $this->cancelOcpTaskOfMetaTask($userId, $metaTask); + $this->metaTaskMapper->delete($metaTask); + } + } + + /** + * @param string $userId + * @param int $metaTaskId + * @return void + * @throws Exception + */ + public function cancelAssistantTask(string $userId, int $metaTaskId): void { + $metaTask = $this->getAssistantTask($userId, $metaTaskId); + if ($metaTask !== null) { + // deal with underlying tasks + if ($metaTask->getStatus() === Application::STATUS_META_TASK_SCHEDULED) { + $this->cancelOcpTaskOfMetaTask($userId, $metaTask); + } + + $metaTask->setStatus(Application::STATUS_META_TASK_FAILED); + $metaTask->setOutput($this->l10n->t('Canceled by user')); + $this->metaTaskMapper->update($metaTask); + } + } + + private function cancelOcpTaskOfMetaTask(string $userId, MetaTask $metaTask) { + if ($metaTask->getCategory() === Application::TASK_CATEGORY_TEXT_GEN) { + try { + $ocpTask = $this->textProcessingManager->getTask($metaTask->getOcpTaskId()); + $this->textProcessingManager->deleteTask($ocpTask); + } catch (NotFoundException $e) { + } + } elseif ($metaTask->getCategory() === Application::TASK_CATEGORY_TEXT_TO_IMAGE) { + $this->text2ImageHelperService->cancelGeneration($metaTask->getOutput(), $userId); + } elseif ($metaTask->getCategory() === Application::TASK_CATEGORY_SPEECH_TO_TEXT) { + // TODO implement task canceling in stt manager + } + } + /** * @param string $type * @param array $inputs diff --git a/lib/Service/NotificationService.php b/lib/Service/NotificationService.php new file mode 100644 index 00000000..9135df52 --- /dev/null +++ b/lib/Service/NotificationService.php @@ -0,0 +1,88 @@ +notificationManager; + $notification = $manager->createNotification(); + + $params = [ + 'appId' => $task->getAppId(), + 'id' => $task->getId(), + 'inputs' => $task->getInputsAsArray(), + 'target' => $customTarget ?? $this->getDefaultTarget($task), + 'actionLabel' => $actionLabel, + 'result' => $resultPreview, + ]; + $params['taskTypeClass'] = $task->getTaskType(); + $params['taskCategory'] = $task->getCategory(); + + switch ($task->getCategory()) { + case Application::TASK_CATEGORY_TEXT_TO_IMAGE: + { + $taskSuccessful = $task->getStatus() === TextToImageTask::STATUS_SUCCESSFUL; + break; + } + case Application::TASK_CATEGORY_TEXT_GEN: + { + $taskSuccessful = $task->getStatus() === TextProcessingTask::STATUS_SUCCESSFUL; + break; + } + case Application::TASK_CATEGORY_SPEECH_TO_TEXT: + { + $taskSuccessful = $task->getStatus() === Application::STT_TASK_SUCCESSFUL; + break; + } + default: + { + $taskSuccessful = false; + break; + } + } + + $subject = $taskSuccessful + ? 'success' + : 'failure'; + + $objectType = $customTarget === null + ? 'task' + : 'task-with-custom-target'; + + $notification->setApp(Application::APP_ID) + ->setUser($task->getUserId()) + ->setDateTime(new DateTime()) + ->setObject($objectType, (string) ($task->getId() ?? 0)) + ->setSubject($subject, $params); + + $manager->notify($notification); + } + + private function getDefaultTarget(MetaTask $task): string { + return $this->url->linkToRouteAbsolute(Application::APP_ID . '.assistant.getAssistantTaskResultPage', ['metaTaskId' => $task->getId()]); + } +} diff --git a/lib/Service/SpeechToText/SpeechToTextService.php b/lib/Service/SpeechToText/SpeechToTextService.php index b7fa0d2f..84aa8e0c 100644 --- a/lib/Service/SpeechToText/SpeechToTextService.php +++ b/lib/Service/SpeechToText/SpeechToTextService.php @@ -40,9 +40,9 @@ class SpeechToTextService { public function __construct( private ISpeechToTextManager $speechToTextManager, - private IRootFolder $rootFolder, - private IConfig $config, - private MetaTaskMapper $metaTaskMapper, + private IRootFolder $rootFolder, + private IConfig $config, + private MetaTaskMapper $metaTaskMapper, ) { } diff --git a/lib/Service/Text2Image/Text2ImageHelperService.php b/lib/Service/Text2Image/Text2ImageHelperService.php index c3783b65..daa2cd31 100644 --- a/lib/Service/Text2Image/Text2ImageHelperService.php +++ b/lib/Service/Text2Image/Text2ImageHelperService.php @@ -17,7 +17,7 @@ use OCA\TpAssistant\Db\Text2Image\PromptMapper; use OCA\TpAssistant\Db\Text2Image\StaleGenerationMapper; -use OCA\TpAssistant\Service\AssistantService; +use OCA\TpAssistant\Service\NotificationService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\AppFramework\Http; @@ -42,17 +42,17 @@ class Text2ImageHelperService { private ?ISimpleFolder $imageDataFolder = null; public function __construct( - private LoggerInterface $logger, - private IManager $textToImageManager, - private PromptMapper $promptMapper, + private LoggerInterface $logger, + private IManager $textToImageManager, + private PromptMapper $promptMapper, private ImageGenerationMapper $imageGenerationMapper, - private ImageFileNameMapper $imageFileNameMapper, + private ImageFileNameMapper $imageFileNameMapper, private StaleGenerationMapper $staleGenerationMapper, - private IAppData $appData, - private IURLGenerator $urlGenerator, - private IL10N $l10n, - private AssistantService $assistantService, - private MetaTaskMapper $metaTaskMapper, + private IAppData $appData, + private IURLGenerator $urlGenerator, + private IL10N $l10n, + private NotificationService $notificationService, + private MetaTaskMapper $metaTaskMapper, ) { } @@ -588,7 +588,7 @@ public function notifyWhenReady(string $imageGenId, string $userId): void { // No need to update the output since it's already set $assistantTask = $this->metaTaskMapper->update($assistantTask); - $this->assistantService->sendNotification($assistantTask); + $this->notificationService->sendNotification($assistantTask); } } } diff --git a/src/components/TaskList.vue b/src/components/TaskList.vue index 1b15a159..01add62f 100644 --- a/src/components/TaskList.vue +++ b/src/components/TaskList.vue @@ -1,23 +1,33 @@ diff --git a/src/components/TaskListItem.vue b/src/components/TaskListItem.vue index 6bbfb117..e89b164f 100644 --- a/src/components/TaskListItem.vue +++ b/src/components/TaskListItem.vue @@ -2,13 +2,13 @@ - + :details="details"> + @@ -16,13 +16,14 @@ From 10c1423e702cdc3017151f67c29551fa48b1590f Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 16 Feb 2024 11:08:00 +0100 Subject: [PATCH 04/17] fix transcribe input form reactivity Signed-off-by: Julien Veyssier --- src/assistant.js | 2 ++ src/components/AssistantFormInputs.vue | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/assistant.js b/src/assistant.js index 7aadbe49..2c7b74e4 100644 --- a/src/assistant.js +++ b/src/assistant.js @@ -10,6 +10,8 @@ export async function openAssistantForm(params) { return openAssistantTextProcessingForm(params) } +// TODO add param to lock on specific task type + /** * Creates an assistant modal and return a promise which provides the result * diff --git a/src/components/AssistantFormInputs.vue b/src/components/AssistantFormInputs.vue index bc850dce..487eb67d 100644 --- a/src/components/AssistantFormInputs.vue +++ b/src/components/AssistantFormInputs.vue @@ -154,8 +154,8 @@ export default { this.writingStyle = this.inputs.writingStyle ?? '' this.sourceMaterial = this.inputs.sourceMaterial ?? this.inputs.prompt ?? '' this.prompt = this.inputs.prompt ?? '' - this.sttMode = 'record' - this.sttAudioData = null + // this.sttMode = 'record' + this.sttAudioData = this.inputs.audioData this.sttAudioFilePath = this.inputs.audioFilePath ?? null this.ttiNResults = this.inputs.nResults ?? 1 this.ttiDisplayPrompt = this.inputs.displayPrompt ?? false From d4d1305d5b9bed7750fa9cb108819cedf8ca8ec1 Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 16 Feb 2024 11:29:03 +0100 Subject: [PATCH 05/17] fix stt form validation Signed-off-by: Julien Veyssier --- src/assistant.js | 10 +++++----- src/components/AssistantFormInputs.vue | 12 +++++++----- src/components/AssistantTextProcessingForm.vue | 6 +++++- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/assistant.js b/src/assistant.js index 2c7b74e4..7765a364 100644 --- a/src/assistant.js +++ b/src/assistant.js @@ -191,15 +191,15 @@ export async function runSttTask(inputs) { const { default: axios } = await import(/* webpackChunkName: "axios-lazy" */'@nextcloud/axios') const { generateUrl } = await import(/* webpackChunkName: "router-gen-lazy" */'@nextcloud/router') saveLastSelectedTaskType('speech-to-text') - if (inputs.audioData) { + if (inputs.sttMode === 'choose') { + const url = generateUrl('/apps/assistant/stt/transcribeFile') + const params = { path: this.audioFilePath } + return axios.post(url, params) + } else { const url = generateUrl('/apps/assistant/stt/transcribeAudio') const formData = new FormData() formData.append('audioData', inputs.audioData) return axios.post(url, formData) - } else { - const url = generateUrl('/apps/assistant/stt/transcribeFile') - const params = { path: this.audioFilePath } - return axios.post(url, params) } } diff --git a/src/components/AssistantFormInputs.vue b/src/components/AssistantFormInputs.vue index 487eb67d..545707ef 100644 --- a/src/components/AssistantFormInputs.vue +++ b/src/components/AssistantFormInputs.vue @@ -154,8 +154,8 @@ export default { this.writingStyle = this.inputs.writingStyle ?? '' this.sourceMaterial = this.inputs.sourceMaterial ?? this.inputs.prompt ?? '' this.prompt = this.inputs.prompt ?? '' - // this.sttMode = 'record' - this.sttAudioData = this.inputs.audioData + this.sttMode = this.inputs.sttMode ?? 'record' + this.sttAudioData = this.inputs.audioData ?? null this.sttAudioFilePath = this.inputs.audioFilePath ?? null this.ttiNResults = this.inputs.nResults ?? 1 this.ttiDisplayPrompt = this.inputs.displayPrompt ?? false @@ -226,9 +226,11 @@ export default { onUpdateStt() { this.$emit( 'update:inputs', - this.sttMode === 'record' - ? { audioData: this.sttAudioData } - : { audioFilePath: this.sttAudioFilePath }, + { + sttMode: this.sttMode, + audioData: this.sttAudioData, + audioFilePath: this.sttAudioFilePath, + }, ) }, onUpdateTti() { diff --git a/src/components/AssistantTextProcessingForm.vue b/src/components/AssistantTextProcessingForm.vue index 47af6141..f7a462a6 100644 --- a/src/components/AssistantTextProcessingForm.vue +++ b/src/components/AssistantTextProcessingForm.vue @@ -218,7 +218,11 @@ export default { return this.selectedTaskType }, canSubmit() { - // Check that none of the properties of myInputs are empty + if (this.selectedTaskType.id === 'speech-to-text') { + return (this.myInputs.sttMode === 'record' && this.myInputs.audioData !== null) + || (this.myInputs.sttMode === 'choose' && this.myInputs.audioFilePath !== null) + } + // otherwise, check that none of the properties of myInputs are empty return Object.values(this.myInputs).every(v => { return (typeof v === 'string' && !!v?.trim()) || (typeof v === 'boolean') From a421187e189d28a73acbfcfd776ed38a10cface6 Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 16 Feb 2024 12:03:57 +0100 Subject: [PATCH 06/17] clarify task statuses, fix stt status check when notifying Signed-off-by: Julien Veyssier --- lib/AppInfo/Application.php | 16 +++++-- lib/Listener/TaskFailedListener.php | 2 +- lib/Listener/TaskSuccessfulListener.php | 2 +- .../Text2Image/Text2ImageResultListener.php | 4 +- lib/Service/AssistantService.php | 12 ++++++ lib/Service/NotificationService.php | 43 +++++-------------- src/assistant.js | 2 +- 7 files changed, 40 insertions(+), 41 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index ab91e9c0..fda929fb 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -26,6 +26,7 @@ use OCP\SpeechToText\Events\TranscriptionSuccessfulEvent; use OCP\TextProcessing\Events\TaskFailedEvent as TextTaskFailedEvent; use OCP\TextProcessing\Events\TaskSuccessfulEvent as TextTaskSuccessfulEvent; +use OCP\TextProcessing\Task as OCPTextprocessingTask; use OCP\TextToImage\Events\TaskFailedEvent as TextToImageTaskFailedEvent; use OCP\TextToImage\Events\TaskSuccessfulEvent as TextToImageTaskSuccessfulEvent; @@ -45,11 +46,18 @@ class Application extends App implements IBootstrap { public const STT_TASK_SUCCESSFUL = 1; public const STT_TASK_FAILED = -1; - public const STATUS_META_TASK_FAILED = 4; - public const STATUS_META_TASK_SUCCESSFUL = 3; - public const STATUS_META_TASK_RUNNING = 2; - public const STATUS_META_TASK_SCHEDULED = 1; public const STATUS_META_TASK_UNKNOWN = 0; + public const STATUS_META_TASK_SCHEDULED = 1; + public const STATUS_META_TASK_RUNNING = 2; + public const STATUS_META_TASK_SUCCESSFUL = 3; + public const STATUS_META_TASK_FAILED = 4; + public const TP_STATUS_TO_META_STATUS = [ + OCPTextprocessingTask::STATUS_UNKNOWN => self::STATUS_META_TASK_UNKNOWN, + OCPTextprocessingTask::STATUS_SCHEDULED => self::STATUS_META_TASK_SCHEDULED, + OCPTextprocessingTask::STATUS_RUNNING => self::STATUS_META_TASK_RUNNING, + OCPTextprocessingTask::STATUS_SUCCESSFUL => self::STATUS_META_TASK_SUCCESSFUL, + OCPTextprocessingTask::STATUS_FAILED => self::STATUS_META_TASK_FAILED, + ]; public const TASK_CATEGORY_TEXT_GEN = 0; public const TASK_CATEGORY_TEXT_TO_IMAGE = 1; diff --git a/lib/Listener/TaskFailedListener.php b/lib/Listener/TaskFailedListener.php index 769cc7c6..ba664860 100644 --- a/lib/Listener/TaskFailedListener.php +++ b/lib/Listener/TaskFailedListener.php @@ -58,7 +58,7 @@ public function handle(Event $event): void { } // Update task status and output: - $assistantTask->setStatus($task->getStatus()); + $assistantTask->setStatus(Application::TP_STATUS_TO_META_STATUS[$task->getStatus()]); $assistantTask->setOutput($event->getErrorMessage()); $assistantTask = $this->metaTaskMapper->update($assistantTask); diff --git a/lib/Listener/TaskSuccessfulListener.php b/lib/Listener/TaskSuccessfulListener.php index 3605154b..ff1cf219 100644 --- a/lib/Listener/TaskSuccessfulListener.php +++ b/lib/Listener/TaskSuccessfulListener.php @@ -58,7 +58,7 @@ public function handle(Event $event): void { } // Update task status and output: - $assistantTask->setStatus($task->getStatus()); + $assistantTask->setStatus(Application::TP_STATUS_TO_META_STATUS[$task->getStatus()]); $assistantTask->setOutput($task->getOutput()); $assistantTask = $this->metaTaskMapper->update($assistantTask); diff --git a/lib/Listener/Text2Image/Text2ImageResultListener.php b/lib/Listener/Text2Image/Text2ImageResultListener.php index 7c46338a..5a83ca54 100644 --- a/lib/Listener/Text2Image/Text2ImageResultListener.php +++ b/lib/Listener/Text2Image/Text2ImageResultListener.php @@ -57,7 +57,7 @@ public function handle(Event $event): void { $this->text2ImageService->storeImages($images, $imageGenId); - $assistantTask->setStatus(Task::STATUS_SUCCESSFUL); + $assistantTask->setStatus(Application::STATUS_META_TASK_SUCCESSFUL); $assistantTask = $this->metaTaskMapper->update($assistantTask); } @@ -66,7 +66,7 @@ public function handle(Event $event): void { $this->imageGenerationMapper->setFailed($imageGenId, true); // Update the assistant meta task status: - $assistantTask->setStatus(Task::STATUS_FAILED); + $assistantTask->setStatus(Application::STATUS_META_TASK_FAILED); $assistantTask->setOutput($event->getErrorMessage()); $assistantTask = $this->metaTaskMapper->update($assistantTask); diff --git a/lib/Service/AssistantService.php b/lib/Service/AssistantService.php index 253b5e7f..429e6fc7 100644 --- a/lib/Service/AssistantService.php +++ b/lib/Service/AssistantService.php @@ -4,12 +4,14 @@ require_once __DIR__ . '/../../vendor/autoload.php'; +use OC\SpeechToText\TranscriptionJob; use OCA\TpAssistant\AppInfo\Application; use OCA\TpAssistant\Db\MetaTask; use OCA\TpAssistant\Db\MetaTaskMapper; use OCA\TpAssistant\Service\Text2Image\Text2ImageHelperService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; +use OCP\BackgroundJob\IJobList; use OCP\Common\Exception\NotFoundException; use OCP\DB\Exception; use OCP\Files\File; @@ -35,6 +37,7 @@ public function __construct( private MetaTaskMapper $metaTaskMapper, private LoggerInterface $logger, private IRootFolder $storage, + private IJobList $jobList, private IL10N $l10n, ) { } @@ -163,6 +166,15 @@ private function cancelOcpTaskOfMetaTask(string $userId, MetaTask $metaTask) { $this->text2ImageHelperService->cancelGeneration($metaTask->getOutput(), $userId); } elseif ($metaTask->getCategory() === Application::TASK_CATEGORY_SPEECH_TO_TEXT) { // TODO implement task canceling in stt manager + $jobArguments = [ + 'fileId' => $metaTask->getOcpTaskId(), + 'owner' => $userId, + 'userId' => $userId, + 'appId' => Application::APP_ID, + ]; + if ($this->jobList->has(TranscriptionJob::class, $jobArguments)) { + $this->jobList->remove(TranscriptionJob::class, $jobArguments); + } } } diff --git a/lib/Service/NotificationService.php b/lib/Service/NotificationService.php index 9135df52..41d09fb4 100644 --- a/lib/Service/NotificationService.php +++ b/lib/Service/NotificationService.php @@ -21,49 +21,28 @@ public function __construct( /** * Send a success or failure task result notification * - * @param MetaTask $task + * @param MetaTask $metaTask * @param string|null $customTarget optional notification link target * @param string|null $actionLabel optional label for the notification action button * @param string|null $resultPreview * @return void */ - public function sendNotification(MetaTask $task, ?string $customTarget = null, ?string $actionLabel = null, ?string $resultPreview = null): void { + public function sendNotification(MetaTask $metaTask, ?string $customTarget = null, ?string $actionLabel = null, ?string $resultPreview = null): void { $manager = $this->notificationManager; $notification = $manager->createNotification(); $params = [ - 'appId' => $task->getAppId(), - 'id' => $task->getId(), - 'inputs' => $task->getInputsAsArray(), - 'target' => $customTarget ?? $this->getDefaultTarget($task), + 'appId' => $metaTask->getAppId(), + 'id' => $metaTask->getId(), + 'inputs' => $metaTask->getInputsAsArray(), + 'target' => $customTarget ?? $this->getDefaultTarget($metaTask), 'actionLabel' => $actionLabel, 'result' => $resultPreview, ]; - $params['taskTypeClass'] = $task->getTaskType(); - $params['taskCategory'] = $task->getCategory(); + $params['taskTypeClass'] = $metaTask->getTaskType(); + $params['taskCategory'] = $metaTask->getCategory(); - switch ($task->getCategory()) { - case Application::TASK_CATEGORY_TEXT_TO_IMAGE: - { - $taskSuccessful = $task->getStatus() === TextToImageTask::STATUS_SUCCESSFUL; - break; - } - case Application::TASK_CATEGORY_TEXT_GEN: - { - $taskSuccessful = $task->getStatus() === TextProcessingTask::STATUS_SUCCESSFUL; - break; - } - case Application::TASK_CATEGORY_SPEECH_TO_TEXT: - { - $taskSuccessful = $task->getStatus() === Application::STT_TASK_SUCCESSFUL; - break; - } - default: - { - $taskSuccessful = false; - break; - } - } + $taskSuccessful = $metaTask->getStatus() === Application::STATUS_META_TASK_SUCCESSFUL; $subject = $taskSuccessful ? 'success' @@ -74,9 +53,9 @@ public function sendNotification(MetaTask $task, ?string $customTarget = null, ? : 'task-with-custom-target'; $notification->setApp(Application::APP_ID) - ->setUser($task->getUserId()) + ->setUser($metaTask->getUserId()) ->setDateTime(new DateTime()) - ->setObject($objectType, (string) ($task->getId() ?? 0)) + ->setObject($objectType, (string) ($metaTask->getId() ?? 0)) ->setSubject($subject, $params); $manager->notify($notification); diff --git a/src/assistant.js b/src/assistant.js index 7765a364..48cf6eef 100644 --- a/src/assistant.js +++ b/src/assistant.js @@ -193,7 +193,7 @@ export async function runSttTask(inputs) { saveLastSelectedTaskType('speech-to-text') if (inputs.sttMode === 'choose') { const url = generateUrl('/apps/assistant/stt/transcribeFile') - const params = { path: this.audioFilePath } + const params = { path: inputs.audioFilePath } return axios.post(url, params) } else { const url = generateUrl('/apps/assistant/stt/transcribeAudio') From 67bfee83dd253a5fe5d6c09647db26100aef9b5d Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Fri, 16 Feb 2024 13:40:36 +0100 Subject: [PATCH 07/17] fix psalm errors Signed-off-by: Julien Veyssier --- lib/Service/NotificationService.php | 2 -- psalm.xml | 1 + tests/stubs/oc_transcription.php | 13 +++++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/stubs/oc_transcription.php diff --git a/lib/Service/NotificationService.php b/lib/Service/NotificationService.php index 41d09fb4..cff326e4 100644 --- a/lib/Service/NotificationService.php +++ b/lib/Service/NotificationService.php @@ -7,8 +7,6 @@ use OCA\TpAssistant\Db\MetaTask; use OCP\IURLGenerator; use OCP\Notification\IManager as INotificationManager; -use OCP\TextProcessing\Task as TextProcessingTask; -use OCP\TextToImage\Task as TextToImageTask; class NotificationService { diff --git a/psalm.xml b/psalm.xml index 5613fa39..812a7f51 100644 --- a/psalm.xml +++ b/psalm.xml @@ -49,5 +49,6 @@ + diff --git a/tests/stubs/oc_transcription.php b/tests/stubs/oc_transcription.php new file mode 100644 index 00000000..b5e34001 --- /dev/null +++ b/tests/stubs/oc_transcription.php @@ -0,0 +1,13 @@ + Date: Mon, 19 Feb 2024 14:22:25 +0100 Subject: [PATCH 08/17] add status title Signed-off-by: Julien Veyssier --- src/components/TaskListItem.vue | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/TaskListItem.vue b/src/components/TaskListItem.vue index f034003f..e398fc69 100644 --- a/src/components/TaskListItem.vue +++ b/src/components/TaskListItem.vue @@ -8,7 +8,7 @@ :details="details" @click="$emit('load')">