Phase 9m: KI-Deck-Generation via mana-llm
Some checks are pending
CI / validate (push) Waiting to run
Some checks are pending
CI / validate (push) Waiting to run
Server-side AI-Pfad mit atomischer Deck+Cards-Erzeugung:
POST /api/v1/decks/generate
body { prompt, language?: 'de'|'en', count?: 3..40 }
→ ruft mana-llm /v1/chat/completions mit `mana/structured`-Alias
(JSON-Output, hartes zod-Schema)
→ SystemPrompt fixiert das Output-Format (deck_name + cards mit
front/back), verbietet HTML/Code-Fences, akzeptiert Markdown
→ Validation: zod-strict, halluzinations-resilient
→ Insert: Deck + alle Karten + Reviews in einer DB-Transaction,
contentHash beim Insert geschrieben (Phase-9j-konform)
→ 502 wenn LLM Schema bricht oder Endpoint timeoutet (90s cap)
Frontend:
- Neue Route /decks/new-ai mit Prompt-Form, Anzahl-Karten-Slider
(3-40), Sprach-Wähler (DE/EN, default = aktuelle UI-Sprache).
- 5 klickbare Beispiel-Prompts als Inspiration.
- busy-State zeigt "10-60s typisch" (Disclaimer für die LLM-Latenz).
- "✨ KI-Deck"-Button neben "Neues Deck" auf /decks.
- error-Display mit role=alert.
apps/api/src/services/llm-client.ts kapselt den Aufruf:
- mana/structured als Alias (Routing-Layer wählt Provider)
- response_format json_object
- 90s-Timeout per AbortController
- LlmError mit status + body für saubere 502-Mapping
- Optional CARDS_LLM_API_KEY-Env (für später, wenn mana-llm
GPU_API_KEY enforce'd)
Auth: aktuell User-JWT via authMiddleware. Tier-Gating bewusst
nicht aktiv — Cards-MVP ist tier-frei. Wenn AI-Generation Credits
kosten soll, kommt requireTier('beta') + creditsClient.reserve()
davor (Phase-6-Plumbing ist da, ein-Liner-Aktivierung).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
87a7a31ece
commit
f11df63e7b
6 changed files with 437 additions and 6 deletions
|
|
@ -20,3 +20,10 @@ export function updateDeck(id: string, patch: DeckUpdate) {
|
|||
export function deleteDeck(id: string) {
|
||||
return api<{ deleted: string }>(`/api/v1/decks/${id}`, { method: 'DELETE' });
|
||||
}
|
||||
|
||||
export function generateDeck(input: { prompt: string; language?: 'de' | 'en'; count?: number }) {
|
||||
return api<{ deck: Deck; cards_created: number }>('/api/v1/decks/generate', {
|
||||
method: 'POST',
|
||||
body: input,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue