Commit graph

143 commits

Author SHA1 Message Date
Vadym Samoilenko
9beb2c1936 Fix Studio textarea focus loss on every keystroke
Replaced inner Textarea component (defined inside StudioCustomizeModal)
with a plain renderTextarea() function called directly — prevents React
from unmounting/remounting the textarea on each re-render.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 23:12:32 +00:00
Vadym Samoilenko
b6a30f5830 Redesign notebook detail page to full dark production UI
- Consistent #0D0D0D dark theme throughout, no white sections
- Unified action buttons: dark surface with FFCB05/FF5C00 icon accents
- Studio grid: refined cards with hover lift, pencil shows on hover
- All modals/panels (share, edit, podcast, upload) match dark surface
- Processing/failed banners: dark blue/red tints with proper contrast
- Documents list, synthesis, studio viewer all dark themed
- Studio sub-views (flashcards, quiz, report, datatable) dark themed
- globals.css .dk class resets forced color override for dark sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 23:10:51 +00:00
Vadym Samoilenko
b2585cabab Fix 403→401: HTTPBearer auto_error=False so missing token returns 401
FastAPI HTTPBearer returns 403 when no Authorization header is present,
but the frontend interceptor only handles 401 to redirect to login.
Switching to auto_error=False and throwing 401 manually fixes the redirect.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:50:13 +00:00
Vadym Samoilenko
f1af6b3d5a Studio: always-visible dark grid, customize modals, downloads for all types
UI:
- Studio grid always visible (dark #1C1C1E, 3-col, 8 cards incl. Audio Overview)
- Each card: click body to view/generate, pencil icon to customize
- Active indicator (green dot) on cards with generated content
- StudioCustomizeModal: dark theme, type-specific options (count, difficulty, format, length, orientation, detail, custom_prompt)

Downloads:
- Mind Map → SVG (server endpoint)
- Flashcards → CSV (client-side)
- Quiz → TXT (client-side)
- Infographic → HTML (client-side, styled)
- Data Table → CSV (client-side)
- Slides → PPTX (existing server endpoint)
- Report → PDF (existing server endpoint)

Backend:
- All gen_* endpoints accept StudioGenerateRequest body with optional params
- All generator functions accept options dict and adjust prompts accordingly
- New GET /notebooks/{id}/studio/mindmap/download → SVG

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:47:29 +00:00
Vadym Samoilenko
6dc2096948 Apply OLIVER brand style to Slide Deck viewer and PPTX export
Browser preview:
- White background for content slides, dark (#1A1A1A) for title slide
- Yellow (#FFCB05) top bar, title underline, slide number highlight
- Orange (#FF5C00) bullet dots
- Montserrat font via CSS, responsive clamp() sizing

PPTX download:
- Blank layout with programmatic shapes (no default theme artifacts)
- Dark title slide with yellow left bar and separator line
- White content slides with yellow top/accent bars
- Orange bullet markers, Montserrat font, proper sizing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:33:32 +00:00
Vadym Samoilenko
2526897bd9 Move Studio to top action bar as collapsible button row
Studio is now a 5th button in the main action bar. Clicking it expands a second row of 7 colored buttons (Mind Map, Flashcards, Quiz, Slide Deck, Report, Infographic, Data Table) styled to match existing Chat/Share/Analysis/Podcast buttons. Removes the old card grid section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:29:43 +00:00
Vadym Samoilenko
ad8e857cf6 Update README and add CLAUDE.md developer guide
- README: rewrite for Docker-first setup, add Studio features, update schema/endpoints, add troubleshooting for common Docker issues
- CLAUDE.md: new file with architecture overview, deployment commands, DB schema, common issues for AI assistants

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:27:11 +00:00
Vadym Samoilenko
d36c38e2fd Add Studio features: Flashcards, Quiz, Mind Map, Slides, Report, Infographic, Data Table
- studio_generators.py: 7 Pydantic output models + async generators using LLM factory
- database.py: add studio_data TEXT column with safe ALTER TABLE migration
- notebooks.py: GET /studio, POST /studio/{type}, GET /studio/{slides,report}/download
- types/index.ts, api.ts: Studio type interfaces and API calls
- page.tsx: Studio grid section, modal overlay, 7 viewer sub-components (SVG mind map, 3D flashcard flip, scored quiz, slide carousel, report PDF, infographic, data table)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:18:06 +00:00
Vadym Samoilenko
23494552e7 Fix health check URL: /health -> /api/health
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:50:32 +00:00
Vadym Samoilenko
289cc4c27f Fix backend DB connection inside Docker container
database.py: use pgql_host/pgql_port env vars (default: localhost:5433)
docker-compose.yml: set pgql_host=postgres, pgql_port=5432 for backend service

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:48:56 +00:00
Vadym Samoilenko
15840767b2 Fix 2_deploy.sh: git stash before pull, fix PostgreSQL ROW_COUNT
- Add git stash before git pull to handle locally created directories
- Replace invalid ROW_COUNT() with grep on psql command tag output

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:44:35 +00:00
Vadym Samoilenko
4608ca3c5e Add Docker migration: Dockerfiles, compose config, and deployment scripts
- backend/Dockerfile: Python 3.13-slim with uv, ffmpeg, psycopg2
- frontend/Dockerfile: multi-stage Node 22 build with standalone output
- docker-compose.yml: add backend/frontend services with named volumes
- backend/.dockerignore, frontend/.dockerignore: exclude build artifacts
- audio.py: write podcasts to PODCAST_DATA_DIR env var (default: conversations/)
- background_tasks.py: handle .md files directly without LlamaParse
- pyproject.toml: add python-pptx, weasyprint, matplotlib deps
- page.tsx: add Markdown to supported file types hint
- scripts/1_backup.sh: pg_dump + tar files + Docker volume backup
- scripts/2_deploy.sh: full systemd→Docker migration with health checks
- scripts/3_cleanup.sh: post-migration cleanup of build artifacts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:34:59 +00:00
michael
7dfdb0dd35 Add get_db_session() for direct session access
The previous commit changed get_db() to a generator for FastAPI
dependency injection. This broke code that called get_db() directly.

- Add get_db_session() that returns Session directly for non-FastAPI code
- Update all manager files to use get_db_session()
- Update all route files to use get_db_session() for direct calls
- Update Streamlit pages to use get_db_session()
- Keep get_db() as generator for FastAPI Depends() usage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 10:37:25 -06:00
michael
7a94a527ae Fix SQLAlchemy connection pool exhaustion
- Fix get_db() to use generator pattern with proper session cleanup
- Increase pool size from 10+20 to 20+30 with pool_pre_ping
- Refactor admin routes to use FastAPI dependency injection
- Eliminate double-session issue in check_admin()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 08:58:01 -06:00
michael
f2b1bc47a7 Fix document list auto-refresh after upload
Replace broken useEffect-based refresh (which had race conditions) with
simpler refetchInterval approach. Now the notebook query polls every 2s
while any tasks are processing, then stops when all complete.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 17:21:52 -06:00
michael
abb746c8ad Update dependency to llama-index-llms-google-genai
Replace deprecated llama-index-llms-gemini with the new google-genai package
to match the SDK migration in llm_factory.py.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 17:13:34 -06:00
michael
9fd1979c34 Fix notebook deletion to preserve shared pipeline
When deleting a notebook using the shared pipeline, now only deletes that
notebook's document files instead of the entire pipeline. Legacy notebooks
with dedicated pipelines still get full pipeline deletion.

Added is_shared_pipeline_async() with fallback lookup for server restarts
and delete_notebook_documents_from_pipeline() for selective file deletion.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 17:09:53 -06:00
michael
5cd835f589 Auto-refresh document list when processing completes
Added useEffect that tracks completed task count and invalidates the
notebook query when new tasks finish. This ensures documents appear
in the list immediately after processing without requiring a manual
page refresh.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 17:03:37 -06:00
michael
610df753b7 Use gpt-5 instead of gpt-5-pro
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 17:00:52 -06:00
michael
e1f44b534d Fix gpt-5.1 model not recognized by llama-index
Changed gpt-5.1 to gpt-5-pro since llama-index-llms-openai 0.6.10 doesn't
have gpt-5.1 in its supported models list yet. gpt-5-pro is the closest
available model in the supported list.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 17:00:12 -06:00
michael
1c48c56a2f Improve error handling for deleted legacy pipelines
- Add specific detection for "pipeline not found" errors in query engine
- Log helpful message explaining the documents need re-uploading
- Update chat error message to guide users when index doesn't exist

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 16:51:26 -06:00
michael
5c51379065 Update LLM model options and migrate to new Google GenAI SDK
- Upgrade GPT-5 to GPT-5.1 (gpt5-exp -> gpt51-exp)
- Migrate Gemini from deprecated llama-index-llms-gemini to llama-index-llms-google-genai
- Update Gemini models: gemini-2.5-pro -> gemini-3-pro-preview, gemini-2.0-flash -> gemini-2.5-flash
- Remove GPT-4 option from frontend (legacy, expensive)
- Update pricing information for all models

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 16:40:41 -06:00
michael
d962bd93b9 Implement shared pipeline with metadata-based notebook isolation
Replace one-pipeline-per-notebook architecture with a single shared pipeline
to avoid hitting LlamaCloud's pipeline limit. Notebook isolation is now
achieved through metadata filtering:

- Add get_or_create_shared_pipeline() to auto-create/find shared pipeline
- Set notebook_id as custom_metadata when uploading documents
- Filter queries by notebook_id metadata for shared pipeline notebooks
- Legacy notebooks with dedicated pipelines continue to work unchanged

Files modified:
- pipeline_manager.py: Add shared pipeline mgmt, metadata on upload/query
- notebooks.py: Use shared pipeline for new notebooks
- background_tasks.py: Pass notebook_id when uploading documents
- chat.py: Pass notebook_id when querying pipeline

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 16:23:55 -06:00
michael
269117a460 Add voice preview functionality to podcast generation UI
Users can now preview ElevenLabs voices before selecting them for podcast
generation. Added play/stop buttons next to each voice dropdown that play
the official ElevenLabs preview audio samples.

- Added previewUrl to each voice in the voices array
- Added playPreview function with HTML5 Audio API
- Added play/stop buttons with visual feedback when playing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 10:27:34 -06:00
michael
78761d2d71 Add detailed logging to trace voice IDs through the entire flow
Added logging at:
- API endpoint: logs raw request values before defaults applied
- audio.py: logs exact voice_id being sent to ElevenLabs for each segment

This will help diagnose if voice IDs are being lost somewhere in the pipeline.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 09:43:15 -06:00
michael
4c331fac67 Add detailed logging for podcast target_length throughout generation flow
Added logging to track target_length parameter from task execution through
outline and script generation. This helps verify that the user's selected
podcast duration is being correctly passed through the system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 09:26:03 -06:00
michael
5ae16025c6 Fix voice selection not being passed to podcast generation
The frontend was sending voice IDs in a JSON body, but the FastAPI endpoint
was defining them as query parameters. Created a PodcastRequest Pydantic
model to properly receive the JSON body. Also changed logging level from
DEBUG to INFO.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 09:21:14 -06:00
michael
97833dfbde Add comprehensive voice selection logging for podcast generation
Add proper logging throughout the podcast generation flow to track which
voices are selected by users and used with the ElevenLabs API. Creates a
centralized voice_config.py with voice ID to name mapping and updates all
podcast-related files to use the logging module instead of print statements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 09:13:20 -06:00
michael
a996b259d7 Enable debug logging and use logging module in background tasks 2025-11-26 09:00:30 -06:00
michael
ee0d98d585 Fix podcast voice selection and update default voice IDs 2025-11-26 08:33:15 -06:00
michael
c2d7f80e8a Update podcast voices list 2025-11-25 15:53:04 -06:00
michael
a86da7fb68 Fix: use authenticated user for chat sessions 2025-11-24 07:40:19 -06:00
michael
f252968fac fix case-sensitive email lookup preventing notebook sharing
Made email lookups case-insensitive to resolve issue where users couldn't see shared notebooks due to email casing mismatches between SSO registration (lowercase) and manual sharing input.

Changes:
- Updated get_user_by_email() to use ilike for case-insensitive matching
- Normalized email input to lowercase in share endpoint
- Added logging for debugging share operations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 14:49:07 -06:00
michael
4df7d52a60 JWT improvements to MSAL routine, .env changes 2025-11-17 14:10:08 -06:00
Michael Clervi
b683c392da .env 2025-11-17 19:48:56 +00:00
michael
3df343adef Implement JWT authentication, email autocomplete for sharing, and fix local dev routing
Security improvements:
- Add JWT token authentication for all API endpoints
- Create jwt_auth middleware with token generation and validation
- Update auth routes to return access tokens on login/signup
- Add Authorization header interceptor in frontend API client
- Store JWT tokens in Zustand auth store
- Remove insecure user_id query parameters

Sharing enhancements:
- Add user search API endpoint (GET /api/auth/users/search)
- Implement autocomplete in share modal with debounced search
- Show email and username suggestions in dropdown
- Add keyboard navigation (arrows, Enter, Escape)
- Filter out already-shared users and current user from results
- Add email format validation on frontend and backend

Developer experience:
- Make basePath environment-specific (empty in dev, /notebookllama in prod)
- Update next.config.js to support local development without basePath
- Fix routing issues in local development (login/signup redirects)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:51:39 -06:00
michael
7c8e84eb6a made podcast generation fully parallel/async with no queue 2025-10-31 11:31:38 -05:00
michael
05ff5f0bec added back end logging for podcast generation 2025-10-31 10:12:23 -05:00
Michael Clervi
50897b8a5d changed permissions on deploy script 2025-10-28 21:26:51 +00:00
michael
0556a7f0f9 added deploy script 2025-10-28 16:25:35 -05:00
michael
074eb1bf08 fixed systemd service file for standalone operation 2025-10-28 16:15:18 -05:00
michael
b72281a87a reordered messages in ascending order for chat 2025-10-21 15:47:24 -05:00
michael
09a74425ca extended LLM timeouts 2025-10-20 15:52:51 -05:00
michael
a7d64a385e reduced repetitive logging 2025-10-20 15:23:47 -05:00
michael
e48471a88b added API logging 2025-10-20 15:20:16 -05:00
michael
60baaa2597 added red banner and retries for pipline initialization on document uploads 2025-10-20 13:38:12 -05:00
michael
244b550c48 separation between queued and processing in UI 2025-10-20 13:18:59 -05:00
michael
630637e3e7 adjusted document processing logic so only successful documents make it to the documents list 2025-10-20 13:01:18 -05:00
michael
3c0ba1b01c added retry for failed document processing 2025-10-20 12:47:33 -05:00
michael
b83e998a9a fix for failed notebook creation due to llamaindex outage 2025-10-20 12:15:46 -05:00