Spaces:
Sleeping
Sleeping
File size: 5,319 Bytes
32f259e ffe08d3 32f259e ffe08d3 32f259e ffe08d3 32f259e ffe08d3 32f259e |
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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
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)
|