Spaces:
Runtime error
Runtime error
| from __future__ import annotations | |
| import asyncio | |
| import tempfile | |
| from pathlib import Path | |
| from typing import Optional | |
| import gradio as gr | |
| from conversation_storyline.io import load_messages, load_messages_from_text | |
| from conversation_storyline.pipeline import run_pipeline | |
| from conversation_storyline.plots import ( | |
| load_graph_json, | |
| load_interactions_df, | |
| plot_reply_sankey, | |
| plot_sentiment_histogram, | |
| plot_sentiment_over_time, | |
| plot_speaker_activity_heatmap, | |
| plot_speaker_topic_heatmap, | |
| plot_topic_shift_timeline, | |
| ) | |
| def get_backend(name: str): | |
| if name == "openai": | |
| from conversation_storyline.llm_backends.openai_backend import OpenAIBackend | |
| return OpenAIBackend() | |
| elif name == "outlines": | |
| from conversation_storyline.llm_backends.outlines_backend import OutlinesBackend | |
| return OutlinesBackend() | |
| else: | |
| raise ValueError("backend inválido") | |
| async def _run(file_path: Optional[str], transcript_text: str, backend: str): | |
| transcript_text = (transcript_text or "").strip() | |
| if transcript_text: | |
| msgs = load_messages_from_text(transcript_text) | |
| else: | |
| if not file_path: | |
| raise ValueError("Debes pegar un transcript o subir un archivo.") | |
| msgs = load_messages(file_path) | |
| b = get_backend(backend) | |
| outdir = Path(tempfile.mkdtemp(prefix="storyline_")) | |
| await run_pipeline(msgs, b, str(outdir)) | |
| png = outdir / "storyline.png" | |
| html = outdir / "storyline.html" | |
| graph = outdir / "graph.json" | |
| interactions = outdir / "interactions.jsonl" | |
| metrics = outdir / "metrics.parquet" | |
| html_inline = html.read_text(encoding="utf-8", errors="ignore") if html.exists() else None | |
| figs = [None] * 5 | |
| try: | |
| df = load_interactions_df(outdir) | |
| g = load_graph_json(outdir) | |
| figs = [ | |
| plot_sentiment_over_time(df), | |
| plot_sentiment_histogram(df), | |
| plot_speaker_topic_heatmap(df), | |
| plot_speaker_activity_heatmap(df), | |
| plot_reply_sankey(g), | |
| ] | |
| topic_shift_fig = plot_topic_shift_timeline(df) | |
| except Exception: | |
| topic_shift_fig = None | |
| return ( | |
| str(png) if png.exists() else None, | |
| html_inline, | |
| str(html) if html.exists() else None, | |
| str(graph) if graph.exists() else None, | |
| str(interactions) if interactions.exists() else None, | |
| str(metrics) if metrics.exists() else None, | |
| figs[0], | |
| figs[1], | |
| figs[2], | |
| figs[3], | |
| figs[4], | |
| topic_shift_fig, | |
| ) | |
| def run_ui(file_obj, transcript_text: str, backend: str): | |
| file_path = file_obj.name if file_obj is not None else None | |
| return asyncio.run(_run(file_path, transcript_text, backend)) | |
| with gr.Blocks(title="Conversation Storyline – v4") as demo: | |
| gr.Markdown("# Conversation Storyline – v4\nPega un transcript o sube TXT/CSV.") | |
| with gr.Row(): | |
| f = gr.File(label="Upload (.txt o .csv)") | |
| backend = gr.Dropdown(choices=["openai", "outlines"], value="openai", label="Backend LLM") | |
| transcript_text = gr.Textbox(label="O pega aquí el transcript", lines=10) | |
| btn = gr.Button("Run", variant="primary") | |
| with gr.Tabs(): | |
| with gr.Tab("Storyline"): | |
| with gr.Row(): | |
| out_png = gr.Image(label="Storyline (PNG)", type="filepath") | |
| out_story_html = gr.HTML(label="Storyline (HTML embebido)") | |
| out_html_file = gr.File(label="Storyline HTML (descarga)") | |
| with gr.Tab("Analítica"): | |
| out_sentiment = gr.Plot(label="Sentiment timeline") | |
| out_hist = gr.Plot(label="Sentiment histogram") | |
| out_topic_heat = gr.Plot(label="Speaker × topic heatmap") | |
| out_activity_heat = gr.Plot(label="Speaker activity heatmap") | |
| out_topic_shifts = gr.Plot(label="Topic shifts timeline") | |
| with gr.Tab("Grafo"): | |
| out_sankey = gr.Plot(label="Sankey replies") | |
| out_graph = gr.File(label="Graph JSON") | |
| with gr.Tab("Artifacts"): | |
| out_interactions = gr.File(label="interactions.jsonl") | |
| out_metrics = gr.File(label="metrics.parquet") | |
| btn.click( | |
| fn=run_ui, | |
| inputs=[f, transcript_text, backend], | |
| outputs=[ | |
| out_png, | |
| out_story_html, | |
| out_html_file, | |
| out_graph, | |
| out_interactions, | |
| out_metrics, | |
| out_sentiment, | |
| out_hist, | |
| out_topic_heat, | |
| out_activity_heat, | |
| out_sankey, | |
| out_topic_shifts, | |
| ], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |