+
+
+ @if (title) {
+
+ }
+
+
+
+
+ @if (showReveal) {
+
+ }
+
+
+ {{error}}
+
+ @if (hint) {
+
}
-
- {{error}}
-
- @if (hint) {
-
- }
diff --git a/src-ui/src/app/data/paperless-config.ts b/src-ui/src/app/data/paperless-config.ts
index 1d8f27b33..eea134692 100644
--- a/src-ui/src/app/data/paperless-config.ts
+++ b/src-ui/src/app/data/paperless-config.ts
@@ -44,6 +44,7 @@ export enum ConfigOptionType {
Boolean = 'boolean',
JSON = 'json',
File = 'file',
+ Password = 'password',
}
export const ConfigCategory = {
@@ -53,6 +54,11 @@ export const ConfigCategory = {
AI: $localize`AI Settings`,
}
+export const LLMBackendConfig = {
+ OPENAI: 'openai',
+ OLLAMA: 'ollama',
+}
+
export interface ConfigOption {
key: string
title: string
@@ -267,7 +273,8 @@ export const PaperlessConfigOptions: ConfigOption[] = [
{
key: 'llm_backend',
title: $localize`LLM Backend`,
- type: ConfigOptionType.String,
+ type: ConfigOptionType.Select,
+ choices: mapToItems(LLMBackendConfig),
config_key: 'PAPERLESS_LLM_BACKEND',
category: ConfigCategory.AI,
},
@@ -281,7 +288,7 @@ export const PaperlessConfigOptions: ConfigOption[] = [
{
key: 'llm_api_key',
title: $localize`LLM API Key`,
- type: ConfigOptionType.String,
+ type: ConfigOptionType.Password,
config_key: 'PAPERLESS_LLM_API_KEY',
category: ConfigCategory.AI,
},
diff --git a/src/paperless/serialisers.py b/src/paperless/serialisers.py
index 9943a76ee..716b72a8a 100644
--- a/src/paperless/serialisers.py
+++ b/src/paperless/serialisers.py
@@ -190,6 +190,10 @@ class ProfileSerializer(serializers.ModelSerializer):
class ApplicationConfigurationSerializer(serializers.ModelSerializer):
user_args = serializers.JSONField(binary=True, allow_null=True)
barcode_tag_mapping = serializers.JSONField(binary=True, allow_null=True)
+ llm_api_key = ObfuscatedPasswordField(
+ required=False,
+ allow_null=True,
+ )
def run_validation(self, data):
# Empty strings treated as None to avoid unexpected behavior