LLM-translator/backend/models.py

168 lines
5 KiB
Python

"""Pydantic request/response models for the API."""
from pydantic import BaseModel, Field
# ── Auth ───────────────────────────────────────────────
class LoginRequest(BaseModel):
id: str
password: str
class TokenResponse(BaseModel):
access_token: str
token_type: str = "bearer"
class UserInfo(BaseModel):
user_id: str
is_admin: bool = False
class CreateUserRequest(BaseModel):
id: str = Field(min_length=1, max_length=50, pattern=r"^[A-Za-z0-9_.-]+$")
password: str = Field(min_length=8, max_length=200)
is_admin: bool = False
class UpdateUserRequest(BaseModel):
password: str | None = Field(default=None, min_length=8, max_length=200)
is_admin: bool | None = None
is_active: bool | None = None
class UserSummary(BaseModel):
id: str
is_admin: bool
is_active: bool
created_at: str
updated_at: str
# ── LLM Config ───────────────────────────────────────
class LLMConfig(BaseModel):
alias: str
base_url: str
api_key: str
model: str
context_size: int
# ── Translation Session ────────────────────────────────
class ProperNoun(BaseModel):
original: str # 원문 고유명사
suggested: str # 제안 번역
final: str = "" # 사용자 최종 결정 (Phase 2)
class Phase1Result(BaseModel):
translated: str # 초벌 번역 결과
proper_nouns: list[ProperNoun] # 추출된 고유명사 리스트
summary: str # 내용 요약
style: str # 문체 분석 결과
warnings: list[str] = Field(default_factory=list)
class TranslationChunk(BaseModel):
source_text: str
translated: str
class PhaseProgress(BaseModel):
phase: int
chunk: int
total_chunks: int
status: str
preview: str = ""
class TranslationSession(BaseModel):
"""Full translation session state."""
source_text: str = "" # 원문
source_language: str = "auto" # 출발어 (auto = 자동판단)
target_language: str = "한국어" # 도착어
model_phase1: str = "" # Phase 1 LLM 모델 alias
model_phase2: str = "" # Phase 2 LLM 모델 alias
model_phase3: str = "" # Phase 3 LLM 모델 alias
model_phase4: str = "" # Phase 4 LLM 모델 alias
phase1_result: Phase1Result | None = None # 초벌 번역 결과
phase1_chunks: list[TranslationChunk] = Field(default_factory=list)
phase2_proper_nouns: list[ProperNoun] = Field(default_factory=list)
phase2_style: str = "" # Phase 2에서 최종 확정된 문체
phase2_confirmed: bool = False
phase3_result: str = "" # 재번역 결과
phase3_chunks: list[str] = Field(default_factory=list)
phase4_result: str = "" # 마무리 다듬기 결과
progress: PhaseProgress | None = None # 장기 작업 진행 상태
# ── API Requests ───────────────────────────────────────
class CreateSessionRequest(BaseModel):
source_text: str
source_language: str = "auto"
target_language: str = "한국어"
model_phase1: str = ""
model_phase2: str = ""
model_phase3: str = ""
model_phase4: str = ""
title: str | None = Field(default=None, max_length=120)
class PhaseUpdateRequest(BaseModel):
"""Partial update for a specific phase."""
source_text: str | None = None
source_language: str | None = None
target_language: str | None = None
model_phase1: str | None = None
model_phase2: str | None = None
model_phase3: str | None = None
model_phase4: str | None = None
title: str | None = Field(default=None, max_length=120)
expected_version: int
class Phase2ConfirmRequest(BaseModel):
"""User confirms or edits proper nouns and style for Phase 2."""
proper_nouns: list[ProperNoun]
style: str
expected_version: int
# ── API Responses ──────────────────────────────────────
class SessionResponse(BaseModel):
session_id: str
data: TranslationSession
title: str = ""
status: str = "draft"
current_phase: int = 0
version: int = 0
created_at: str = ""
updated_at: str = ""
archived_at: str | None = None
class SessionSummary(BaseModel):
session_id: str
title: str
source_preview: str
target_language: str
status: str
current_phase: int
version: int
created_at: str
updated_at: str
archived_at: str | None = None
class RevisionResponse(BaseModel):
data: TranslationSession
reason: str
created_at: str