cleanup podcast

This commit is contained in:
LUIS NOVO 2024-11-13 17:02:48 -03:00
parent 06c6842f11
commit 182ae741d8
2 changed files with 45 additions and 98 deletions

View file

@ -2,7 +2,7 @@ from typing import ClassVar, List, Optional
from loguru import logger from loguru import logger
from podcastfy.client import generate_podcast from podcastfy.client import generate_podcast
from pydantic import Field, field_validator from pydantic import Field, field_validator, model_validator
from open_notebook.config import DATA_FOLDER from open_notebook.config import DATA_FOLDER
from open_notebook.domain.notebook import ObjectModel from open_notebook.domain.notebook import ObjectModel
@ -23,8 +23,8 @@ class PodcastConfig(ObjectModel):
podcast_name: str podcast_name: str
podcast_tagline: str podcast_tagline: str
output_language: str = Field(default="English") output_language: str = Field(default="English")
person1_role: str person1_role: List[str]
person2_role: str person2_role: List[str]
conversation_style: List[str] conversation_style: List[str]
engagement_technique: List[str] engagement_technique: List[str]
dialogue_structure: List[str] dialogue_structure: List[str]
@ -35,10 +35,24 @@ class PodcastConfig(ObjectModel):
wordcount: int = Field(ge=400, le=10000) wordcount: int = Field(ge=400, le=10000)
creativity: float = Field(ge=0, le=1) creativity: float = Field(ge=0, le=1)
provider: str = Field(default="openai") provider: str = Field(default="openai")
voice1: Optional[str] = None voice1: str
voice2: Optional[str] = None voice2: str
model: str model: str
# Backwards compatibility
@field_validator("person1_role", "person2_role", mode="before")
@classmethod
def split_string_to_list(cls, value):
if isinstance(value, str):
return [item.strip() for item in value.split(",")]
return value
@model_validator(mode="after")
def validate_voices(self) -> "PodcastConfig":
if not self.voice1 or not self.voice2:
raise ValueError("Both voice1 and voice2 must be provided")
return self
def generate_episode(self, episode_name, text, instructions=None): def generate_episode(self, episode_name, text, instructions=None):
self.user_instructions = ( self.user_instructions = (
instructions if instructions else self.user_instructions instructions if instructions else self.user_instructions
@ -140,13 +154,8 @@ conversation_styles = [
"Debate-style", "Debate-style",
"Interview-style", "Interview-style",
"Storytelling", "Storytelling",
"Reflective",
"Narrative",
"Satirical", "Satirical",
"Educational", "Educational",
"Conversational",
"Critical",
"Empathetic",
"Philosophical", "Philosophical",
"Speculative", "Speculative",
"Motivational", "Motivational",
@ -156,25 +165,15 @@ conversation_styles = [
"Serious", "Serious",
"Investigative", "Investigative",
"Debunking", "Debunking",
"Collaborative",
"Didactic", "Didactic",
"Thought-provoking", "Thought-provoking",
"Controversial", "Controversial",
"Skeptical",
"Optimistic",
"Pessimistic",
"Objective",
"Subjective",
"Sarcastic", "Sarcastic",
"Emotional", "Emotional",
"Exploratory", "Exploratory",
"Friendly",
"Fast-paced", "Fast-paced",
"Slow-paced", "Slow-paced",
"Introspective", "Introspective",
"Open-ended",
"Affirmative",
"Dissenting",
] ]
# Dialogue Structures # Dialogue Structures
@ -191,15 +190,10 @@ dialogue_structures = [
"Pro Arguments", "Pro Arguments",
"Con Arguments", "Con Arguments",
"Cross-examination", "Cross-examination",
"Rebuttal",
"Expert Interviews", "Expert Interviews",
"Panel Discussion",
"Case Studies", "Case Studies",
"Myth Busting", "Myth Busting",
"Debunking Misconceptions",
"Audience Questions",
"Q&A Session", "Q&A Session",
"Listener Feedback",
"Rapid-fire Questions", "Rapid-fire Questions",
"Summary of Key Points", "Summary of Key Points",
"Recap", "Recap",
@ -207,29 +201,11 @@ dialogue_structures = [
"Actionable Tips", "Actionable Tips",
"Call to Action", "Call to Action",
"Future Outlook", "Future Outlook",
"Teaser for Next Episode",
"Closing Remarks", "Closing Remarks",
"Thank You and Credits",
"Outtakes or Bloopers",
"Sponsor Messages",
"Social Media Shout-outs",
"Resource Recommendations", "Resource Recommendations",
"Feedback Request",
"Lightning Round",
"Behind-the-Scenes Insights",
"Ethical Considerations",
"Fact-checking Segment",
"Trending Topics", "Trending Topics",
"Closing Inspirational Quote", "Closing Inspirational Quote",
"Final Reflections", "Final Reflections",
"Debrief",
"Farewell Messages",
"Next Episode Preview",
"Live Reactions",
"Call-in Segment",
"Acknowledgements",
"Transition Segments",
"Break Segments",
] ]
# Podcast Participant Roles # Podcast Participant Roles
@ -265,15 +241,7 @@ participant_roles = [
"Researcher", "Researcher",
"Reporter", "Reporter",
"Advocate", "Advocate",
"Influencer",
"Observer",
"Listener",
"Facilitator",
"Innovator",
"Debater", "Debater",
"Educator",
"Motivator",
"Narrator",
"Explorer", "Explorer",
"Opponent", "Opponent",
"Proponent", "Proponent",
@ -289,49 +257,17 @@ participant_roles = [
"Author", "Author",
"Journalist", "Journalist",
"Activist", "Activist",
"Challenger",
"Supporter",
"Mentor",
"Mentee",
"Panelist", "Panelist",
"Audience Representative",
"Case Study Presenter",
"Data Analyst", "Data Analyst",
"Ethicist",
"Cultural Critic",
"Technologist",
"Environmentalist",
"Legal Expert",
"Healthcare Professional",
"Financial Advisor",
"Policy Maker",
"Sociologist",
"Anthropologist",
"Myth Buster", "Myth Buster",
"Trend Analyst", "Trend Analyst",
"Futurist", "Futurist",
"Negotiator",
"Community Leader",
"Voice of Reason", "Voice of Reason",
"Conflict Resolver",
"Emotional Support",
"Pragmatist", "Pragmatist",
"Idealist", "Idealist",
"Realist", "Realist",
"Satirist", "Satirist",
"Story Analyst",
"Language Expert",
"Historical Witness",
"Survivor",
"Inspirational Figure",
"Cultural Ambassador",
"Digital Nomad",
"Remote Correspondent",
"Field Reporter", "Field Reporter",
"Data Scientist",
"Gamer",
"Musician",
"Filmmaker",
] ]
# Engagement Techniques # Engagement Techniques

View file

@ -82,19 +82,26 @@ with templates_tab:
"User Instructions", "User Instructions",
help="Any additional intructions to pass to the LLM that will generate the transcript", help="Any additional intructions to pass to the LLM that will generate the transcript",
) )
pd_cfg["person1_role"] = st.text_input("Person 1 role") pd_cfg["person1_role"] = st_tags(
[], participant_roles, "Person 1 roles", key="person1_roles"
)
st.caption(f"Suggestions:{', '.join(participant_roles)}") st.caption(f"Suggestions:{', '.join(participant_roles)}")
pd_cfg["person2_role"] = st.text_input("Person 2 role") pd_cfg["person2_role"] = st_tags(
[], participant_roles, "Person 2 roles", key="person2_roles"
)
pd_cfg["conversation_style"] = st_tags( pd_cfg["conversation_style"] = st_tags(
[], conversation_styles, "Conversation Style" [], conversation_styles, "Conversation Style", key="conversation_styles"
) )
st.caption(f"Suggestions:{', '.join(conversation_styles)}") st.caption(f"Suggestions:{', '.join(conversation_styles)}")
pd_cfg["engagement_technique"] = st_tags( pd_cfg["engagement_technique"] = st_tags(
[], engagement_techniques, "Engagement Techniques" [],
engagement_techniques,
"Engagement Techniques",
key="engagement_techniques",
) )
st.caption(f"Suggestions:{', '.join(engagement_techniques)}") st.caption(f"Suggestions:{', '.join(engagement_techniques)}")
pd_cfg["dialogue_structure"] = st_tags( pd_cfg["dialogue_structure"] = st_tags(
[], dialogue_structures, "Dialogue Structure" [], dialogue_structures, "Dialogue Structure", key="dialogue_structures"
) )
st.caption(f"Suggestions:{', '.join(dialogue_structures)}") st.caption(f"Suggestions:{', '.join(dialogue_structures)}")
pd_cfg["wordcount"] = st.slider( pd_cfg["wordcount"] = st.slider(
@ -126,6 +133,8 @@ with templates_tab:
pd_cfg["voice1"] = st.text_input( pd_cfg["voice1"] = st.text_input(
"Voice 1", help="You can use Elevenlabs voice ID" "Voice 1", help="You can use Elevenlabs voice ID"
) )
st.caption("Voice names are case sensitive. Be sure to add the exact name.")
st.markdown( st.markdown(
"[Open AI voices](https://platform.openai.com/docs/guides/text-to-speech)" "[Open AI voices](https://platform.openai.com/docs/guides/text-to-speech)"
) )
@ -142,10 +151,8 @@ with templates_tab:
pd = PodcastConfig(**pd_cfg) pd = PodcastConfig(**pd_cfg)
pd_cfg = {} pd_cfg = {}
pd.save() pd.save()
st.rerun()
except Exception as e: except Exception as e:
st.error(e) st.error(e)
st.exception(e)
for pd_config in PodcastConfig.get_all(order_by="created desc"): for pd_config in PodcastConfig.get_all(order_by="created desc"):
with st.expander(pd_config.name): with st.expander(pd_config.name):
@ -174,17 +181,20 @@ with templates_tab:
value=pd_config.output_language, value=pd_config.output_language,
key=f"output_language_{pd_config.id}", key=f"output_language_{pd_config.id}",
) )
pd_config.person1_role = st.text_input( pd_config.person1_role = st_tags(
"Person 1 role", pd_config.person1_role,
value=pd_config.person1_role, conversation_styles,
key=f"person1_role_{pd_config.id}", "Person 1 Roles",
key=f"person_1_roles_{pd_config.id}",
) )
st.caption(f"Suggestions:{', '.join(participant_roles)}") st.caption(f"Suggestions:{', '.join(participant_roles)}")
pd_config.person2_role = st.text_input( pd_config.person2_role = st_tags(
"Person 2 role", pd_config.person2_role,
value=pd_config.person2_role, conversation_styles,
key=f"person2_role_{pd_config.id}", "Person 2 Roles",
key=f"person_2_roles_{pd_config.id}",
) )
pd_config.conversation_style = st_tags( pd_config.conversation_style = st_tags(
pd_config.conversation_style, pd_config.conversation_style,
conversation_styles, conversation_styles,
@ -293,6 +303,7 @@ with templates_tab:
key=f"voice1_{pd_config.id}", key=f"voice1_{pd_config.id}",
help="You can use Elevenlabs voice ID", help="You can use Elevenlabs voice ID",
) )
st.caption("Voice names are case sensitive. Be sure to add the exact name.")
st.markdown( st.markdown(
"[Open AI voices](https://platform.openai.com/docs/guides/text-to-speech)" "[Open AI voices](https://platform.openai.com/docs/guides/text-to-speech)"
) )