Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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)
]]> </description>
<version>3.3.0</version>
<version>3.3.1-dev.0</version>
<licence>agpl</licence>
<author>Julien Veyssier</author>
<namespace>Assistant</namespace>
Expand Down
5 changes: 4 additions & 1 deletion lib/Controller/ChattyLLMController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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') {
Expand Down
7 changes: 6 additions & 1 deletion lib/Controller/ConfigController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Listener/BeforeTemplateRenderedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion lib/Listener/FreePrompt/FreePromptReferenceListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/Listener/LoadAdditionalScriptsListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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', [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/Listener/Text2Image/Text2ImageReferenceListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/Listener/Text2Image/Text2StickerListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 8 additions & 3 deletions lib/Migration/Version020201Date20250120174409.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
}
Expand Down
53 changes: 53 additions & 0 deletions lib/Migration/Version030301Date20260225130151.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Assistant\Migration;

use Closure;
use OCP\AppFramework\Services\IAppConfig;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
use Override;

class Version030301Date20260225130151 extends SimpleMigrationStep {
private static array $configKeys = [
'chat_user_instructions',
'chat_user_instructions_title',
'chat_last_n_messages',
'free_prompt_picker_enabled',
'text_to_image_picker_enabled',
'text_to_sticker_picker_enabled',
'speech_to_text_picker_enabled',
'new_image_file_menu_plugin',
]; // do not lazy store assistant_enabled as it is needed for capabilities
public function __construct(
private IAppConfig $appConfig,
) {
}

/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
#[Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$allSetKeys = $this->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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you double check whether we need to delete the entry first for the lazy-setting to work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as intended for me, I don't know if there could be differences between db systems but it's just another column in the db entry so I wouldn't know why it shouldn't

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great

}
}
}
4 changes: 2 additions & 2 deletions lib/Service/SessionSummaryService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
16 changes: 8 additions & 8 deletions lib/Settings/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 5 additions & 5 deletions lib/Settings/Personal.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';


Expand Down