File size: 4,088 Bytes
8c9f790
cdb0d14
c19f44b
79b85f2
c19f44b
 
79b85f2
c19f44b
 
8c9f790
c19f44b
8c9f790
c19f44b
 
 
 
 
 
8c9f790
c19f44b
8c9f790
79b85f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c19f44b
79b85f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c19f44b
 
 
79b85f2
 
 
 
 
c19f44b
79b85f2
c19f44b
 
 
 
 
79b85f2
c19f44b
79b85f2
 
c19f44b
79b85f2
c19f44b
 
79b85f2
 
c19f44b
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import gradio as gr
from transformers import pipeline
import requests
import os
import html
import base64
import random
import json
from datetime import datetime

chat_gen = pipeline("text-generation", model="mistralai/Mistral-7B-Instruct-v0.2")

voice_options = {
    "Rachel": "EXAVITQu4vr4xnSDxMaL",
    "Adam": "21m00Tcm4TlvDq8ikWAM",
    "Elli": "AZnzlk1XvdvUeBnXmlld",
    "Josh": "VR6AewLTigWG4xSOukaG"
}

library_file = "/tmp/library.json"

def generate_chat_bundle(prompt, character_inputs):
    characters = [c.split(":")[0].strip() for c in character_inputs if ":" in c]
    voices = {c.split(":")[0].strip(): c.split(":")[1].strip() for c in character_inputs if ":" in c}

    system_prompt = (
        f"Group chat between {', '.join(characters)}. Prompt: {prompt}. "
        "Use casual texting style: Name: message"
    )
    response = chat_gen(system_prompt, max_new_tokens=400)[0]["generated_text"]
    chat_lines = [(line.split(':', 1)[0].strip(), line.split(':', 1)[1].strip()) for line in response.splitlines() if ':' in line]

    html_chat = ""
    file_paths = []

    for i, (name, msg) in enumerate(chat_lines):
        color = random.choice(["#DCF8C6", "#FEE2E2", "#EDEDED", "#C7E2FF"])
        html_chat += f"""<div style='margin: 10px; text-align: {'left' if i % 2 == 0 else 'right'}'>
        <div style='display:inline-block; padding: 10px 15px; background: {color}; border-radius: 15px; max-width: 70%;'>
        <strong>{html.escape(name)}:</strong> {html.escape(msg)}
        </div></div>"""

        voice_id = voices.get(name, list(voice_options.values())[0])
        eleven_response = requests.post(
            f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
            headers={
                "xi-api-key": os.environ.get("ELEVEN_API_KEY", "demo-key"),
                "Content-Type": "application/json"
            },
            json={"text": msg, "model_id": "eleven_monolingual_v1"}
        )

        if eleven_response.status_code == 200:
            file_path = f"/tmp/audio_{i}_{name}.mp3"
            with open(file_path, 'wb') as f:
                f.write(eleven_response.content)
            file_paths.append(file_path)

    # Save HTML for download
    timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')
    html_path = f"/tmp/fakechat_{timestamp}.html"
    with open(html_path, "w") as f:
        f.write(f"<html><body>{html_chat}</body></html>")
    file_paths.append(html_path)

    # Save metadata
    if os.path.exists(library_file):
        with open(library_file, "r") as f:
            lib = json.load(f)
    else:
        lib = []

    lib.insert(0, {
        "timestamp": timestamp,
        "characters": characters,
        "prompt": prompt,
        "html": html_path,
        "audio_files": file_paths[:-1]
    })

    with open(library_file, "w") as f:
        json.dump(lib, f, indent=2)

    return file_paths

def get_library():
    if not os.path.exists(library_file):
        return "No stories saved yet."
    with open(library_file, "r") as f:
        lib = json.load(f)
    html_links = [f"<li><b>{item['timestamp']}</b>: {', '.join(item['characters'])} β€” <a href='file={item['html']}' target='_blank'>Chat</a></li>" for item in lib]
    return "<ul>" + "".join(html_links) + "</ul>"

def build_character_inputs():
    return [gr.Textbox(label=f"Character {i+1} (Format: Name:Voice)", placeholder="e.g. Anna:Rachel") for i in range(4)]

with gr.Blocks() as app:
    with gr.Row():
        with gr.Column(scale=3):
            characters = build_character_inputs()
            prompt = gr.Textbox(label="Scene Prompt")
            generate_btn = gr.Button("🎀 Generate Chat + Audio")
            file_output = gr.File(file_types=[".html", ".mp3"], label="Download Files")
        with gr.Column(scale=1):
            lib_html = gr.HTML(label="πŸ“ My Saved Stories")
            refresh_btn = gr.Button("πŸ” Refresh Library")

    generate_btn.click(fn=generate_chat_bundle, inputs=[prompt, characters], outputs=file_output)
    refresh_btn.click(fn=get_library, outputs=lib_html)

app.launch()