]> source.dussan.org Git - nextcloud-server.git/commitdiff
AI admin settings: Use config values in AI feature managers
authorMarcel Klehr <mklehr@gmx.net>
Tue, 25 Jul 2023 12:17:57 +0000 (14:17 +0200)
committerJulien Veyssier <julien-nc@posteo.net>
Wed, 2 Aug 2023 10:37:35 +0000 (12:37 +0200)
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
apps/settings/lib/Settings/Admin/ArtificialIntelligence.php
lib/private/SpeechToText/SpeechToTextManager.php
lib/private/TextProcessing/Manager.php
lib/private/Translation/TranslationManager.php

index ad5425d8ded9b62e725636b09ae2e6d6166bf96d..2f36e4b033070103b561df69081cb6c35dd1df64 100644 (file)
@@ -112,7 +112,7 @@ class ArtificialIntelligence implements IDelegatedSettings {
                        $value = $defaultValue;
                        $json = $this->config->getAppValue('core', $key, '');
                        if ($json !== '') {
-                               $value = json_decode($json, JSON_OBJECT_AS_ARRAY);
+                               $value = json_decode($json, true);
                                switch($key) {
                                        case 'ai.textprocessing_provider_preferences':
                                                // fill $value with $defaultValue values
index 757fc02485e9820ac34c2aada2b7a387b8d6850c..bdd04ad365176468d84afd64e3629556760293f0 100644 (file)
@@ -34,6 +34,7 @@ use OCP\BackgroundJob\IJobList;
 use OCP\Files\File;
 use OCP\Files\InvalidPathException;
 use OCP\Files\NotFoundException;
+use OCP\IConfig;
 use OCP\IServerContainer;
 use OCP\PreConditionNotMetException;
 use OCP\SpeechToText\ISpeechToTextManager;
@@ -53,6 +54,7 @@ class SpeechToTextManager implements ISpeechToTextManager {
                private Coordinator $coordinator,
                private LoggerInterface $logger,
                private IJobList $jobList,
+               private IConfig $config,
        ) {
        }
 
@@ -111,7 +113,18 @@ class SpeechToTextManager implements ISpeechToTextManager {
                        throw new PreConditionNotMetException('No SpeechToText providers have been registered');
                }
 
-               foreach ($this->getProviders() as $provider) {
+               $providers = $this->getProviders();
+
+               $json = $this->config->getAppValue('core', 'ai.stt_provider', '');
+               if ($json !== '') {
+                       $className = json_decode($json, true);
+                       $provider = current(array_filter($providers, fn ($provider) => $provider::class === $className));
+                       if ($provider !== false) {
+                               $providers = [$provider];
+                       }
+               }
+
+               foreach ($providers as $provider) {
                        try {
                                return $provider->transcribeFile($file);
                        } catch (\Throwable $e) {
index f52482bbb321985c4262ad1029feb0b06091d7fd..05e046a004978080d10a6710b6974bc9bd3fe916 100644 (file)
@@ -27,6 +27,7 @@ namespace OC\TextProcessing;
 
 use OC\AppFramework\Bootstrap\Coordinator;
 use OC\TextProcessing\Db\Task as DbTask;
+use OCP\IConfig;
 use OCP\TextProcessing\Task as OCPTask;
 use OC\TextProcessing\Db\TaskMapper;
 use OCP\AppFramework\Db\DoesNotExistException;
@@ -52,6 +53,7 @@ class Manager implements IManager {
                private LoggerInterface $logger,
                private IJobList $jobList,
                private TaskMapper $taskMapper,
+               private IConfig $config,
        ) {
        }
 
@@ -111,7 +113,21 @@ class Manager implements IManager {
                if (!$this->canHandleTask($task)) {
                        throw new PreConditionNotMetException('No text processing provider is installed that can handle this task');
                }
-               foreach ($this->getProviders() as $provider) {
+               $providers = $this->getProviders();
+               $json = $this->config->getAppValue('core', 'ai.textprocessing_provider_preferences', '');
+               if ($json !== '') {
+                       $preferences = json_decode($json, true);
+                       if (isset($preferences[$task->getType()])) {
+                               // If a preference for this task type is set, move the preferred provider to the start
+                               $provider = current(array_filter($providers, fn ($provider) => $provider::class === $preferences[$task->getType()]));
+                               if ($provider !== false) {
+                                       $providers = array_filter($providers, fn ($p) => $p !== $provider);
+                                       array_unshift($providers, $provider);
+                               }
+                       }
+               }
+
+               foreach ($providers as $provider) {
                        if (!$task->canUseProvider($provider)) {
                                continue;
                        }
index 8456c41cdfcebdd8afc13ae8c780ce26293b350a..48a0e2cdebdda7bf9c32aa93a36cc4ee738f010f 100644 (file)
@@ -28,6 +28,7 @@ namespace OC\Translation;
 
 use InvalidArgumentException;
 use OC\AppFramework\Bootstrap\Coordinator;
+use OCP\IConfig;
 use OCP\IServerContainer;
 use OCP\PreConditionNotMetException;
 use OCP\Translation\CouldNotTranslateException;
@@ -48,6 +49,7 @@ class TranslationManager implements ITranslationManager {
                private IServerContainer $serverContainer,
                private Coordinator $coordinator,
                private LoggerInterface $logger,
+               private IConfig $config,
        ) {
        }
 
@@ -64,8 +66,25 @@ class TranslationManager implements ITranslationManager {
                        throw new PreConditionNotMetException('No translation providers available');
                }
 
+               $providers = $this->getProviders();
+               $json = $this->config->getAppValue('core', 'ai.translation_provider_preferences', '');
+
+               if ($json !== '') {
+                       $precedence = json_decode($json, true);
+                       $newProviders = [];
+                       foreach ($precedence as $className) {
+                               $provider = current(array_filter($providers, fn ($provider) => $provider::class === $className));
+                               if ($provider !== false) {
+                                       $newProviders[] = $provider;
+                               }
+                       }
+                       // Add all providers that haven't been added so far
+                       $newProviders += array_udiff($providers, $newProviders, fn ($a, $b) => $a::class > $b::class ? 1 : ($a::class < $b::class ? -1 : 0));
+                       $providers = $newProviders;
+               }
+
                if ($fromLanguage === null) {
-                       foreach ($this->getProviders() as $provider) {
+                       foreach ($providers as $provider) {
                                if ($provider instanceof IDetectLanguageProvider) {
                                        $fromLanguage = $provider->detectLanguage($text);
                                }
@@ -84,11 +103,11 @@ class TranslationManager implements ITranslationManager {
                        return $text;
                }
 
-               foreach ($this->getProviders() as $provider) {
+               foreach ($providers as $provider) {
                        try {
                                return $provider->translate($fromLanguage, $toLanguage, $text);
                        } catch (RuntimeException $e) {
-                               $this->logger->warning("Failed to translate from {$fromLanguage} to {$toLanguage}", ['exception' => $e]);
+                               $this->logger->warning("Failed to translate from {$fromLanguage} to {$toLanguage} using provider {$provider->getName()}", ['exception' => $e]);
                        }
                }