An interactive PDF presentation viewer with integrated ElevenLabs voice AI agent. Navigate slides using voice commands, view conversation transcripts, and control presentations through both UI and voice.
- π PDF Rendering - Smooth, high-quality PDF slide rendering using PDF.js
- π€ Voice Control - Navigate presentations using natural voice commands via ElevenLabs
- π¬ Live Transcript - Real-time conversation transcript with chat interface
- π§ Multiple Navigation - Click buttons, use keyboard shortcuts, or speak commands
- π± Responsive Design - Works on desktop, tablet, and mobile devices
- π¨ Modern UI - Clean, dark-themed interface with glassmorphism effects
- ποΈ Slide Sidebar - Hamburger menu with slide navigation and titles
- π§ Modular Architecture - Well-organized, maintainable codebase
- A web server (cannot run from
file://protocol) - An ElevenLabs account with a Conversational AI agent
- Your presentation in PDF format
- Python 3 (for PDF extraction utility)
-
Clone or download this repository
git clone <your-repo-url> cd presentation_viewer
-
Place your PDF file
cp your-presentation.pdf presentation.pdf
-
Configure ElevenLabs
cp config.example.js config.js
Edit
config.jsand add your ElevenLabs agent ID:export const CONFIG = { ELEVENLABS_AGENT_ID: 'agent_your_id_here', PDF_PATH: './presentation.pdf' };
-
Extract PDF content (auto-generates slide navigation)
pip install pdfplumber python extract_pdf.py presentation.pdf
This creates:
- RAG content file for your ElevenLabs agent
modules/slide-titles.jswith auto-extracted slide titles
See docs/PDF_EXTRACTION.md for details.
-
Start a web server
# Python python3 -m http.server 8000 # Node.js npx http-server -p 8000 # PHP php -S localhost:8000
-
Open in browser
Navigate to
http://localhost:8000and you're ready!
Your ElevenLabs agent should be configured with these client tools to enable voice navigation:
| Tool Name | Description | Parameters |
|---|---|---|
nextPage |
Navigate to next slide | none |
previousPage |
Navigate to previous slide | none |
goToPage |
Jump to specific slide | pageNumber (number) |
getCurrentPage |
Get current slide number | none |
getTotalPages |
Get total number of slides | none |
getPageText |
Extract text from current slide | none |
You are a helpful presentation assistant. You can help users navigate through
a PDF presentation using voice commands.
You have access to these tools:
- nextPage: Move to the next slide
- previousPage: Move to the previous slide
- goToPage: Jump to a specific slide number
- getCurrentPage: Check what slide we're on
- getTotalPages: Find out how many slides there are
- getPageText: Read the text content from the current slide
When users ask you to navigate (e.g., "next slide", "go to slide 5",
"what's on this page"), use the appropriate tool and let them know what
slide they're on.
Be conversational and helpful. If they ask about the content, use getPageText
to read it to them.
The viewer automatically registers these tools when it initializes. See the ElevenLabs documentation for more information.
Click the microphone button to start a conversation, then use natural language:
- "Go to the next slide"
- "Show me slide 5"
- "What page are we on?"
- "Go back to the previous slide"
- "Read the text on this slide"
- Previous/Next Buttons - Navigate slides
- Hamburger Menu (β°) - View slide list and jump to any slide
- Chat Button (π¬) - Toggle conversation transcript
- Microphone Button - Start/end voice conversation
β/β- Previous/Next slideHome/End- First/Last slideEsc- Close sidebar/chat
For testing and debugging, use the window.pdfController API:
// Navigate programmatically
window.pdfController.nextPage()
window.pdfController.previousPage()
window.pdfController.goToPage(5)
// Get state
window.pdfController.getCurrentPage() // Returns { current: 1, total: 20 }
window.pdfController.getTotalPages() // Returns 20
// Extract text
await window.pdfController.getPageText() // Returns text contentexport const CONFIG = {
// Required: Your ElevenLabs agent ID
ELEVENLABS_AGENT_ID: 'agent_xxxxx',
// PDF file path
PDF_PATH: './presentation.pdf',
// Optional: Customize loading messages
LOADING_MESSAGES: {
init: 'Initializing...',
loading: 'Loading PDF...',
rendering: 'Rendering slides...'
}
};Auto-generated by extract_pdf.py, but you can manually edit:
export const SLIDE_TITLES = [
{ page: 1, title: 'Introduction' },
{ page: 2, title: 'Key Concepts' },
{ page: 3, title: 'Data Analysis' },
// ...
];Edit css/presentation.css to customize:
- Colors and themes
- Fonts and typography
- Avatar image (line 183)
- Responsive breakpoints
Each module has a single responsibility and clear interface:
presentation_viewer/
βββ index.html # Main HTML entry point
βββ main.js # System orchestrator
βββ config.js # User configuration
βββ extract_pdf.py # PDF extraction utility
βββ css/
β βββ presentation.css # All styles
βββ docs/
β βββ PDF_EXTRACTION.md # PDF extraction guide
βββ modules/
βββ state-manager.js # State tracking and events
βββ pdf-renderer.js # PDF.js integration
βββ navigation.js # Navigation logic
βββ ui-controls.js # UI buttons and controls
βββ voice-controls.js # Voice button UI
βββ client-tools.js # ElevenLabs tool registration
βββ chat-interface.js # Chat UI panel
βββ transcript-manager.js # Message routing
βββ slide-sidebar.js # Sidebar navigation
βββ api-controller.js # Testing API
βββ slide-titles.js # Slide metadata
Voice Input β ElevenLabs Agent β Client Tools β Navigation β PDF Renderer
β
Transcript Manager β Chat Interface
- Create a new module in
modules/your-feature.js - Export a class with clear public methods
- Import in
main.jsand wire it up - Update this README
Module Template:
/**
* YOUR MODULE
*
* Purpose: Brief description
* Contract: What it does
* Dependencies: What it needs
*/
export class YourModule {
constructor(dependencies) {
// Initialize
}
// Public methods
publicMethod() {
// Implementation
}
// Private methods (prefix with _)
_privateMethod() {
// Implementation
}
}- β
Ensure you're serving via HTTP/HTTPS (not
file://) - β
Check PDF path in
config.js - β Look for errors in browser console (F12)
- β
Verify your ElevenLabs agent ID in
config.js - β Check that client tools are registered in your ElevenLabs agent
- β Ensure microphone permissions are granted
- β Check browser console for connection errors
- β Ensure voice session is active (click microphone button)
- β
Check that
onMessagecallback is receiving data - β
Use
window.chatDebughelpers for testing:window.chatDebug.addTestMessage('user', 'Hello!') window.chatDebug.showChat()
- β
Run
python extract_pdf.py presentation.pdfto auto-generate titles - β
Or manually edit
modules/slide-titles.js
| Browser | Status |
|---|---|
| Chrome/Edge | β Fully supported |
| Firefox | β Fully supported |
| Safari | β Fully supported |
| Mobile browsers | β Responsive design |
Contributions welcome! This is designed to be a clean, reusable base for AI-powered presentations.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE file for details.
Feel free to use this in your own projects!
- Built with PDF.js by Mozilla
- Voice AI powered by ElevenLabs
- PDF extraction using pdfplumber
For issues or questions:
- Check the Troubleshooting section
- Review browser console for errors (F12)
- Verify ElevenLabs agent configuration
- Open an issue on GitHub
Enjoy your AI-powered presentations! π€πβ¨
