update
This commit is contained in:
@@ -17,47 +17,47 @@ class GuideCreateRequest(BaseModel):
|
||||
format: FormatType
|
||||
instructions: str = Field(default="", max_length=2000)
|
||||
provider: ProviderType = "claude"
|
||||
ab_step: int | None = Field(default=None, ge=0, le=4) # Re-Run ab Guide-Schritt (0 Gliederung … 4 Lese-Prüfung); None = voll/Resume
|
||||
ab_step: int | None = Field(default=None, ge=0, le=4) # re-run from guide step (0 outline … 4 read-exam); None = full/resume
|
||||
|
||||
|
||||
class TopicCreateRequest(BaseModel):
|
||||
name: str = Field(min_length=1, max_length=100)
|
||||
|
||||
|
||||
class BausteineCreateRequest(BaseModel):
|
||||
class BlocksCreateRequest(BaseModel):
|
||||
topic: str = Field(min_length=1, max_length=100)
|
||||
instructions: str = Field(default="", max_length=2000)
|
||||
provider: ProviderType = "claude"
|
||||
source_type: SourceType = "thema"
|
||||
source_ort: str = Field(default="", max_length=2000)
|
||||
ab_phase: int | None = Field(default=None, ge=1, le=9) # Re-Run ab grober Phase (Position in _phasen(topic), 1-based; bis 9: …Gliederung/Fragen/Artefakte); None = Resume/Fortsetzen ohne Löschen
|
||||
ab_step: int | None = Field(default=None, ge=0) # Re-Run ab feinem Teilschritt (0-basierter Index in _bausteine_steps); hat Vorrang vor ab_phase
|
||||
source_location: str = Field(default="", max_length=2000)
|
||||
ab_phase: int | None = Field(default=None, ge=1, le=9) # re-run from a coarse phase (position in _phasen(topic), 1-based; up to 9: …outline/questions/artifacts); None = resume/continue without deleting
|
||||
ab_step: int | None = Field(default=None, ge=0) # re-run from a fine sub-step (0-based index into _blocks_steps); takes precedence over ab_phase
|
||||
|
||||
|
||||
class BausteineResetStepRequest(BaseModel):
|
||||
class BlocksResetStepRequest(BaseModel):
|
||||
topic: str = Field(min_length=1, max_length=100)
|
||||
ab_step: int = Field(ge=0) # NUR zurücksetzen ab diesem Teilschritt (kein Neu-Generieren)
|
||||
ab_step: int = Field(ge=0) # ONLY reset from this sub-step (no regeneration)
|
||||
|
||||
|
||||
class BausteineStep(BaseModel):
|
||||
class BlocksStep(BaseModel):
|
||||
label: str
|
||||
state: Literal["done", "active", "pending"]
|
||||
|
||||
|
||||
class BausteineFeinStep(BaseModel):
|
||||
class BlocksFineStep(BaseModel):
|
||||
label: str
|
||||
phase: str = ""
|
||||
state: Literal["done", "active", "pending"]
|
||||
|
||||
|
||||
class BausteineStatusResponse(BaseModel):
|
||||
class BlocksStatusResponse(BaseModel):
|
||||
ready: bool
|
||||
generating: bool
|
||||
progress: str | None = None
|
||||
error: str | None = None
|
||||
partial: bool = False
|
||||
steps: list[BausteineStep] = []
|
||||
feine_steps: list[BausteineFeinStep] = []
|
||||
steps: list[BlocksStep] = []
|
||||
feine_steps: list[BlocksFineStep] = []
|
||||
|
||||
|
||||
class ProjectResponse(BaseModel):
|
||||
@@ -66,33 +66,33 @@ class ProjectResponse(BaseModel):
|
||||
|
||||
class FolderResponse(BaseModel):
|
||||
name: str
|
||||
ort: str # relativer Pfad ab Repo-Root (z.B. "projects/foo")
|
||||
location: str # path relative to the repo root (e.g. "projects/foo")
|
||||
|
||||
|
||||
class BausteineQuelleUpdate(BaseModel):
|
||||
class BlocksSourceUpdate(BaseModel):
|
||||
topic: str = Field(min_length=1, max_length=100)
|
||||
type: SourceType = "thema"
|
||||
ort: str = Field(default="", max_length=2000)
|
||||
location: str = Field(default="", max_length=2000)
|
||||
spec: str = Field(default="", max_length=2000)
|
||||
|
||||
|
||||
class BausteineQuelleResponse(BaseModel):
|
||||
class BlocksSourceResponse(BaseModel):
|
||||
type: SourceType
|
||||
ort: str
|
||||
location: str
|
||||
spec: str
|
||||
|
||||
|
||||
class SubbausteinInfo(BaseModel):
|
||||
titel: str
|
||||
stufe: Literal["anfaenger", "fortgeschritten", "experte", "einfach", "mittel", "schwer"]
|
||||
relevanz: Literal["relevant", "rand"] | None = None
|
||||
class SubblockInfo(BaseModel):
|
||||
title: str
|
||||
level: Literal["beginner", "advanced", "expert", "easy", "medium", "hard"]
|
||||
relevance: Literal["relevant", "peripheral"] | None = None
|
||||
|
||||
|
||||
class BausteinUebersicht(BaseModel):
|
||||
class BlockOverview(BaseModel):
|
||||
num: int
|
||||
titel: str
|
||||
beschreibung: str = ""
|
||||
subbausteine: list[SubbausteinInfo] = []
|
||||
title: str
|
||||
description: str = ""
|
||||
subblocks: list[SubblockInfo] = []
|
||||
|
||||
|
||||
class ProviderInfo(BaseModel):
|
||||
@@ -168,7 +168,7 @@ class ElementCheckResponse(BaseModel):
|
||||
|
||||
class ElementStyleChange(BaseModel):
|
||||
text: str
|
||||
action: Literal["entfernen", "anpassen", "hinzufuegen"]
|
||||
action: Literal["remove", "adjust", "add"]
|
||||
target: Literal["title", "description", "examples", "hints"]
|
||||
index: int | None = None
|
||||
content: str = ""
|
||||
@@ -207,104 +207,104 @@ class ProgressResponse(BaseModel):
|
||||
chapters: list[str]
|
||||
|
||||
|
||||
# --- Baustein-Lernen ---
|
||||
# --- Block learning ---
|
||||
|
||||
class BausteinChatRequest(BaseModel):
|
||||
class BlockChatRequest(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) # ausführliche Fassung
|
||||
section_kompakt: str = Field(default="", max_length=20000) # kompakte Fassung (Merksätze)
|
||||
block: str = Field(min_length=1, max_length=200)
|
||||
section: str = Field(default="", max_length=20000) # detailed version
|
||||
section_compact: str = Field(default="", max_length=20000) # compact version (mnemonics)
|
||||
messages: list[ChatMessage] = Field(min_length=1)
|
||||
provider: ProviderType = "claude"
|
||||
|
||||
|
||||
class BausteinChatResponse(BaseModel):
|
||||
class BlockChatResponse(BaseModel):
|
||||
reply: str
|
||||
|
||||
|
||||
class BausteinPruefungRequest(BaseModel):
|
||||
class BlockExamRequest(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) # ausführliche Fassung
|
||||
section_kompakt: str = Field(default="", max_length=20000) # kompakte Fassung (Merksätze)
|
||||
aktion: Literal[
|
||||
"frage", "diskussion", "antwort", "antwort_pruefen",
|
||||
"quiz_frage", "quiz_antwort", "lueck_frage", "lueck_antwort",
|
||||
] = "frage"
|
||||
frage: str = Field(default="", max_length=2000) # aktuell geprüfte Frage (für diskussion/antwort); Anker der Basis
|
||||
auswahl: list[int] = [] # Quiz/Lückentext-Auswahl: vom Lerner gewählte Options-Indizes
|
||||
korrekt: list[int] = [] # Quiz/Lückentext-Auswahl: korrekte Indizes (Client hält sie aus der Generierung)
|
||||
loesung: str = Field(default="", max_length=500) # Lückentext frei: erwarteter Begriff
|
||||
alternativen: list[str] = [] # Lückentext frei: akzeptierte Synonyme
|
||||
eingabe: str = Field(default="", max_length=500) # Lückentext frei: getippter Begriff
|
||||
schwer: bool = False # Variante: leicht (+1/−1) vs schwer (+3/−1)
|
||||
letzte_bewertung: str = Field(default="", max_length=2000) # Feedback der letzten Bewertung (Kontext für diskussion)
|
||||
vermeide: list[str] = [] # schon gestellte + vorgemerkte Fragen — sinngemäß nicht wiederholen
|
||||
nachgefragt: bool = False # für diese Frage wurde nachgefragt → Gewinn auf +1 gedeckelt
|
||||
begruendung: str = Field(default="", max_length=2000) # „Gründlich prüfen": warum mit der Bewertung unzufrieden
|
||||
muster: str = Field(default="", max_length=2000) # gezogenes Frage-Muster (Saat); leer → Live-Generierung (Fallback)
|
||||
# Basis + cap werden serverseitig geführt (Anker bzw. Subs×25) — Client-cap nur Hinweis.
|
||||
cap: int = Field(default=10, ge=1, le=10000) # Score-Deckel = freigeschaltete Subbausteine × 25
|
||||
messages: list[ChatMessage] = [] # Dialog bisher; leer = erste Frage
|
||||
block: str = Field(min_length=1, max_length=200)
|
||||
section: str = Field(default="", max_length=20000) # detailed version
|
||||
section_compact: str = Field(default="", max_length=20000) # compact version (mnemonics)
|
||||
action: Literal[
|
||||
"question", "discussion", "answer", "answer_check",
|
||||
"quiz_question", "quiz_answer", "gap_question", "gap_answer",
|
||||
] = "question"
|
||||
question: str = Field(default="", max_length=2000) # currently checked question (for discussion/answer); base anchor
|
||||
selection: list[int] = [] # quiz/gap-text choice: option indices picked by the learner
|
||||
correct: list[int] = [] # quiz/gap-text choice: correct indices (the client keeps them from generation)
|
||||
solution: str = Field(default="", max_length=500) # gap text free: expected term
|
||||
alternatives: list[str] = [] # gap text free: accepted synonyms
|
||||
input: str = Field(default="", max_length=500) # gap text free: typed term
|
||||
schwer: bool = False # variant: easy (+1/−1) vs hard (+3/−1)
|
||||
last_rating: str = Field(default="", max_length=2000) # feedback of the last rating (context for discussion)
|
||||
avoid: list[str] = [] # already-asked + earmarked questions — don't repeat them in substance
|
||||
asked_again: bool = False # asked_again was used for this question → gain capped at +1
|
||||
reason: str = Field(default="", max_length=2000) # "thorough check": why dissatisfied with the rating
|
||||
pattern: str = Field(default="", max_length=2000) # drawn question pattern (seed); empty → live generation (fallback)
|
||||
# Base + cap are kept server-side (anchor / subs×25) — the client cap is only a hint.
|
||||
cap: int = Field(default=10, ge=1, le=10000) # score cap = unlocked subblocks × 25
|
||||
messages: list[ChatMessage] = [] # dialog so far; empty = first question
|
||||
provider: ProviderType = "claude"
|
||||
gruendlich: bool = False # „Gründlich prüfen": Bewertung mit starkem Modell (role guide)
|
||||
thorough: bool = False # "thorough check": rating with a strong model (role guide)
|
||||
|
||||
|
||||
class QuizOption(BaseModel):
|
||||
text: str
|
||||
korrekt: bool
|
||||
correct: bool
|
||||
|
||||
|
||||
class BausteinPruefungResponse(BaseModel):
|
||||
frage: str | None = None
|
||||
class BlockExamResponse(BaseModel):
|
||||
question: str | None = None
|
||||
reply: str | None = None
|
||||
feedback: str | None = None
|
||||
punkte: int | None = None # Punkt-Delta dieser Antwort (−2 … +3); schnell = voraussichtlich
|
||||
bewertung: Literal["gut", "neutral", "schlecht"] | None = None # aus Vorzeichen, fürs Einfärben
|
||||
optionen: list[QuizOption] | None = None # Quiz: 4 Optionen + Korrekt-Flags
|
||||
satz: str | None = None # Lückentext: Satz mit Lücke (___)
|
||||
loesung: str | None = None # Lückentext: erwarteter Begriff
|
||||
alternativen: list[str] | None = None # Lückentext: akzeptierte Synonyme
|
||||
gute_antworten: int
|
||||
streak: int = 0 # aktuelle Serie korrekter Antworten (je Baustein)
|
||||
cap: int = 10 # cap_final = alle Subs × 25 — Frontend leitet die Lernstufe ab
|
||||
points: int | None = None # points delta of this answer (−2 … +3); fast = expected
|
||||
rating: Literal["gut", "neutral", "schlecht"] | None = None # from the sign, for coloring
|
||||
options: list[QuizOption] | None = None # quiz: 4 options + correct flags
|
||||
sentence: str | None = None # gap text: sentence with a gap (___)
|
||||
solution: str | None = None # gap text: expected term
|
||||
alternatives: list[str] | None = None # gap text: accepted synonyms
|
||||
good_answers: int
|
||||
streak: int = 0 # current run of correct answers (per block)
|
||||
cap: int = 10 # cap_final = all subs × 25 — the frontend derives the learning level
|
||||
|
||||
|
||||
class BausteinLernstand(BaseModel):
|
||||
gute_antworten: int
|
||||
class BlockLearnState(BaseModel):
|
||||
good_answers: int
|
||||
streak: int = 0
|
||||
cap: int = 0 # cap_final = alle Subbausteine × 25
|
||||
cap_aktuell: int = 0 # erreichbarer cap der aktuell freigeschalteten Ebene
|
||||
freie_ebene: int = 1 # 1=A · 2=F · 3=E · 4=V
|
||||
cap: int = 0 # cap_final = all subblocks × 25
|
||||
cap_aktuell: int = 0 # reachable cap of the currently unlocked level
|
||||
freie_level: int = 1 # 1=A · 2=F · 3=E · 4=V
|
||||
|
||||
|
||||
class BausteinLernstandResponse(BaseModel):
|
||||
bausteine: dict[str, BausteinLernstand]
|
||||
class BlockLearnStateResponse(BaseModel):
|
||||
blocks: dict[str, BlockLearnState]
|
||||
|
||||
|
||||
# --- Block-Inhalt: einen Abschnitt on-demand prüfen + übernehmen (Fokus, Rechtsklick) ---
|
||||
# --- Block content: check + apply one section on demand (focus, right-click) ---
|
||||
|
||||
class BlockPruefenRequest(BaseModel):
|
||||
baustein: str = Field(min_length=1, max_length=200)
|
||||
stelle: str = "ausführlich" # "kompakt" | "ausführlich" (angezeigtes Feld)
|
||||
block: str = Field(min_length=1, max_length=20000) # roher Markdown-Block
|
||||
hinweis: str = Field(default="", max_length=2000) # optionaler Zusatz (✏️)
|
||||
block: str = Field(min_length=1, max_length=200)
|
||||
spot: str = "ausführlich" # "compact" | "ausführlich" (displayed field)
|
||||
snippet: str = Field(min_length=1, max_length=20000) # raw markdown block
|
||||
hint: str = Field(default="", max_length=2000) # optional addition (✏️)
|
||||
provider: ProviderType = "claude"
|
||||
|
||||
|
||||
class BlockPruefenResponse(BaseModel):
|
||||
neu: str # korrigierter Block als Markdown
|
||||
revised: str # corrected block as markdown
|
||||
|
||||
|
||||
class BlockUebernehmenRequest(BaseModel):
|
||||
baustein: str = Field(min_length=1, max_length=200)
|
||||
stelle: str = "ausführlich"
|
||||
block: str = Field(min_length=1, max_length=200)
|
||||
spot: str = "ausführlich"
|
||||
alt: str = Field(min_length=1, max_length=20000)
|
||||
neu: str = Field(default="", max_length=20000)
|
||||
revised: str = Field(default="", max_length=20000)
|
||||
provider: ProviderType = "claude"
|
||||
|
||||
|
||||
class BlockUebernehmenResponse(BaseModel):
|
||||
kompakt: str
|
||||
compact: str
|
||||
md: str
|
||||
gefunden: bool
|
||||
found: bool
|
||||
|
||||
Reference in New Issue
Block a user