-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaurora_orchestrator.py
More file actions
341 lines (276 loc) · 14.1 KB
/
aurora_orchestrator.py
File metadata and controls
341 lines (276 loc) · 14.1 KB
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
"""A lightweight simulation of the A.U.R.O.R.A. multi-agent orchestrator.
This module exposes the :class:`AuroraOrchestrator` used to run a scripted
simulation of multiple collaborating personas. The original proof-of-concept
lived in a notebook; this version is refactored for clarity and reusability.
Running the module as a script will execute the default main loop and persist
an ``aurora_final_state.json`` file with a snapshot of the shared project
state.
"""
from __future__ import annotations
import json
import os
import time
from dataclasses import dataclass, field
from datetime import datetime
from typing import Dict, Optional
# --- CONFIGURATION ------------------------------------------------------------------
CONFIG: Dict[str, str] = {
"project_name": "A.D.E.P.T. SaaS",
"domain_name": "getadept.io",
"payment_provider": "Stripe",
"cloud_provider": "GCP",
"code_language": "Python (Flask)",
"frontend_framework": "React",
}
@dataclass
class SimulationSettings:
"""Mutable settings for tuning the simulation behaviour.
The default values mimic the timing of the notebook prototype while offering
environment variables for faster test execution.
"""
api_latency_seconds: float = field(default_factory=lambda: float(os.getenv("AURORA_API_LATENCY", 2)))
loop_pause_seconds: float = field(default_factory=lambda: float(os.getenv("AURORA_LOOP_PAUSE", 3)))
# --- A.U.R.O.R.A. SHARED STATE ------------------------------------------------------
PROJECT_STATE: Dict[str, Dict] = {
"tasks": {
"todo": [],
"in_progress": [],
"in_review": [],
"completed": [],
},
"codebase": {
"description": "File system for the A.D.E.P.T. SaaS application.",
"files": {},
},
"design_system": {
"description": "Central design language, components, and brand assets.",
"colors": {},
"typography": {},
"components": {},
},
"message_bus": [],
"last_update": None,
}
# --- AGENT PERSONAS & STANDARD OPERATING PROCEDURES (SOPs) -------------------------
LEAD_DEV_PERSONA = """
**Role:** Senior Full-Stack Developer ("LeadDev")
**Core Objective:** Oversee and execute the technical architecture and development of the A.D.E.P.T. SaaS platform, ensuring scalability, security, and code quality.
**Key Responsibilities:**
- Design the overall application architecture.
- Set up the initial project structure, boilerplate, and deployment pipelines.
- Implement complex backend features (e.g., payment processing, user authentication).
- Review code submitted by CoreDev for quality and adherence to standards.
- Break down large business goals into smaller, actionable technical tasks.
**Standard Operating Procedures (SOPs):**
1. Prioritize tasks related to architecture, security, and backend infrastructure.
2. When creating a new feature, first create a technical spec file in the codebase.
3. When a `[NEEDS_REVIEW]` message appears on the message bus from CoreDev, create a "Code Review" task, assign it to yourself, and perform the review.
4. Communicate completed tasks with `[COMPLETED]` and a summary of the implementation.
5. If blocked, post a `[BLOCKED]` message with the specific problem and tag the relevant agent (e.g., `@Designer`).
"""
CORE_DEV_PERSONA = """
**Role:** Mid-Level Full-Stack Developer ("CoreDev")
**Core Objective:** Implement front-end components and general application features based on designs and technical specifications.
**Key Responsibilities:**
- Develop React components based on the design system.
- Connect front-end components to backend APIs.
- Write unit and integration tests for new features.
- Refactor existing code for clarity and performance.
- Manage the project's CSS and styling.
**Standard Operating Procedures (SOPs):**
1. Prioritize tasks related to front-end development and feature implementation.
2. Always check the `design_system` before building a new UI component.
3. After implementing a feature, write the code to the `PROJECT_STATE['codebase']`.
4. Post a `[NEEDS_REVIEW]` message to the message bus with the path to the completed file(s).
5. If a design is unclear, post a `[CLARIFICATION_NEEDED]` message to the bus and tag `@Designer`.
"""
DESIGNER_PERSONA = """
**Role:** UX/UI Designer ("Designer")
**Core Objective:** Define the visual identity and user experience of the A.D.E.P.T. platform, ensuring it is intuitive, professional, and user-friendly.
**Key Responsibilities:**
- Establish the brand identity (colors, typography).
- Design user flows, wireframes, and high-fidelity mockups.
- Create a component library within the `design_system`.
- Provide CSS and styling guidance to CoreDev.
**Standard Operating Procedures (SOPs):**
1. Start by defining the core brand assets in `PROJECT_STATE['design_system']`.
2. When a new feature is requested, first provide a user flow description, then component specs.
3. Respond to `[CLARIFICATION_NEEDED]` messages from @CoreDev by providing more detailed specifications.
4. Communicate new designs by posting a `[DESIGN_READY]` message with a description of the components added to the design system.
"""
BIZ_ADMIN_PERSONA = """
**Role:** Business & Legal Administrator ("BizAdmin")
**Core Objective:** Handle all non-technical aspects of launching the product, including business formalization, legal documentation, and defining high-level product requirements.
**Key Responsibilities:**
- Generate legal documents (Terms of Service, Privacy Policy).
- Define the business logic for features like subscription tiers and payments.
- Create marketing copy for the landing page.
- Monitor overall project progress and create high-level "Epic" tasks.
**Standard Operating Procedures (SOPs):**
1. Begin by creating foundational tasks for legal and branding.
2. When defining a feature like payments, create a high-level task describing the user flow and business rules.
3. Work with @LeadDev to translate business requirements into technical epics.
4. Post `[MILESTONE_ACHIEVED]` messages when major business goals are met (e.g., "Legal Docs Drafted").
"""
@dataclass
class Task:
"""Lightweight representation of a work item tracked by the orchestrator."""
id: int
name: str
status: str = "todo"
assignee: Optional[str] = None
class AuroraOrchestrator:
"""Main orchestrator for the A.U.R.O.R.A. system simulation."""
def __init__(self, settings: Optional[SimulationSettings] = None) -> None:
self.settings = settings or SimulationSettings()
self.agents = {
"LeadDev": LEAD_DEV_PERSONA,
"CoreDev": CORE_DEV_PERSONA,
"Designer": DESIGNER_PERSONA,
"BizAdmin": BIZ_ADMIN_PERSONA,
}
print("A.U.R.O.R.A. Orchestrator Initialized. State is clean.")
def sleep(self, seconds: float) -> None:
"""Wrapper that sleeps only when ``seconds`` is positive."""
if seconds <= 0:
return
time.sleep(seconds)
def post_message(self, agent_name: str, message: str) -> None:
"""Append a structured message to the shared message bus."""
PROJECT_STATE["message_bus"].append(f"[{agent_name}] {message}")
print(f" -> Posted message to bus: {message}")
def llm_call_simulation(self, agent_name: str, task: Task) -> Dict[str, str]:
"""Simulate a call to a powerful LLM based on the agent persona."""
print(f"\n[AURORA_CORE] >>> Sending task '{task.name}' to agent '{agent_name}'...")
self.sleep(self.settings.api_latency_seconds)
output: Dict[str, str] = {"message": f"Task '{task.name}' completed by {agent_name}."}
if "Create Landing Page HTML" in task.name:
output = {
"file_path": "frontend/src/components/LandingPage.jsx",
"content": (
"/* Placeholder for React Landing Page Component */\n"
"const LandingPage = () => (\n"
" <div>\n"
" <h1>Welcome to A.D.E.P.T.</h1>\n"
" <p>Sign up now!</p>\n"
" </div>\n"
");\n"
"export default LandingPage;\n"
),
"message": (
"[NEEDS_REVIEW] @LeadDev: Initial structure for LandingPage.jsx is "
"complete. Needs styling and form logic. File path: "
"frontend/src/components/LandingPage.jsx"
),
}
elif "Design System" in task.name:
PROJECT_STATE["design_system"]["colors"] = {"primary": "#007BFF", "secondary": "#6C757D"}
PROJECT_STATE["design_system"]["typography"] = {"font": "Inter, sans-serif"}
output = {
"message": "[DESIGN_READY] @CoreDev: Initial color palette and typography defined in Design System."
}
elif "Setup Stripe Backend" in task.name:
output = {
"file_path": "backend/src/payments.py",
"content": (
"# Placeholder for Stripe payment processing logic\n"
"import os\n"
"import stripe\n\n"
"stripe.api_key = os.environ.get('STRIPE_SECRET_KEY')\n\n"
"def create_checkout_session(user_id):\n"
" \"\"\"Create a Stripe checkout session for the provided user id.\"\"\"\n"
" # TODO: Implement checkout session logic\n"
" raise NotImplementedError\n"
),
"message": (
"[COMPLETED] @BizAdmin: Basic Stripe configuration file created at "
"backend/src/payments.py. Ready for business logic implementation."
),
}
elif "Generate Terms of Service" in task.name:
output = {
"file_path": "legal/terms_of_service.md",
"content": (
"# A.D.E.P.T. SaaS - Terms of Service\n\n"
"Welcome! By using our service, you agree to these terms...\n"
),
"message": "[MILESTONE_ACHIEVED] Draft of Terms of Service is complete.",
}
print(f"[AURORA_CORE] <<< Agent '{agent_name}' responded.")
return output
def assign_and_execute_task(self, task: Task) -> None:
"""Assign the task to the best agent, simulate execution, and update state."""
agent_name = self.select_agent(task)
task.status = "in_progress"
task.assignee = agent_name
PROJECT_STATE["tasks"]["in_progress"].append(task.__dict__)
result = self.llm_call_simulation(agent_name, task)
file_path = result.get("file_path")
content = result.get("content")
if file_path and content is not None:
PROJECT_STATE["codebase"]["files"][file_path] = content
print(f" -> Wrote code to {file_path}")
message = result.get("message")
if message:
self.post_message(agent_name, message)
PROJECT_STATE["tasks"]["in_progress"].remove(task.__dict__)
task.status = "completed"
PROJECT_STATE["tasks"]["completed"].append(task.__dict__)
PROJECT_STATE["last_update"] = datetime.now().isoformat()
@staticmethod
def select_agent(task: Task) -> str:
"""Select the most appropriate agent based on the task name."""
task_name_lower = task.name.lower()
if any(keyword in task_name_lower for keyword in ("architecture", "backend", "review")):
return "LeadDev"
if any(keyword in task_name_lower for keyword in ("design", "ux", "style")):
return "Designer"
if any(keyword in task_name_lower for keyword in ("legal", "terms", "business", "copy")):
return "BizAdmin"
return "CoreDev"
def generate_initial_tasks(self) -> None:
"""Bootstrap the project with the first set of high-level tasks."""
tasks = [
Task(id=1, name="Generate Terms of Service and Privacy Policy"),
Task(id=2, name="Define core Brand Identity and Design System"),
Task(id=3, name="Set up initial Flask backend architecture"),
Task(id=4, name="Create basic React frontend structure"),
Task(id=5, name="Create Landing Page HTML and Components"),
Task(id=6, name="Implement business logic for Stripe Backend"),
]
PROJECT_STATE["tasks"]["todo"] = [task.__dict__ for task in tasks]
print("[AURORA_CORE] Initial task list generated. Ready to begin execution.")
def main_loop(self) -> None:
"""Run the simulation until there are no tasks left in the todo queue."""
print("\n" + "=" * 50)
print("A.U.R.O.R.A. Main Execution Loop - ACTIVE")
print("Press Ctrl+C to shut down.")
print("=" * 50)
while PROJECT_STATE["tasks"]["todo"]:
current_task_dict = PROJECT_STATE["tasks"]["todo"].pop(0)
current_task = Task(**current_task_dict)
self.assign_and_execute_task(current_task)
print("\n--- CURRENT PROJECT STATE ---")
print(f"Tasks Completed: {len(PROJECT_STATE['tasks']['completed'])}")
print(f"Files in Codebase: {len(PROJECT_STATE['codebase']['files'])}")
print(f"Messages on Bus: {len(PROJECT_STATE['message_bus'])}")
print("---------------------------\n")
self.sleep(self.settings.loop_pause_seconds)
print("\n[AURORA_CORE] No tasks in 'todo'. Project launch MVP may be complete. Shutting down.")
def persist_final_state(output_path: str = "aurora_final_state.json") -> None:
"""Persist the global project state to ``output_path`` as JSON."""
final_state_json = json.dumps(PROJECT_STATE, indent=2)
with open(output_path, "w", encoding="utf-8") as file:
file.write(final_state_json)
print("\n" + "=" * 50)
print("A.U.R.O.R.A. SHUTDOWN - FINAL STATE REPORT")
print("=" * 50)
print(final_state_json)
print(f"\nFinal project state saved to '{output_path}'")
def main() -> None:
orchestrator = AuroraOrchestrator()
orchestrator.generate_initial_tasks()
orchestrator.main_loop()
persist_final_state()
if __name__ == "__main__":
main()