eaglelandsonce commited on
Commit
4977282
·
verified ·
1 Parent(s): 3877bd6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -201
app.py CHANGED
@@ -7,57 +7,11 @@ import queue
7
  import threading
8
  import os
9
 
10
- analysis_text = """
11
- Stage 1: Ground-Based Spin-Up and Launch Initiation
12
- • Concept:
13
- A large, energy‑efficient, electrically powered centrifuge is built on the ground. This “spin launcher” uses renewable energy (for example, solar‐assisted electricity) to accelerate a specially designed payload assembly along a rotating arm or in a long circular tunnel.
14
- • Benefits:
15
- Because most of the kinetic energy is imparted mechanically (rather than via chemical propellant), the system drastically reduces the need for traditional, polluting rocket propellants. This stage is also relatively low‑cost because the “engine” is essentially an electromagnetic drive rather than a rocket motor.
16
-
17
- Stage 2: Controlled Payload Release and Orbital Injection
18
- • Concept:
19
- At a pre‑calculated high tangential velocity, the payload is released from the spin launcher. A very short, minimal‐burn liquid or electric thruster (if needed) “tunes” the trajectory so that the payload enters a stable, low‑Earth orbit.
20
- • Benefits:
21
- The primary acceleration is mechanical, so only a tiny amount of propellant is required for orbital insertion. This greatly cuts both cost and the environmental impact typically associated with rocket launches.
22
-
23
- Stage 3: Autonomous On-Orbit Stabilization and Despinning
24
- • Concept:
25
- Once in orbit, the payload’s onboard guidance and control systems (such as small reaction control thrusters or a yo-yo de-spin mechanism) despin and stabilize the payload. Integrated sensors and attitude-control software adjust the payload’s orientation and gently circularize the orbit.
26
- • Benefits:
27
- Autonomous stabilization minimizes additional propellant use and prepares the payload for a safe, predictable rendezvous. The controlled despinning ensures that the payload’s docking adapter remains in the proper orientation for subsequent attachment.
28
-
29
- Stage 4: Rendezvous and Docking with the Manned Vehicle
30
- • Concept:
31
- A separately launched or pre‑positioned manned spacecraft (or space station) maneuvers to intercept the payload. The payload is equipped with a dedicated docking adapter (for instance, a magnetic or mechanical latch system engineered for high-precision contact under low‑g conditions).
32
- • Benefits:
33
- This phase uses conventional low‑delta‑V maneuvers that are far less expensive than a full chemical orbital insertion burn. The docking system is designed to absorb minor mismatches in velocity or attitude, allowing the crew to safely “hook on” to the payload. This minimizes extra propellant usage during the rendezvous phase.
34
-
35
- Stage 5: Integrated Mission Operations and Continued Space Activity
36
- • Concept:
37
- Once docked, the combined system—the manned vehicle with the attached spin-delivered payload—continues its mission. The payload might provide additional resources (such as extra fuel, scientific instruments, or habitat modules) that augment the manned vehicle’s capabilities.
38
- • Benefits:
39
- With the payload permanently attached, mission operations (such as orbital adjustments, inter-station transfers, or even on-orbit assembly of larger structures) proceed with enhanced capabilities. The system’s reliance on mechanical acceleration for the bulk of the launch cut both launch costs and the environmental footprint, leaving only minor orbital maneuvers to be performed with conventional thrusters.
40
-
41
- Summary
42
- This five-stage system marries a ground-based spin acceleration concept with in-space docking and integration to achieve a “propellant-light” method for delivering payloads into orbit. By using a spin launcher to achieve high velocity on the ground (Stage 1) and minimizing onboard chemical propellant (Stage 2), the payload is inserted into orbit economically and with reduced environmental impact. On-orbit stabilization (Stage 3) prepares it for rendezvous with a manned vehicle (Stage 4), after which the combined system carries out the mission (Stage 5).
43
-
44
- """
45
-
46
- summary_txt = """
47
-
48
- Summary
49
- This five-stage system marries a ground-based spin acceleration concept with in-space docking and integration to achieve a “propellant-light” method for delivering payloads into orbit. By using a spin launcher to achieve high velocity on the ground (Stage 1) and minimizing onboard chemical propellant (Stage 2), the payload is inserted into orbit economically and with reduced environmental impact. On-orbit stabilization (Stage 3) prepares it for rendezvous with a manned vehicle (Stage 4), after which the combined system carries out the mission (Stage 5).
50
-
51
-
52
- """
53
-
54
  class AgentMessageQueue:
55
  def __init__(self):
56
  self.message_queue = queue.Queue()
57
- self.last_agent = None
58
 
59
  def add_message(self, message: Dict):
60
- print(f"Adding message to queue: {message}") # Debug print
61
  self.message_queue.put(message)
62
 
63
  def get_messages(self) -> List[Dict]:
@@ -66,15 +20,14 @@ class AgentMessageQueue:
66
  messages.append(self.message_queue.get())
67
  return messages
68
 
69
- class ArticleCrew:
70
  def __init__(self, api_key: str = None):
71
  self.api_key = api_key
72
  self.message_queue = AgentMessageQueue()
73
- self.planner = None
74
  self.writer = None
75
  self.editor = None
76
  self.current_agent = None
77
- self.final_article = None
78
 
79
  def initialize_agents(self, topic: str):
80
  if not self.api_key:
@@ -83,95 +36,88 @@ class ArticleCrew:
83
  os.environ["OPENAI_API_KEY"] = self.api_key
84
  llm = ChatOpenAI(temperature=0.7, model="gpt-4")
85
 
86
- self.planner = Agent(
87
- role="Content Planner",
88
- goal=f"Plan engaging and factually accurate content on {topic}",
89
- backstory="Expert content planner with focus on creating engaging outlines",
90
  allow_delegation=False,
91
  verbose=True,
92
  llm=llm
93
  )
94
 
95
  self.writer = Agent(
96
- role="Content Writer",
97
- goal=f"Write insightful and factually accurate piece about {topic}",
98
- backstory="Expert content writer with focus on engaging articles",
99
  allow_delegation=False,
100
  verbose=True,
101
  llm=llm
102
  )
103
 
104
  self.editor = Agent(
105
- role="Editor",
106
- goal="Polish and refine the article",
107
- backstory="Expert editor with eye for detail and clarity",
108
  allow_delegation=False,
109
  verbose=True,
110
  llm=llm
111
  )
112
 
113
  def create_tasks(self, topic: str) -> List[Task]:
114
- planner_task = Task(
115
- description=f"""Create a detailed content plan for an article about {topic} by:
116
- 1. Prioritizing the latest trends, key players, and noteworthy news
117
- 2. Identifying the target audience, considering their interests and pain points
118
- 3. Developing a detailed content outline including introduction, key points, and call to action
119
- 4. Including SEO keywords and relevant data or sources""",
120
- expected_output="A comprehensive content plan with outline, keywords, and target audience analysis",
121
- agent=self.planner
122
  )
123
 
124
  writer_task = Task(
125
- description="""Based on the provided content plan:
126
- 1. Use the content plan to craft a compelling blog post
127
- 2. Incorporate SEO keywords naturally
128
- 3. Ensure sections/subtitles are properly named in an engaging manner
129
- 4. Create proper structure with introduction, body, and conclusion
130
- 5. Proofread for grammatical errors""",
131
- expected_output="A well-written article draft following the content plan",
132
  agent=self.writer
133
  )
134
 
135
  editor_task = Task(
136
- description="""Review the written article by:
137
- 1. Checking for clarity and coherence
138
- 2. Correcting any grammatical errors and typos
139
- 3. Ensuring consistent tone and style
140
- 4. Verifying proper formatting and structure""",
141
- expected_output="A polished, final version of the article ready for publication",
142
  agent=self.editor
143
  )
144
 
145
- return [planner_task, writer_task, editor_task]
146
 
147
- async def process_article(self, topic: str) -> Generator[List[Dict], None, None]:
148
- def add_agent_messages(agent_name: str, tasks: str, emoji: str = "🤖"):
149
- # Add agent header
150
  self.message_queue.add_message({
151
  "role": "assistant",
152
  "content": agent_name,
153
  "metadata": {"title": f"{emoji} {agent_name}"}
154
  })
155
-
156
- # Add task description
157
  self.message_queue.add_message({
158
  "role": "assistant",
159
  "content": tasks,
160
- "metadata": {"title": f"🚀 Task for {agent_name}"}
161
  })
162
 
163
  def setup_next_agent(current_agent: str) -> None:
164
  agent_sequence = {
165
- "Content Planner": ("Content Writer", """1. Use the content plan to craft a compelling blog post
166
- 2. Incorporate SEO keywords naturally
167
- 3. Ensure sections/subtitles are properly named in an engaging manner
168
- 4. Create proper structure with introduction, body, and conclusion
169
- 5. Proofread for grammatical errors"""),
170
 
171
- "Content Writer": ("Editor", """1. Review the article for clarity and coherence
172
- 2. Check for grammatical errors and typos
173
- 3. Ensure consistent tone and style
174
- 4. Verify proper formatting and structure""")
175
  }
176
 
177
  if current_agent in agent_sequence:
@@ -179,78 +125,48 @@ class ArticleCrew:
179
  self.current_agent = next_agent
180
  add_agent_messages(next_agent, tasks)
181
 
182
-
183
  def task_callback(task_output) -> None:
184
- print(f"Task callback received: {task_output}") # Debug print
185
 
186
- # Extract content from raw output
187
- raw_output = task_output.raw
188
- if "## Final Answer:" in raw_output:
189
- content = raw_output.split("## Final Answer:")[1].strip()
190
- else:
191
- content = raw_output.strip()
192
-
193
- # Handle the output based on current agent
194
- if self.current_agent == "Editor":
195
- # Don't show editor's output with metadata
196
- # Instead, show completion message and final article
197
  self.message_queue.add_message({
198
  "role": "assistant",
199
- "content": "Final article is ready!",
200
- "metadata": {"title": "📝 Final Article"}
201
  })
202
-
203
- # Convert common markdown patterns to Gradio-compatible markdown
204
- formatted_content = content
205
- # Ensure proper spacing for headers
206
- formatted_content = formatted_content.replace("\n#", "\n\n#")
207
- # Ensure proper spacing for lists
208
- formatted_content = formatted_content.replace("\n-", "\n\n-")
209
- formatted_content = formatted_content.replace("\n*", "\n\n*")
210
- formatted_content = formatted_content.replace("\n1.", "\n\n1.")
211
- # Ensure proper spacing for paragraphs
212
- formatted_content = formatted_content.replace("\n\n\n", "\n\n")
213
-
214
- # Add the final article content without metadata
215
  self.message_queue.add_message({
216
  "role": "assistant",
217
- "content": formatted_content
218
  })
219
  else:
220
- # For other agents, show their output with metadata
221
  self.message_queue.add_message({
222
  "role": "assistant",
223
- "content": content,
224
- "metadata": {"title": f" Output from {self.current_agent}"}
225
  })
226
- # Setup next agent
227
  setup_next_agent(self.current_agent)
228
 
229
  def step_callback(output: Any) -> None:
230
- print(f"Step callback received: {output}") # Debug print
231
- # We'll only use step_callback for logging purposes now
232
  pass
233
 
234
  try:
235
  self.initialize_agents(topic)
236
- self.current_agent = "Content Planner"
237
 
238
- # Start process
239
  yield [{
240
  "role": "assistant",
241
- "content": "Starting work on your launch article...",
242
- "metadata": {"title": "🚀 Process Started"}
243
  }]
244
 
245
- # Initialize first agent
246
- add_agent_messages("Content Planner",
247
- """1. Prioritize the latest trends, key players, and noteworthy news
248
- 2. Identify the target audience, considering their interests and pain points
249
- 3. Develop a detailed content outline including introduction, key points, and call to action
250
- 4. Include SEO keywords and relevant data or sources""")
251
 
252
  crew = Crew(
253
- agents=[self.planner, self.writer, self.editor],
254
  tasks=self.create_tasks(topic),
255
  verbose=True,
256
  step_callback=step_callback,
@@ -261,7 +177,6 @@ class ArticleCrew:
261
  try:
262
  crew.kickoff()
263
  except Exception as e:
264
- print(f"Error in crew execution: {str(e)}") # Debug print
265
  self.message_queue.add_message({
266
  "role": "assistant",
267
  "content": f"An error occurred: {str(e)}",
@@ -274,99 +189,58 @@ class ArticleCrew:
274
  while thread.is_alive() or not self.message_queue.message_queue.empty():
275
  messages = self.message_queue.get_messages()
276
  if messages:
277
- print(f"Yielding messages: {messages}") # Debug print
278
  yield messages
279
  await asyncio.sleep(0.1)
280
 
281
  except Exception as e:
282
- print(f"Error in process_article: {str(e)}") # Debug print
283
  yield [{
284
  "role": "assistant",
285
  "content": f"An error occurred: {str(e)}",
286
  "metadata": {"title": "❌ Error"}
287
  }]
288
 
289
- # [Rest of the code remains the same]
290
-
291
-
292
  def create_demo():
293
- article_crew = None
294
 
295
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
296
- gr.Markdown("# 🚀 AI Space Launch Crew")
297
 
298
  openai_api_key = gr.Textbox(
299
  label='OpenAI API Key',
300
  type='password',
301
- placeholder='Enter your OpenAI API key...',
302
- interactive=True
303
  )
304
 
305
  chatbot = gr.Chatbot(
306
- label="Writing Process",
307
  height=700,
308
  type="messages",
309
- show_label=True,
310
- visible=False,
311
- avatar_images=(None, "https://avatars.githubusercontent.com/u/170677839?v=4"),
312
- render_markdown=True # Enable markdown rendering
313
  )
314
 
315
- with gr.Row(equal_height=True):
316
- topic = gr.Textbox(
317
- label="Launch Topic",
318
- placeholder="Enter topic...",
319
- scale=4,
320
- visible=False
321
- )
322
- btn = gr.Button("Write Article", variant="primary", scale=1, visible=False)
323
 
324
  async def process_input(topic, history, api_key):
325
- nonlocal article_crew
326
  if not api_key:
327
- history = history or []
328
- history.append({
329
- "role": "assistant",
330
- "content": "Please provide an OpenAI API key.",
331
- "metadata": {"title": "❌ Error"}
332
- })
333
- yield history
334
  return
335
 
336
- if article_crew is None:
337
- article_crew = ArticleCrew(api_key=api_key)
338
-
339
- history = history or []
340
- history.append({"role": "user", "content": f"Write an article about: {topic}"})
341
- yield history
342
 
343
- try:
344
- async for messages in article_crew.process_article(topic):
345
- history.extend(messages)
346
- yield history
347
- except Exception as e:
348
- history.append({
349
- "role": "assistant",
350
- "content": f"An error occurred: {str(e)}",
351
- "metadata": {"title": "❌ Error"}
352
- })
353
- yield history
354
-
355
- def show_interface():
356
- return {
357
- openai_api_key: gr.Textbox(visible=False),
358
- chatbot: gr.Chatbot(visible=True),
359
- topic: gr.Textbox(visible=True),
360
- btn: gr.Button(visible=True)
361
- }
362
 
363
- openai_api_key.submit(show_interface, None, [openai_api_key, chatbot, topic, btn])
364
  btn.click(process_input, [topic, chatbot, openai_api_key], [chatbot])
365
- topic.submit(process_input, [topic, chatbot, openai_api_key], [chatbot])
366
 
367
  return demo
368
 
369
  if __name__ == "__main__":
370
  demo = create_demo()
371
  demo.queue()
372
- demo.launch(debug=True)
 
7
  import threading
8
  import os
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  class AgentMessageQueue:
11
  def __init__(self):
12
  self.message_queue = queue.Queue()
 
13
 
14
  def add_message(self, message: Dict):
 
15
  self.message_queue.put(message)
16
 
17
  def get_messages(self) -> List[Dict]:
 
20
  messages.append(self.message_queue.get())
21
  return messages
22
 
23
+ class PressReleaseCrew:
24
  def __init__(self, api_key: str = None):
25
  self.api_key = api_key
26
  self.message_queue = AgentMessageQueue()
27
+ self.researcher = None
28
  self.writer = None
29
  self.editor = None
30
  self.current_agent = None
 
31
 
32
  def initialize_agents(self, topic: str):
33
  if not self.api_key:
 
36
  os.environ["OPENAI_API_KEY"] = self.api_key
37
  llm = ChatOpenAI(temperature=0.7, model="gpt-4")
38
 
39
+ self.researcher = Agent(
40
+ role="News Researcher",
41
+ goal=f"Gather critical details and facts for a press release about {topic}",
42
+ backstory="An experienced journalist who specializes in gathering news and structuring press releases.",
43
  allow_delegation=False,
44
  verbose=True,
45
  llm=llm
46
  )
47
 
48
  self.writer = Agent(
49
+ role="Press Release Writer",
50
+ goal=f"Draft a compelling and structured press release about {topic}",
51
+ backstory="A seasoned news writer with expertise in crafting clear and engaging press releases.",
52
  allow_delegation=False,
53
  verbose=True,
54
  llm=llm
55
  )
56
 
57
  self.editor = Agent(
58
+ role="News Editor",
59
+ goal="Refine and finalize the press release for accuracy and professionalism.",
60
+ backstory="A skilled editor with an eye for clarity, conciseness, and journalistic integrity.",
61
  allow_delegation=False,
62
  verbose=True,
63
  llm=llm
64
  )
65
 
66
  def create_tasks(self, topic: str) -> List[Task]:
67
+ researcher_task = Task(
68
+ description=f"""As a news researcher, compile essential details for a press release on {topic} by:
69
+ 1. Identifying key facts, statistics, and industry trends
70
+ 2. Structuring the information into a brief, clear outline
71
+ 3. Suggesting a compelling press release headline""",
72
+ expected_output="A structured summary with key facts, statistics, and a proposed headline.",
73
+ agent=self.researcher
 
74
  )
75
 
76
  writer_task = Task(
77
+ description="""Using the research provided:
78
+ 1. Write a clear and engaging press release following a journalistic structure
79
+ 2. Ensure it includes a compelling headline, subheading, lead paragraph, supporting details, and a boilerplate
80
+ 3. Maintain a professional and neutral tone""",
81
+ expected_output="A structured press release draft ready for editing.",
 
 
82
  agent=self.writer
83
  )
84
 
85
  editor_task = Task(
86
+ description="""Review and refine the press release by:
87
+ 1. Checking for clarity, conciseness, and accuracy
88
+ 2. Ensuring proper journalistic tone and structure
89
+ 3. Correcting any grammatical or formatting issues""",
90
+ expected_output="A polished, publication-ready press release.",
 
91
  agent=self.editor
92
  )
93
 
94
+ return [researcher_task, writer_task, editor_task]
95
 
96
+ async def process_press_release(self, topic: str) -> Generator[List[Dict], None, None]:
97
+ def add_agent_messages(agent_name: str, tasks: str, emoji: str = "📰"):
 
98
  self.message_queue.add_message({
99
  "role": "assistant",
100
  "content": agent_name,
101
  "metadata": {"title": f"{emoji} {agent_name}"}
102
  })
 
 
103
  self.message_queue.add_message({
104
  "role": "assistant",
105
  "content": tasks,
106
+ "metadata": {"title": f"📄 Task for {agent_name}"}
107
  })
108
 
109
  def setup_next_agent(current_agent: str) -> None:
110
  agent_sequence = {
111
+ "News Researcher": ("Press Release Writer", """Write a structured and engaging press release including:
112
+ 1. A compelling headline and subheading
113
+ 2. A strong lead paragraph
114
+ 3. Supporting details and key statistics
115
+ 4. A conclusion with a call to action or company statement"""),
116
 
117
+ "Press Release Writer": ("News Editor", """Review and refine the press release for:
118
+ 1. Clarity and conciseness
119
+ 2. Proper journalistic tone and structure
120
+ 3. Grammatical accuracy and formatting""")
121
  }
122
 
123
  if current_agent in agent_sequence:
 
125
  self.current_agent = next_agent
126
  add_agent_messages(next_agent, tasks)
127
 
 
128
  def task_callback(task_output) -> None:
129
+ raw_output = task_output.raw.strip()
130
 
131
+ if self.current_agent == "News Editor":
 
 
 
 
 
 
 
 
 
 
132
  self.message_queue.add_message({
133
  "role": "assistant",
134
+ "content": "Final press release is ready!",
135
+ "metadata": {"title": "📝 Final Press Release"}
136
  })
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  self.message_queue.add_message({
138
  "role": "assistant",
139
+ "content": raw_output
140
  })
141
  else:
 
142
  self.message_queue.add_message({
143
  "role": "assistant",
144
+ "content": raw_output,
145
+ "metadata": {"title": f"📰 Output from {self.current_agent}"}
146
  })
 
147
  setup_next_agent(self.current_agent)
148
 
149
  def step_callback(output: Any) -> None:
 
 
150
  pass
151
 
152
  try:
153
  self.initialize_agents(topic)
154
+ self.current_agent = "News Researcher"
155
 
 
156
  yield [{
157
  "role": "assistant",
158
+ "content": "Starting press release preparation...",
159
+ "metadata": {"title": "🚀 Press Release Process Started"}
160
  }]
161
 
162
+ add_agent_messages("News Researcher",
163
+ """Gather essential details for a press release:
164
+ 1. Identify key facts, statistics, and industry trends
165
+ 2. Structure information into a brief outline
166
+ 3. Suggest a compelling headline""")
 
167
 
168
  crew = Crew(
169
+ agents=[self.researcher, self.writer, self.editor],
170
  tasks=self.create_tasks(topic),
171
  verbose=True,
172
  step_callback=step_callback,
 
177
  try:
178
  crew.kickoff()
179
  except Exception as e:
 
180
  self.message_queue.add_message({
181
  "role": "assistant",
182
  "content": f"An error occurred: {str(e)}",
 
189
  while thread.is_alive() or not self.message_queue.message_queue.empty():
190
  messages = self.message_queue.get_messages()
191
  if messages:
 
192
  yield messages
193
  await asyncio.sleep(0.1)
194
 
195
  except Exception as e:
 
196
  yield [{
197
  "role": "assistant",
198
  "content": f"An error occurred: {str(e)}",
199
  "metadata": {"title": "❌ Error"}
200
  }]
201
 
 
 
 
202
  def create_demo():
203
+ press_release_crew = None
204
 
205
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
206
+ gr.Markdown("# 📰 AI Newsroom - Press Release Generator")
207
 
208
  openai_api_key = gr.Textbox(
209
  label='OpenAI API Key',
210
  type='password',
211
+ placeholder='Enter your OpenAI API key...'
 
212
  )
213
 
214
  chatbot = gr.Chatbot(
215
+ label="Press Release Process",
216
  height=700,
217
  type="messages",
218
+ show_label=True
 
 
 
219
  )
220
 
221
+ topic = gr.Textbox(
222
+ label="Press Release Topic",
223
+ placeholder="Enter topic..."
224
+ )
225
+ btn = gr.Button("Generate Press Release", variant="primary")
 
 
 
226
 
227
  async def process_input(topic, history, api_key):
228
+ nonlocal press_release_crew
229
  if not api_key:
230
+ yield history + [{"role": "assistant", "content": "Please provide an OpenAI API key."}]
 
 
 
 
 
 
231
  return
232
 
233
+ if press_release_crew is None:
234
+ press_release_crew = PressReleaseCrew(api_key=api_key)
 
 
 
 
235
 
236
+ async for messages in press_release_crew.process_press_release(topic):
237
+ yield messages
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
 
 
239
  btn.click(process_input, [topic, chatbot, openai_api_key], [chatbot])
 
240
 
241
  return demo
242
 
243
  if __name__ == "__main__":
244
  demo = create_demo()
245
  demo.queue()
246
+ demo.launch(debug=True)