Skip to content
Draft
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
10 changes: 10 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,16 @@
'url' => '/api/follow-up/check-message-ids',
'verb' => 'POST',
],
[
'name' => 'AiPrompt#getPrompts',
'url' => '/api/prompts',
'verb' => 'GET',
],
[
'name' => 'AiPrompt#setPrompt',
'url' => '/api/prompts/{key}',
'verb' => 'POST',
],
],
'resources' => [
'accounts' => ['url' => '/api/accounts'],
Expand Down
91 changes: 91 additions & 0 deletions lib/Controller/AiPromptController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

declare(strict_types=1);

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

namespace OCA\Mail\Controller;

use OCA\Mail\AppInfo\Application;
use OCA\Mail\Http\JsonResponse;
use OCA\Mail\Http\TrapError;
use OCA\Mail\Service\AiIntegrations\AiIntegrationsPromptsService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\IRequest;

class AiPromptController extends Controller {

public function __construct(

Check warning on line 22 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L22

Added line #L22 was not covered by tests
IRequest $request,
private AiIntegrationsPromptsService $service,
) {
parent::__construct(Application::APP_ID, $request);

Check warning on line 26 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L26

Added line #L26 was not covered by tests
}

/**
* @return JsonResponse
*/
#[TrapError]

Check warning on line 32 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L32

Added line #L32 was not covered by tests
public function getPrompts(): JsonResponse {
$prompts['event_data_prompt_preamble'] = $this->service->getEventDataPromptPreamble();

Check failure on line 34 in lib/Controller/AiPromptController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

PossiblyUndefinedVariable

lib/Controller/AiPromptController.php:34:3: PossiblyUndefinedVariable: Possibly undefined variable $prompts, first seen on line 34 (see https://psalm.dev/018)
$prompts['summarize_email_prompt'] = $this->service->getSummarizeEmailPrompt();
$prompts['smart_reply_prompt_preamble'] = $this->service->getSmartReplyPromptPreamble();
$prompts['smart_reply_prompt_postamble'] = $this->service->getSmartReplyPromptPostamble();
$prompts['requires_followup_prompt_preamble'] = $this->service->getRequiresFollowupPromptPreamble();
$prompts['requires_followup_prompt_postamble'] = $this->service->getRequiresFollowupPromptPostamble();

Check warning on line 39 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L34-L39

Added lines #L34 - L39 were not covered by tests

return JsonResponse::success($prompts, Http::STATUS_CREATED);

Check warning on line 41 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L41

Added line #L41 was not covered by tests
}

/**
* @NoAdminRequired
*
* @param string $email
* @param string $type
* @return JsonResponse
*/
#[TrapError]

Check warning on line 51 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L51

Added line #L51 was not covered by tests
public function setPrompt(string $key, string $value): JsonResponse {
switch ($key) {
case 'event_data_prompt_preamble':
$this->service->setEventDataPromptPreamble($value);
break;
case 'summarize_email_prompt':
$this->service->setSummarizeEmailPrompt($value);
break;
case 'smart_reply_prompt_preamble':
$this->service->setSmartReplyPreamble($value);
break;
case 'smart_reply_prompt_postamble':
$this->service->setSmartReplyPostamble($value);
break;
case 'requires_followup_prompt_preamble':
$this->service->setRequiresFollowupPreamble($value);
break;
case 'requires_followup_prompt_postamble':
$this->service->setRequiresFollowupPostamble($value);
break;

Check warning on line 71 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L54-L71

Added lines #L54 - L71 were not covered by tests
default:
return JsonResponse::error('Invalid prompt key', Http::STATUS_BAD_REQUEST);

Check warning on line 73 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L73

Added line #L73 was not covered by tests
}

return JsonResponse::success(null);

Check warning on line 76 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L76

Added line #L76 was not covered by tests
}
/**
* @NoAdminRequired
*
* @return JsonResponse
*/
#[TrapError]

Check warning on line 83 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L83

Added line #L83 was not covered by tests
public function list(): JsonResponse {
$list = $this->trustedSenderService->getTrusted(

Check failure on line 85 in lib/Controller/AiPromptController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedThisPropertyFetch

lib/Controller/AiPromptController.php:85:11: UndefinedThisPropertyFetch: Instance property OCA\Mail\Controller\AiPromptController::$trustedSenderService is not defined (see https://psalm.dev/041)
$this->uid

Check failure on line 86 in lib/Controller/AiPromptController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedThisPropertyFetch

lib/Controller/AiPromptController.php:86:4: UndefinedThisPropertyFetch: Instance property OCA\Mail\Controller\AiPromptController::$uid is not defined (see https://psalm.dev/041)
);

Check warning on line 87 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L85-L87

Added lines #L85 - L87 were not covered by tests

return JsonResponse::success($list);

Check warning on line 89 in lib/Controller/AiPromptController.php

View check run for this annotation

Codecov / codecov/patch

lib/Controller/AiPromptController.php#L89

Added line #L89 was not covered by tests
}
}
107 changes: 107 additions & 0 deletions lib/Service/AiIntegrations/AiIntegrationsPromptsService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Mail\Service\AiIntegrations;

use OCP\AppFramework\Services\IAppConfig;

class AiIntegrationsPromptsService {
public function __construct(
private IAppConfig $appConfig,
) {
}

private const EVENT_DATA_PROMPT_PREAMBLE = <<<PROMPT
I am scheduling an event based on an email thread and need an event title and agenda. Provide the result as JSON with keys for "title" and "agenda". For example ```{ "title": "Project kick-off meeting", "agenda": "* Introduction\\n* Project goals\\n* Next steps" }```.

The email contents are:

PROMPT;

private const SUMMARIZE_EMAIL_PROMPT = "You are tasked with formulating a helpful summary of a email message. \r\n"
. "The summary should be less than 160 characters. \r\n"
. "Output *ONLY* the summary itself, leave out any introduction. \r\n"
. "Here is the ***E-MAIL*** for which you must generate a helpful summary: \r\n";

private const SMART_REPLY_PROMPT_PREAMPBLE = "You are tasked with formulating helpful replies or reply templates to e-mails provided that have been sent to me. If you don't know some relevant information for answering the e-mails (like my schedule) leave blanks in the text that can later be filled by me. You must write the replies from my point of view as replies to the original sender of the provided e-mail!

Formulate two extremely succinct reply suggestions to the provided ***E-MAIL***. Please, do not invent any context for the replies but, rather, leave blanks for me to fill in with relevant information where necessary. Provide the output formatted as valid JSON with the keys 'reply1' and 'reply2' for the reply suggestions.

Each suggestion must be of 25 characters or less.

Here is the ***E-MAIL*** for which you must suggest the replies to: ***START_OF_E-MAIL***";
private const SMART_REPLY_PROMPT_POSTAMBLE = "***END_OF_E-MAIL***

Please, output *ONLY* a valid JSON string with the keys 'reply1' and 'reply2' for the reply suggestions. Leave out any other text besides the JSON! Be extremely succinct and write the replies from my point of view.";


private const REQUIRES_FOLLOWUP_PROMPT_PREAMPBLE = "Consider the following TypeScript function prototype:
---
/**
* This function takes in an email text and returns a boolean indicating whether the email author expects a response.
*
* @param emailText - string with the email text
* @returns boolean true if the email expects a reply, false if not
*/
declare function doesEmailExpectReply(emailText: string): Promise<boolean>;
---
Tell me what the function outputs for the following parameters.

emailText:\r\n";

private const REQUIRES_FOLLOWUP_PROMPT_POSTAMBLE = "\r\nThe JSON output should be in the form: {\"expectsReply\": true}
Never return null or undefined.";

public function getEventDataPromptPreamble(): string {
return $this->appConfig->getValueString('mail', 'event_data_prompt_preamble', self::EVENT_DATA_PROMPT_PREAMBLE);

Check failure on line 61 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedInterfaceMethod

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php:61:28: UndefinedInterfaceMethod: Method OCP\AppFramework\Services\IAppConfig::getValueString does not exist (see https://psalm.dev/181)

Check warning on line 61 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L60-L61

Added lines #L60 - L61 were not covered by tests
}
public function getSummarizeEmailPrompt(): string {
return $this->appConfig->getValueString('mail', 'summarize_email_prompt', self::SUMMARIZE_EMAIL_PROMPT);

Check failure on line 64 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedInterfaceMethod

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php:64:28: UndefinedInterfaceMethod: Method OCP\AppFramework\Services\IAppConfig::getValueString does not exist (see https://psalm.dev/181)

Check warning on line 64 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L63-L64

Added lines #L63 - L64 were not covered by tests
}
public function getSmartReplyPrompt(string $message): string {
return $this->appConfig->getValueString('mail', 'smart_reply_prompt_preamble', self::SMART_REPLY_PROMPT_PREAMPBLE) . $message . $this->appConfig->getAppValue('mail', 'smart_reply_prompt_postamble', self::SMART_REPLY_PROMPT_POSTAMBLE);

Check failure on line 67 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

TooManyArguments

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php:67:149: TooManyArguments: Too many arguments for method OCP\AppFramework\Services\IAppConfig::getappvalue - saw 3 (see https://psalm.dev/026)

Check failure on line 67 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedInterfaceMethod

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php:67:28: UndefinedInterfaceMethod: Method OCP\AppFramework\Services\IAppConfig::getValueString does not exist (see https://psalm.dev/181)

Check warning on line 67 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L66-L67

Added lines #L66 - L67 were not covered by tests
}
public function getSmartReplyPromptPreamble(): string {
return $this->appConfig->getValueString('mail', 'smart_reply_prompt_preamble', self::SMART_REPLY_PROMPT_PREAMPBLE);

Check failure on line 70 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedInterfaceMethod

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php:70:28: UndefinedInterfaceMethod: Method OCP\AppFramework\Services\IAppConfig::getValueString does not exist (see https://psalm.dev/181)

Check warning on line 70 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L69-L70

Added lines #L69 - L70 were not covered by tests
}
public function getSmartReplyPromptPostamble(): string {
return $this->appConfig->getValueString('mail', 'smart_reply_prompt_postamble', self::SMART_REPLY_PROMPT_POSTAMBLE);

Check failure on line 73 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedInterfaceMethod

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php:73:28: UndefinedInterfaceMethod: Method OCP\AppFramework\Services\IAppConfig::getValueString does not exist (see https://psalm.dev/181)

Check warning on line 73 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L72-L73

Added lines #L72 - L73 were not covered by tests
}

public function getRequiresFollowupPrompt(string $message): string {
return $this->appConfig->getValueString('mail', 'requires_followup_prompt_preamble', self::REQUIRES_FOLLOWUP_PROMPT_PREAMPBLE) . $message . $this->appConfig->getAppValue('mail', 'requires_followup_prompt_postamble', self::REQUIRES_FOLLOWUP_PROMPT_POSTAMBLE);

Check failure on line 77 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedInterfaceMethod

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php:77:28: UndefinedInterfaceMethod: Method OCP\AppFramework\Services\IAppConfig::getValueString does not exist (see https://psalm.dev/181)

Check warning on line 77 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L76-L77

Added lines #L76 - L77 were not covered by tests
}
public function getRequiresFollowupPromptPreamble(): string {
return $this->appConfig->getValueString('mail', 'requires_followup_prompt_preamble', self::REQUIRES_FOLLOWUP_PROMPT_PREAMPBLE);

Check warning on line 80 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L79-L80

Added lines #L79 - L80 were not covered by tests
}
public function getRequiresFollowupPromptPostamble(): string {
return $this->appConfig->getValueString('mail', 'requires_followup_prompt_postamble', self::REQUIRES_FOLLOWUP_PROMPT_POSTAMBLE);

Check warning on line 83 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L82-L83

Added lines #L82 - L83 were not covered by tests
}

public function setEventDataPromptPreamble(string $preamble): void {
$this->appConfig->setValueString('mail', 'event_data_prompt_preamble', $preamble);

Check warning on line 87 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L86-L87

Added lines #L86 - L87 were not covered by tests
}
public function setSummarizeEmailPrompt(string $prompt): void {
$this->appConfig->setValueString('mail', 'summarize_email_prompt', $prompt);

Check warning on line 90 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L89-L90

Added lines #L89 - L90 were not covered by tests
}
public function setSmartReplyPreamble(string $prompt): void {
$this->appConfig->setValueString('mail', 'smart_reply_prompt_preamble', $prompt);

Check warning on line 93 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L92-L93

Added lines #L92 - L93 were not covered by tests
}

public function setSmartReplyPostamble(string $postamble): void {
$this->appConfig->setValueString('mail', 'smart_reply_prompt_postamble', $postamble);

Check warning on line 97 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L96-L97

Added lines #L96 - L97 were not covered by tests
}
public function setRequiresFollowupPreamble(string $preamble): void {
$this->appConfig->setValueString('mail', 'requires_followup_prompt_preamble', $preamble);

Check warning on line 100 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L99-L100

Added lines #L99 - L100 were not covered by tests
}
public function setRequiresFollowupPostamble(string $postamble): void {
$this->appConfig->setValueString('mail', 'requires_followup_prompt_postamble', $postamble);

Check warning on line 103 in lib/Service/AiIntegrations/AiIntegrationsPromptsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsPromptsService.php#L102-L103

Added lines #L102 - L103 were not covered by tests
}


}
46 changes: 5 additions & 41 deletions lib/Service/AiIntegrations/AiIntegrationsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@

class AiIntegrationsService {

private const EVENT_DATA_PROMPT_PREAMBLE = <<<PROMPT
I am scheduling an event based on an email thread and need an event title and agenda. Provide the result as JSON with keys for "title" and "agenda". For example ```{ "title": "Project kick-off meeting", "agenda": "* Introduction\\n* Project goals\\n* Next steps" }```.

The email contents are:

PROMPT;

public function __construct(
private ContainerInterface $container,
private LoggerInterface $logger,
Expand All @@ -53,6 +46,7 @@
private IMAPClientFactory $clientFactory,
private IMailManager $mailManager,
private TaskProcessingManager $taskProcessingManager,
private AiIntegrationsPromptsService $promptsService,
) {
}

Expand Down Expand Up @@ -96,10 +90,7 @@
}
// construct prompt and task
$messageBody = $message->getPlainBody();
$prompt = "You are tasked with formulating a helpful summary of a email message. \r\n"
. "The summary should be less than 160 characters. \r\n"
. "Output *ONLY* the summary itself, leave out any introduction. \r\n"
. "Here is the ***E-MAIL*** for which you must generate a helpful summary: \r\n"
$prompt = $this->promptsService->getSummarizeEmailPrompt()

Check warning on line 93 in lib/Service/AiIntegrations/AiIntegrationsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsService.php#L93

Added line #L93 was not covered by tests
. "***START_OF_E-MAIL***\r\n$messageBody\r\n***END_OF_E-MAIL***\r\n";
$task = new TaskProcessingTask(
TextToText::ID,
Expand Down Expand Up @@ -203,7 +194,7 @@

$task = new Task(
FreePromptTaskType::class,
self::EVENT_DATA_PROMPT_PREAMBLE . implode("\n\n---\n\n", $messageBodies),
$this->promptsService->getEventDataPromptPreamble() . implode("\n\n---\n\n", $messageBodies),

Check warning on line 197 in lib/Service/AiIntegrations/AiIntegrationsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsService.php#L197

Added line #L197 was not covered by tests
'mail',
$currentUserId,
"event_data_$threadId",
Expand Down Expand Up @@ -248,20 +239,7 @@
} finally {
$client->logout();
}
$prompt = "You are tasked with formulating helpful replies or reply templates to e-mails provided that have been sent to me. If you don't know some relevant information for answering the e-mails (like my schedule) leave blanks in the text that can later be filled by me. You must write the replies from my point of view as replies to the original sender of the provided e-mail!

Formulate two extremely succinct reply suggestions to the provided ***E-MAIL***. Please, do not invent any context for the replies but, rather, leave blanks for me to fill in with relevant information where necessary. Provide the output formatted as valid JSON with the keys 'reply1' and 'reply2' for the reply suggestions.

Each suggestion must be of 25 characters or less.

Here is the ***E-MAIL*** for which you must suggest the replies to:

***START_OF_E-MAIL***" . $messageBody . "

***END_OF_E-MAIL***

Please, output *ONLY* a valid JSON string with the keys 'reply1' and 'reply2' for the reply suggestions. Leave out any other text besides the JSON! Be extremely succinct and write the replies from my point of view.
";
$prompt = $this->promptsService->getSmartReplyPrompt($messageBody);

Check warning on line 242 in lib/Service/AiIntegrations/AiIntegrationsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsService.php#L242

Added line #L242 was not covered by tests
$task = new Task(FreePromptTaskType::class, $prompt, 'mail,', $currentUserId);
$manager->runTask($task);
$replies = $task->getOutput();
Expand Down Expand Up @@ -323,21 +301,7 @@
$messageBody = $imapMessage->getPlainBody();
$messageBody = str_replace('"', '\"', $messageBody);

$prompt = "Consider the following TypeScript function prototype:
---
/**
* This function takes in an email text and returns a boolean indicating whether the email author expects a response.
*
* @param emailText - string with the email text
* @returns boolean true if the email expects a reply, false if not
*/
declare function doesEmailExpectReply(emailText: string): Promise<boolean>;
---
Tell me what the function outputs for the following parameters.

emailText: \"$messageBody\"
The JSON output should be in the form: {\"expectsReply\": true}
Never return null or undefined.";
$prompt = $this->promptsService->getRequiresFollowupPrompt($messageBody);

Check warning on line 304 in lib/Service/AiIntegrations/AiIntegrationsService.php

View check run for this annotation

Codecov / codecov/patch

lib/Service/AiIntegrations/AiIntegrationsService.php#L304

Added line #L304 was not covered by tests
$task = new Task(FreePromptTaskType::class, $prompt, Application::APP_ID, $currentUserId);

$manager->runTask($task);
Expand Down
56 changes: 56 additions & 0 deletions lib/Settings/AiPromptSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

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

namespace OCA\Mail\Settings;

use OCA\Assistant\AppInfo\Application;
use OCA\Mail\Service\AiIntegrations\AiIntegrationsService;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\IAppConfig;
use OCP\Settings\ISettings;
use OCP\TextProcessing\FreePromptTaskType;

class AiPromptSettings implements ISettings {

public function __construct(

Check warning on line 20 in lib/Settings/AiPromptSettings.php

View check run for this annotation

Codecov / codecov/patch

lib/Settings/AiPromptSettings.php#L20

Added line #L20 was not covered by tests
private IAppConfig $appConfig,
private IInitialState $initialStateService,
private AiIntegrationsService $aiIntegrationsService,
) {
}

Check warning on line 25 in lib/Settings/AiPromptSettings.php

View check run for this annotation

Codecov / codecov/patch

lib/Settings/AiPromptSettings.php#L25

Added line #L25 was not covered by tests

/**
* @return TemplateResponse
*/
public function getForm(): TemplateResponse {

Check warning on line 30 in lib/Settings/AiPromptSettings.php

View check run for this annotation

Codecov / codecov/patch

lib/Settings/AiPromptSettings.php#L30

Added line #L30 was not covered by tests

$this->initialStateService->provideInitialState(
Application::APP_ID,
'llm_processing',
$this->aiIntegrationsService->isLlmProcessingEnabled(),
);
$this->initialStateService->provideInitialState(
Application::APP_ID,
'enabled_llm_free_prompt_backend',
$this->aiIntegrationsService->isLlmAvailable(FreePromptTaskType::class)
);

Check warning on line 41 in lib/Settings/AiPromptSettings.php

View check run for this annotation

Codecov / codecov/patch

lib/Settings/AiPromptSettings.php#L32-L41

Added lines #L32 - L41 were not covered by tests

return new TemplateResponse(Application::APP_ID, 'ai-prompt-settings');

Check warning on line 43 in lib/Settings/AiPromptSettings.php

View check run for this annotation

Codecov / codecov/patch

lib/Settings/AiPromptSettings.php#L43

Added line #L43 was not covered by tests
}

public function getSection(): string {
if ($this->aiIntegrationsService->isLlmProcessingEnabled()) {
return null;

Check warning on line 48 in lib/Settings/AiPromptSettings.php

View check run for this annotation

Codecov / codecov/patch

lib/Settings/AiPromptSettings.php#L46-L48

Added lines #L46 - L48 were not covered by tests
}
return 'ai';

Check warning on line 50 in lib/Settings/AiPromptSettings.php

View check run for this annotation

Codecov / codecov/patch

lib/Settings/AiPromptSettings.php#L50

Added line #L50 was not covered by tests
}

public function getPriority(): int {
return 11;

Check warning on line 54 in lib/Settings/AiPromptSettings.php

View check run for this annotation

Codecov / codecov/patch

lib/Settings/AiPromptSettings.php#L53-L54

Added lines #L53 - L54 were not covered by tests
}
}
13 changes: 13 additions & 0 deletions src/ai-prompt-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import Vue from 'vue'
import { translate } from '@nextcloud/l10n'
import AdminAiPrommptsSettings from './components/settings/AdminAiPrommptsSettings.vue'

Vue.prototype.$t = translate

const View = Vue.extend(AdminAiPrommptsSettings);

(new View({})).$mount('#ai-prompts-settings')
Loading
Loading