ysharma HF staff commited on
Commit
c3fdfdd
Β·
verified Β·
1 Parent(s): 86a2708

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +164 -0
app.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from crewai import Agent, Task, Crew
2
+ import gradio as gr
3
+ from gradio import ChatMessage
4
+ import asyncio
5
+ import re
6
+ import sys
7
+ from typing import List, Generator
8
+ import os
9
+ from langchain_openai import ChatOpenAI
10
+ from dotenv import load_dotenv
11
+
12
+ load_dotenv()
13
+
14
+ class ArticleCrew:
15
+ def __init__(self):
16
+ # Agent definitions remain the same
17
+ self.planner = Agent(
18
+ role="Content Planner",
19
+ goal="Plan engaging and factually accurate content on {topic}",
20
+ backstory="You're working on planning a blog article about the topic: {topic}. "
21
+ "You collect information that helps the audience learn something "
22
+ "and make informed decisions.",
23
+ allow_delegation=False,
24
+ verbose=True
25
+ )
26
+
27
+ self.writer = Agent(
28
+ role="Content Writer",
29
+ goal="Write insightful and factually accurate opinion piece about the topic: {topic}",
30
+ backstory="You're working on writing a new opinion piece about the topic: {topic}. "
31
+ "You base your writing on the work of the Content Planner.",
32
+ allow_delegation=False,
33
+ verbose=True
34
+ )
35
+
36
+ self.editor = Agent(
37
+ role="Editor",
38
+ goal="Edit a given blog post to align with the writing style",
39
+ backstory="You are an editor who receives a blog post from the Content Writer.",
40
+ allow_delegation=False,
41
+ verbose=True
42
+ )
43
+
44
+ self.output_parser = OutputParser()
45
+
46
+ def create_tasks(self, topic: str):
47
+ # Task definitions remain the same
48
+ plan_task = Task(
49
+ description=(
50
+ f"1. Prioritize the latest trends, key players, and noteworthy news on {topic}.\n"
51
+ f"2. Identify the target audience, considering their interests and pain points.\n"
52
+ f"3. Develop a detailed content outline including introduction, key points, and call to action.\n"
53
+ f"4. Include SEO keywords and relevant data or sources."
54
+ ),
55
+ expected_output="A comprehensive content plan document with an outline, audience analysis, SEO keywords, and resources.",
56
+ agent=self.planner
57
+ )
58
+
59
+ write_task = Task(
60
+ description=(
61
+ "1. Use the content plan to craft a compelling blog post.\n"
62
+ "2. Incorporate SEO keywords naturally.\n"
63
+ "3. Sections/Subtitles are properly named in an engaging manner.\n"
64
+ "4. Ensure proper structure with introduction, body, and conclusion.\n"
65
+ "5. Proofread for grammatical errors."
66
+ ),
67
+ expected_output="A well-written blog post in markdown format, ready for publication.",
68
+ agent=self.writer
69
+ )
70
+
71
+ edit_task = Task(
72
+ description="Proofread the given blog post for grammatical errors and alignment with the brand's voice.",
73
+ expected_output="A well-written blog post in markdown format, ready for publication.",
74
+ agent=self.editor
75
+ )
76
+
77
+ return [plan_task, write_task, edit_task]
78
+
79
+ async def process_article(self, topic: str) -> Generator[List[ChatMessage], None, None]:
80
+ crew = Crew(
81
+ agents=[self.planner, self.writer, self.editor],
82
+ tasks=self.create_tasks(topic),
83
+ verbose=2
84
+ )
85
+
86
+ class StreamCapture:
87
+ def __init__(self):
88
+ self.data = []
89
+ self.current_chunk = ""
90
+
91
+ def write(self, text):
92
+ self.current_chunk += text
93
+ if "\n" in text:
94
+ self.data.append(self.current_chunk)
95
+ self.current_chunk = ""
96
+ return len(text)
97
+
98
+ stream = StreamCapture()
99
+ original_stdout = sys.stdout
100
+ sys.stdout = stream
101
+
102
+ try:
103
+ result = crew.kickoff(inputs={"topic": topic})
104
+
105
+ # Process intermediate outputs
106
+ for chunk in stream.data:
107
+ messages = self.output_parser.parse_output(chunk)
108
+ if messages:
109
+ for msg in messages:
110
+ yield [msg]
111
+
112
+ # Send final result
113
+ yield [ChatMessage(
114
+ role="assistant",
115
+ content=result,
116
+ metadata={"title": "πŸ“ Final Article"}
117
+ )]
118
+
119
+ finally:
120
+ sys.stdout = original_stdout
121
+
122
+ def create_demo():
123
+ article_crew = ArticleCrew()
124
+
125
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
126
+ gr.Markdown("# πŸ“ AI Article Writing Crew")
127
+ gr.Markdown("Watch as our AI crew collaborates to create your article!")
128
+
129
+ chatbot = gr.Chatbot(
130
+ label="Writing Process",
131
+ avatar_images=(None, "πŸ€–"),
132
+ height=700,
133
+ type="messages",
134
+ show_label=True
135
+ )
136
+
137
+ topic = gr.Textbox(
138
+ label="Article Topic",
139
+ placeholder="Enter the topic you want an article about...",
140
+ lines=2
141
+ )
142
+
143
+ async def process_input(topic, history):
144
+ # Add user message as ChatMessage
145
+ history.append(ChatMessage(role="user", content=f"Write an article about: {topic}"))
146
+ yield history
147
+
148
+ # Process and add agent messages
149
+ async for messages in article_crew.process_article(topic):
150
+ history.extend(messages)
151
+ yield history
152
+
153
+ btn = gr.Button("Write Article")
154
+ btn.click(
155
+ process_input,
156
+ inputs=[topic, chatbot],
157
+ outputs=[chatbot]
158
+ )
159
+
160
+ return demo
161
+
162
+ if __name__ == "__main__":
163
+ demo = create_demo()
164
+ demo.launch(debug=True, share=True)