|
|
import gradio as gr |
|
|
import os |
|
|
import requests |
|
|
from gtts import gTTS |
|
|
import tempfile |
|
|
import uuid |
|
|
import datetime |
|
|
from fpdf import FPDF |
|
|
import whisper |
|
|
|
|
|
|
|
|
model = whisper.load_model("base") |
|
|
|
|
|
|
|
|
def ai_chat(text): |
|
|
url = "https://openrouter.ai/api/v1/chat/completions" |
|
|
headers = { |
|
|
"Authorization": f"Bearer {os.getenv('OPENROUTER_API_KEY')}", |
|
|
"Content-Type": "application/json" |
|
|
} |
|
|
payload = { |
|
|
"model": "mistralai/mistral-7b-instruct", |
|
|
"messages": [{"role": "user", "content": text}] |
|
|
} |
|
|
res = requests.post(url, headers=headers, json=payload) |
|
|
if res.ok: |
|
|
return res.json()["choices"][0]["message"]["content"] |
|
|
return "[OpenRouter error]" |
|
|
|
|
|
|
|
|
def generate_pdf(chat_history, session_id): |
|
|
pdf = FPDF() |
|
|
pdf.add_page() |
|
|
pdf.set_font("Arial", size=12) |
|
|
for turn in chat_history: |
|
|
pdf.multi_cell(0, 10, f"You: {turn['user']}\nAI: {turn['ai']}\n") |
|
|
path = f"{session_id}_chat.pdf" |
|
|
pdf.output(path) |
|
|
return path |
|
|
|
|
|
|
|
|
def voice_chat(audio_file, chat_history, session_id): |
|
|
if not audio_file: |
|
|
return None, chat_history, session_id, None |
|
|
|
|
|
if not session_id: |
|
|
session_id = str(uuid.uuid4()) |
|
|
|
|
|
result = model.transcribe(audio_file) |
|
|
user_text = result["text"] |
|
|
ai_reply = ai_chat(user_text) |
|
|
|
|
|
|
|
|
tts = gTTS(ai_reply, lang='en') |
|
|
tts_path = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) |
|
|
tts.save(tts_path.name) |
|
|
|
|
|
|
|
|
chat_history.append({"user": user_text, "ai": ai_reply}) |
|
|
|
|
|
|
|
|
display = "" |
|
|
for turn in chat_history: |
|
|
display += f"π§βπ¬ **You**: {turn['user']}\n\nπ€ **AI**: {turn['ai']}\n\n" |
|
|
|
|
|
return tts_path.name, chat_history, session_id, display |
|
|
|
|
|
|
|
|
def download_pdf(chat_history, session_id): |
|
|
if not chat_history or not session_id: |
|
|
return None |
|
|
return generate_pdf(chat_history, session_id) |
|
|
|
|
|
|
|
|
with gr.Blocks(theme=gr.themes.Soft()) as demo: |
|
|
gr.Markdown("## π€ Chat with AI (Voice + Text, Powered by OpenRouter)") |
|
|
|
|
|
session_id = gr.State() |
|
|
chat_history = gr.State([]) |
|
|
|
|
|
chatbox = gr.Markdown("") |
|
|
|
|
|
with gr.Row(): |
|
|
mic = gr.Audio(label="", type="filepath", show_label=False, interactive=True) |
|
|
send_btn = gr.Button("ποΈ Speak", variant="primary") |
|
|
|
|
|
with gr.Row(): |
|
|
audio_out = gr.Audio(label="π AI Voice Reply", interactive=False) |
|
|
|
|
|
with gr.Row(): |
|
|
download_btn = gr.Button("π₯ Download Chat as PDF") |
|
|
download_link = gr.File() |
|
|
|
|
|
send_btn.click(voice_chat, inputs=[mic, chat_history, session_id], |
|
|
outputs=[audio_out, chat_history, session_id, chatbox]) |
|
|
|
|
|
download_btn.click(download_pdf, inputs=[chat_history, session_id], outputs=[download_link]) |
|
|
|
|
|
demo.launch() |
|
|
|