Files
creator/backend/models.py
2026-06-15 18:51:50 +02:00

227 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from pydantic import BaseModel, Field
from typing import Literal
FormatType = Literal[
"OnePager",
"MiniGuide",
"Guide",
"FullGuide",
]
ProviderType = Literal["claude", "minimax", "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]
# --- Baustein-Lernen ---
VertiefungArt = Literal["vertiefung", "deepdive"]
class VertiefungRequest(BaseModel):
topic: str = Field(min_length=1, max_length=100)
baustein: str = Field(min_length=1, max_length=200)
section: str = Field(default="", max_length=20000)
art: VertiefungArt = "vertiefung"
provider: ProviderType = "claude"
class VertiefungResponse(BaseModel):
md: str
class BausteinChatRequest(BaseModel):
topic: str = Field(min_length=1, max_length=100)
baustein: str = Field(min_length=1, max_length=200)
section: str = Field(default="", max_length=20000)
messages: list[ChatMessage] = Field(min_length=1)
provider: ProviderType = "claude"
class BausteinChatResponse(BaseModel):
reply: str
class BausteinPruefungRequest(BaseModel):
topic: str = Field(min_length=1, max_length=100)
baustein: str = Field(min_length=1, max_length=200)
section: str = Field(default="", max_length=20000)
aktion: Literal["frage", "diskussion", "antwort", "antwort_pruefen"] = "frage"
frage: str = Field(default="", max_length=2000) # aktuell geprüfte Frage (für diskussion/antwort)
letzte_bewertung: str = Field(default="", max_length=2000) # Feedback der letzten Bewertung (Kontext für diskussion)
score_vor_frage: int = 0 # Score, als die Frage gestellt wurde → driftfreies (Re-)Bewerten
streak: int = 0 # Folge korrekter Antworten VOR dieser Frage (Streak-Bonus)
tier2: bool = False # ganzer Guide absolviert (alle ≥3) → 1 bei falsch, Deckel 10
tier3: bool = False # ganzer Guide verstanden (alle ≥10) → Meisterpfad, 2 bei falsch, Deckel 25
messages: list[ChatMessage] = [] # Dialog bisher; leer = erste Frage
provider: ProviderType = "claude"
class BausteinPruefungResponse(BaseModel):
frage: str | None = None
reply: str | None = None
feedback: str | None = None
bewertung: Literal["gut", "schlecht"] | None = None
gute_antworten: int
absolviert: bool
verstanden: bool = False
gemeistert: bool = False
class BausteinLernstand(BaseModel):
gute_antworten: int
absolviert: bool
verstanden: bool
gemeistert: bool
vertiefung: bool
deepdive: bool
class BausteinLernstandResponse(BaseModel):
bausteine: dict[str, BausteinLernstand]