from pydantic import BaseModel, Field from typing import Literal FormatType = Literal[ "OnePager", "MiniGuide", "Guide", "FullGuide", ] ProviderType = Literal["claude", "minimax", "minimax-direkt", "lokal"] class GuideCreateRequest(BaseModel): topic: str = Field(min_length=1, max_length=100) format: FormatType instructions: str = Field(default="", max_length=2000) provider: ProviderType = "claude" class TopicCreateRequest(BaseModel): name: str = Field(min_length=1, max_length=100) class BausteineCreateRequest(BaseModel): topic: str = Field(min_length=1, max_length=100) instructions: str = Field(default="", max_length=2000) provider: ProviderType = "claude" class BausteineStep(BaseModel): label: str state: Literal["done", "active", "pending"] class BausteineStatusResponse(BaseModel): ready: bool generating: bool progress: str | None = None error: str | None = None partial: bool = False steps: list[BausteineStep] = [] class ProjectResponse(BaseModel): name: str class ProviderInfo(BaseModel): id: str available: bool class GuideResponse(BaseModel): id: str topic: str format: str status: str progress: str | None = None step: int | None = None error_msg: str | None = None created_at: str updated_at: str class ChatMessage(BaseModel): role: Literal["user", "assistant"] content: str = Field(min_length=1, max_length=8000) class GuideChatRequest(BaseModel): section: str = Field(default="", max_length=20000) outline: str = Field(default="", max_length=8000) messages: list[ChatMessage] = Field(min_length=1) provider: ProviderType = "claude" class GuideChatResponse(BaseModel): reply: str class ElementResponse(BaseModel): id: str topic: str title: str description: str = "" examples: list[str] = [] hints: list[str] = [] created_at: str updated_at: str class ElementCreateRequest(BaseModel): topic: str = Field(min_length=1, max_length=100) hint: str = Field(default="", max_length=500) provider: ProviderType = "claude" class ElementUpdateRequest(BaseModel): title: str | None = Field(default=None, max_length=200) description: str | None = None examples: list[str] | None = None hints: list[str] | None = None class ElementCheckRequest(BaseModel): provider: ProviderType = "claude" class ElementSuggestion(BaseModel): text: str target: Literal["description", "examples", "hints"] content: str class ElementCheckResponse(BaseModel): suggestions: list[ElementSuggestion] class ElementStyleChange(BaseModel): text: str action: Literal["entfernen", "anpassen", "hinzufuegen"] target: Literal["title", "description", "examples", "hints"] index: int | None = None content: str = "" class ElementStyleResponse(BaseModel): changes: list[ElementStyleChange] class ElementChatRequest(BaseModel): messages: list[ChatMessage] = Field(min_length=1) provider: ProviderType = "claude" class ElementChatResponse(BaseModel): reply: str changes: list[ElementStyleChange] = [] class ElementRefineRequest(BaseModel): suggestion: ElementStyleChange instruction: str = Field(min_length=1, max_length=2000) provider: ProviderType = "claude" class ElementRefineResponse(BaseModel): change: ElementStyleChange class ProgressUpdate(BaseModel): chapter: str = Field(min_length=1, max_length=100) done: bool class ProgressResponse(BaseModel): chapters: list[str]