Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/pull_request_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ jobs:
echo "No Python files changed; skipping typecheck."
exit 0
fi
echo "$CHANGED_PY" | tr '\n' '\0' | xargs -0 mypy --ignore-missing-imports --follow-imports=silent
while IFS= read -r py_file; do
[ -z "$py_file" ] && continue
mypy --ignore-missing-imports --follow-imports=silent --explicit-package-bases "$py_file"
done <<< "$CHANGED_PY"

validate-architecture:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ innovation-lab-examples/
| [Crewai-agents](Crewai-agents/) | CrewAI agents — trip planner, code analyzer, meeting prep, blood report | Python, CrewAI, uAgents | 🟡–🔴 Collection |
| [ag2-agents](ag2-agents/) | AG2 framework — research synthesis, payment approval | Python, AG2, uAgents | 🔴 Advanced |
| [community_agent](community_agent/) | AI community growth agent for events and hackathons | Python, uAgents, ASI:One, Tavily | 🟡 Intermediate |
| [pdf-podcast-agent](pdf-podcast-agent/) | PDF-to-podcast with live debate, Q&A, and Stripe payments | Python, uAgents, ASI:One, OpenAI TTS, Stripe | 🔴 Advanced |

### 🌐 Web3 & Blockchain

Expand Down
71 changes: 71 additions & 0 deletions pdf-podcast-agent/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# ─────────────────────────────────────────────────────────────────────────────
# PDF-to-Podcast Agent – environment variables
# Copy this file to .env and fill in your real values.
# Never commit .env to version control.
# ─────────────────────────────────────────────────────────────────────────────

# ── Required ──────────────────────────────────────────────────────────────────

# ASI:One API key — used for all text generation (debate, DOCX, host Q&A)
# Get yours at https://asi1.ai/
ASI1_API_KEY=

# OpenAI API key — used for TTS audio generation only
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Agentverse / ASI:One API key (needed for agent registration & mailbox)
AGENTVERSE_API_KEY=AV-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# ── Sub-agent addresses (run `python get_addresses.py` to get these) ─────────
EXTRACTOR_ADDRESS=
SCRIPTWRITER_ADDRESS=
VOICE_STUDIO_ADDRESS=

# Post-show Q&A host agents (start host_a_agent.py + host_b_agent.py first)
HOST_A_ADDRESS=
HOST_B_ADDRESS=

# ── Optional: override agent seed phrases ─────────────────────────────────────
# Changing a seed changes the agent's on-chain address.
# Leave blank to use the built-in defaults.
ORCHESTRATOR_SEED=
EXTRACTOR_SEED=
SCRIPTWRITER_SEED=
VOICE_STUDIO_SEED=
HOST_A_SEED=
HOST_B_SEED=

# ── Optional: LLM / TTS model overrides ──────────────────────────────────────
# ASI:One text generation model (default: asi1-mini)
ASI1_MODEL=asi1-mini

# Extraction + scripting model (sub-agents)
EXTRACTION_MODEL=gpt-4o-mini
SCRIPTWRITER_MODEL=gpt-4o-mini

# TTS model: "tts-1" (fast) or "tts-1-hd" (higher quality)
TTS_MODEL=tts-1

# Host voices (OpenAI: alloy | echo | fable | onyx | nova | shimmer)
VOICE_HOST_A=alloy
VOICE_HOST_B=echo

# ── Optional: audio ───────────────────────────────────────────────────────────
# Milliseconds of silence injected between each dialogue line (default: 400)
SILENCE_MS=400

# Directory where MP3 files are saved (default: ./output)
OUTPUT_DIR=output

# ── Stripe Payments (Live Show Pass) ──────────────────────────────────────────
# Get your API keys at https://dashboard.stripe.com/apikeys
# Leave STRIPE_SECRET_KEY blank to disable payment gating (free/dev mode).
STRIPE_SECRET_KEY=sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
STRIPE_PUBLISHABLE_KEY=pk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Price of the Live Show Pass in USD cents (default: 1000 = $10.00)
STRIPE_LIVE_SHOW_PRICE_CENTS=1000

# URL shown after a successful payment
STRIPE_SUCCESS_URL=https://asi1.ai
STRIPE_CANCEL_URL=https://asi1.ai
28 changes: 28 additions & 0 deletions pdf-podcast-agent/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Environment & secrets
.env

# Python
venv/
.venv/
__pycache__/
*.py[cod]
*.egg-info/

# Agent runtime state (deterministic — regenerated on startup)
agent1q*_data.json

# Generated output
output/*.mp3
output/*.docx
output/*.png

# OS files
.DS_Store
Thumbs.db
desktop.ini

# IDE
.vscode/
.idea/
*.swp
*.swo
203 changes: 203 additions & 0 deletions pdf-podcast-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
# PDF-to-Podcast Agent

Turn any research PDF into a 2-host debate podcast with live Q&A, interactive debates, and Stripe-gated premium features — all inside ASI:One.

- **Category:** `Multi-Agent`, `LLM`, `Payments`, `RAG`
- **Difficulty:** Advanced
- **Tech stack:** Python, uAgents, ASI:One, OpenAI TTS, Stripe, pydub, pdfplumber

## Overview

Reading dense research papers causes serious fatigue. This agent replicates the "NotebookLM" podcast experience: upload a PDF, get back an MP3 debate between two AI hosts — a Skeptic and an Expert. After the podcast, the hosts stay in chat for live Q&A and can run a turn-by-turn live debate, gated by a $10 Stripe payment via the AgentPaymentProtocol.

## Features

- ✅ PDF text extraction with pdfplumber
- ✅ RAG-style key insight extraction (core thesis, metrics, controversy)
- ✅ AI-generated debate script (10–14 lines) between a Skeptic and an Expert
- ✅ Parallel TTS voice synthesis with pydub audio stitching → MP3
- ✅ DOCX transcript with extended director's cut
- ✅ Free live Q&A — tag @skeptic-agent or @expert-agent in chat
- ✅ Paid live debate — 8-turn agent-to-agent debate streamed in chat
- ✅ Host personality customization — 16 combos across 4 presets
- ✅ Stripe payment gate ($10) via AgentPaymentProtocol (embedded checkout)

## Prerequisites

- Python 3.10+
- ffmpeg on PATH (`winget install ffmpeg` · `brew install ffmpeg` · `apt install ffmpeg`)
- ASI:One API key — [asi1.ai](https://asi1.ai)
- OpenAI API key (TTS only) — [platform.openai.com](https://platform.openai.com)
- Agentverse API key — [agentverse.ai](https://agentverse.ai)
- Stripe API keys (optional) — [dashboard.stripe.com](https://dashboard.stripe.com/apikeys)

## Installation

```bash
cd innovation-lab-examples/pdf-podcast-agent

python -m venv .venv
source .venv/bin/activate # macOS / Linux
# .\.venv\Scripts\Activate.ps1 # Windows

pip install -r requirements.txt
```

## Environment Variables

Create a `.env` file using `.env.example`:

```bash
cp .env.example .env
```

Then run `python get_addresses.py` and paste the printed addresses into `.env`.

### Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `ASI1_API_KEY` | Yes | ASI:One LLM — all text generation |
| `OPENAI_API_KEY` | Yes | OpenAI TTS — audio synthesis only |
| `AGENTVERSE_API_KEY` | Yes | Agent registration and mailbox |
| `EXTRACTOR_ADDRESS` | Yes | From `get_addresses.py` |
| `SCRIPTWRITER_ADDRESS` | Yes | From `get_addresses.py` |
| `VOICE_STUDIO_ADDRESS` | Yes | From `get_addresses.py` |
| `HOST_A_ADDRESS` | Yes | From `get_addresses.py` |
| `HOST_B_ADDRESS` | Yes | From `get_addresses.py` |
| `STRIPE_SECRET_KEY` | No | Enables Stripe payment gate |
| `STRIPE_PUBLISHABLE_KEY` | No | For embedded Stripe checkout |

## Run the Agent

Start all 6 agents (sub-agents first, orchestrator last):

```bash
python extractor_agent.py # Terminal 1
python scriptwriter_agent.py # Terminal 2
python voice_studio_agent.py # Terminal 3
python host_a_agent.py # Terminal 4
python host_b_agent.py # Terminal 5
python orchestrator.py # Terminal 6 (start last)
```

Or use the convenience launcher:

```bash
python run.py
```

## Expected Output

After starting, the orchestrator prints:

```
INFO: [pdf_podcast_orchestrator]: Starting agent with address: agent1q...
INFO: [pdf_podcast_orchestrator]: Agent inspector available at https://agentverse.ai/inspect/?uri=...
INFO: [pdf_podcast_orchestrator]: [Orchestrator] sub-agents wired:
Extractor agent1q...
Scriptwriter agent1q...
Voice Studio agent1q...
Host A agent1q...
Host B agent1q...
```

When a user uploads a PDF via ASI:One, the agent replies with:

- Episode title and duration
- MP3 download link
- DOCX transcript link
- Script preview (core argument, metrics, controversy)
- Live Q&A prompt (free) and Live Show Pass ($10)

## Demo

PDF upload and podcast generation:

![PDF upload and generated podcast](./assets/demo-podcast-ready.png)

Live Q&A and paid live show entry point:

![Live Q&A and paid pass prompt](./assets/demo-live-qa-pass.png)

Stripe payment confirmation for Live Show Pass:

![Stripe payment flow](./assets/demo-stripe-pass.png)

Host personality customization menu:

![Host personality customization](./assets/demo-customize-hosts.png)

## Architecture

```text
User uploads PDF to ASI:One
┌─────────────┐ ExtractRequest ┌──────────────┐
│ Orchestrator │──────────────────────▶│ RAG Extractor│
│ (port 8000) │◀─ ResearchInsights ──│ (port 8001) │
│ │ └──────────────┘
│ │ PodcastScript ┌──────────────┐
│ │──────────────────────▶│ Scriptwriter │
│ │◀─ PodcastScript ─────│ (port 8002) │
│ │ └──────────────┘
│ │ PodcastScript ┌──────────────┐
│ │──────────────────────▶│ Voice Studio │
│ │◀─ AudioResponse ─────│ (port 8003) │
│ │ └──────────────┘
│ │ ContextInjection ┌──────────────┐
│ │─────────────────────▶│ Host A │
│ │ DebateTurn │ "Skeptic" │
│ │─────────────────────▶│ (port 8004) │
│ │ └──────────────┘
│ │ ContextInjection ┌──────────────┐
│ │─────────────────────▶│ Host B │
│ │ DebateTurn │ "Expert" │
│ │─────────────────────▶│ (port 8005) │
└─────────────┘ └──────────────┘
```

### Payment flow

1. User types **"debate"** or **"customize"** in chat
2. Orchestrator sends `RequestPayment` with embedded Stripe Checkout (`ui_mode="embedded"`)
3. User completes payment in the Stripe overlay
4. ASI:One sends `CommitPayment` → Orchestrator verifies → sends `CompletePayment`
5. User types **"continue debate"** to start the live show

## Project Structure

```text
pdf-podcast-agent/
├── orchestrator.py # Main agent — chat protocol, payment, debate relay
├── extractor_agent.py # Agent 1: RAG extraction (port 8001)
├── scriptwriter_agent.py # Agent 2: Debate script generation (port 8002)
├── voice_studio_agent.py # Agent 3: TTS + audio stitching (port 8003)
├── host_a_agent.py # Host A: The Skeptic — Q&A + debate (port 8004)
├── host_b_agent.py # Host B: The Expert — Q&A + debate (port 8005)
├── schemas.py # Pydantic models (typed contracts between agents)
├── get_addresses.py # Prints agent addresses (run first)
├── run.py # Convenience launcher (all 6 agents)
├── test_pipeline.py # Local smoke test
├── requirements.txt
├── .env.example
├── render.yaml # Render.com deployment config
└── output/ # Generated MP3/DOCX files (gitignored)
```

## Troubleshooting

- **"Missing ASI1_API_KEY / OPENAI_API_KEY"** — Check `.env` is created from `.env.example` with real values.
- **"I do not have enough funds to register on Almanac contract"** — Safe to ignore for local dev.
- **Port already in use** — Kill stale process on that port and restart.
- **Debate hosts repeat arguments** — Full debate history is passed via `debate_history` field with anti-repetition prompts.

## Resources

- [Innovation Lab Docs](https://innovationlab.fetch.ai/resources/docs/intro)
- [Agentverse](https://agentverse.ai/)
- [ASI:One API](https://asi1.ai/)
- [uAgents Framework](https://github.com/fetchai/uAgents)
- [Agent Payment Protocol](https://innovationlab.fetch.ai/resources/docs/payments)
- [Stripe Sandboxes](https://docs.stripe.com/sandboxes)
Empty file.
Binary file added pdf-podcast-agent/assets/demo-customize-hosts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pdf-podcast-agent/assets/demo-live-qa-pass.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pdf-podcast-agent/assets/demo-podcast-ready.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pdf-podcast-agent/assets/demo-stripe-pass.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading