Download app.py from dlaima/Writeflow: direct link, hf CLI and curl.
- Browser
- Download file 6.49 kB
-
https://huggingface.co/spaces/dlaima/Writeflow/resolve/bf01035e9aa755f960b8c899f28924c55efe9f65/app.py
- Command line
-
hf download hf://spaces/dlaima/Writeflow@bf01035e9aa755f960b8c899f28924c55efe9f65/app.py
-
curl -L -o app.py https://huggingface.co/spaces/dlaima/Writeflow/resolve/bf01035e9aa755f960b8c899f28924c55efe9f65/app.py
6.49 kB
| import warnings | |
| warnings.filterwarnings("ignore", message=".*TqdmWarning.*") | |
| from dotenv import load_dotenv | |
| _ = load_dotenv() | |
| from langgraph.graph import StateGraph, END | |
| from typing import TypedDict, Annotated, List | |
| import operator | |
| from langchain_core.messages import SystemMessage, HumanMessage | |
| from langchain_openai import ChatOpenAI | |
| from pydantic import BaseModel | |
| from tavily import TavilyClient | |
| import os | |
| import gradio as gr | |
| # Define agent state class | |
| class AgentState(TypedDict): | |
| task: str | |
| lnode: str | |
| plan: str | |
| research_queries: List[str] | |
| draft: str | |
| critique: str | |
| content: List[str] | |
| revision_number: int | |
| max_revisions: int | |
| count: Annotated[int, operator.add] | |
| # Define queries class | |
| class Queries(BaseModel): | |
| queries: List[str] | |
| # Writer Agent Class | |
| class Ewriter(): | |
| def __init__(self): | |
| self.model = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) | |
| self.PLAN_PROMPT = "You are an expert writer tasked with writing a high-level outline of a short 3-paragraph essay." | |
| self.RESEARCH_PROMPT = "Generate three research queries to help in writing an essay on the given topic." | |
| self.WRITER_PROMPT = "You are an essay assistant tasked with writing an excellent 3-paragraph essay." | |
| self.REFLECTION_PROMPT = "You are a teacher grading an essay. Provide critique and suggestions." | |
| self.tavily = TavilyClient(api_key=os.environ["TAVILY_API_KEY"]) | |
| # Initialize Graph | |
| builder = StateGraph(AgentState) | |
| builder.add_node("planner", self.plan_node) | |
| builder.add_node("research", self.research_node) | |
| builder.add_node("generate", self.generation_node) | |
| builder.add_node("reflect", self.reflection_node) | |
| builder.set_entry_point("planner") | |
| builder.add_edge("planner", "research") | |
| builder.add_edge("research", "generate") | |
| builder.add_edge("generate", "reflect") | |
| builder.add_edge("reflect", END) # Ensure reflect is not a dead-end | |
| self.graph = builder.compile() | |
| def plan_node(self, state: AgentState): | |
| try: | |
| response = self.model.invoke([SystemMessage(content=self.PLAN_PROMPT), HumanMessage(content=state['task'])]) | |
| return {"plan": response.content, "lnode": "planner", "count": 1} | |
| except Exception as e: | |
| return {"plan": f"Error occurred in planning: {str(e)}", "lnode": "planner", "count": 0} | |
| def research_node(self, state: AgentState): | |
| try: | |
| response = self.model.invoke([SystemMessage(content=self.RESEARCH_PROMPT), HumanMessage(content=state['task'])]) | |
| return {"research_queries": response.content.split('\n'), "lnode": "research", "count": 1} | |
| except Exception as e: | |
| return {"research_queries": f"Error occurred in research: {str(e)}", "lnode": "research", "count": 0} | |
| def generation_node(self, state: AgentState): | |
| try: | |
| response = self.model.invoke([SystemMessage(content=self.WRITER_PROMPT), HumanMessage(content=state['task'])]) | |
| return {"draft": response.content, "lnode": "generate", "count": 1} | |
| except Exception as e: | |
| return {"draft": f"Error occurred in generation: {str(e)}", "lnode": "generate", "count": 0} | |
| def reflection_node(self, state: AgentState): | |
| try: | |
| response = self.model.invoke([SystemMessage(content=self.REFLECTION_PROMPT), HumanMessage(content=state['draft'])]) | |
| return {"critique": response.content, "lnode": "reflect", "count": 1} | |
| except Exception as e: | |
| return {"critique": f"Error occurred in reflection: {str(e)}", "lnode": "reflect", "count": 0} | |
| # Gradio UI | |
| class WriterGui(): | |
| def __init__(self, graph): | |
| self.graph = graph | |
| self.demo = self.create_interface() | |
| def run_agent(self, topic, revision_number, max_revisions): | |
| config = {'task': topic, 'max_revisions': max_revisions, 'revision_number': revision_number, 'lnode': "", 'count': 0} | |
| response = self.graph.invoke(config) | |
| return response["draft"], response["lnode"], response["count"], response.get("critique", ""), response.get("research_queries", []) | |
| def continue_agent(self, topic, revision_number, max_revisions, last_node, current_draft): | |
| config = {'task': topic, 'max_revisions': max_revisions, 'revision_number': revision_number, 'lnode': last_node, 'draft': current_draft, 'count': 0} | |
| response = self.graph.invoke(config) | |
| return response["draft"], response["lnode"], response["count"], response.get("critique", ""), response.get("research_queries", []) | |
| def create_interface(self): | |
| with gr.Blocks() as demo: | |
| with gr.Tabs(): | |
| with gr.Tab("Agent"): | |
| topic_input = gr.Textbox(label="Essay Topic") | |
| last_node = gr.Textbox(label="Last Node", interactive=False) | |
| next_node = gr.Textbox(label="Next Node", interactive=False) | |
| thread = gr.Textbox(label="Thread", interactive=False) | |
| draft_rev = gr.Textbox(label="Draft Revision", interactive=False) | |
| count = gr.Textbox(label="Count", interactive=False) | |
| generate_button = gr.Button("Generate Essay", variant="primary") | |
| continue_button = gr.Button("Continue Essay") | |
| with gr.Row(): | |
| gr.Markdown("**Manage Agent**") | |
| with gr.Row(): | |
| output_text = gr.Textbox(label="Live Agent Output", interactive=False) | |
| with gr.Row(): | |
| critique_text = gr.Textbox(label="Critique", interactive=False) | |
| with gr.Row(): | |
| research_text = gr.Textbox(label="Research Queries", interactive=False) | |
| generate_button.click(fn=self.run_agent, inputs=[topic_input, gr.State(0), gr.State(2)], outputs=[output_text, last_node, next_node, critique_text, research_text]) | |
| continue_button.click(fn=self.continue_agent, inputs=[topic_input, gr.State(0), gr.State(2), last_node, draft_rev], outputs=[output_text, last_node, next_node, critique_text, research_text]) | |
| return demo | |
| def launch(self): | |
| self.demo.launch(share=True) | |
| # Run the App | |
| MultiAgent = Ewriter() | |
| app = WriterGui(MultiAgent.graph) | |
| app.launch() | |