KheemDH's picture
Update app.py
ffe08d3 verified
from __future__ import annotations
import json
import os
import sys
import textwrap
from typing import List
import gradio as gr
# Ensure the local src/ directory is on sys.path (for Hugging Face Spaces)
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
SRC_DIR = os.path.join(ROOT_DIR, "src")
if SRC_DIR not in sys.path:
sys.path.append(SRC_DIR)
from agentic_multiwriter.state import AgentState, ResearchSnippet
from agentic_multiwriter.agents import (
researcher_node,
aggregator_node,
writer_node,
critic_node,
formatter_node,
)
from agentic_multiwriter.tools import get_logger
logger = get_logger()
def _format_sources(snippets: List[ResearchSnippet]) -> str:
if not snippets:
return "No web sources were retrieved."
lines = []
for s in snippets:
title = s["title"] or s["url"]
url = s["url"]
snippet = s["snippet"]
if url:
lines.append(f"- [{title}]({url})\n \n > {snippet}")
else:
lines.append(f"- {title}\n \n > {snippet}")
return "\n\n".join(lines)
def generate(topic: str, mode: str, progress=gr.Progress()):
"""Gradio callback to run the pipeline step-by-step with progress."""
topic = topic.strip()
if not topic:
return (
"Please enter a topic.",
"",
"",
"",
"",
)
# Initial state
state: AgentState = {
"topic": topic,
"mode": mode,
"research_snippets": [],
"outline": [],
"draft": "",
"revised_draft": "",
"final_output": "",
"meta": {},
}
# 1. Research
progress(0.1, "Researching the web...")
logger.info("UI: starting researcher_node")
state = researcher_node(state)
# 2. Aggregate
progress(0.25, "Aggregating and cleaning snippets...")
logger.info("UI: starting aggregator_node")
state = aggregator_node(state)
# 3. Write draft
progress(0.5, "Writing first draft...")
logger.info("UI: starting writer_node")
state = writer_node(state)
initial_draft = state.get("draft", "") or ""
# 4. Critic / edit
progress(0.7, "Reviewing and improving draft...")
logger.info("UI: starting critic_node")
state = critic_node(state)
revised_draft = state.get("revised_draft", "") or initial_draft
# 5. Format final output
progress(0.9, f"Formatting final output as {mode}...")
logger.info("UI: starting formatter_node")
state = formatter_node(state)
final_output = state.get("final_output", "") or revised_draft
# 6. Prepare outline, meta, sources
outline = state.get("outline", []) or []
meta = state.get("meta", {}) or {}
snippets = state.get("research_snippets", []) or []
outline_text = "\n".join(f"- {item}" for item in outline)
meta_text = json.dumps(meta, indent=2)
sources_md = _format_sources(snippets)
progress(1.0, "Done.")
return final_output, initial_draft, revised_draft, sources_md, meta_text
def build_interface() -> gr.Blocks:
with gr.Blocks(title="Agentic Multiwriter") as demo:
gr.Markdown(
"""
# 🧠 Agentic Multiwriter
Multi-agent research & writing system built with **LangGraph**.
1. Researches your topic on the web
2. Aggregates and cleans snippets
3. Writes a draft
4. Critiques and improves it
5. Formats it as a blog, research summary, or LinkedIn-style post
"""
)
with gr.Row():
topic_input = gr.Textbox(
label="Topic",
placeholder="e.g. Future of agentic AI",
lines=2,
)
mode_input = gr.Radio(
choices=["blog", "research_summary", "linkedin_post"],
value="blog",
label="Output mode",
)
run_button = gr.Button("Generate", variant="primary")
with gr.Tab("Final Output"):
final_output_box = gr.Markdown(label="Final Output")
with gr.Tab("Initial Draft (Writer)"):
initial_draft_box = gr.Markdown(label="Initial Draft")
with gr.Tab("Revised Draft (Critic)"):
revised_draft_box = gr.Markdown(label="Revised Draft")
with gr.Tab("Sources"):
sources_box = gr.Markdown(label="Web Sources Used")
with gr.Tab("Meta"):
meta_box = gr.Textbox(label="Meta (timings, counts, etc.)", lines=10)
run_button.click(
fn=generate,
inputs=[topic_input, mode_input],
outputs=[
final_output_box,
initial_draft_box,
revised_draft_box,
sources_box,
meta_box,
],
)
gr.Markdown(
textwrap.dedent(
"""
---
⚠️ **Note**: First run may take longer while the model loads or if you are
using a local model. On Spaces, this app uses an open-source model via
Hugging Face Inference API.
"""
)
)
return demo
if __name__ == "__main__":
demo = build_interface()
demo.launch(server_name="0.0.0.0", server_port=7860)