cicboy commited on
Commit
2fe9eb8
·
1 Parent(s): 5250c66

update the application file and requirements

Browse files
Files changed (2) hide show
  1. app.py +179 -0
  2. requirements.txt +3 -0
app.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import relevant libraries and modules
2
+
3
+ import warnings
4
+ from crewai import LLM, Task, Agent, Crew
5
+ import os
6
+ from dotenv import load_dotenv
7
+ from pathlib import Path
8
+ import gradio as gr
9
+
10
+ # control warnings
11
+ warnings.filterwarnings("ignore")
12
+
13
+ load_dotenv()
14
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
15
+
16
+ #Define LLMs
17
+ llm_planner = LLM(model="gpt-4o-mini", temperature=0.5)
18
+ llm_writer = LLM(model="gpt-5-mini", temperature=1.0)
19
+ llm_editor = LLM(model="gpt-4-turbo", temperature=0.3)
20
+ llm_fact=LLM(model="gpt-4o-mini", temperature=0.3)
21
+
22
+ #Creating Agents
23
+
24
+ planner = Agent(
25
+ role="Content Planner",
26
+ goal="Plan engaging and factually accurate content on {topic}",
27
+ backstory="You are working on planning a blog article about the topic {topic}."
28
+ "You collect relevant information that helps the audience learn something and make informed decisions. "
29
+ "Your work is the basis for the Content Writer to write an article on this topic.",
30
+ allow_delegation=False,
31
+ verbose=True,
32
+ llm=llm_planner
33
+ )
34
+
35
+ writer = Agent(
36
+ role="Content Writer",
37
+ goal="Write an insightful and factually accurate opinion piece about the topic: {topic}",
38
+ backstory="You are working on writing a new opnion piece about the topic: {topic}. "
39
+ "You base your writing on the work of the Content Planner, who provides an outline and relevant context about the topic. "
40
+ "You follow the main objectives and direction of the outline, as provided by the Content Planner. "
41
+ "You also provide objective and impartial insights, supported by relevant information that is provided by the Content Planner. "
42
+ "You acknowledge in your opnion piece when your statements are opinions as opposed to objective staements.",
43
+ allow_delegation=False,
44
+ verbose=True,
45
+ llm=llm_writer
46
+ )
47
+
48
+ fact_checker = Agent(
49
+ role="Fact Checker",
50
+ goal="Verify factual accuracy, detect unsupported claims and identify missing references or sources.",
51
+ backstory="You are a meticulous research analyst who checks every claim against known facts and relaible sources",
52
+ allow_delegation=False,
53
+ verbose=True,
54
+ llm=llm_fact
55
+ )
56
+
57
+ editor = Agent(
58
+ role="Editor",
59
+ goal="Edit a given blog post to align with the context and narrative style of the {topic} (e.g. academic, informal, satirical).",
60
+ backstory="You are an editor who receives a blog post from the Content Writer. "
61
+ "Your goal is to review the blog post to ensure that it follows journalistic best practices, "
62
+ "provides balanced viewpoints, when providing opinions or assertions, "
63
+ "and also avoids major controversial topics or opinions when possible. "
64
+ "The blog post should align with the context and narrative style of the topic being discussed.",
65
+ allow_delegation=False,
66
+ verbose=True,
67
+ llm=llm_editor
68
+ )
69
+
70
+ #Creating Tasks
71
+
72
+ plan = Task(
73
+ name="content_planner_task",
74
+ description=(
75
+ "1. Prioritize the latest trends, key players, and groundbreaking news on {topic}.\n"
76
+ "2. Identify the target audience, considering their interests and pain points.\n"
77
+ "3. Develop a detailed content outline including and introduction, key points, and a call to action.\n"
78
+ "4. Include SEO keywords and relevant data or sources"
79
+ ),
80
+ expected_output="A comprehensive content plan document with an outline, audience analysis, SEO keywords, and resources.",
81
+ agent = planner
82
+ )
83
+
84
+ write = Task(
85
+ name="blog_writer_task",
86
+ description=(
87
+ "1. Use the provided content plan to craft a compelling blog post on {topic}.\n"
88
+ "2. Incorporate SEO keywords naturally.\n"
89
+ "3. Sections/Subtitles are properly named in an engaging manner.\n"
90
+ "4. Ensure the post structured with an engaging introduction, insightful body, and a summarizing conclusion.\n"
91
+ "5. The narrative style and language used should be determined by the target audience and {tone}.\n"
92
+ "6. Proofread for grammatical errors and alignment with the target audience.\n"
93
+ ),
94
+ expected_output="A well-written blog post in markdown format, ready for publication. "
95
+ "Each section should have 2 or 3 paragraphs and the whole blog should be a maximum of 1000 words.",
96
+ agent=writer,
97
+ context=[plan]
98
+ )
99
+
100
+ fact_check = Task(
101
+ name="fact_checker_task",
102
+ description=(
103
+ "Carefully review the drafted blog post provided by the Content Writer. "
104
+ "Check all factual statements for accuracy and ensure sources or references are mentioned. "
105
+ "Identify any unsupported claims, logical inconsistencies, or outdated information. "
106
+ "Provide corrections or highlight areas that require further verification."
107
+ ),
108
+ expected_output=(
109
+ "A revised version of the blog post in markdown format, with annotations or corrections "
110
+ "for any inaccurate or unsupported statements."
111
+ ),
112
+ agent=fact_checker,
113
+ context=[write]
114
+ )
115
+
116
+ edit = Task(
117
+ name="editor_task",
118
+ description=("Edit and refine the fact-checked blog post to ensure clarity, flow and consistent {tone}.\n"
119
+ "Polish grammar, readability, and overall style."
120
+ ),
121
+ expected_output="A well-written blog post in markdown format, ready for publication. "
122
+ "Each section should have 2 or 3 paragraphs and the whole blog should be a maximum of 1000 words",
123
+ agent=editor,
124
+ context=[fact_check]
125
+ )
126
+
127
+ # Creating the Crew
128
+
129
+ crew = Crew(
130
+ agents=[planner, writer, fact_checker, editor],
131
+ tasks=[plan, write, fact_check, edit],
132
+ process="sequential",
133
+ verbose=True
134
+ )
135
+
136
+ # Define Gradio Handler
137
+ def generate_blog(topic, tone):
138
+ yield "⏳ Generating blog — this may take a few moments..."
139
+ result = crew.kickoff(inputs={"topic": topic, "tone": tone})
140
+
141
+ # CrewOutput -> extract text
142
+ if hasattr(result, "raw_output"):
143
+ final_text = result.raw_output
144
+ elif hasattr(result, "final_output"):
145
+ final_text = result.final_output
146
+ else:
147
+ final_text = str(result)
148
+
149
+ yield final_text
150
+
151
+ # Build Gradio Interface
152
+ with gr.Blocks(theme=gr.themes.Glass(primary_hue="purple")) as demo:
153
+ gr.Markdown(
154
+ """
155
+ # ✍️ AI Blog Writer Multi-Agent
156
+ Create a professional, fact-checked, and polished article using CrewAI agents.
157
+ """
158
+ )
159
+
160
+ with gr.Row():
161
+ topic = gr.Textbox(
162
+ label="Blog Topic",
163
+ placeholder="e.g. Sustainable Investing, Vegan cuisine, AI in Healthcare",
164
+ value="Sustainable Investing"
165
+ )
166
+ tone=gr.Dropdown(
167
+ ["professional", "playful", "academic", "casual", "satirical"],
168
+ label="Select Writing Tone",
169
+ value="academic"
170
+ )
171
+
172
+ run_button = gr.Button("🚀 Generate Blog", variant="primary")
173
+ output = gr.Markdown(label="📰 Generated Blog Post")
174
+
175
+ run_button.click(generate_blog, inputs=[topic, tone], outputs=output)
176
+
177
+ #Launch app
178
+ if __name__=="__main__":
179
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=True)
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ crewai
2
+ gradio
3
+ python-dotenv