226 lines
5.7 KiB
Python
226 lines
5.7 KiB
Python
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
|
||
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]
|