Integrate backend generation, live views, and Tome Home#46
Merged
Conversation
Adds POST /api/generate/{flashcards,quiz,report} on a new router. Each
endpoint pulls excerpts from the knowledge base (semantic search when a
topic is provided, random sample otherwise — optionally scoped to a
tome), prompts the configured LLM with response_format=json_object on
OpenAI-compatible providers, and validates the parsed payload before
responding. An empty KB returns 400 with a hint to upload documents.
Also exposes an llm_text(...) helper used by the audio endpoint for
plain-text completions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
POST /api/generate/audio retrieves KB context (or randomly samples it),
prompts the configured provider for a spoken-style narration script,
and segments it into sentence-level chunks with word-rate-estimated
timings for transcript scroll-lock.
When OPENAI_API_KEY is configured, the script is also synthesized to
MP3 via OpenAI's tts-1 voice (default: alloy) and cached to disk; the
response includes audio_url. Without a key, audio_url is null and the
frontend falls back to the browser's SpeechSynthesis voice.
GET /api/audio/{audio_id}.mp3 streams the cached file with a regex
guard against directory traversal.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Adds KnowledgeStore.list_sessions(): one SQL pass joining sessions, messages, and tomes that returns derived title (first user message), tome name, message count, and last activity timestamp. Ordered by most-recent activity. - Adds GET /api/chat/sessions?limit=<n> as a thin wrapper for the History panel. - Extends the chat SYSTEM_PROMPT with an "App capabilities you should know about" section so the model can describe its own routed features (quiz / flashcards / audio / report / history / tomes / knowledge base / upload) accurately when the user asks "what can you do?", and skips replying when the frontend has already routed away. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds typed helpers covering every new backend surface: - Knowledge base: listDocuments, getDocument, deleteDocument plus DocumentSummary / DocumentDetail. - Generation: generateFlashcards, generateQuiz, generateReport, generateAudio with shared GenerateOpts and GeneratedSource. - Audio: AudioGeneration / AudioSegment plus resolveAudioUrl() that joins a relative audio path against the active API base (so it works from both the Next.js dev server and the Tauri sidecar). - History: listChatSessions and ChatSessionSummary. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds two new components reachable from the round button next to the command-bar pill: - UploadModal: paste / drag-drop / file-picker ingest of text-like files (.txt, .md, .markdown, .rst, .csv, .json, .log). Backend dedupes by content hash so re-uploads are safe. - KnowledgeBaseWidget: two-pane list+detail browser over every ingested document. Lists titles with doc_type/source/timestamp, shows chunk count, content hash, linked tomes, and a 200-char preview. Per-row delete. An "Add document" button in the header opens UploadModal and refreshes the list on close. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the hard-coded SAMPLE_* placeholders that the original FlashcardWidget / QuizWidget / AudioPlayerWidget / ReportViewWidget rendered with real, KB-grounded views that POST to the new /api/generate/* endpoints. Each view shares the same shape: loading card, error card with retry, content card, and a "Grounded in: ..." source footer listing the distinct source documents. AudioPlayerWidget gains two new props — audioUrl and script — and switches between two playback modes: - <audio> element when the backend synthesized an MP3 (OpenAI TTS). Timeupdate events drive currentTime; a Download link appears. - SpeechSynthesis fallback when no audio_url. Seek bar restarts speech from the nearest segment; a "Browser TTS" badge appears in place of Download. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- ChatWidget now POSTs to /api/chat via sendChat(), tracks sessionId across turns, surfaces backend errors inline as assistant-style messages, and accepts an initialQuery prop so the first command-bar prompt seeds the conversation. - The verb router used to live only in the command bar. detectView() is now lifted to page.tsx and shared with ChatWidget through an onCommand callback, so typing "make flashcards on attention" from inside the chat view routes correctly instead of being answered as prose. Supported verbs: quiz / test / flashcards / audio / podcast / listen / report / study guide / summary / history / tome / collection / library / knowledge / kb / docs. - CommandBar gets a circular knowledge-base button (icon: library_add) to the right of the pill that opens the KB browser; the model badge is now driven by getRuntimeConfig() instead of being hard-coded. - page.tsx threads generationPrompt through the routed views so the user's full command text becomes the topic for /api/generate/*. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the SAMPLE_HISTORY array with a fetch against
GET /api/chat/sessions. Filters out stub sessions (no user message
or zero messages), derives a row title from the first user message
(first line, 90 char cap), and groups rows into Today / Yesterday /
Earlier this week / Older buckets using a shared formatTimestamp
helper that handles both `datetime('now')` and ISO timestamp formats.
Search input filters by title or tome name client-side. Loading,
error, and empty states are inline. The filter pills (chat / quiz /
flashcard / etc.) are removed for now — only chat rows exist until
the other generations gain server-side persistence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test Plan
cd backend && uv run --group dev pytestcd frontend && npm run buildNotes