From 02b0c97807e469bb11d8694a13edad862c6ddcd0 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Wed, 26 Nov 2025 15:13:56 +0100 Subject: [PATCH 1/3] feat: Add system tags to AI generated files Signed-off-by: Marcel Klehr --- .../FileActionTaskSuccessfulListener.php | 8 ++++ .../NewFileMenuTaskSuccessfulListener.php | 10 ++++- lib/Service/AssistantService.php | 32 +++++++++----- lib/Service/SystemTagService.php | 43 +++++++++++++++++++ 4 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 lib/Service/SystemTagService.php diff --git a/lib/Listener/FileActionTaskSuccessfulListener.php b/lib/Listener/FileActionTaskSuccessfulListener.php index f04d15c3..437c66cb 100644 --- a/lib/Listener/FileActionTaskSuccessfulListener.php +++ b/lib/Listener/FileActionTaskSuccessfulListener.php @@ -10,10 +10,12 @@ namespace OCA\Assistant\Listener; use OCA\Assistant\Service\NotificationService; +use OCA\Assistant\Service\SystemTagService; use OCA\Assistant\Service\TaskProcessingService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\Files\IRootFolder; +use OCP\SystemTag\TagNotFoundException; use OCP\TaskProcessing\Events\TaskSuccessfulEvent; use OCP\TaskProcessing\TaskTypes\TextToTextSummary; use Psr\Log\LoggerInterface; @@ -28,6 +30,7 @@ public function __construct( private NotificationService $notificationService, private IRootFolder $rootFolder, private LoggerInterface $logger, + private SystemTagService $systemTagService, ) { } @@ -79,6 +82,11 @@ class_exists('OCP\\TaskProcessing\\TaskTypes\\TextToSpeech') $targetFile = $sourceFileParent->newFile($targetFileName, $textResult); $this->logger->debug('FileActionTaskListener wrote file', ['target' => $targetFileName]); } + try { + $this->systemTagService->assignAiTagToFile((string)$targetFile->getId()); + } catch (TagNotFoundException $e) { + $this->logger->warning('FileActionTaskListener could not write AI tag to file', ['target' => $targetFileName, 'exception' => $e]); + } $this->notificationService->sendFileActionNotification( $task->getUserId(), $taskTypeId, $task->getId(), $sourceFileId, $sourceFile->getName(), $userFolder->getRelativePath($sourceFile->getPath()), diff --git a/lib/Listener/NewFileMenuTaskSuccessfulListener.php b/lib/Listener/NewFileMenuTaskSuccessfulListener.php index f6b2fb28..cb7cf2e4 100644 --- a/lib/Listener/NewFileMenuTaskSuccessfulListener.php +++ b/lib/Listener/NewFileMenuTaskSuccessfulListener.php @@ -9,9 +9,11 @@ use OCA\Assistant\Service\AssistantService; use OCA\Assistant\Service\NotificationService; +use OCA\Assistant\Service\SystemTagService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\Files\IRootFolder; +use OCP\SystemTag\TagNotFoundException; use OCP\TaskProcessing\Events\TaskSuccessfulEvent; use Psr\Log\LoggerInterface; @@ -25,6 +27,7 @@ public function __construct( private AssistantService $assistantService, private LoggerInterface $logger, private IRootFolder $rootFolder, + private SystemTagService $systemTagService, ) { } @@ -50,6 +53,11 @@ public function handle(Event $event): void { $fileId = (int)$task->getOutput()['images'][0]; try { $targetFile = $this->assistantService->saveNewFileMenuActionFile($task->getUserId(), $task->getId(), $fileId, $directoryId); + try { + $this->systemTagService->assignAiTagToFile((string)$targetFile->getId()); + } catch (TagNotFoundException $e) { + $this->logger->warning('NewFileMenuTaskListener could not write AI tag to file', ['target' => $targetFile->getName(), 'exception' => $e]); + } $userFolder = $this->rootFolder->getUserFolder($task->getUserId()); $directory = $targetFile->getParent(); $this->notificationService->sendNewImageFileNotification( @@ -58,7 +66,7 @@ public function handle(Event $event): void { $targetFile->getId(), $targetFile->getName(), $userFolder->getRelativePath($targetFile->getPath()), ); } catch (\Exception $e) { - $this->logger->error('TaskSuccessfulListener: Failed to save new file menu action file.', [ + $this->logger->error('NewFileMenuTaskListener: Failed to save new file menu action file.', [ 'task' => $task->jsonSerialize(), 'exception' => $e, ]); diff --git a/lib/Service/AssistantService.php b/lib/Service/AssistantService.php index 1998549f..0edb871e 100644 --- a/lib/Service/AssistantService.php +++ b/lib/Service/AssistantService.php @@ -31,6 +31,7 @@ use OCP\PreConditionNotMetException; use OCP\Share\IManager as IShareManager; use OCP\Share\IShare; +use OCP\SystemTag\TagNotFoundException; use OCP\TaskProcessing\EShapeType; use OCP\TaskProcessing\Exception\Exception as TaskProcessingException; use OCP\TaskProcessing\Exception\NotFoundException; @@ -81,14 +82,15 @@ class AssistantService { public function __construct( private ITaskProcessingManager $taskProcessingManager, private TaskNotificationMapper $taskNotificationMapper, - private NotificationService $notificationService, - private PreviewService $previewService, - private LoggerInterface $logger, - private IRootFolder $rootFolder, - private IL10N $l10n, - private ITempManager $tempManager, - private IConfig $config, - private IShareManager $shareManager, + private NotificationService $notificationService, + private PreviewService $previewService, + private LoggerInterface $logger, + private IRootFolder $rootFolder, + private IL10N $l10n, + private ITempManager $tempManager, + private IConfig $config, + private IShareManager $shareManager, + private SystemTagService $systemTagService, ) { $this->informationSources = [ 'ask_context_chat' => $this->l10n->t('Context Chat'), @@ -540,16 +542,24 @@ private function saveFile(string $userId, int $ocpTaskId, int $fileId): File { $existingTarget = $assistantDataFolder->get($targetFileName); if ($existingTarget instanceof File) { if ($existingTarget->getSize() === $taskOutputFile->getSize()) { - return $existingTarget; + $file = $existingTarget; } else { - return $assistantDataFolder->newFile($targetFileName, $taskOutputFile->fopen('rb')); + $file = $assistantDataFolder->newFile($targetFileName, $taskOutputFile->fopen('rb')); } } else { throw new Exception('Impossible to copy output file, a directory with this name already exists', Http::STATUS_UNAUTHORIZED); } } else { - return $assistantDataFolder->newFile($targetFileName, $taskOutputFile->fopen('rb')); + $file = $assistantDataFolder->newFile($targetFileName, $taskOutputFile->fopen('rb')); } + + try { + $this->systemTagService->assignAiTagToFile((string)$file->getId()); + } catch (TagNotFoundException $e) { + $this->logger->warning('Could not write AI tag to file', ['target' => $file->getName(), 'exception' => $e]); + } + + return $file; } /** diff --git a/lib/Service/SystemTagService.php b/lib/Service/SystemTagService.php new file mode 100644 index 00000000..31379a54 --- /dev/null +++ b/lib/Service/SystemTagService.php @@ -0,0 +1,43 @@ +systemTagManager->getTag(self::AI_TAG_NAME, true, true); + } catch (TagNotFoundException $e) { + return $this->systemTagManager->createTag(self::AI_TAG_NAME, true, true); + } + } + + /** + * @param string|list $fileId + * @return void + * @throws TagNotFoundException + */ + public function assignAiTagToFile(string|array $fileId) { + $this->systemTagObjectMapper->assignTags($fileId, 'files', $this->getAiTag()->getId()); + } +} \ No newline at end of file From 2c9e6377a7d3c7d0ef470c9190b6ddee8780681c Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Wed, 26 Nov 2025 15:16:33 +0100 Subject: [PATCH 2/3] fix: Run cs:fix Signed-off-by: Marcel Klehr --- .../NewFileMenuTaskSuccessfulListener.php | 2 +- lib/Service/AssistantService.php | 18 +++++++++--------- lib/Service/SystemTagService.php | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/Listener/NewFileMenuTaskSuccessfulListener.php b/lib/Listener/NewFileMenuTaskSuccessfulListener.php index cb7cf2e4..4a679ca5 100644 --- a/lib/Listener/NewFileMenuTaskSuccessfulListener.php +++ b/lib/Listener/NewFileMenuTaskSuccessfulListener.php @@ -27,7 +27,7 @@ public function __construct( private AssistantService $assistantService, private LoggerInterface $logger, private IRootFolder $rootFolder, - private SystemTagService $systemTagService, + private SystemTagService $systemTagService, ) { } diff --git a/lib/Service/AssistantService.php b/lib/Service/AssistantService.php index 0edb871e..a42bbe54 100644 --- a/lib/Service/AssistantService.php +++ b/lib/Service/AssistantService.php @@ -82,15 +82,15 @@ class AssistantService { public function __construct( private ITaskProcessingManager $taskProcessingManager, private TaskNotificationMapper $taskNotificationMapper, - private NotificationService $notificationService, - private PreviewService $previewService, - private LoggerInterface $logger, - private IRootFolder $rootFolder, - private IL10N $l10n, - private ITempManager $tempManager, - private IConfig $config, - private IShareManager $shareManager, - private SystemTagService $systemTagService, + private NotificationService $notificationService, + private PreviewService $previewService, + private LoggerInterface $logger, + private IRootFolder $rootFolder, + private IL10N $l10n, + private ITempManager $tempManager, + private IConfig $config, + private IShareManager $shareManager, + private SystemTagService $systemTagService, ) { $this->informationSources = [ 'ask_context_chat' => $this->l10n->t('Context Chat'), diff --git a/lib/Service/SystemTagService.php b/lib/Service/SystemTagService.php index 31379a54..5fe93053 100644 --- a/lib/Service/SystemTagService.php +++ b/lib/Service/SystemTagService.php @@ -16,7 +16,7 @@ class SystemTagService { - const AI_TAG_NAME = 'Generated using AI'; + public const AI_TAG_NAME = 'Generated using AI'; public function __construct( private ISystemTagManager $systemTagManager, @@ -40,4 +40,4 @@ public function getAiTag() { public function assignAiTagToFile(string|array $fileId) { $this->systemTagObjectMapper->assignTags($fileId, 'files', $this->getAiTag()->getId()); } -} \ No newline at end of file +} From 26425464f37bee85ccafe7aa50d2c9dc28247dd1 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Wed, 26 Nov 2025 15:16:33 +0100 Subject: [PATCH 3/3] fix: Address review comment Signed-off-by: Marcel Klehr --- lib/Service/SystemTagService.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Service/SystemTagService.php b/lib/Service/SystemTagService.php index 5fe93053..742c31fa 100644 --- a/lib/Service/SystemTagService.php +++ b/lib/Service/SystemTagService.php @@ -33,11 +33,11 @@ public function getAiTag() { } /** - * @param string|list $fileId + * @param string $fileId * @return void * @throws TagNotFoundException */ - public function assignAiTagToFile(string|array $fileId) { + public function assignAiTagToFile(string $fileId) { $this->systemTagObjectMapper->assignTags($fileId, 'files', $this->getAiTag()->getId()); } }