259 lines
8.4 KiB
Python
259 lines
8.4 KiB
Python
"""Pydantic schemas for application-level runtime settings."""
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class ProviderSettingsResponse(BaseModel):
|
|
"""Represents a persisted model provider with non-secret connection metadata."""
|
|
|
|
id: str
|
|
label: str
|
|
provider_type: str = "openai_compatible"
|
|
base_url: str
|
|
timeout_seconds: int
|
|
api_key_set: bool
|
|
api_key_masked: str = ""
|
|
|
|
|
|
class ProviderSettingsUpdateRequest(BaseModel):
|
|
"""Represents a model provider create-or-update request."""
|
|
|
|
id: str
|
|
label: str
|
|
provider_type: str = "openai_compatible"
|
|
base_url: str
|
|
timeout_seconds: int = Field(default=45, ge=5, le=180)
|
|
api_key: str | None = None
|
|
clear_api_key: bool = False
|
|
|
|
|
|
class OcrTaskSettingsResponse(BaseModel):
|
|
"""Represents OCR task runtime settings and prompt configuration."""
|
|
|
|
enabled: bool
|
|
provider_id: str
|
|
model: str
|
|
prompt: str
|
|
|
|
|
|
class OcrTaskSettingsUpdateRequest(BaseModel):
|
|
"""Represents OCR task settings updates."""
|
|
|
|
enabled: bool | None = None
|
|
provider_id: str | None = None
|
|
model: str | None = None
|
|
prompt: str | None = None
|
|
|
|
|
|
class SummaryTaskSettingsResponse(BaseModel):
|
|
"""Represents summarization task runtime settings."""
|
|
|
|
enabled: bool
|
|
provider_id: str
|
|
model: str
|
|
prompt: str
|
|
max_input_tokens: int
|
|
|
|
|
|
class SummaryTaskSettingsUpdateRequest(BaseModel):
|
|
"""Represents summarization task settings updates."""
|
|
|
|
enabled: bool | None = None
|
|
provider_id: str | None = None
|
|
model: str | None = None
|
|
prompt: str | None = None
|
|
max_input_tokens: int | None = Field(default=None, ge=512, le=64000)
|
|
|
|
|
|
class RoutingTaskSettingsResponse(BaseModel):
|
|
"""Represents routing task runtime settings for path and tag classification."""
|
|
|
|
enabled: bool
|
|
provider_id: str
|
|
model: str
|
|
prompt: str
|
|
neighbor_count: int
|
|
neighbor_min_similarity: float
|
|
auto_apply_confidence_threshold: float
|
|
auto_apply_neighbor_similarity_threshold: float
|
|
neighbor_path_override_enabled: bool
|
|
neighbor_path_override_min_similarity: float
|
|
neighbor_path_override_min_gap: float
|
|
neighbor_path_override_max_confidence: float
|
|
|
|
|
|
class RoutingTaskSettingsUpdateRequest(BaseModel):
|
|
"""Represents routing task settings updates."""
|
|
|
|
enabled: bool | None = None
|
|
provider_id: str | None = None
|
|
model: str | None = None
|
|
prompt: str | None = None
|
|
neighbor_count: int | None = Field(default=None, ge=1, le=40)
|
|
neighbor_min_similarity: float | None = Field(default=None, ge=0.0, le=1.0)
|
|
auto_apply_confidence_threshold: float | None = Field(default=None, ge=0.0, le=1.0)
|
|
auto_apply_neighbor_similarity_threshold: float | None = Field(default=None, ge=0.0, le=1.0)
|
|
neighbor_path_override_enabled: bool | None = None
|
|
neighbor_path_override_min_similarity: float | None = Field(default=None, ge=0.0, le=1.0)
|
|
neighbor_path_override_min_gap: float | None = Field(default=None, ge=0.0, le=1.0)
|
|
neighbor_path_override_max_confidence: float | None = Field(default=None, ge=0.0, le=1.0)
|
|
|
|
|
|
class UploadDefaultsResponse(BaseModel):
|
|
"""Represents default upload destination and default tags."""
|
|
|
|
logical_path: str
|
|
tags: list[str] = Field(default_factory=list)
|
|
|
|
|
|
class UploadDefaultsUpdateRequest(BaseModel):
|
|
"""Represents updates for default upload destination and default tags."""
|
|
|
|
logical_path: str | None = None
|
|
tags: list[str] | None = None
|
|
|
|
|
|
class DisplaySettingsResponse(BaseModel):
|
|
"""Represents document-list display preferences."""
|
|
|
|
cards_per_page: int = Field(default=12, ge=1, le=200)
|
|
log_typing_animation_enabled: bool = True
|
|
|
|
|
|
class DisplaySettingsUpdateRequest(BaseModel):
|
|
"""Represents updates for document-list display preferences."""
|
|
|
|
cards_per_page: int | None = Field(default=None, ge=1, le=200)
|
|
log_typing_animation_enabled: bool | None = None
|
|
|
|
|
|
class ProcessingLogRetentionSettingsResponse(BaseModel):
|
|
"""Represents retention limits used when pruning processing pipeline logs."""
|
|
|
|
keep_document_sessions: int = Field(default=2, ge=0, le=20)
|
|
keep_unbound_entries: int = Field(default=80, ge=0, le=400)
|
|
|
|
|
|
class ProcessingLogRetentionSettingsUpdateRequest(BaseModel):
|
|
"""Represents partial updates for processing log retention limits."""
|
|
|
|
keep_document_sessions: int | None = Field(default=None, ge=0, le=20)
|
|
keep_unbound_entries: int | None = Field(default=None, ge=0, le=400)
|
|
|
|
|
|
class PredefinedPathEntryResponse(BaseModel):
|
|
"""Represents one predefined logical path with global discoverability scope."""
|
|
|
|
value: str
|
|
global_shared: bool
|
|
|
|
|
|
class PredefinedPathEntryUpdateRequest(BaseModel):
|
|
"""Represents one predefined logical path create-or-update request."""
|
|
|
|
value: str
|
|
global_shared: bool = False
|
|
|
|
|
|
class PredefinedTagEntryResponse(BaseModel):
|
|
"""Represents one predefined tag with global discoverability scope."""
|
|
|
|
value: str
|
|
global_shared: bool
|
|
|
|
|
|
class PredefinedTagEntryUpdateRequest(BaseModel):
|
|
"""Represents one predefined tag create-or-update request."""
|
|
|
|
value: str
|
|
global_shared: bool = False
|
|
|
|
|
|
class HandwritingStyleSettingsResponse(BaseModel):
|
|
"""Represents handwriting-style clustering settings used by Typesense image embeddings."""
|
|
|
|
enabled: bool
|
|
embed_model: str
|
|
neighbor_limit: int
|
|
match_min_similarity: float
|
|
bootstrap_match_min_similarity: float
|
|
bootstrap_sample_size: int
|
|
image_max_side: int
|
|
|
|
|
|
class HandwritingStyleSettingsUpdateRequest(BaseModel):
|
|
"""Represents updates for handwriting-style clustering and match thresholds."""
|
|
|
|
enabled: bool | None = None
|
|
embed_model: str | None = None
|
|
neighbor_limit: int | None = Field(default=None, ge=1, le=32)
|
|
match_min_similarity: float | None = Field(default=None, ge=0.0, le=1.0)
|
|
bootstrap_match_min_similarity: float | None = Field(default=None, ge=0.0, le=1.0)
|
|
bootstrap_sample_size: int | None = Field(default=None, ge=1, le=30)
|
|
image_max_side: int | None = Field(default=None, ge=256, le=4096)
|
|
|
|
|
|
class TaskSettingsResponse(BaseModel):
|
|
"""Represents all task-level model bindings and prompt settings."""
|
|
|
|
ocr_handwriting: OcrTaskSettingsResponse
|
|
summary_generation: SummaryTaskSettingsResponse
|
|
routing_classification: RoutingTaskSettingsResponse
|
|
|
|
|
|
class TaskSettingsUpdateRequest(BaseModel):
|
|
"""Represents partial updates for task-level settings."""
|
|
|
|
ocr_handwriting: OcrTaskSettingsUpdateRequest | None = None
|
|
summary_generation: SummaryTaskSettingsUpdateRequest | None = None
|
|
routing_classification: RoutingTaskSettingsUpdateRequest | None = None
|
|
|
|
|
|
class AppSettingsResponse(BaseModel):
|
|
"""Represents all application settings exposed by the API."""
|
|
|
|
upload_defaults: UploadDefaultsResponse
|
|
display: DisplaySettingsResponse
|
|
processing_log_retention: ProcessingLogRetentionSettingsResponse
|
|
handwriting_style_clustering: HandwritingStyleSettingsResponse
|
|
predefined_paths: list[PredefinedPathEntryResponse] = Field(default_factory=list)
|
|
predefined_tags: list[PredefinedTagEntryResponse] = Field(default_factory=list)
|
|
providers: list[ProviderSettingsResponse]
|
|
tasks: TaskSettingsResponse
|
|
|
|
|
|
class AppSettingsUpdateRequest(BaseModel):
|
|
"""Represents full settings update input for providers and task bindings."""
|
|
|
|
upload_defaults: UploadDefaultsUpdateRequest | None = None
|
|
display: DisplaySettingsUpdateRequest | None = None
|
|
processing_log_retention: ProcessingLogRetentionSettingsUpdateRequest | None = None
|
|
handwriting_style_clustering: HandwritingStyleSettingsUpdateRequest | None = None
|
|
predefined_paths: list[PredefinedPathEntryUpdateRequest] | None = None
|
|
predefined_tags: list[PredefinedTagEntryUpdateRequest] | None = None
|
|
providers: list[ProviderSettingsUpdateRequest] | None = None
|
|
tasks: TaskSettingsUpdateRequest | None = None
|
|
|
|
|
|
class HandwritingSettingsResponse(BaseModel):
|
|
"""Represents legacy handwriting response shape kept for backward compatibility."""
|
|
|
|
provider: str = "openai_compatible"
|
|
enabled: bool
|
|
openai_base_url: str
|
|
openai_model: str
|
|
openai_timeout_seconds: int
|
|
openai_api_key_set: bool
|
|
openai_api_key_masked: str = ""
|
|
|
|
|
|
class HandwritingSettingsUpdateRequest(BaseModel):
|
|
"""Represents legacy handwriting update shape kept for backward compatibility."""
|
|
|
|
enabled: bool | None = None
|
|
openai_base_url: str | None = None
|
|
openai_model: str | None = None
|
|
openai_timeout_seconds: int | None = Field(default=None, ge=5, le=180)
|
|
openai_api_key: str | None = None
|
|
clear_openai_api_key: bool = False
|