|
|
import gradio as gr |
|
|
import json |
|
|
import os |
|
|
from openai import OpenAI |
|
|
|
|
|
|
|
|
SYSTEM_PROMPT = """You are Herman Poppleberry, a friendly and slightly eccentric donkey who lives with Daniel in Jerusalem. You have a brother called Corn who is a sloth. |
|
|
|
|
|
Your task is as follows: |
|
|
|
|
|
The user (Daniel) will provide you with a prompt. You should infer this prompt to be a question. If the text provided does not ask a direction question, understand it as if it did. |
|
|
|
|
|
You must answer the prompt by generating a podcast episode based upon it. The podcast is called 'The Daniel Prompt Hour' and it consists of you answering the prompts which Daniel sends in. |
|
|
|
|
|
The outputs you provide are single-turn. In response to Daniel's prompt/request, you must provide the following in a JSON array: |
|
|
|
|
|
- episode_title: A catchy episode name that encapsulates the subject manner. Make this slightly clickbaity and capricious. |
|
|
- episode_description: Up to 100 words describing the episode |
|
|
- episode_transcript: The entire episode transcript |
|
|
|
|
|
The episode transcript which you generate must be: |
|
|
|
|
|
- Written in plain text |
|
|
- Containing no elements which would be inappropriate for text to speech generation. For example, you do not include URLs or reference footnotes. |
|
|
- Written in the format of a typical podcast episode: you begin by welcoming listeners to another edition; then provide your answer to Daniel's question; then thank the audience for listening. |
|
|
|
|
|
Your answers to Daniel's questions should be well researched and informative. You have a dry and slightly sly sense of humor. |
|
|
You are a donkey. You mention this in passing but do not dwell upon the fact. You sometimes make joking comments about your brother Corn (the sloth). |
|
|
|
|
|
The episode transcripts should be about 1,500 words each.""" |
|
|
|
|
|
def generate_podcast_transcript(user_prompt, api_key, model_choice="gpt-4o-mini"): |
|
|
""" |
|
|
Generate a podcast transcript using Herman Poppleberry persona |
|
|
""" |
|
|
if not api_key or api_key.strip() == "": |
|
|
return "β **Error**: Please provide your OpenAI API key to generate podcast episodes.\n\nYou can get an API key at: https://platform.openai.com/api-keys" |
|
|
|
|
|
try: |
|
|
|
|
|
client = OpenAI(api_key=api_key.strip()) |
|
|
|
|
|
|
|
|
response = client.chat.completions.create( |
|
|
model=model_choice, |
|
|
messages=[ |
|
|
{"role": "system", "content": SYSTEM_PROMPT}, |
|
|
{"role": "user", "content": f"User prompt: {user_prompt}\n\nPlease generate the podcast episode in JSON format with episode_title, episode_description, and episode_transcript fields."} |
|
|
], |
|
|
max_tokens=3000, |
|
|
temperature=0.7, |
|
|
top_p=0.9 |
|
|
) |
|
|
|
|
|
|
|
|
response_text = response.choices[0].message.content |
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
clean_text = response_text.strip() |
|
|
if clean_text.startswith("```json"): |
|
|
clean_text = clean_text[7:] |
|
|
if clean_text.endswith("```"): |
|
|
clean_text = clean_text[:-3] |
|
|
|
|
|
podcast_data = json.loads(clean_text) |
|
|
|
|
|
|
|
|
formatted_output = f"""# {podcast_data.get('episode_title', 'The Daniel Prompt Hour Episode')} |
|
|
|
|
|
## Episode Description |
|
|
{podcast_data.get('episode_description', 'No description available')} |
|
|
|
|
|
## Episode Transcript |
|
|
{podcast_data.get('episode_transcript', 'No transcript available')}""" |
|
|
|
|
|
return formatted_output |
|
|
|
|
|
except json.JSONDecodeError: |
|
|
|
|
|
return f"# The Daniel Prompt Hour Episode\n\n## Raw Response\n{response_text}" |
|
|
|
|
|
except Exception as e: |
|
|
return f"Error generating podcast transcript: {str(e)}" |
|
|
|
|
|
|
|
|
with gr.Blocks( |
|
|
title="The Daniel Prompt Hour - Podcast Generator", |
|
|
theme=gr.themes.Soft(), |
|
|
css=""" |
|
|
.gradio-container { |
|
|
max-width: 900px !important; |
|
|
} |
|
|
.header { |
|
|
text-align: center; |
|
|
margin-bottom: 20px; |
|
|
} |
|
|
""" |
|
|
) as demo: |
|
|
|
|
|
gr.HTML(""" |
|
|
<div class="header"> |
|
|
<img src="https://res.cloudinary.com/drrvnflqy/image/upload/v1757667960/Flux_Dev_a_donkey_wearing_a_top_hat_is_in_a_recording_studio_s_3_czrkbs.jpg" |
|
|
alt="Herman Poppleberry in the recording studio" |
|
|
style="width: 200px; height: 200px; object-fit: cover; border-radius: 15px; margin-bottom: 20px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"> |
|
|
<h1>ποΈ The Daniel Prompt Hour</h1> |
|
|
<h3>Featuring Herman Poppleberry, the Donkey π«</h3> |
|
|
<p>Enter any prompt and Herman will turn it into a podcast episode!</p> |
|
|
</div> |
|
|
""") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(scale=2): |
|
|
api_key_input = gr.Textbox( |
|
|
label="OpenAI API Key", |
|
|
placeholder="Enter your OpenAI API key (sk-...)", |
|
|
type="password", |
|
|
info="Your API key is not stored and only used for this session" |
|
|
) |
|
|
|
|
|
user_input = gr.Textbox( |
|
|
label="Your Prompt", |
|
|
placeholder="Enter any question or topic you'd like Herman to discuss in a podcast episode...", |
|
|
lines=3, |
|
|
max_lines=5 |
|
|
) |
|
|
|
|
|
model_dropdown = gr.Dropdown( |
|
|
choices=[ |
|
|
"gpt-4o-mini", |
|
|
"gpt-4o", |
|
|
"gpt-4-turbo", |
|
|
"gpt-3.5-turbo" |
|
|
], |
|
|
value="gpt-4o-mini", |
|
|
label="OpenAI Model", |
|
|
info="Choose the OpenAI model to generate the podcast transcript" |
|
|
) |
|
|
|
|
|
generate_btn = gr.Button("ποΈ Generate Podcast Episode", variant="primary", size="lg") |
|
|
|
|
|
with gr.Column(scale=3): |
|
|
output = gr.Markdown( |
|
|
label="Generated Podcast Episode", |
|
|
value="Enter a prompt and click 'Generate Podcast Episode' to see Herman's response!", |
|
|
height=600 |
|
|
) |
|
|
|
|
|
|
|
|
gr.Examples( |
|
|
examples=[ |
|
|
["What's the future of artificial intelligence?"], |
|
|
["How do I make the perfect hummus?"], |
|
|
["Why do cats purr?"], |
|
|
["What's the meaning of life?"], |
|
|
["How does quantum computing work?"], |
|
|
["What makes a good podcast?"] |
|
|
], |
|
|
inputs=user_input, |
|
|
label="Example Prompts" |
|
|
) |
|
|
|
|
|
|
|
|
generate_btn.click( |
|
|
fn=generate_podcast_transcript, |
|
|
inputs=[user_input, api_key_input, model_dropdown], |
|
|
outputs=output, |
|
|
show_progress=True |
|
|
) |
|
|
|
|
|
user_input.submit( |
|
|
fn=generate_podcast_transcript, |
|
|
inputs=[user_input, api_key_input, model_dropdown], |
|
|
outputs=output, |
|
|
show_progress=True |
|
|
) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch( |
|
|
server_name="0.0.0.0", |
|
|
server_port=7860, |
|
|
share=False |
|
|
) |
|
|
|