Podify.exe is a serverless, multi-agent document intelligence platform that transforms static PDFs into dynamic, conversational audio podcasts. Instead of reading long papers or textbooks, users listen to a structured discussion between two AI hosts (Alexis and Devon) and can interject at any time with text or questions, pausing the show to guide the conversation.
The application is styled with a premium, retro-futuristic hacker terminal interface, complete with micro-animations, glassmorphism, looping video backdrops, and interactive dashboard analytics.
graph TD
A[User Uploads PDF] --> B[FastAPI Ingestion]
B --> C[PDF Text Processor]
C --> D[Gemini 1.5 Text Embeddings]
D --> E[Neon PostgreSQL + pgvector]
B --> F[Podcast Planner Agent]
F --> G[LangGraph Moderator Node]
G --> H[Host Alexis: Expert]
G --> I[Co-Host Devon: Adaptive]
H & I --> J[edge-tts Voice Synthesis]
J --> K[Next.js Client Player]
- Text Extraction: PDFs are parsed page-by-page and chunked dynamically.
- Vector Store: Semantic embeddings are calculated via Google's
text-embedding-004model. - pgvector Search: Embeddings are stored in Neon PostgreSQL. During user interjections, the system retrieves relevant document chunks using cosine distance.
The podcast script and flow are driven by a multi-agent state graph:
- The Moderator (Hidden): Manages topic progression, controls transitions, and logs session history.
- Alexis (Visible - Expert Host): Explains complex concepts, references specific sections of the PDF, and answers user interjections.
- Devon (Visible - Curious Co-Host): Asks questions to keep the dialogue engaging. Devon adjusts his query style based on the user's selected Listener Skill Profile:
- Beginner Mode: Requests intuitive analogies and simplified terms.
- Expert Mode: Challenges Alexis with theoretical comparisons and deep dives.
- Dialogue turns are synthesised on-the-fly into mp3 files using
edge-tts. - Generated audio assets are served dynamically to the Next.js frontend, allowing natural pacing and playback in the Podcast Room.
- User authentication is handled directly by the backend using cryptographically signed JSON Web Tokens (JWT).
- Passwords are hashed during registration and validated during login using
bcryptsalting. - Session tokens are stored in
localStorageand client cookies (auth_token), allowing edge-compatible Next.js routing middleware validation. - All backend database models (
documents,podcast_sessions) are user-partitioned via the verified user ID claims extracted from the JWT signature, preventing unauthorized cross-user access.
- Create a serverless PostgreSQL database on Neon (or any standard PostgreSQL instance).
- Retrieve your database connection string (URI format starting with
postgresql://). (Note: Neon Auth activation is NOT required, as authentication is fully self-hosted by the application using JWT).
Open a terminal in the /backend directory:
-
Configure Environment Variables: Create a
.envfile inside/backend(using.env.exampleas a template):DATABASE_URL="postgresql://neondb_owner:YOUR_PASSWORD@YOUR_POOLER_HOST/neondb?sslmode=require" GEMINI_API_KEY="your-google-gemini-api-key" GROQ_API_KEY="your-groq-api-key" CEREBRAS_API_KEY="your-cerebras-api-key" JWT_SECRET="optional-custom-jwt-secret-key"
-
Activate the Virtual Environment:
- Windows (PowerShell):
venv\Scripts\Activate.ps1
- macOS/Linux:
source venv/bin/activate
- Windows (PowerShell):
-
Install Dependencies:
pip install -r requirements.txt
-
Start the API Server:
uvicorn app.main:app --reload --port 8000
Note: On startup, the server automatically initializes database tables (
documents,document_chunks,podcast_sessions,podcast_turns) in the public schema and verifies connectivity.
Open a terminal in the /frontend directory:
-
Configure Environment Variables: Create a
.env.localfile inside/frontendif you wish to override the default local backend URL:NEXT_PUBLIC_API_URL="http://localhost:8000/api"
(By default, the frontend points to
http://localhost:8000/apiif no variable is provided). -
Run Dev Server:
npm run dev
-
Open http://localhost:3000 in your browser.