diff --git a/appinfo/info.xml b/appinfo/info.xml index 55a48c6b..0c98896f 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -62,7 +62,7 @@ Known providers: More details on how to set this up in the [admin docs](https://docs.nextcloud.com/server/latest/admin_manual/ai/index.html) ]]> - 3.3.0 + 3.3.1-dev.0 agpl Julien Veyssier Assistant diff --git a/lib/Controller/ChattyLLMController.php b/lib/Controller/ChattyLLMController.php index e996cb0e..5b31199f 100644 --- a/lib/Controller/ChattyLLMController.php +++ b/lib/Controller/ChattyLLMController.php @@ -134,6 +134,7 @@ public function newSession(int $timestamp, ?string $title = null): JSONResponse Application::APP_ID, 'chat_user_instructions', Application::CHAT_USER_INSTRUCTIONS, + lazy: true, ) ?: Application::CHAT_USER_INSTRUCTIONS; $userInstructions = str_replace('{user}', $user->getDisplayName(), $userInstructions); @@ -879,6 +880,7 @@ public function generateTitle(int $sessionId): JSONResponse { Application::APP_ID, 'chat_user_instructions_title', Application::CHAT_USER_INSTRUCTIONS_TITLE, + lazy: true, ) ?: Application::CHAT_USER_INSTRUCTIONS_TITLE; $userInstructions = str_replace('{user}', $user->getDisplayName(), $userInstructions); @@ -952,6 +954,7 @@ public function checkTitleGenerationTask(int $taskId, int $sessionId): JSONRespo Application::APP_ID, 'chat_user_instructions_title', Application::CHAT_USER_INSTRUCTIONS_TITLE, + lazy: true, ) ?: Application::CHAT_USER_INSTRUCTIONS_TITLE; $userInstructions = str_replace('{user}', $user->getDisplayName(), $userInstructions); $title = str_replace($userInstructions, '', $taskOutput); @@ -982,7 +985,7 @@ public function checkTitleGenerationTask(int $taskId, int $sessionId): JSONRespo * @throws \OCP\DB\Exception */ private function getRawLastMessages(int $sessionId): array { - $lastNMessages = intval($this->appConfig->getValueString(Application::APP_ID, 'chat_last_n_messages', '10')); + $lastNMessages = intval($this->appConfig->getValueString(Application::APP_ID, 'chat_last_n_messages', '10', lazy: true)); $messages = $this->messageMapper->getMessages($sessionId, 0, $lastNMessages); if ($messages[0]->getRole() === 'system') { diff --git a/lib/Controller/ConfigController.php b/lib/Controller/ConfigController.php index 367f208f..7709bfd8 100644 --- a/lib/Controller/ConfigController.php +++ b/lib/Controller/ConfigController.php @@ -64,7 +64,12 @@ public function getConfigValue(string $key): DataResponse { */ public function setAdminConfig(array $values): DataResponse { foreach ($values as $key => $value) { - $this->appConfig->setValueString(Application::APP_ID, $key, $value); + if ($key == 'assistant_enabled') { + // do not lazy store assistant_enabled as it is needed for capabilities + $this->appConfig->setValueString(Application::APP_ID, $key, $value); + } else { + $this->appConfig->setValueString(Application::APP_ID, $key, $value, lazy: true); + } } return new DataResponse(1); } diff --git a/lib/Listener/BeforeTemplateRenderedListener.php b/lib/Listener/BeforeTemplateRenderedListener.php index 97e9ebba..2c4fd6f0 100644 --- a/lib/Listener/BeforeTemplateRenderedListener.php +++ b/lib/Listener/BeforeTemplateRenderedListener.php @@ -58,7 +58,7 @@ public function handle(Event $event): void { $this->eventDispatcher->dispatchTyped(new RenderReferenceEvent()); - $adminAssistantEnabled = $this->appConfig->getValueString(Application::APP_ID, 'assistant_enabled', '1') === '1'; + $adminAssistantEnabled = $this->appConfig->getValueString(Application::APP_ID, 'assistant_enabled', '1', lazy: true) === '1'; $userAssistantEnabled = $this->config->getUserValue($this->userId, Application::APP_ID, 'assistant_enabled', '1') === '1'; $assistantEnabled = $adminAssistantEnabled && $userAssistantEnabled; $this->initialStateService->provideInitialState('assistant-enabled', $assistantEnabled); @@ -68,7 +68,7 @@ public function handle(Event $event): void { $lastTargetLanguage = $this->config->getUserValue($this->userId, Application::APP_ID, 'last_target_language', ''); $this->initialStateService->provideInitialState('last-target-language', $lastTargetLanguage); - $indexingComplete = $this->appConfig->getValueInt('context_chat', 'last_indexed_time', 0) !== 0; + $indexingComplete = $this->appConfig->getValueInt('context_chat', 'last_indexed_time', 0, lazy: true) !== 0; $this->initialStateService->provideInitialState('contextChatIndexingComplete', $indexingComplete); $this->initialStateService->provideInitialState('contextAgentToolSources', $this->assistantService->informationSources); $this->initialStateService->provideInitialState('audio_chat_available', $this->assistantService->isAudioChatAvailable()); diff --git a/lib/Listener/FreePrompt/FreePromptReferenceListener.php b/lib/Listener/FreePrompt/FreePromptReferenceListener.php index c7aa46b2..b0b39f2c 100644 --- a/lib/Listener/FreePrompt/FreePromptReferenceListener.php +++ b/lib/Listener/FreePrompt/FreePromptReferenceListener.php @@ -36,7 +36,7 @@ public function handle(Event $event): void { return; } - if ($this->appConfig->getValueString(Application::APP_ID, 'free_prompt_picker_enabled', '1') === '1' + if ($this->appConfig->getValueString(Application::APP_ID, 'free_prompt_picker_enabled', '1', lazy: true) === '1' && $this->config->getUserValue($this->userId, Application::APP_ID, 'free_prompt_picker_enabled', '1') === '1') { // Double check that at least one provider is registered diff --git a/lib/Listener/LoadAdditionalScriptsListener.php b/lib/Listener/LoadAdditionalScriptsListener.php index 714c7a10..5043d483 100644 --- a/lib/Listener/LoadAdditionalScriptsListener.php +++ b/lib/Listener/LoadAdditionalScriptsListener.php @@ -49,7 +49,7 @@ public function handle(Event $event): void { Util::addInitScript(Application::APP_ID, Application::APP_ID . '-fileActions'); // New file menu to generate images - $isNewFileMenuEnabled = $this->appConfig->getValueInt(Application::APP_ID, 'new_image_file_menu_plugin', 1) === 1; + $isNewFileMenuEnabled = $this->appConfig->getValueInt(Application::APP_ID, 'new_image_file_menu_plugin', 1, lazy: true) === 1; if ($isNewFileMenuEnabled) { $hasText2Image = array_key_exists(TextToImage::ID, $availableTaskTypes); $this->initialStateService->provideInitialState('new-file-generate-image', [ diff --git a/lib/Listener/SpeechToText/SpeechToTextReferenceListener.php b/lib/Listener/SpeechToText/SpeechToTextReferenceListener.php index d7005350..cc57cdc6 100644 --- a/lib/Listener/SpeechToText/SpeechToTextReferenceListener.php +++ b/lib/Listener/SpeechToText/SpeechToTextReferenceListener.php @@ -34,7 +34,7 @@ public function handle(Event $event): void { if (!$event instanceof RenderReferenceEvent) { return; } - if ($this->appConfig->getValueString(Application::APP_ID, 'speech_to_text_picker_enabled', '1') === '1' + if ($this->appConfig->getValueString(Application::APP_ID, 'speech_to_text_picker_enabled', '1', lazy: true) === '1' && ($this->userId === null || $this->config->getUserValue($this->userId, Application::APP_ID, 'speech_to_text_picker_enabled', '1') === '1')) { // Double check that at least one provider is registered diff --git a/lib/Listener/Text2Image/Text2ImageReferenceListener.php b/lib/Listener/Text2Image/Text2ImageReferenceListener.php index ae581c04..ea92d8e3 100644 --- a/lib/Listener/Text2Image/Text2ImageReferenceListener.php +++ b/lib/Listener/Text2Image/Text2ImageReferenceListener.php @@ -35,7 +35,7 @@ public function handle(Event $event): void { return; } - if ($this->appConfig->getValueString(Application::APP_ID, 'text_to_image_picker_enabled', '1') === '1' + if ($this->appConfig->getValueString(Application::APP_ID, 'text_to_image_picker_enabled', '1', lazy: true) === '1' && $this->config->getUserValue($this->userId, Application::APP_ID, 'text_to_image_picker_enabled', '1') === '1') { // Double check that at least one provider is registered diff --git a/lib/Listener/Text2Image/Text2StickerListener.php b/lib/Listener/Text2Image/Text2StickerListener.php index 28d00fd5..8edab0e1 100644 --- a/lib/Listener/Text2Image/Text2StickerListener.php +++ b/lib/Listener/Text2Image/Text2StickerListener.php @@ -36,7 +36,7 @@ public function handle(Event $event): void { return; } - if ($this->appConfig->getValueString(Application::APP_ID, 'text_to_sticker_picker_enabled', '1') === '1' + if ($this->appConfig->getValueString(Application::APP_ID, 'text_to_sticker_picker_enabled', '1', lazy: true) === '1' && $this->config->getUserValue($this->userId, Application::APP_ID, 'text_to_sticker_picker_enabled', '1') === '1') { // Double check that all necessary task types are available diff --git a/lib/Migration/Version020201Date20250120174409.php b/lib/Migration/Version020201Date20250120174409.php index bd7eabe1..ca2bc2cf 100644 --- a/lib/Migration/Version020201Date20250120174409.php +++ b/lib/Migration/Version020201Date20250120174409.php @@ -39,10 +39,15 @@ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array ]; foreach ($keysToFix as $key) { if ($this->appConfig->hasKey(Application::APP_ID, $key) - && $this->appConfig->getValueType(Application::APP_ID, $key) === IAppConfig::VALUE_INT) { - $value = $this->appConfig->getValueInt(Application::APP_ID, $key); + && $this->appConfig->getValueType(Application::APP_ID, $key, lazy: true) === IAppConfig::VALUE_INT) { + $value = $this->appConfig->getValueInt(Application::APP_ID, $key, lazy: true); $this->appConfig->deleteKey(Application::APP_ID, $key); - $this->appConfig->setValueString(Application::APP_ID, $key, (string)$value); + if ($key == 'assistant_enabled') { + // do not lazy store assistant_enabled as it is needed for capabilities + $this->appConfig->setValueString(Application::APP_ID, $key, (string)$value); + } else { + $this->appConfig->setValueString(Application::APP_ID, $key, (string)$value, lazy: true); + } } } } diff --git a/lib/Migration/Version030301Date20260225130151.php b/lib/Migration/Version030301Date20260225130151.php new file mode 100644 index 00000000..faf710a7 --- /dev/null +++ b/lib/Migration/Version030301Date20260225130151.php @@ -0,0 +1,53 @@ +appConfig->getAppKeys(); + + foreach (self::$configKeys as $key) { + // skip if not already set + if (!in_array($key, $allSetKeys)) { + continue; + } + $value = $this->appConfig->getAppValueString($key); + $this->appConfig->setAppValueString($key, $value, lazy: true); + } + } +} diff --git a/lib/Service/SessionSummaryService.php b/lib/Service/SessionSummaryService.php index da62a28d..b7ca5fb0 100644 --- a/lib/Service/SessionSummaryService.php +++ b/lib/Service/SessionSummaryService.php @@ -120,13 +120,13 @@ public function getMemories(?string $userId): array { if ($session->getSummary() !== null) { $memory = $session->getSummary() ?? ''; if (!$session->getIsSummaryUpToDate()) { - $lastNMessages = intval($this->appConfig->getValueString(Application::APP_ID, 'chat_last_n_messages', '10')); + $lastNMessages = intval($this->appConfig->getValueString(Application::APP_ID, 'chat_last_n_messages', '10', lazy: true)); $chatHistory = $this->messageMapper->getMessages($session->getId(), 0, $lastNMessages); $memory .= 'The summary is outdated. These are the last messages in the raw chat history: ' . json_encode($chatHistory); } } else { - $lastNMessages = intval($this->appConfig->getValueString(Application::APP_ID, 'chat_last_n_messages', '10')); + $lastNMessages = intval($this->appConfig->getValueString(Application::APP_ID, 'chat_last_n_messages', '10', lazy: true)); $chatHistory = $this->messageMapper->getMessages($session->getId(), 0, $lastNMessages); $memory = 'This is the raw chat history of a chat between the user and Assistant: ' . json_encode($chatHistory); } diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php index 15ee290a..9aa45291 100644 --- a/lib/Settings/Admin.php +++ b/lib/Settings/Admin.php @@ -40,18 +40,18 @@ public function getForm(): TemplateResponse { $textToImageAvailable = array_key_exists(TextToImage::ID, $availableTaskTypes); $textToStickerAvailable = array_key_exists(TextToStickerTaskType::ID, $availableTaskTypes); - $assistantEnabled = $this->appConfig->getValueString(Application::APP_ID, 'assistant_enabled', '1') === '1'; + $assistantEnabled = $this->appConfig->getValueString(Application::APP_ID, 'assistant_enabled', '1', lazy: true) === '1'; - $freePromptPickerEnabled = $this->appConfig->getValueString(Application::APP_ID, 'free_prompt_picker_enabled', '1') === '1'; - $textToImagePickerEnabled = $this->appConfig->getValueString(Application::APP_ID, 'text_to_image_picker_enabled', '1') === '1'; + $freePromptPickerEnabled = $this->appConfig->getValueString(Application::APP_ID, 'free_prompt_picker_enabled', '1', lazy: true) === '1'; + $textToImagePickerEnabled = $this->appConfig->getValueString(Application::APP_ID, 'text_to_image_picker_enabled', '1', lazy: true) === '1'; // if we can't generate images, let's assume the sticker picker is disabled // but when image generation will be available again, we have kept the value set by the admin - $textToStickerPickerEnabled = $this->appConfig->getValueString(Application::APP_ID, 'text_to_sticker_picker_enabled', '1') === '1'; + $textToStickerPickerEnabled = $this->appConfig->getValueString(Application::APP_ID, 'text_to_sticker_picker_enabled', '1', lazy: true) === '1'; - $speechToTextEnabled = $this->appConfig->getValueString(Application::APP_ID, 'speech_to_text_picker_enabled', '1') === '1'; - $chattyLLMUserInstructions = $this->appConfig->getValueString(Application::APP_ID, 'chat_user_instructions', Application::CHAT_USER_INSTRUCTIONS) ?: Application::CHAT_USER_INSTRUCTIONS; - $chattyLLMUserInstructionsTitle = $this->appConfig->getValueString(Application::APP_ID, 'chat_user_instructions_title', Application::CHAT_USER_INSTRUCTIONS_TITLE) ?: Application::CHAT_USER_INSTRUCTIONS_TITLE; - $chattyLLMLastNMessages = (int)$this->appConfig->getValueString(Application::APP_ID, 'chat_last_n_messages', '10'); + $speechToTextEnabled = $this->appConfig->getValueString(Application::APP_ID, 'speech_to_text_picker_enabled', '1', lazy: true) === '1'; + $chattyLLMUserInstructions = $this->appConfig->getValueString(Application::APP_ID, 'chat_user_instructions', Application::CHAT_USER_INSTRUCTIONS, lazy: true) ?: Application::CHAT_USER_INSTRUCTIONS; + $chattyLLMUserInstructionsTitle = $this->appConfig->getValueString(Application::APP_ID, 'chat_user_instructions_title', Application::CHAT_USER_INSTRUCTIONS_TITLE, lazy: true) ?: Application::CHAT_USER_INSTRUCTIONS_TITLE; + $chattyLLMLastNMessages = (int)$this->appConfig->getValueString(Application::APP_ID, 'chat_last_n_messages', '10', lazy: true); $adminConfig = [ 'task_processing_available' => $taskProcessingAvailable, diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php index 1a8d8335..44ee8b3c 100644 --- a/lib/Settings/Personal.php +++ b/lib/Settings/Personal.php @@ -48,19 +48,19 @@ public function getForm(): TemplateResponse { || (class_exists('OCP\\TaskProcessing\\TaskTypes\\ContextAgentAudioInteraction') && array_key_exists(\OCP\TaskProcessing\TaskTypes\ContextAgentAudioInteraction::ID, $availableTaskTypes)); $autoplayAudioChat = $this->config->getUserValue($this->userId, Application::APP_ID, 'autoplay_audio_chat', '1') === '1'; - $assistantAvailable = $taskProcessingAvailable && $this->appConfig->getValueString(Application::APP_ID, 'assistant_enabled', '1') === '1'; + $assistantAvailable = $taskProcessingAvailable && $this->appConfig->getValueString(Application::APP_ID, 'assistant_enabled', '1', lazy: true) === '1'; $assistantEnabled = $this->config->getUserValue($this->userId, Application::APP_ID, 'assistant_enabled', '1') === '1'; - $textToImagePickerAvailable = $textToImageAvailable && $this->appConfig->getValueString(Application::APP_ID, 'text_to_image_picker_enabled', '1') === '1'; + $textToImagePickerAvailable = $textToImageAvailable && $this->appConfig->getValueString(Application::APP_ID, 'text_to_image_picker_enabled', '1', lazy: true) === '1'; $textToImagePickerEnabled = $this->config->getUserValue($this->userId, Application::APP_ID, 'text_to_image_picker_enabled', '1') === '1'; - $textToStickerPickerAvailable = $textToImageAvailable && $this->appConfig->getValueString(Application::APP_ID, 'text_to_sticker_picker_enabled', '1') === '1'; + $textToStickerPickerAvailable = $textToImageAvailable && $this->appConfig->getValueString(Application::APP_ID, 'text_to_sticker_picker_enabled', '1', lazy: true) === '1'; $textToStickerPickerEnabled = $this->config->getUserValue($this->userId, Application::APP_ID, 'text_to_sticker_picker_enabled', '1') === '1'; - $freePromptPickerAvailable = $freePromptTaskTypeAvailable && $this->appConfig->getValueString(Application::APP_ID, 'free_prompt_picker_enabled', '1') === '1'; + $freePromptPickerAvailable = $freePromptTaskTypeAvailable && $this->appConfig->getValueString(Application::APP_ID, 'free_prompt_picker_enabled', '1', lazy: true) === '1'; $freePromptPickerEnabled = $this->config->getUserValue($this->userId, Application::APP_ID, 'free_prompt_picker_enabled', '1') === '1'; - $speechToTextPickerAvailable = $speechToTextAvailable && $this->appConfig->getValueString(Application::APP_ID, 'speech_to_text_picker_enabled', '1') === '1'; + $speechToTextPickerAvailable = $speechToTextAvailable && $this->appConfig->getValueString(Application::APP_ID, 'speech_to_text_picker_enabled', '1', lazy: true) === '1'; $speechToTextPickerEnabled = $this->config->getUserValue($this->userId, Application::APP_ID, 'speech_to_text_picker_enabled', '1') === '1';