fix podcast generation

This commit is contained in:
thierryverse 2025-11-11 04:02:04 +02:00
parent 678d8fbbcd
commit 55e5b45a42
26 changed files with 477 additions and 223 deletions

View file

@ -1,5 +1,12 @@
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/surfsense
SECRET_KEY=SECRET
NEXT_FRONTEND_URL=http://localhost:3000
#Celery Config
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/0
#Celery Config
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/0

View file

@ -1,50 +0,0 @@
"""Add podcast staleness detection columns to chats and podcasts tables
This feature allows the system to detect when a podcast is outdated compared to the current state of the chat it was generated from, enabling users to regenerate podcasts when needed.
Revision ID: 32
Revises: 31
"""
from collections.abc import Sequence
import sqlalchemy as sa
from alembic import op
# revision identifiers
revision: str = "32"
down_revision: str | None = "31"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
"""Add state_version, chat_state_version, and chat_id to chats and podcasts tables."""
# Add state_version column to chats table with default value of 1
op.add_column(
"chats",
sa.Column("state_version", sa.BigInteger(), nullable=False, server_default="1"),
)
# Add chat_state_version column to podcasts table (nullable, set when podcast is generated)
op.add_column(
"podcasts", sa.Column("chat_state_version", sa.BigInteger(), nullable=True)
)
# Add chat_id column to podcasts table (nullable, set when podcast is generated from a chat)
op.add_column("podcasts", sa.Column("chat_id", sa.Integer(), nullable=True))
def downgrade() -> None:
"""Remove state_version, chat_state_version, and chat_id columns."""
# Remove chat_state_version from podcasts table
op.drop_column("podcasts", "chat_state_version")
# Remove chat_id from podcasts table
op.drop_column("podcasts", "chat_id")
# Remove state_version from chats table
op.drop_column("chats", "state_version")

View file

@ -0,0 +1,60 @@
"""Add podcast staleness detection columns to chats and podcasts tables
This feature allows the system to detect when a podcast is outdated compared to
the current state of the chat it was generated from, enabling users to regenerate
podcasts when needed.
Revision ID: 34
Revises: 33
"""
from collections.abc import Sequence
from alembic import op
# revision identifiers
revision: str = "34"
down_revision: str | None = "33"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
"""Add columns only if they don't already exist (safe for re-runs)."""
# Add 'state_version' column to chats table (default 1)
op.execute("""
ALTER TABLE chats
ADD COLUMN IF NOT EXISTS state_version BIGINT DEFAULT 1 NOT NULL
""")
# Add 'chat_state_version' column to podcasts table
op.execute("""
ALTER TABLE podcasts
ADD COLUMN IF NOT EXISTS chat_state_version BIGINT
""")
# Add 'chat_id' column to podcasts table
op.execute("""
ALTER TABLE podcasts
ADD COLUMN IF NOT EXISTS chat_id INTEGER
""")
def downgrade() -> None:
"""Remove columns only if they exist."""
op.execute("""
ALTER TABLE podcasts
DROP COLUMN IF EXISTS chat_state_version
""")
op.execute("""
ALTER TABLE podcasts
DROP COLUMN IF EXISTS chat_id
""")
op.execute("""
ALTER TABLE chats
DROP COLUMN IF EXISTS state_version
""")

View file

@ -29,6 +29,7 @@ async def create_podcast_transcript(
configuration = Configuration.from_runnable_config(config)
user_id = configuration.user_id
search_space_id = configuration.search_space_id
podcast_title = configuration.podcast_title
# Get user's long context LLM
llm = await get_user_long_context_llm(state.db_session, user_id, search_space_id)
@ -37,8 +38,8 @@ async def create_podcast_transcript(
print(error_message)
raise RuntimeError(error_message)
# Get the prompt
prompt = get_podcast_generation_prompt()
# Get the prompt with podcast_title as user_prompt
prompt = get_podcast_generation_prompt(user_prompt=podcast_title)
# Create the messages
messages = [

View file

@ -1,11 +1,19 @@
import datetime
def get_podcast_generation_prompt():
def get_podcast_generation_prompt(user_prompt: str | None = None):
user_prompt_section = ""
if user_prompt:
user_prompt_section = f"""
<user_instructions>
{user_prompt}
</user_instructions>
"""
return f"""
Today's date: {datetime.datetime.now().strftime("%Y-%m-%d")}
<podcast_generation_system>
You are a master podcast scriptwriter, adept at transforming diverse input content into a lively, engaging, and natural-sounding conversation between two distinct podcast hosts. Your primary objective is to craft authentic, flowing dialogue that captures the spontaneity and chemistry of a real podcast discussion, completely avoiding any hint of robotic scripting or stiff formality. Think dynamic interplay, not just information delivery.
You are a master podcast scriptwriter, adept at transforming diverse input content into a lively, engaging, and natural-sounding conversation between two distinct podcast hosts. Your primary objective is to craft authentic, flowing dialogue that captures the spontaneity and chemistry of a real podcast discussion, completely avoiding any hint of robotic scripting or stiff formality. Think dynamic interplay, not just information delivery.{user_prompt_section}
<input>
- '<source_content>': A block of text containing the information to be discussed in the podcast. This could be research findings, an article summary, a detailed outline, user chat history related to the topic, or any other relevant raw information. The content might be unstructured but serves as the factual basis for the podcast dialogue.

View file

@ -46,7 +46,7 @@ def generate_chat_podcast_task(
Args:
chat_id: ID of the chat to generate podcast from
search_space_id: ID of the search space
podcast_title: Title for the podcast
podcast_title: Title for the podcast (used as user prompt for generation)
user_id: ID of the user
"""
loop = asyncio.new_event_loop()

View file

@ -96,7 +96,7 @@ async def generate_chat_podcast(
config = {
"configurable": {
"podcast_title": "SurfSense",
"podcast_title": podcast_title,
"user_id": str(user_id),
"search_space_id": search_space_id,
}