From 15abc4b7fdccb69ddb27911afeea5c0f6f6c5736 Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Fri, 8 May 2026 08:27:51 +0200 Subject: [PATCH 1/5] Resolve feedback Signed-off-by: Lukas Schaefer --- lib/TaskProcessing/ReformatParagraphsProvider.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/TaskProcessing/ReformatParagraphsProvider.php b/lib/TaskProcessing/ReformatParagraphsProvider.php index e7d3ac37..2308b187 100644 --- a/lib/TaskProcessing/ReformatParagraphsProvider.php +++ b/lib/TaskProcessing/ReformatParagraphsProvider.php @@ -21,6 +21,7 @@ use OCP\TaskProcessing\ISynchronousProvider; use OCP\TaskProcessing\ShapeDescriptor; use RuntimeException; +use InvalidArgumentException; class ReformatParagraphsProvider implements ISynchronousProvider { private const TASK_TYPE_ID = 'core:text2text:reformatparagraphs'; From 7f4ab39340df7832d6bb69b25f4375bf45a8bc01 Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Wed, 6 May 2026 14:44:54 -0400 Subject: [PATCH 2/5] Create enhanced AudioToTextEnhancedProvider that also reformats text from transcription Signed-off-by: Lukas Schaefer --- lib/AppInfo/Application.php | 4 ++ .../AudioToTextEnhancedProvider.php | 70 +++++++++++++++++++ lib/TaskProcessing/AudioToTextProvider.php | 8 +-- 3 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 lib/TaskProcessing/AudioToTextEnhancedProvider.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 902dbfe6..34c1941b 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -11,6 +11,7 @@ use OCA\OpenAi\Notification\Notifier; use OCA\OpenAi\OldProcessing\Translation\TranslationProvider as OldTranslationProvider; use OCA\OpenAi\TaskProcessing\AudioToAudioChatProvider; +use OCA\OpenAi\TaskProcessing\AudioToTextEnhancedProvider; use OCA\OpenAi\TaskProcessing\AudioToTextProvider; use OCA\OpenAi\TaskProcessing\ChangeToneProvider; use OCA\OpenAi\TaskProcessing\ChangeToneTaskType; @@ -108,6 +109,9 @@ public function register(IRegistrationContext $context): void { } if ($this->appConfig->getValueString(Application::APP_ID, 'stt_provider_enabled', '1') === '1') { $context->registerTaskProcessingProvider(AudioToTextProvider::class); + if (class_exists('OCP\\TaskProcessing\\TaskTypes\\TextToTextReformatParagraphs')) { + $context->registerTaskProcessingProvider(AudioToTextEnhancedProvider::class); + } } $serviceUrl = $this->appConfig->getValueString(Application::APP_ID, 'url'); diff --git a/lib/TaskProcessing/AudioToTextEnhancedProvider.php b/lib/TaskProcessing/AudioToTextEnhancedProvider.php new file mode 100644 index 00000000..06eed2af --- /dev/null +++ b/lib/TaskProcessing/AudioToTextEnhancedProvider.php @@ -0,0 +1,70 @@ +taskProcessingManager = $taskProcessingManager; + } + + public function getId(): string { + return parent::getId() . '-enhanced'; + } + + public function getName(): string { + return parent::getName() . ' ' . $this->l->t('(with paragraph reformatting)'); + } + + public function process(?string $userId, array $input, callable $reportProgress): array { + $transcription = parent::process($userId, $input, $reportProgress)['output']; + + $reformatTask = new Task( + self::REFORMAT_PARAGRAPHS_TASK_TYPE_ID, + ['input' => $transcription], + Application::APP_ID, + $userId, + 'audio2text_enhanced', + ); + + try { + $finished = $this->taskProcessingManager->runTask($reformatTask); + $output = $finished->getOutput(); + if (is_array($output) && isset($output['output']) && is_string($output['output']) && $output['output'] !== '') { + return ['output' => $output['output']]; + } + $this->logger->warning('ReformatParagraphs follow-up task returned no usable output, falling back to raw transcription'); + } catch (Throwable $e) { + $this->logger->warning('ReformatParagraphs follow-up task failed, falling back to raw transcription: ' . $e->getMessage(), ['exception' => $e]); + } + + return ['output' => $transcription]; + } +} diff --git a/lib/TaskProcessing/AudioToTextProvider.php b/lib/TaskProcessing/AudioToTextProvider.php index b78a3948..bb050803 100644 --- a/lib/TaskProcessing/AudioToTextProvider.php +++ b/lib/TaskProcessing/AudioToTextProvider.php @@ -26,10 +26,10 @@ class AudioToTextProvider implements ISynchronousProvider { public function __construct( - private OpenAiAPIService $openAiAPIService, - private LoggerInterface $logger, - private IAppConfig $appConfig, - private IL10N $l, + protected OpenAiAPIService $openAiAPIService, + protected LoggerInterface $logger, + protected IAppConfig $appConfig, + protected IL10N $l, ) { } From 0cc77cbd056d0955219bc276176cc7915af958dc Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Fri, 8 May 2026 10:41:53 +0200 Subject: [PATCH 3/5] Switch away from extend and to dependency injection Signed-off-by: Lukas Schaefer --- .../AudioToTextEnhancedProvider.php | 74 ++++++++++++++----- lib/TaskProcessing/AudioToTextProvider.php | 8 +- .../ReformatParagraphsProvider.php | 1 - 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/lib/TaskProcessing/AudioToTextEnhancedProvider.php b/lib/TaskProcessing/AudioToTextEnhancedProvider.php index 06eed2af..9079529b 100644 --- a/lib/TaskProcessing/AudioToTextEnhancedProvider.php +++ b/lib/TaskProcessing/AudioToTextEnhancedProvider.php @@ -11,43 +11,81 @@ use OCA\OpenAi\AppInfo\Application; use OCA\OpenAi\Service\OpenAiAPIService; -use OCP\IAppConfig; -use OCP\IL10N; use OCP\TaskProcessing\IManager; +use OCP\TaskProcessing\ISynchronousProvider; use OCP\TaskProcessing\Task; +use OCP\TaskProcessing\TaskTypes\AudioToText; use Psr\Log\LoggerInterface; use Throwable; -// Built on top of the AudioToTextProvider to add paragraph reformatting. -class AudioToTextEnhancedProvider extends AudioToTextProvider { - private const REFORMAT_PARAGRAPHS_TASK_TYPE_ID = 'core:text2text:reformatparagraphs'; - - private IManager $taskProcessingManager; +class AudioToTextEnhancedProvider implements ISynchronousProvider { public function __construct( - OpenAiAPIService $openAiAPIService, - LoggerInterface $logger, - IAppConfig $appConfig, - IL10N $l, - IManager $taskProcessingManager, + private AudioToTextProvider $audioToTextProvider, + private OpenAiAPIService $openAiAPIService, + private IManager $taskProcessingManager, + private LoggerInterface $logger, ) { - parent::__construct($openAiAPIService, $logger, $appConfig, $l); - $this->taskProcessingManager = $taskProcessingManager; } public function getId(): string { - return parent::getId() . '-enhanced'; + return $this->audioToTextProvider->getId() . '-enhanced'; } public function getName(): string { - return parent::getName() . ' ' . $this->l->t('(with paragraph reformatting)'); + return $this->audioToTextProvider->getName() . ' (with paragraph reformatting)'; + } + + public function getTaskTypeId(): string { + return AudioToText::ID; + } + + public function getExpectedRuntime(): int { + return $this->audioToTextProvider->getExpectedRuntime(); + } + + public function getInputShapeEnumValues(): array { + return $this->audioToTextProvider->getInputShapeEnumValues(); + } + + public function getInputShapeDefaults(): array { + return $this->audioToTextProvider->getInputShapeDefaults(); + } + + public function getOptionalInputShape(): array { + return $this->audioToTextProvider->getOptionalInputShape(); + } + + public function getOptionalInputShapeEnumValues(): array { + return $this->audioToTextProvider->getOptionalInputShapeEnumValues(); + } + + public function getOptionalInputShapeDefaults(): array { + return $this->audioToTextProvider->getOptionalInputShapeDefaults(); + } + + public function getOutputShapeEnumValues(): array { + return $this->audioToTextProvider->getOutputShapeEnumValues(); + } + + public function getOptionalOutputShape(): array { + return $this->audioToTextProvider->getOptionalOutputShape(); + } + + public function getOptionalOutputShapeEnumValues(): array { + return $this->audioToTextProvider->getOptionalOutputShapeEnumValues(); } public function process(?string $userId, array $input, callable $reportProgress): array { - $transcription = parent::process($userId, $input, $reportProgress)['output']; + $transcription = $this->audioToTextProvider->process($userId, $input, $reportProgress)['output']; + + // Skip reformatting if the transcription is empty + if (trim($transcription) === '') { + return ['output' => $transcription]; + } $reformatTask = new Task( - self::REFORMAT_PARAGRAPHS_TASK_TYPE_ID, + \OCP\TaskProcessing\TaskTypes\TextToTextReformatParagraphs::ID, ['input' => $transcription], Application::APP_ID, $userId, diff --git a/lib/TaskProcessing/AudioToTextProvider.php b/lib/TaskProcessing/AudioToTextProvider.php index bb050803..b78a3948 100644 --- a/lib/TaskProcessing/AudioToTextProvider.php +++ b/lib/TaskProcessing/AudioToTextProvider.php @@ -26,10 +26,10 @@ class AudioToTextProvider implements ISynchronousProvider { public function __construct( - protected OpenAiAPIService $openAiAPIService, - protected LoggerInterface $logger, - protected IAppConfig $appConfig, - protected IL10N $l, + private OpenAiAPIService $openAiAPIService, + private LoggerInterface $logger, + private IAppConfig $appConfig, + private IL10N $l, ) { } diff --git a/lib/TaskProcessing/ReformatParagraphsProvider.php b/lib/TaskProcessing/ReformatParagraphsProvider.php index 2308b187..e7d3ac37 100644 --- a/lib/TaskProcessing/ReformatParagraphsProvider.php +++ b/lib/TaskProcessing/ReformatParagraphsProvider.php @@ -21,7 +21,6 @@ use OCP\TaskProcessing\ISynchronousProvider; use OCP\TaskProcessing\ShapeDescriptor; use RuntimeException; -use InvalidArgumentException; class ReformatParagraphsProvider implements ISynchronousProvider { private const TASK_TYPE_ID = 'core:text2text:reformatparagraphs'; From 910c47bc8f85eb763d2bc92dc6a7405206cb126d Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Mon, 11 May 2026 11:33:03 +0200 Subject: [PATCH 4/5] Don't use AudioToTextProvider functions for output types Signed-off-by: Lukas Schaefer --- lib/TaskProcessing/AudioToTextEnhancedProvider.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/TaskProcessing/AudioToTextEnhancedProvider.php b/lib/TaskProcessing/AudioToTextEnhancedProvider.php index 9079529b..5fbe8bce 100644 --- a/lib/TaskProcessing/AudioToTextEnhancedProvider.php +++ b/lib/TaskProcessing/AudioToTextEnhancedProvider.php @@ -41,7 +41,7 @@ public function getTaskTypeId(): string { } public function getExpectedRuntime(): int { - return $this->audioToTextProvider->getExpectedRuntime(); + return $this->audioToTextProvider->getExpectedRuntime() + $this->openAiAPIService->getExpTextProcessingTime(); } public function getInputShapeEnumValues(): array { @@ -65,15 +65,15 @@ public function getOptionalInputShapeDefaults(): array { } public function getOutputShapeEnumValues(): array { - return $this->audioToTextProvider->getOutputShapeEnumValues(); + return []; } public function getOptionalOutputShape(): array { - return $this->audioToTextProvider->getOptionalOutputShape(); + return []; } public function getOptionalOutputShapeEnumValues(): array { - return $this->audioToTextProvider->getOptionalOutputShapeEnumValues(); + return []; } public function process(?string $userId, array $input, callable $reportProgress): array { From 693e6e828206a9fe13720d50f5e44d925945e490 Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Mon, 11 May 2026 14:30:49 +0200 Subject: [PATCH 5/5] Disclaimer about runtime Signed-off-by: Lukas Schaefer --- lib/TaskProcessing/AudioToTextEnhancedProvider.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/TaskProcessing/AudioToTextEnhancedProvider.php b/lib/TaskProcessing/AudioToTextEnhancedProvider.php index 5fbe8bce..a2dcf079 100644 --- a/lib/TaskProcessing/AudioToTextEnhancedProvider.php +++ b/lib/TaskProcessing/AudioToTextEnhancedProvider.php @@ -41,6 +41,7 @@ public function getTaskTypeId(): string { } public function getExpectedRuntime(): int { + // The audio to text provider may not be openai and this assumes it is return $this->audioToTextProvider->getExpectedRuntime() + $this->openAiAPIService->getExpTextProcessingTime(); }