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
15 changes: 10 additions & 5 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
use OCP\Security\CSP\AddContentSecurityPolicyEvent;
use OCP\TaskProcessing\Events\TaskFailedEvent;
use OCP\TaskProcessing\Events\TaskSuccessfulEvent;
use OCP\TaskProcessing\IManager;

class Application extends App implements IBootstrap {

Expand All @@ -56,11 +57,14 @@ class Application extends App implements IBootstrap {
public const CHAT_USER_INSTRUCTIONS_TITLE = 'Above is a chat session in a specific language between the user and you, Nextcloud Assistant. Generate a suitable title summarizing the conversation in the same language. Output only the title in plain text, nothing else.';

private IAppConfig $appConfig;
private IManager $taskProcessingManager;

public function __construct(array $urlParams = []) {
parent::__construct(self::APP_ID, $urlParams);

$container = $this->getContainer();
$this->appConfig = $container->get(IAppConfig::class);
$this->taskProcessingManager = $container->get(IManager::class);
}

public function register(IRegistrationContext $context): void {
Expand All @@ -69,7 +73,6 @@ public function register(IRegistrationContext $context): void {
$context->registerCapability(Capabilities::class);

$context->registerReferenceProvider(Text2ImageReferenceProvider::class);
$context->registerReferenceProvider(Text2StickerProvider::class);
$context->registerReferenceProvider(FreePromptReferenceProvider::class);
$context->registerReferenceProvider(SpeechToTextReferenceProvider::class);
$context->registerReferenceProvider(TaskOutputFileReferenceProvider::class);
Expand Down Expand Up @@ -101,10 +104,12 @@ public function register(IRegistrationContext $context): void {
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\ContextAgentAudioInteraction')) {
$context->registerTaskProcessingProvider(ContextAgentAudioInteractionProvider::class);
}
if ($this->appConfig->getValueString(Application::APP_ID, 'text_to_sticker_picker_enabled', '1') === '1') {
$context->registerTaskProcessingTaskType(TextToStickerTaskType::class);
$context->registerTaskProcessingProvider(TextToStickerProvider::class);
}

// TODO use this when we drop NC <= 31
// if (in_array(TextToImage::ID, $this->taskProcessingManager->getAvailableTaskTypeIds(), true)) {
$context->registerTaskProcessingTaskType(TextToStickerTaskType::class);
$context->registerTaskProcessingProvider(TextToStickerProvider::class);
$context->registerReferenceProvider(Text2StickerProvider::class);
}

public function boot(IBootContext $context): void {
Expand Down
8 changes: 6 additions & 2 deletions lib/Listener/Text2Image/Text2StickerListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace OCA\Assistant\Listener\Text2Image;

use OCA\Assistant\AppInfo\Application;
use OCA\Assistant\TaskProcessing\TextToStickerTaskType;
use OCP\Collaboration\Reference\RenderReferenceEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
Expand Down Expand Up @@ -38,10 +39,13 @@ public function handle(Event $event): void {
if ($this->appConfig->getValueString(Application::APP_ID, 'text_to_sticker_picker_enabled', '1') === '1'
&& $this->config->getUserValue($this->userId, Application::APP_ID, 'text_to_sticker_picker_enabled', '1') === '1') {

// Double check that at least one provider is registered
// Double check that all necessary task types are available
// For some reason, taskProcessingManager->getAvailableTaskTypeIds does not return all the task types here
// most likely because all providers are not registered when RenderReferenceEvent is fired
$availableTaskTypes = $this->taskProcessingManager->getAvailableTaskTypes();
$textToImageAvailable = array_key_exists(TextToImage::ID, $availableTaskTypes);
if ($textToImageAvailable) {
$textToStickerAvailable = array_key_exists(TextToStickerTaskType::ID, $availableTaskTypes);
if ($textToImageAvailable && $textToStickerAvailable) {
Util::addScript(Application::APP_ID, Application::APP_ID . '-stickerGeneration');
}
}
Expand Down
2 changes: 0 additions & 2 deletions lib/Reference/Text2StickerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,4 @@ public function getCacheKey(string $referenceId): ?string {
public function invalidateUserCache(string $userId): void {
$this->referenceManager->invalidateCache($userId);
}


}
9 changes: 5 additions & 4 deletions lib/Settings/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace OCA\Assistant\Settings;

use OCA\Assistant\AppInfo\Application;
use OCA\Assistant\TaskProcessing\TextToStickerTaskType;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\IAppConfig;
Expand Down Expand Up @@ -37,16 +38,15 @@ public function getForm(): TemplateResponse {
$freePromptTaskTypeAvailable = array_key_exists(TextToText::ID, $availableTaskTypes);
$speechToTextAvailable = array_key_exists(AudioToText::ID, $availableTaskTypes);
$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';

$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';
// 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';
if ($textToStickerPickerEnabled && !$textToImageAvailable) {
$this->appConfig->setValueString(Application::APP_ID, 'text_to_sticker_picker_enabled', '0');
$textToStickerPickerEnabled = false;
}

$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;
Expand All @@ -57,6 +57,7 @@ public function getForm(): TemplateResponse {
'text_processing_available' => $taskProcessingAvailable,
'assistant_enabled' => $assistantEnabled,
'text_to_image_picker_available' => $textToImageAvailable,
'text_to_sticker_available' => $textToStickerAvailable,
'text_to_image_picker_enabled' => $textToImagePickerEnabled,
'text_to_sticker_picker_enabled' => $textToStickerPickerEnabled,
'free_prompt_task_type_available' => $freePromptTaskTypeAvailable,
Expand Down
7 changes: 7 additions & 0 deletions lib/TaskProcessing/TextToStickerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use OCA\Assistant\AppInfo\Application;
use OCA\Assistant\Service\TaskProcessingService;
use OCP\IL10N;
use OCP\TaskProcessing\IManager;
use OCP\TaskProcessing\ISynchronousProvider;
use OCP\TaskProcessing\Task;
use OCP\TaskProcessing\TaskTypes\TextToImage;
Expand All @@ -24,6 +25,7 @@ class TextToStickerProvider implements ISynchronousProvider {
public function __construct(
private IL10N $l,
private TaskProcessingService $taskProcessingService,
private IManager $taskProcessingManager,
private LoggerInterface $logger,
) {
}
Expand Down Expand Up @@ -83,6 +85,11 @@ public function process(?string $userId, array $input, callable $reportProgress)
}
$input = $input['input'];

$availableTaskTypes = $this->taskProcessingManager->getAvailableTaskTypes();
if (!array_key_exists(TextToImage::ID, $availableTaskTypes)) {
throw new RuntimeException('Text to image task type not available');
}

// Generate Image with custom prompt
try {
$task = new Task(
Expand Down
15 changes: 9 additions & 6 deletions src/components/AdminSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
{{ t('assistant', 'Nextcloud Assistant') }}
</h2>
<p><a href="https://docs.nextcloud.com/server/latest/admin_manual/ai/index.html">{{ t('assistant', 'Find more details on how to set up Assistant and recommended backends in the Administration documentation.') }}</a></p>
<NcNoteCard v-if="state.text_to_sticker_available && !state.text_to_image_picker_available" type="warning">
{{ t('assistant', 'The sticker generation feature won`t work without being able to generate images. Please install and enable a "Generate image" provider or disable the "Generate sticker" task type.') }}
</NcNoteCard>
<div id="assistant-content">
<div>
<h3>
Expand All @@ -21,7 +24,7 @@
{{ t('assistant', 'Enable Nextcloud Assistant in header') }}
</div>
</NcCheckboxRadioSwitch>
<NcNoteCard v-if="!state.text_processing_available" type="info">
<NcNoteCard v-if="!state.text_processing_available" type="warning">
{{ t('assistant', 'To be able to use this feature, please install at least one AI task processing provider.') }}
</NcNoteCard>
<NcCheckboxRadioSwitch
Expand All @@ -35,7 +38,7 @@
<NcNoteCard v-if="!state.free_prompt_task_type_available" type="info">
<div class="checkbox-text">
<span>
{{ t('assistant', 'To enable this feature, please install an AI task processing provider for the free prompt task type:') }}
{{ t('assistant', 'To enable text generation in the smart picker, please install an AI task processing provider for the "Free text to text prompt" task type:') }}
</span>
<ul>
<li><a href="https://github.com/nextcloud/llm2#readme">Local Large language model app</a></li>
Expand All @@ -59,10 +62,10 @@
{{ t('assistant', 'Enable text-to-sticker in smart picker') }}
</div>
</NcCheckboxRadioSwitch>
<NcNoteCard v-if="!state.text_to_image_picker_available" type="info">
<NcNoteCard v-if="!state.text_to_image_picker_available" type="warning">
<div class="checkbox-text">
<span>
{{ t('assistant', 'To enable this feature, please install a text-to-image provider:') }}
{{ t('assistant', 'To enable the sticker generation picker or the image generation picker, please install and enable a "Generate image" provider:') }}
</span>
<ul>
<li><a href="https://github.com/nextcloud/text2image_stablediffusion#readme">Local Text-To-Image StableDiffusion</a></li>
Expand All @@ -78,10 +81,10 @@
{{ t('assistant', 'Enable speech-to-text in smart picker') }}
</div>
</NcCheckboxRadioSwitch>
<NcNoteCard v-if="!state.speech_to_text_picker_available" type="info">
<NcNoteCard v-if="!state.speech_to_text_picker_available" type="warning">
<div class="checkbox-text">
<span>
{{ t('assistant', 'To enable this feature, please install a speech-to-text provider:') }}
{{ t('assistant', 'To enable speech-to-text in the smart picker, please install and enable a "Transcribe audio" provider:') }}
</span>
<ul>
<li><a href="https://github.com/nextcloud/stt_whisper2#readme">Local Speech-To-Text Whisper</a></li>
Expand Down
2 changes: 1 addition & 1 deletion src/components/PersonalSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch v-if="state.text_to_sticker_picker_available"
:model-value="state.text_to_sticker_picker_enabled"
@update:model-value="onCheckboxChanged($event, 'text_to_image_picker_enabled')">
@update:model-value="onCheckboxChanged($event, 'text_to_sticker_picker_enabled')">
<div class="checkbox-text">
{{ t('assistant', 'Enable AI sticker generation in smart picker') }}
</div>
Expand Down