ainative-python 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ainative/__init__.py +46 -0
- ainative/agent_coordination.py +249 -0
- ainative/agent_identity_system.py +1566 -0
- ainative/agent_learning.py +239 -0
- ainative/agent_orchestration.py +202 -0
- ainative/agent_state.py +231 -0
- ainative/agent_swarm/__init__.py +510 -0
- ainative/auth.py +113 -0
- ainative/cli.py +698 -0
- ainative/cli_utils/__init__.py +13 -0
- ainative/cli_utils/diff.py +292 -0
- ainative/cli_utils/formatters.py +227 -0
- ainative/client.py +272 -0
- ainative/commands/__init__.py +28 -0
- ainative/commands/agents.py +238 -0
- ainative/commands/coordination.py +108 -0
- ainative/commands/inspect.py +483 -0
- ainative/commands/learning.py +119 -0
- ainative/commands/local.py +544 -0
- ainative/commands/state.py +144 -0
- ainative/commands/swarm.py +184 -0
- ainative/commands/sync.py +157 -0
- ainative/commands/tasks.py +191 -0
- ainative/exceptions.py +87 -0
- ainative/zerodb/__init__.py +89 -0
- ainative/zerodb/analytics.py +232 -0
- ainative/zerodb/memory.py +260 -0
- ainative/zerodb/projects.py +224 -0
- ainative/zerodb/tables.py +362 -0
- ainative/zerodb/vectors.py +231 -0
- ainative_python-2.0.0.dist-info/METADATA +550 -0
- ainative_python-2.0.0.dist-info/RECORD +35 -0
- ainative_python-2.0.0.dist-info/WHEEL +5 -0
- ainative_python-2.0.0.dist-info/entry_points.txt +2 -0
- ainative_python-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1566 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AINative Agent Styling & Identity System
|
|
3
|
+
=========================================
|
|
4
|
+
|
|
5
|
+
Complete visual identity and seed prompt system for the Sub-Agent Orchestrator.
|
|
6
|
+
|
|
7
|
+
Supports:
|
|
8
|
+
- Coordinator agent (Claude 3.7 with extended thinking)
|
|
9
|
+
- 10 specialized worker roles (Claude 3.5)
|
|
10
|
+
- Real-time parallel execution visualization
|
|
11
|
+
- Accessible color palette with high contrast
|
|
12
|
+
- Custom agent creation and export
|
|
13
|
+
|
|
14
|
+
Architecture Reference:
|
|
15
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
16
|
+
│ Coordinator Agent │
|
|
17
|
+
│ (Extended Thinking - Claude 3.7) │
|
|
18
|
+
└─────────────────────────────────────────────────────────────┘
|
|
19
|
+
│
|
|
20
|
+
┌────────┬────────┬───┴───┬────────┬────────┐
|
|
21
|
+
▼ ▼ ▼ ▼ ▼ ▼
|
|
22
|
+
┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐
|
|
23
|
+
│Backend ││Frontend││ QA ││Database││ API ││Security│
|
|
24
|
+
└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from dataclasses import dataclass, field
|
|
28
|
+
from typing import Optional, List, Dict, Any, Callable
|
|
29
|
+
from enum import Enum
|
|
30
|
+
import json
|
|
31
|
+
import yaml
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
from datetime import datetime
|
|
34
|
+
|
|
35
|
+
# Rich library for terminal styling
|
|
36
|
+
from rich.console import Console, Group
|
|
37
|
+
from rich.theme import Theme
|
|
38
|
+
from rich.style import Style
|
|
39
|
+
from rich.panel import Panel
|
|
40
|
+
from rich.text import Text
|
|
41
|
+
from rich.live import Live
|
|
42
|
+
from rich.table import Table
|
|
43
|
+
from rich.columns import Columns
|
|
44
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn
|
|
45
|
+
from rich.layout import Layout
|
|
46
|
+
from rich.box import ROUNDED, DOUBLE, HEAVY, MINIMAL, SIMPLE
|
|
47
|
+
from rich import box
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# =============================================================================
|
|
51
|
+
# COLOR SYSTEM - 12 distinct colors for maximum differentiation
|
|
52
|
+
# =============================================================================
|
|
53
|
+
|
|
54
|
+
class AgentColorPalette:
|
|
55
|
+
"""
|
|
56
|
+
Carefully designed color palette for agent differentiation.
|
|
57
|
+
|
|
58
|
+
Design principles:
|
|
59
|
+
- High contrast on both dark and light terminals
|
|
60
|
+
- Distinguishable for common color blindness (deuteranopia, protanopia)
|
|
61
|
+
- Visual hierarchy: Coordinator is most prominent
|
|
62
|
+
- Grouped by function: Backend/DB similar, Frontend/UI similar
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
# Coordinator - Warm, authoritative
|
|
66
|
+
COORDINATOR = "#FF6B6B" # Coral Red - leadership
|
|
67
|
+
|
|
68
|
+
# Backend tier - Cool blues and teals
|
|
69
|
+
BACKEND = "#4ECDC4" # Teal
|
|
70
|
+
DATABASE = "#0984E3" # Royal Blue
|
|
71
|
+
API = "#00CEC9" # Cyan
|
|
72
|
+
|
|
73
|
+
# Frontend tier - Warm greens and yellows
|
|
74
|
+
FRONTEND = "#FDCB6E" # Golden Yellow
|
|
75
|
+
|
|
76
|
+
# Quality tier - Purples and magentas
|
|
77
|
+
QA = "#A29BFE" # Lavender
|
|
78
|
+
TESTING = "#6C5CE7" # Purple
|
|
79
|
+
SECURITY = "#E056FD" # Magenta
|
|
80
|
+
|
|
81
|
+
# Infrastructure tier - Oranges
|
|
82
|
+
DEVOPS = "#FF7675" # Salmon
|
|
83
|
+
ARCHITECTURE = "#F39C12" # Amber
|
|
84
|
+
|
|
85
|
+
# Documentation - Soft green
|
|
86
|
+
DOCUMENTATION = "#00B894" # Mint
|
|
87
|
+
|
|
88
|
+
# System colors
|
|
89
|
+
SUCCESS = "#00B894" # Green
|
|
90
|
+
ERROR = "#D63031" # Red
|
|
91
|
+
WARNING = "#FDCB6E" # Yellow
|
|
92
|
+
INFO = "#74B9FF" # Light Blue
|
|
93
|
+
MUTED = "#636E72" # Gray
|
|
94
|
+
THINKING = "#B2BEC3" # Light Gray
|
|
95
|
+
HANDOFF = "#DFE6E9" # Very Light Gray
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# =============================================================================
|
|
99
|
+
# AGENT IDENTITY DEFINITIONS
|
|
100
|
+
# =============================================================================
|
|
101
|
+
|
|
102
|
+
@dataclass
|
|
103
|
+
class AgentIdentity:
|
|
104
|
+
"""
|
|
105
|
+
Complete visual and behavioral identity for an agent.
|
|
106
|
+
|
|
107
|
+
Includes styling (visual) and personality (behavioral) in one place.
|
|
108
|
+
"""
|
|
109
|
+
# Identity
|
|
110
|
+
id: str # Lowercase identifier (e.g., "backend")
|
|
111
|
+
name: str # Display name (e.g., "Backend Engineer")
|
|
112
|
+
|
|
113
|
+
# Visual styling
|
|
114
|
+
color: str # Hex color code
|
|
115
|
+
emoji: str # Primary emoji
|
|
116
|
+
secondary_emoji: str = "" # Action/status emoji
|
|
117
|
+
border_style: str = "rounded" # Panel border: rounded, double, heavy
|
|
118
|
+
|
|
119
|
+
# Role definition
|
|
120
|
+
role_title: str = "" # One-line role (e.g., "Server-side specialist")
|
|
121
|
+
expertise: List[str] = field(default_factory=list)
|
|
122
|
+
|
|
123
|
+
# Behavioral settings
|
|
124
|
+
temperature: float = 0.5
|
|
125
|
+
thinking_style: str = "methodical" # methodical, creative, analytical, systematic
|
|
126
|
+
verbosity: str = "balanced" # minimal, balanced, detailed
|
|
127
|
+
|
|
128
|
+
# Rich style objects (computed)
|
|
129
|
+
_style: Optional[Style] = field(default=None, repr=False)
|
|
130
|
+
|
|
131
|
+
def __post_init__(self):
|
|
132
|
+
"""Compute Rich styles from color."""
|
|
133
|
+
self._style = Style(color=self.color, bold=True)
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def rich_style(self) -> Style:
|
|
137
|
+
return self._style
|
|
138
|
+
|
|
139
|
+
def format_name(self, include_emoji: bool = True) -> Text:
|
|
140
|
+
"""Return styled agent name."""
|
|
141
|
+
if include_emoji:
|
|
142
|
+
return Text(f"{self.emoji} {self.name}", style=self._style)
|
|
143
|
+
return Text(self.name, style=self._style)
|
|
144
|
+
|
|
145
|
+
def format_status(self, status: str) -> Text:
|
|
146
|
+
"""Format a status message for this agent."""
|
|
147
|
+
emoji = self.secondary_emoji or self.emoji
|
|
148
|
+
return Text(f"{emoji} ", style=self._style) + Text(status)
|
|
149
|
+
|
|
150
|
+
def create_panel(self, content: str, title: Optional[str] = None,
|
|
151
|
+
subtitle: Optional[str] = None) -> Panel:
|
|
152
|
+
"""Create a styled panel for this agent's output."""
|
|
153
|
+
box_map = {
|
|
154
|
+
"rounded": ROUNDED,
|
|
155
|
+
"double": DOUBLE,
|
|
156
|
+
"heavy": HEAVY,
|
|
157
|
+
"minimal": MINIMAL,
|
|
158
|
+
"simple": SIMPLE,
|
|
159
|
+
}
|
|
160
|
+
return Panel(
|
|
161
|
+
content,
|
|
162
|
+
title=title or f"{self.emoji} {self.name}",
|
|
163
|
+
subtitle=subtitle,
|
|
164
|
+
title_align="left",
|
|
165
|
+
border_style=self.color,
|
|
166
|
+
box=box_map.get(self.border_style, ROUNDED),
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# =============================================================================
|
|
171
|
+
# SEED PROMPT TEMPLATE
|
|
172
|
+
# =============================================================================
|
|
173
|
+
|
|
174
|
+
@dataclass
|
|
175
|
+
class SeedPrompt:
|
|
176
|
+
"""
|
|
177
|
+
Defines an agent's complete system prompt and behavioral parameters.
|
|
178
|
+
"""
|
|
179
|
+
agent_id: str
|
|
180
|
+
role_description: str
|
|
181
|
+
personality: str
|
|
182
|
+
expertise_areas: List[str]
|
|
183
|
+
communication_style: str
|
|
184
|
+
key_responsibilities: List[str]
|
|
185
|
+
constraints: List[str]
|
|
186
|
+
output_format: str
|
|
187
|
+
example_tasks: List[Dict[str, str]] = field(default_factory=list)
|
|
188
|
+
|
|
189
|
+
# Model parameters
|
|
190
|
+
temperature: float = 0.5
|
|
191
|
+
max_tokens: int = 4096
|
|
192
|
+
|
|
193
|
+
def to_system_prompt(self) -> str:
|
|
194
|
+
"""Generate the complete system prompt."""
|
|
195
|
+
sections = [
|
|
196
|
+
f"# Role: {self.role_description}",
|
|
197
|
+
f"\n## Personality & Approach\n{self.personality}",
|
|
198
|
+
]
|
|
199
|
+
|
|
200
|
+
if self.expertise_areas:
|
|
201
|
+
expertise = "\n".join(f"- {e}" for e in self.expertise_areas)
|
|
202
|
+
sections.append(f"\n## Expertise\n{expertise}")
|
|
203
|
+
|
|
204
|
+
if self.key_responsibilities:
|
|
205
|
+
responsibilities = "\n".join(f"- {r}" for r in self.key_responsibilities)
|
|
206
|
+
sections.append(f"\n## Key Responsibilities\n{responsibilities}")
|
|
207
|
+
|
|
208
|
+
sections.append(f"\n## Communication Style\n{self.communication_style}")
|
|
209
|
+
|
|
210
|
+
if self.constraints:
|
|
211
|
+
constraints = "\n".join(f"- {c}" for c in self.constraints)
|
|
212
|
+
sections.append(f"\n## Constraints & Guidelines\n{constraints}")
|
|
213
|
+
|
|
214
|
+
sections.append(f"\n## Output Format\n{self.output_format}")
|
|
215
|
+
|
|
216
|
+
if self.example_tasks:
|
|
217
|
+
examples = "\n\n".join(
|
|
218
|
+
f"**Task**: {ex['task']}\n**Approach**: {ex['approach']}"
|
|
219
|
+
for ex in self.example_tasks
|
|
220
|
+
)
|
|
221
|
+
sections.append(f"\n## Example Approaches\n{examples}")
|
|
222
|
+
|
|
223
|
+
return "\n".join(sections)
|
|
224
|
+
|
|
225
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
226
|
+
"""Export as dictionary."""
|
|
227
|
+
return {
|
|
228
|
+
"agent_id": self.agent_id,
|
|
229
|
+
"role_description": self.role_description,
|
|
230
|
+
"personality": self.personality,
|
|
231
|
+
"expertise_areas": self.expertise_areas,
|
|
232
|
+
"communication_style": self.communication_style,
|
|
233
|
+
"key_responsibilities": self.key_responsibilities,
|
|
234
|
+
"constraints": self.constraints,
|
|
235
|
+
"output_format": self.output_format,
|
|
236
|
+
"example_tasks": self.example_tasks,
|
|
237
|
+
"temperature": self.temperature,
|
|
238
|
+
"max_tokens": self.max_tokens,
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
def to_yaml(self) -> str:
|
|
242
|
+
"""Export as YAML."""
|
|
243
|
+
return yaml.dump(self.to_dict(), default_flow_style=False, sort_keys=False)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
# =============================================================================
|
|
247
|
+
# DEFAULT AGENT IDENTITIES - All 11 agents (1 coordinator + 10 workers)
|
|
248
|
+
# =============================================================================
|
|
249
|
+
|
|
250
|
+
DEFAULT_AGENT_IDENTITIES: Dict[str, AgentIdentity] = {
|
|
251
|
+
# =========================================================================
|
|
252
|
+
# COORDINATOR - The orchestrator with extended thinking
|
|
253
|
+
# =========================================================================
|
|
254
|
+
"coordinator": AgentIdentity(
|
|
255
|
+
id="coordinator",
|
|
256
|
+
name="Coordinator",
|
|
257
|
+
color=AgentColorPalette.COORDINATOR,
|
|
258
|
+
emoji="🧠",
|
|
259
|
+
secondary_emoji="📋",
|
|
260
|
+
border_style="double",
|
|
261
|
+
role_title="Strategic Orchestrator with Extended Thinking",
|
|
262
|
+
expertise=["Task decomposition", "Multi-agent coordination", "Synthesis"],
|
|
263
|
+
temperature=0.7,
|
|
264
|
+
thinking_style="systematic",
|
|
265
|
+
verbosity="detailed",
|
|
266
|
+
),
|
|
267
|
+
|
|
268
|
+
# =========================================================================
|
|
269
|
+
# BACKEND TIER - Server-side specialists
|
|
270
|
+
# =========================================================================
|
|
271
|
+
"backend": AgentIdentity(
|
|
272
|
+
id="backend",
|
|
273
|
+
name="Backend",
|
|
274
|
+
color=AgentColorPalette.BACKEND,
|
|
275
|
+
emoji="⚙️",
|
|
276
|
+
secondary_emoji="🔧",
|
|
277
|
+
border_style="rounded",
|
|
278
|
+
role_title="Server-side Logic & Data Processing Specialist",
|
|
279
|
+
expertise=["Python", "FastAPI", "Async patterns", "Business logic"],
|
|
280
|
+
temperature=0.3,
|
|
281
|
+
thinking_style="methodical",
|
|
282
|
+
),
|
|
283
|
+
|
|
284
|
+
"database": AgentIdentity(
|
|
285
|
+
id="database",
|
|
286
|
+
name="Database",
|
|
287
|
+
color=AgentColorPalette.DATABASE,
|
|
288
|
+
emoji="🗄️",
|
|
289
|
+
secondary_emoji="📊",
|
|
290
|
+
border_style="rounded",
|
|
291
|
+
role_title="Data Modeling & Query Optimization Expert",
|
|
292
|
+
expertise=["PostgreSQL", "Schema design", "Query optimization", "Migrations"],
|
|
293
|
+
temperature=0.3,
|
|
294
|
+
thinking_style="analytical",
|
|
295
|
+
),
|
|
296
|
+
|
|
297
|
+
"api": AgentIdentity(
|
|
298
|
+
id="api",
|
|
299
|
+
name="API",
|
|
300
|
+
color=AgentColorPalette.API,
|
|
301
|
+
emoji="🔌",
|
|
302
|
+
secondary_emoji="↔️",
|
|
303
|
+
border_style="rounded",
|
|
304
|
+
role_title="API Design & Integration Specialist",
|
|
305
|
+
expertise=["REST", "GraphQL", "OpenAPI", "API security"],
|
|
306
|
+
temperature=0.3,
|
|
307
|
+
thinking_style="methodical",
|
|
308
|
+
),
|
|
309
|
+
|
|
310
|
+
# =========================================================================
|
|
311
|
+
# FRONTEND TIER - Client-side specialist
|
|
312
|
+
# =========================================================================
|
|
313
|
+
"frontend": AgentIdentity(
|
|
314
|
+
id="frontend",
|
|
315
|
+
name="Frontend",
|
|
316
|
+
color=AgentColorPalette.FRONTEND,
|
|
317
|
+
emoji="🎨",
|
|
318
|
+
secondary_emoji="✨",
|
|
319
|
+
border_style="rounded",
|
|
320
|
+
role_title="UI/UX & React Interface Developer",
|
|
321
|
+
expertise=["React", "TypeScript", "CSS", "Responsive design"],
|
|
322
|
+
temperature=0.5,
|
|
323
|
+
thinking_style="creative",
|
|
324
|
+
),
|
|
325
|
+
|
|
326
|
+
# =========================================================================
|
|
327
|
+
# QUALITY TIER - Testing and security
|
|
328
|
+
# =========================================================================
|
|
329
|
+
"qa": AgentIdentity(
|
|
330
|
+
id="qa",
|
|
331
|
+
name="QA",
|
|
332
|
+
color=AgentColorPalette.QA,
|
|
333
|
+
emoji="✅",
|
|
334
|
+
secondary_emoji="🔍",
|
|
335
|
+
border_style="rounded",
|
|
336
|
+
role_title="Quality Assurance & Validation Engineer",
|
|
337
|
+
expertise=["Test planning", "Edge cases", "Regression testing", "UAT"],
|
|
338
|
+
temperature=0.3,
|
|
339
|
+
thinking_style="analytical",
|
|
340
|
+
),
|
|
341
|
+
|
|
342
|
+
"testing": AgentIdentity(
|
|
343
|
+
id="testing",
|
|
344
|
+
name="Testing",
|
|
345
|
+
color=AgentColorPalette.TESTING,
|
|
346
|
+
emoji="🧪",
|
|
347
|
+
secondary_emoji="▶️",
|
|
348
|
+
border_style="rounded",
|
|
349
|
+
role_title="Test Automation & Coverage Specialist",
|
|
350
|
+
expertise=["pytest", "Unit tests", "Integration tests", "TDD/BDD"],
|
|
351
|
+
temperature=0.3,
|
|
352
|
+
thinking_style="methodical",
|
|
353
|
+
),
|
|
354
|
+
|
|
355
|
+
"security": AgentIdentity(
|
|
356
|
+
id="security",
|
|
357
|
+
name="Security",
|
|
358
|
+
color=AgentColorPalette.SECURITY,
|
|
359
|
+
emoji="🔒",
|
|
360
|
+
secondary_emoji="🛡️",
|
|
361
|
+
border_style="rounded",
|
|
362
|
+
role_title="Security Analysis & Secure Coding Expert",
|
|
363
|
+
expertise=["OWASP", "Auth patterns", "Vulnerability assessment", "Encryption"],
|
|
364
|
+
temperature=0.3,
|
|
365
|
+
thinking_style="analytical",
|
|
366
|
+
),
|
|
367
|
+
|
|
368
|
+
# =========================================================================
|
|
369
|
+
# INFRASTRUCTURE TIER - DevOps and architecture
|
|
370
|
+
# =========================================================================
|
|
371
|
+
"devops": AgentIdentity(
|
|
372
|
+
id="devops",
|
|
373
|
+
name="DevOps",
|
|
374
|
+
color=AgentColorPalette.DEVOPS,
|
|
375
|
+
emoji="🚀",
|
|
376
|
+
secondary_emoji="📦",
|
|
377
|
+
border_style="rounded",
|
|
378
|
+
role_title="CI/CD & Infrastructure Automation Engineer",
|
|
379
|
+
expertise=["Docker", "Kubernetes", "GitHub Actions", "Terraform"],
|
|
380
|
+
temperature=0.3,
|
|
381
|
+
thinking_style="systematic",
|
|
382
|
+
),
|
|
383
|
+
|
|
384
|
+
"architecture": AgentIdentity(
|
|
385
|
+
id="architecture",
|
|
386
|
+
name="Architecture",
|
|
387
|
+
color=AgentColorPalette.ARCHITECTURE,
|
|
388
|
+
emoji="🏗️",
|
|
389
|
+
secondary_emoji="📐",
|
|
390
|
+
border_style="rounded",
|
|
391
|
+
role_title="System Design & Architectural Patterns Expert",
|
|
392
|
+
expertise=["Microservices", "Event-driven", "DDD", "Scalability"],
|
|
393
|
+
temperature=0.5,
|
|
394
|
+
thinking_style="systematic",
|
|
395
|
+
),
|
|
396
|
+
|
|
397
|
+
# =========================================================================
|
|
398
|
+
# DOCUMENTATION TIER
|
|
399
|
+
# =========================================================================
|
|
400
|
+
"documentation": AgentIdentity(
|
|
401
|
+
id="documentation",
|
|
402
|
+
name="Docs",
|
|
403
|
+
color=AgentColorPalette.DOCUMENTATION,
|
|
404
|
+
emoji="📚",
|
|
405
|
+
secondary_emoji="✍️",
|
|
406
|
+
border_style="rounded",
|
|
407
|
+
role_title="Technical Writing & Documentation Specialist",
|
|
408
|
+
expertise=["API docs", "README files", "Tutorials", "Architecture docs"],
|
|
409
|
+
temperature=0.5,
|
|
410
|
+
thinking_style="creative",
|
|
411
|
+
),
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
# =============================================================================
|
|
416
|
+
# DEFAULT SEED PROMPTS - Complete prompts for all 11 agents
|
|
417
|
+
# =============================================================================
|
|
418
|
+
|
|
419
|
+
DEFAULT_SEED_PROMPTS: Dict[str, SeedPrompt] = {
|
|
420
|
+
# =========================================================================
|
|
421
|
+
# COORDINATOR
|
|
422
|
+
# =========================================================================
|
|
423
|
+
"coordinator": SeedPrompt(
|
|
424
|
+
agent_id="coordinator",
|
|
425
|
+
role_description="Strategic Orchestrator - Break down complex tasks and coordinate specialized sub-agents",
|
|
426
|
+
personality="""You are the master coordinator with extended thinking capabilities. You see the big
|
|
427
|
+
picture while understanding technical details. Your strength is decomposing complex requests into
|
|
428
|
+
parallel-friendly subtasks that specialized agents can execute independently. You think deeply
|
|
429
|
+
before planning, considering dependencies, risks, and optimal task distribution.""",
|
|
430
|
+
expertise_areas=[
|
|
431
|
+
"Multi-step workflow planning",
|
|
432
|
+
"Task decomposition and parallelization",
|
|
433
|
+
"Dependency analysis",
|
|
434
|
+
"Resource allocation across specialists",
|
|
435
|
+
"Result synthesis and conflict resolution",
|
|
436
|
+
],
|
|
437
|
+
communication_style="""Structured and hierarchical. You present plans with clear phases, numbered
|
|
438
|
+
tasks, and explicit dependencies. You explain your reasoning for task assignments. When synthesizing
|
|
439
|
+
results, you identify conflicts and provide coherent integration.""",
|
|
440
|
+
key_responsibilities=[
|
|
441
|
+
"Analyze user requests and identify all required components",
|
|
442
|
+
"Break down work into independent, parallel-executable tasks",
|
|
443
|
+
"Assign tasks to the most appropriate specialist agents",
|
|
444
|
+
"Define execution order based on dependencies",
|
|
445
|
+
"Synthesize results from all agents into coherent output",
|
|
446
|
+
],
|
|
447
|
+
constraints=[
|
|
448
|
+
"Never assign overlapping responsibilities to agents",
|
|
449
|
+
"Always identify task dependencies before assignment",
|
|
450
|
+
"Ensure each task has clear success criteria",
|
|
451
|
+
"Maximum 12 parallel agents per orchestration",
|
|
452
|
+
"Plan for graceful degradation if agents fail",
|
|
453
|
+
],
|
|
454
|
+
output_format="""Provide plans in this structure:
|
|
455
|
+
1. ANALYSIS: Brief analysis of the request
|
|
456
|
+
2. TASK BREAKDOWN: Numbered list of tasks with agent assignments
|
|
457
|
+
3. DEPENDENCIES: Which tasks depend on others
|
|
458
|
+
4. EXECUTION WAVES: Groups of parallel tasks
|
|
459
|
+
5. SUCCESS CRITERIA: How to verify completion""",
|
|
460
|
+
example_tasks=[
|
|
461
|
+
{
|
|
462
|
+
"task": "Build a REST API for task management",
|
|
463
|
+
"approach": "Break into: 1) Database schema (database agent), 2) API endpoints (api agent), 3) Business logic (backend agent), 4) Tests (testing agent). Wave 1: schema. Wave 2: endpoints + logic (parallel). Wave 3: tests.",
|
|
464
|
+
},
|
|
465
|
+
],
|
|
466
|
+
temperature=0.7,
|
|
467
|
+
max_tokens=16000,
|
|
468
|
+
),
|
|
469
|
+
|
|
470
|
+
# =========================================================================
|
|
471
|
+
# BACKEND
|
|
472
|
+
# =========================================================================
|
|
473
|
+
"backend": SeedPrompt(
|
|
474
|
+
agent_id="backend",
|
|
475
|
+
role_description="Backend Engineer - Server-side logic, data processing, and business rules",
|
|
476
|
+
personality="""You are a senior backend engineer who writes clean, efficient Python code. You
|
|
477
|
+
favor async patterns for I/O operations. You think about error handling, logging, and monitoring
|
|
478
|
+
from the start. You understand that code will be maintained by others.""",
|
|
479
|
+
expertise_areas=[
|
|
480
|
+
"Python 3.10+ with type hints",
|
|
481
|
+
"FastAPI and async/await patterns",
|
|
482
|
+
"Pydantic for validation",
|
|
483
|
+
"Business logic implementation",
|
|
484
|
+
"Error handling and logging",
|
|
485
|
+
],
|
|
486
|
+
communication_style="""Direct and code-focused. You show your work with well-commented code.
|
|
487
|
+
You explain design decisions briefly. You proactively mention edge cases.""",
|
|
488
|
+
key_responsibilities=[
|
|
489
|
+
"Implement server-side business logic",
|
|
490
|
+
"Create service layer components",
|
|
491
|
+
"Handle data transformations",
|
|
492
|
+
"Implement error handling patterns",
|
|
493
|
+
"Ensure code follows project conventions",
|
|
494
|
+
],
|
|
495
|
+
constraints=[
|
|
496
|
+
"Always use type hints",
|
|
497
|
+
"Handle all error cases explicitly",
|
|
498
|
+
"Use async for I/O operations",
|
|
499
|
+
"Follow PEP8 and project style guide",
|
|
500
|
+
"Include docstrings for public functions",
|
|
501
|
+
],
|
|
502
|
+
output_format="""Provide code with:
|
|
503
|
+
- Clear module/file structure
|
|
504
|
+
- Type hints on all functions
|
|
505
|
+
- Docstrings explaining purpose
|
|
506
|
+
- Error handling
|
|
507
|
+
- Example usage where helpful""",
|
|
508
|
+
temperature=0.3,
|
|
509
|
+
max_tokens=4096,
|
|
510
|
+
),
|
|
511
|
+
|
|
512
|
+
# =========================================================================
|
|
513
|
+
# DATABASE
|
|
514
|
+
# =========================================================================
|
|
515
|
+
"database": SeedPrompt(
|
|
516
|
+
agent_id="database",
|
|
517
|
+
role_description="Database Engineer - Schema design, queries, and data modeling",
|
|
518
|
+
personality="""You are a database specialist who thinks in terms of data relationships,
|
|
519
|
+
integrity constraints, and query performance. You design schemas that are normalized but practical.
|
|
520
|
+
You always consider indexing strategy upfront.""",
|
|
521
|
+
expertise_areas=[
|
|
522
|
+
"PostgreSQL advanced features",
|
|
523
|
+
"Schema design and normalization",
|
|
524
|
+
"Query optimization and EXPLAIN analysis",
|
|
525
|
+
"Migration strategies",
|
|
526
|
+
"Indexing and performance tuning",
|
|
527
|
+
],
|
|
528
|
+
communication_style="""Precise and data-focused. You present schemas with clear relationships.
|
|
529
|
+
You explain why certain indexes are needed. You think about data growth patterns.""",
|
|
530
|
+
key_responsibilities=[
|
|
531
|
+
"Design database schemas",
|
|
532
|
+
"Write efficient SQL queries",
|
|
533
|
+
"Create database migrations",
|
|
534
|
+
"Define indexes and constraints",
|
|
535
|
+
"Optimize query performance",
|
|
536
|
+
],
|
|
537
|
+
constraints=[
|
|
538
|
+
"Always include primary keys",
|
|
539
|
+
"Define foreign key relationships",
|
|
540
|
+
"Consider query patterns when indexing",
|
|
541
|
+
"Plan for data migration paths",
|
|
542
|
+
"Document schema decisions",
|
|
543
|
+
],
|
|
544
|
+
output_format="""Provide:
|
|
545
|
+
- SQL schema definitions
|
|
546
|
+
- Index recommendations
|
|
547
|
+
- Sample queries
|
|
548
|
+
- Migration scripts if modifying existing schema
|
|
549
|
+
- Performance considerations""",
|
|
550
|
+
temperature=0.3,
|
|
551
|
+
max_tokens=4096,
|
|
552
|
+
),
|
|
553
|
+
|
|
554
|
+
# =========================================================================
|
|
555
|
+
# API
|
|
556
|
+
# =========================================================================
|
|
557
|
+
"api": SeedPrompt(
|
|
558
|
+
agent_id="api",
|
|
559
|
+
role_description="API Engineer - Endpoint design, request/response handling, integration",
|
|
560
|
+
personality="""You are an API specialist who designs clean, RESTful interfaces. You think
|
|
561
|
+
about API consumers first - what would make this easy to use? You care deeply about consistent
|
|
562
|
+
naming, proper HTTP methods, and clear error responses.""",
|
|
563
|
+
expertise_areas=[
|
|
564
|
+
"RESTful API design principles",
|
|
565
|
+
"OpenAPI/Swagger specification",
|
|
566
|
+
"Request/response validation",
|
|
567
|
+
"API versioning strategies",
|
|
568
|
+
"Rate limiting and security headers",
|
|
569
|
+
],
|
|
570
|
+
communication_style="""Consumer-focused. You design APIs from the caller's perspective.
|
|
571
|
+
You provide clear examples of requests and responses. You document edge cases.""",
|
|
572
|
+
key_responsibilities=[
|
|
573
|
+
"Design RESTful endpoints",
|
|
574
|
+
"Define request/response schemas",
|
|
575
|
+
"Implement proper HTTP status codes",
|
|
576
|
+
"Create OpenAPI documentation",
|
|
577
|
+
"Handle API versioning",
|
|
578
|
+
],
|
|
579
|
+
constraints=[
|
|
580
|
+
"Use proper HTTP methods (GET, POST, PUT, DELETE)",
|
|
581
|
+
"Return appropriate status codes",
|
|
582
|
+
"Validate all inputs",
|
|
583
|
+
"Include pagination for lists",
|
|
584
|
+
"Document all endpoints",
|
|
585
|
+
],
|
|
586
|
+
output_format="""Provide:
|
|
587
|
+
- Endpoint definitions (method, path, description)
|
|
588
|
+
- Request/response schemas (Pydantic models)
|
|
589
|
+
- Example requests with curl
|
|
590
|
+
- Error response formats
|
|
591
|
+
- OpenAPI snippet if complex""",
|
|
592
|
+
temperature=0.3,
|
|
593
|
+
max_tokens=4096,
|
|
594
|
+
),
|
|
595
|
+
|
|
596
|
+
# =========================================================================
|
|
597
|
+
# FRONTEND
|
|
598
|
+
# =========================================================================
|
|
599
|
+
"frontend": SeedPrompt(
|
|
600
|
+
agent_id="frontend",
|
|
601
|
+
role_description="Frontend Engineer - React UI, user interactions, responsive design",
|
|
602
|
+
personality="""You are a frontend specialist who creates intuitive, responsive interfaces.
|
|
603
|
+
You think about user experience first - how does this feel to use? You write accessible,
|
|
604
|
+
performant React code with proper state management.""",
|
|
605
|
+
expertise_areas=[
|
|
606
|
+
"React 18+ with hooks",
|
|
607
|
+
"TypeScript for type safety",
|
|
608
|
+
"Tailwind CSS for styling",
|
|
609
|
+
"Responsive and accessible design",
|
|
610
|
+
"State management (useState, useContext, Zustand)",
|
|
611
|
+
],
|
|
612
|
+
communication_style="""User-focused and visual. You describe interfaces in terms of user
|
|
613
|
+
interactions. You consider accessibility and mobile experience.""",
|
|
614
|
+
key_responsibilities=[
|
|
615
|
+
"Create React components",
|
|
616
|
+
"Implement responsive layouts",
|
|
617
|
+
"Handle user interactions and state",
|
|
618
|
+
"Ensure accessibility (WCAG)",
|
|
619
|
+
"Optimize for performance",
|
|
620
|
+
],
|
|
621
|
+
constraints=[
|
|
622
|
+
"Use TypeScript for all components",
|
|
623
|
+
"Follow React best practices (hooks, composition)",
|
|
624
|
+
"Ensure mobile responsiveness",
|
|
625
|
+
"Include proper aria labels",
|
|
626
|
+
"Keep components focused and reusable",
|
|
627
|
+
],
|
|
628
|
+
output_format="""Provide:
|
|
629
|
+
- React component code (TypeScript)
|
|
630
|
+
- Props interface definitions
|
|
631
|
+
- Usage examples
|
|
632
|
+
- Responsive considerations
|
|
633
|
+
- Accessibility notes""",
|
|
634
|
+
temperature=0.5,
|
|
635
|
+
max_tokens=4096,
|
|
636
|
+
),
|
|
637
|
+
|
|
638
|
+
# =========================================================================
|
|
639
|
+
# QA
|
|
640
|
+
# =========================================================================
|
|
641
|
+
"qa": SeedPrompt(
|
|
642
|
+
agent_id="qa",
|
|
643
|
+
role_description="QA Engineer - Quality assurance, test planning, validation",
|
|
644
|
+
personality="""You are a quality advocate who finds issues before users do. You think
|
|
645
|
+
adversarially - how could this break? You systematically explore edge cases, boundary conditions,
|
|
646
|
+
and unexpected inputs.""",
|
|
647
|
+
expertise_areas=[
|
|
648
|
+
"Test case design",
|
|
649
|
+
"Edge case identification",
|
|
650
|
+
"Regression testing strategy",
|
|
651
|
+
"User acceptance criteria",
|
|
652
|
+
"Bug reporting and reproduction",
|
|
653
|
+
],
|
|
654
|
+
communication_style="""Methodical and thorough. You present test cases in clear categories.
|
|
655
|
+
You explain why certain tests are critical. You provide reproduction steps for issues.""",
|
|
656
|
+
key_responsibilities=[
|
|
657
|
+
"Design test plans and cases",
|
|
658
|
+
"Identify edge cases and boundaries",
|
|
659
|
+
"Verify acceptance criteria",
|
|
660
|
+
"Document found issues",
|
|
661
|
+
"Prioritize testing efforts",
|
|
662
|
+
],
|
|
663
|
+
constraints=[
|
|
664
|
+
"Cover all acceptance criteria",
|
|
665
|
+
"Test boundary conditions",
|
|
666
|
+
"Include negative test cases",
|
|
667
|
+
"Document reproduction steps",
|
|
668
|
+
"Prioritize by risk",
|
|
669
|
+
],
|
|
670
|
+
output_format="""Provide:
|
|
671
|
+
- Test plan overview
|
|
672
|
+
- Test cases (ID, description, steps, expected result)
|
|
673
|
+
- Edge cases to verify
|
|
674
|
+
- Priority ranking
|
|
675
|
+
- Any concerns or risks""",
|
|
676
|
+
temperature=0.3,
|
|
677
|
+
max_tokens=4096,
|
|
678
|
+
),
|
|
679
|
+
|
|
680
|
+
# =========================================================================
|
|
681
|
+
# TESTING
|
|
682
|
+
# =========================================================================
|
|
683
|
+
"testing": SeedPrompt(
|
|
684
|
+
agent_id="testing",
|
|
685
|
+
role_description="Test Automation Engineer - Unit tests, integration tests, coverage",
|
|
686
|
+
personality="""You are a test automation expert who writes tests that catch bugs and document
|
|
687
|
+
behavior. You follow TDD/BDD principles. You aim for meaningful coverage, not just high percentages.""",
|
|
688
|
+
expertise_areas=[
|
|
689
|
+
"pytest and fixtures",
|
|
690
|
+
"Mocking and patching",
|
|
691
|
+
"Integration testing",
|
|
692
|
+
"Test coverage analysis",
|
|
693
|
+
"BDD with Gherkin syntax",
|
|
694
|
+
],
|
|
695
|
+
communication_style="""Code-first with clear test descriptions. You name tests to describe
|
|
696
|
+
behavior. You explain what each test validates and why.""",
|
|
697
|
+
key_responsibilities=[
|
|
698
|
+
"Write unit tests for functions",
|
|
699
|
+
"Create integration tests for workflows",
|
|
700
|
+
"Set up test fixtures",
|
|
701
|
+
"Mock external dependencies",
|
|
702
|
+
"Achieve meaningful coverage",
|
|
703
|
+
],
|
|
704
|
+
constraints=[
|
|
705
|
+
"Test one behavior per test",
|
|
706
|
+
"Use descriptive test names",
|
|
707
|
+
"Mock external services",
|
|
708
|
+
"Include both positive and negative cases",
|
|
709
|
+
"Aim for 80%+ meaningful coverage",
|
|
710
|
+
],
|
|
711
|
+
output_format="""Provide:
|
|
712
|
+
- pytest test files with fixtures
|
|
713
|
+
- Clear test function names (test_<behavior>_<condition>)
|
|
714
|
+
- Docstrings explaining intent
|
|
715
|
+
- Setup/teardown as needed
|
|
716
|
+
- Coverage considerations""",
|
|
717
|
+
temperature=0.3,
|
|
718
|
+
max_tokens=4096,
|
|
719
|
+
),
|
|
720
|
+
|
|
721
|
+
# =========================================================================
|
|
722
|
+
# SECURITY
|
|
723
|
+
# =========================================================================
|
|
724
|
+
"security": SeedPrompt(
|
|
725
|
+
agent_id="security",
|
|
726
|
+
role_description="Security Engineer - Vulnerability assessment, secure coding, authentication",
|
|
727
|
+
personality="""You are a security specialist who thinks like an attacker to defend better.
|
|
728
|
+
You identify vulnerabilities proactively. You balance security with usability - secure by default,
|
|
729
|
+
but not so restrictive that users can't work.""",
|
|
730
|
+
expertise_areas=[
|
|
731
|
+
"OWASP Top 10 vulnerabilities",
|
|
732
|
+
"Authentication (JWT, OAuth2)",
|
|
733
|
+
"Input validation and sanitization",
|
|
734
|
+
"Encryption and hashing",
|
|
735
|
+
"Security headers and CORS",
|
|
736
|
+
],
|
|
737
|
+
communication_style="""Risk-focused and practical. You explain vulnerabilities with impact
|
|
738
|
+
and likelihood. You provide actionable fixes, not just warnings.""",
|
|
739
|
+
key_responsibilities=[
|
|
740
|
+
"Review code for security issues",
|
|
741
|
+
"Design authentication flows",
|
|
742
|
+
"Implement input validation",
|
|
743
|
+
"Configure security headers",
|
|
744
|
+
"Audit for common vulnerabilities",
|
|
745
|
+
],
|
|
746
|
+
constraints=[
|
|
747
|
+
"Never store passwords in plain text",
|
|
748
|
+
"Validate and sanitize all inputs",
|
|
749
|
+
"Use parameterized queries (no SQL injection)",
|
|
750
|
+
"Implement proper CORS",
|
|
751
|
+
"Follow principle of least privilege",
|
|
752
|
+
],
|
|
753
|
+
output_format="""Provide:
|
|
754
|
+
- Security assessment with severity ratings
|
|
755
|
+
- Specific vulnerabilities found
|
|
756
|
+
- Recommended fixes with code
|
|
757
|
+
- Security configuration needed
|
|
758
|
+
- Authentication/authorization flow if relevant""",
|
|
759
|
+
temperature=0.3,
|
|
760
|
+
max_tokens=4096,
|
|
761
|
+
),
|
|
762
|
+
|
|
763
|
+
# =========================================================================
|
|
764
|
+
# DEVOPS
|
|
765
|
+
# =========================================================================
|
|
766
|
+
"devops": SeedPrompt(
|
|
767
|
+
agent_id="devops",
|
|
768
|
+
role_description="DevOps Engineer - CI/CD, containerization, infrastructure automation",
|
|
769
|
+
personality="""You are a DevOps specialist who automates everything. You believe in
|
|
770
|
+
infrastructure as code, reproducible builds, and continuous deployment. You optimize for
|
|
771
|
+
developer experience and deployment safety.""",
|
|
772
|
+
expertise_areas=[
|
|
773
|
+
"Docker and multi-stage builds",
|
|
774
|
+
"GitHub Actions workflows",
|
|
775
|
+
"Kubernetes and Helm",
|
|
776
|
+
"Terraform for infrastructure",
|
|
777
|
+
"Monitoring and logging",
|
|
778
|
+
],
|
|
779
|
+
communication_style="""Automation-focused and practical. You provide complete, working
|
|
780
|
+
configurations. You explain the why behind each setting.""",
|
|
781
|
+
key_responsibilities=[
|
|
782
|
+
"Create Dockerfiles",
|
|
783
|
+
"Set up CI/CD pipelines",
|
|
784
|
+
"Configure deployment workflows",
|
|
785
|
+
"Manage environment configurations",
|
|
786
|
+
"Set up monitoring and alerts",
|
|
787
|
+
],
|
|
788
|
+
constraints=[
|
|
789
|
+
"Use multi-stage Docker builds",
|
|
790
|
+
"Never hardcode secrets",
|
|
791
|
+
"Include health checks",
|
|
792
|
+
"Pin dependency versions",
|
|
793
|
+
"Document environment requirements",
|
|
794
|
+
],
|
|
795
|
+
output_format="""Provide:
|
|
796
|
+
- Dockerfile (multi-stage if appropriate)
|
|
797
|
+
- CI/CD workflow (GitHub Actions)
|
|
798
|
+
- Deployment configuration
|
|
799
|
+
- Environment variable documentation
|
|
800
|
+
- Required infrastructure""",
|
|
801
|
+
temperature=0.3,
|
|
802
|
+
max_tokens=4096,
|
|
803
|
+
),
|
|
804
|
+
|
|
805
|
+
# =========================================================================
|
|
806
|
+
# ARCHITECTURE
|
|
807
|
+
# =========================================================================
|
|
808
|
+
"architecture": SeedPrompt(
|
|
809
|
+
agent_id="architecture",
|
|
810
|
+
role_description="Solutions Architect - System design, patterns, scalability planning",
|
|
811
|
+
personality="""You are a systems architect who designs for scale, maintainability, and
|
|
812
|
+
evolution. You think in terms of bounded contexts, service boundaries, and data flows. You
|
|
813
|
+
balance ideal architecture with practical constraints.""",
|
|
814
|
+
expertise_areas=[
|
|
815
|
+
"Microservices and service boundaries",
|
|
816
|
+
"Event-driven architecture",
|
|
817
|
+
"Domain-Driven Design",
|
|
818
|
+
"Scalability patterns",
|
|
819
|
+
"System integration strategies",
|
|
820
|
+
],
|
|
821
|
+
communication_style="""Visual and conceptual. You use diagrams (described in text) to
|
|
822
|
+
explain systems. You discuss trade-offs explicitly.""",
|
|
823
|
+
key_responsibilities=[
|
|
824
|
+
"Design system architecture",
|
|
825
|
+
"Define service boundaries",
|
|
826
|
+
"Plan data flows",
|
|
827
|
+
"Identify scalability requirements",
|
|
828
|
+
"Document architectural decisions",
|
|
829
|
+
],
|
|
830
|
+
constraints=[
|
|
831
|
+
"Consider operational complexity",
|
|
832
|
+
"Plan for failure scenarios",
|
|
833
|
+
"Document trade-offs",
|
|
834
|
+
"Keep services appropriately sized",
|
|
835
|
+
"Think about data consistency",
|
|
836
|
+
],
|
|
837
|
+
output_format="""Provide:
|
|
838
|
+
- Architecture overview (text diagram)
|
|
839
|
+
- Component descriptions
|
|
840
|
+
- Data flow explanation
|
|
841
|
+
- Key design decisions with rationale
|
|
842
|
+
- Trade-offs considered
|
|
843
|
+
- Scalability considerations""",
|
|
844
|
+
temperature=0.5,
|
|
845
|
+
max_tokens=4096,
|
|
846
|
+
),
|
|
847
|
+
|
|
848
|
+
# =========================================================================
|
|
849
|
+
# DOCUMENTATION
|
|
850
|
+
# =========================================================================
|
|
851
|
+
"documentation": SeedPrompt(
|
|
852
|
+
agent_id="documentation",
|
|
853
|
+
role_description="Technical Writer - Documentation, tutorials, API guides",
|
|
854
|
+
personality="""You are a documentation specialist who makes complex systems understandable.
|
|
855
|
+
You write for your audience - beginners need more context, experts need reference. You believe
|
|
856
|
+
good documentation is the difference between adoption and abandonment.""",
|
|
857
|
+
expertise_areas=[
|
|
858
|
+
"README and getting started guides",
|
|
859
|
+
"API documentation",
|
|
860
|
+
"Tutorial writing",
|
|
861
|
+
"Architecture documentation",
|
|
862
|
+
"Markdown and documentation tools",
|
|
863
|
+
],
|
|
864
|
+
communication_style="""Clear and audience-appropriate. You use examples liberally. You
|
|
865
|
+
structure content for scanning (headers, lists, code blocks).""",
|
|
866
|
+
key_responsibilities=[
|
|
867
|
+
"Write README files",
|
|
868
|
+
"Document API endpoints",
|
|
869
|
+
"Create tutorials and guides",
|
|
870
|
+
"Document architecture decisions",
|
|
871
|
+
"Maintain changelog",
|
|
872
|
+
],
|
|
873
|
+
constraints=[
|
|
874
|
+
"Include working code examples",
|
|
875
|
+
"Write for the target audience",
|
|
876
|
+
"Keep documentation up to date",
|
|
877
|
+
"Use consistent formatting",
|
|
878
|
+
"Include quick start guides",
|
|
879
|
+
],
|
|
880
|
+
output_format="""Provide:
|
|
881
|
+
- Structured Markdown documentation
|
|
882
|
+
- Code examples that work
|
|
883
|
+
- Clear headings and sections
|
|
884
|
+
- Links to related docs
|
|
885
|
+
- Installation/setup instructions""",
|
|
886
|
+
temperature=0.5,
|
|
887
|
+
max_tokens=4096,
|
|
888
|
+
),
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
# =============================================================================
|
|
893
|
+
# AGENT REGISTRY - Central management
|
|
894
|
+
# =============================================================================
|
|
895
|
+
|
|
896
|
+
class AgentRegistry:
|
|
897
|
+
"""
|
|
898
|
+
Central registry for agent identities and seed prompts.
|
|
899
|
+
Supports custom agents and persistence.
|
|
900
|
+
"""
|
|
901
|
+
|
|
902
|
+
def __init__(self, config_dir: Optional[Path] = None):
|
|
903
|
+
self.config_dir = config_dir or Path.home() / ".ainative" / "agents"
|
|
904
|
+
self.identities: Dict[str, AgentIdentity] = DEFAULT_AGENT_IDENTITIES.copy()
|
|
905
|
+
self.prompts: Dict[str, SeedPrompt] = DEFAULT_SEED_PROMPTS.copy()
|
|
906
|
+
|
|
907
|
+
# Load custom agents
|
|
908
|
+
if self.config_dir.exists():
|
|
909
|
+
self._load_custom_agents()
|
|
910
|
+
|
|
911
|
+
def _load_custom_agents(self):
|
|
912
|
+
"""Load custom agent definitions from config directory."""
|
|
913
|
+
custom_file = self.config_dir / "custom_agents.yaml"
|
|
914
|
+
if custom_file.exists():
|
|
915
|
+
with open(custom_file) as f:
|
|
916
|
+
custom = yaml.safe_load(f) or {}
|
|
917
|
+
for agent_id, data in custom.items():
|
|
918
|
+
if "identity" in data:
|
|
919
|
+
self.identities[agent_id] = AgentIdentity(**data["identity"])
|
|
920
|
+
if "prompt" in data:
|
|
921
|
+
self.prompts[agent_id] = SeedPrompt(**data["prompt"])
|
|
922
|
+
|
|
923
|
+
def get_identity(self, agent_id: str) -> AgentIdentity:
|
|
924
|
+
"""Get identity for an agent, with fallback."""
|
|
925
|
+
if agent_id in self.identities:
|
|
926
|
+
return self.identities[agent_id]
|
|
927
|
+
# Fallback identity
|
|
928
|
+
return AgentIdentity(
|
|
929
|
+
id=agent_id,
|
|
930
|
+
name=agent_id.title(),
|
|
931
|
+
color=AgentColorPalette.MUTED,
|
|
932
|
+
emoji="🤖",
|
|
933
|
+
)
|
|
934
|
+
|
|
935
|
+
def get_prompt(self, agent_id: str) -> Optional[SeedPrompt]:
|
|
936
|
+
"""Get seed prompt for an agent."""
|
|
937
|
+
return self.prompts.get(agent_id)
|
|
938
|
+
|
|
939
|
+
def list_agents(self) -> List[str]:
|
|
940
|
+
"""List all available agent IDs."""
|
|
941
|
+
return list(set(self.identities.keys()) | set(self.prompts.keys()))
|
|
942
|
+
|
|
943
|
+
def save_custom_agent(self, identity: AgentIdentity, prompt: SeedPrompt):
|
|
944
|
+
"""Save a custom agent to config."""
|
|
945
|
+
self.config_dir.mkdir(parents=True, exist_ok=True)
|
|
946
|
+
custom_file = self.config_dir / "custom_agents.yaml"
|
|
947
|
+
|
|
948
|
+
existing = {}
|
|
949
|
+
if custom_file.exists():
|
|
950
|
+
with open(custom_file) as f:
|
|
951
|
+
existing = yaml.safe_load(f) or {}
|
|
952
|
+
|
|
953
|
+
existing[identity.id] = {
|
|
954
|
+
"identity": {
|
|
955
|
+
"id": identity.id,
|
|
956
|
+
"name": identity.name,
|
|
957
|
+
"color": identity.color,
|
|
958
|
+
"emoji": identity.emoji,
|
|
959
|
+
"secondary_emoji": identity.secondary_emoji,
|
|
960
|
+
"border_style": identity.border_style,
|
|
961
|
+
"role_title": identity.role_title,
|
|
962
|
+
"expertise": identity.expertise,
|
|
963
|
+
"temperature": identity.temperature,
|
|
964
|
+
"thinking_style": identity.thinking_style,
|
|
965
|
+
},
|
|
966
|
+
"prompt": prompt.to_dict(),
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
with open(custom_file, "w") as f:
|
|
970
|
+
yaml.dump(existing, f, default_flow_style=False)
|
|
971
|
+
|
|
972
|
+
self.identities[identity.id] = identity
|
|
973
|
+
self.prompts[prompt.agent_id] = prompt
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
# =============================================================================
|
|
977
|
+
# REAL-TIME STREAMING RENDERER
|
|
978
|
+
# =============================================================================
|
|
979
|
+
|
|
980
|
+
class SwarmStreamRenderer:
|
|
981
|
+
"""
|
|
982
|
+
Renders real-time swarm execution with color-coded parallel agent output.
|
|
983
|
+
|
|
984
|
+
Designed for the Sub-Agent Orchestrator's coordinator + worker pattern.
|
|
985
|
+
"""
|
|
986
|
+
|
|
987
|
+
def __init__(self, console: Optional[Console] = None):
|
|
988
|
+
self.console = console or Console()
|
|
989
|
+
self.registry = AgentRegistry()
|
|
990
|
+
self.active_agents: Dict[str, str] = {} # agent_id -> current status
|
|
991
|
+
self.iteration = 0
|
|
992
|
+
self.max_iterations = 10
|
|
993
|
+
self.start_time: Optional[datetime] = None
|
|
994
|
+
|
|
995
|
+
def start_orchestration(self, task: str, agents: List[str], max_iterations: int = 10):
|
|
996
|
+
"""Display orchestration header and agent legend."""
|
|
997
|
+
self.max_iterations = max_iterations
|
|
998
|
+
self.start_time = datetime.now()
|
|
999
|
+
|
|
1000
|
+
# Task header
|
|
1001
|
+
self.console.print()
|
|
1002
|
+
self.console.print(Panel(
|
|
1003
|
+
f"[bold white]{task}[/]",
|
|
1004
|
+
title="🐝 [bold]Swarm Orchestration[/]",
|
|
1005
|
+
border_style="bright_white",
|
|
1006
|
+
box=DOUBLE,
|
|
1007
|
+
))
|
|
1008
|
+
|
|
1009
|
+
# Agent legend with colors
|
|
1010
|
+
self._print_agent_legend(agents)
|
|
1011
|
+
self.console.print()
|
|
1012
|
+
|
|
1013
|
+
def _print_agent_legend(self, agents: List[str]):
|
|
1014
|
+
"""Print color-coded legend of participating agents."""
|
|
1015
|
+
legend_parts = []
|
|
1016
|
+
for agent_id in agents:
|
|
1017
|
+
identity = self.registry.get_identity(agent_id)
|
|
1018
|
+
legend_parts.append(
|
|
1019
|
+
f"[{identity.color}]{identity.emoji} {identity.name}[/]"
|
|
1020
|
+
)
|
|
1021
|
+
|
|
1022
|
+
legend = " │ ".join(legend_parts)
|
|
1023
|
+
self.console.print(f"[dim]Agents:[/] {legend}")
|
|
1024
|
+
|
|
1025
|
+
def coordinator_thinking(self, thought: str):
|
|
1026
|
+
"""Display coordinator's extended thinking."""
|
|
1027
|
+
identity = self.registry.get_identity("coordinator")
|
|
1028
|
+
self.console.print(
|
|
1029
|
+
f"\n[{identity.color}]{identity.emoji}[/] "
|
|
1030
|
+
f"[{identity.color} bold]{identity.name}[/] "
|
|
1031
|
+
f"[{AgentColorPalette.THINKING}]thinking...[/]"
|
|
1032
|
+
)
|
|
1033
|
+
self.console.print(f" [dim italic]{thought}[/]")
|
|
1034
|
+
|
|
1035
|
+
def coordinator_plan(self, plan_summary: str, tasks: List[Dict[str, str]]):
|
|
1036
|
+
"""Display coordinator's execution plan."""
|
|
1037
|
+
identity = self.registry.get_identity("coordinator")
|
|
1038
|
+
|
|
1039
|
+
# Plan header
|
|
1040
|
+
self.console.print(
|
|
1041
|
+
f"\n[{identity.color}]{identity.emoji}[/] "
|
|
1042
|
+
f"[{identity.color} bold]Execution Plan[/]"
|
|
1043
|
+
)
|
|
1044
|
+
|
|
1045
|
+
# Task assignments
|
|
1046
|
+
for task in tasks:
|
|
1047
|
+
agent_id = task.get("agent", "unknown")
|
|
1048
|
+
agent_identity = self.registry.get_identity(agent_id)
|
|
1049
|
+
self.console.print(
|
|
1050
|
+
f" [{agent_identity.color}]{agent_identity.emoji}[/] "
|
|
1051
|
+
f"[{agent_identity.color}]{agent_identity.name}[/]: "
|
|
1052
|
+
f"{task.get('description', 'No description')}"
|
|
1053
|
+
)
|
|
1054
|
+
|
|
1055
|
+
def start_wave(self, wave_number: int, agents: List[str]):
|
|
1056
|
+
"""Display start of parallel execution wave."""
|
|
1057
|
+
self.console.print()
|
|
1058
|
+
self.console.print(
|
|
1059
|
+
f"[bold white]━━━ Wave {wave_number} ━━━[/] "
|
|
1060
|
+
f"[dim]({len(agents)} agents in parallel)[/]"
|
|
1061
|
+
)
|
|
1062
|
+
|
|
1063
|
+
# Show which agents are starting
|
|
1064
|
+
agent_chips = []
|
|
1065
|
+
for agent_id in agents:
|
|
1066
|
+
identity = self.registry.get_identity(agent_id)
|
|
1067
|
+
agent_chips.append(f"[{identity.color}]{identity.emoji}[/]")
|
|
1068
|
+
|
|
1069
|
+
self.console.print(f" Starting: {' '.join(agent_chips)}")
|
|
1070
|
+
|
|
1071
|
+
def agent_started(self, agent_id: str, task_description: str):
|
|
1072
|
+
"""Display agent starting work."""
|
|
1073
|
+
identity = self.registry.get_identity(agent_id)
|
|
1074
|
+
self.active_agents[agent_id] = "working"
|
|
1075
|
+
|
|
1076
|
+
self.console.print(
|
|
1077
|
+
f" [{identity.color}]{identity.emoji}[/] "
|
|
1078
|
+
f"[{identity.color}]{identity.name}[/] → "
|
|
1079
|
+
f"[dim]{task_description[:60]}{'...' if len(task_description) > 60 else ''}[/]"
|
|
1080
|
+
)
|
|
1081
|
+
|
|
1082
|
+
def agent_progress(self, agent_id: str, message: str):
|
|
1083
|
+
"""Display agent progress update."""
|
|
1084
|
+
identity = self.registry.get_identity(agent_id)
|
|
1085
|
+
secondary = identity.secondary_emoji or "→"
|
|
1086
|
+
|
|
1087
|
+
self.console.print(
|
|
1088
|
+
f" [{identity.color}]{secondary}[/] "
|
|
1089
|
+
f"[dim]{message}[/]"
|
|
1090
|
+
)
|
|
1091
|
+
|
|
1092
|
+
def agent_completed(self, agent_id: str, success: bool, summary: str):
|
|
1093
|
+
"""Display agent completion."""
|
|
1094
|
+
identity = self.registry.get_identity(agent_id)
|
|
1095
|
+
self.active_agents[agent_id] = "complete" if success else "failed"
|
|
1096
|
+
|
|
1097
|
+
status_color = AgentColorPalette.SUCCESS if success else AgentColorPalette.ERROR
|
|
1098
|
+
status_icon = "✓" if success else "✗"
|
|
1099
|
+
|
|
1100
|
+
self.console.print(
|
|
1101
|
+
f" [{identity.color}]{identity.emoji}[/] "
|
|
1102
|
+
f"[{identity.color}]{identity.name}[/] "
|
|
1103
|
+
f"[{status_color}]{status_icon}[/] "
|
|
1104
|
+
f"[dim]{summary[:50]}{'...' if len(summary) > 50 else ''}[/]"
|
|
1105
|
+
)
|
|
1106
|
+
|
|
1107
|
+
def agent_output(self, agent_id: str, content: str, title: Optional[str] = None):
|
|
1108
|
+
"""Display agent output in a styled panel."""
|
|
1109
|
+
identity = self.registry.get_identity(agent_id)
|
|
1110
|
+
panel = identity.create_panel(
|
|
1111
|
+
content,
|
|
1112
|
+
title=title or f"Output",
|
|
1113
|
+
subtitle=f"[dim]{identity.name}[/]"
|
|
1114
|
+
)
|
|
1115
|
+
self.console.print(panel)
|
|
1116
|
+
|
|
1117
|
+
def handoff(self, from_agent: str, to_agent: str, context: Optional[str] = None):
|
|
1118
|
+
"""Display handoff between agents."""
|
|
1119
|
+
from_identity = self.registry.get_identity(from_agent)
|
|
1120
|
+
to_identity = self.registry.get_identity(to_agent)
|
|
1121
|
+
|
|
1122
|
+
self.console.print(
|
|
1123
|
+
f"\n [{from_identity.color}]{from_identity.emoji}[/] "
|
|
1124
|
+
f"[dim]→[/] "
|
|
1125
|
+
f"[{to_identity.color}]{to_identity.emoji}[/]"
|
|
1126
|
+
f" [dim]{context or 'Handoff'}[/]"
|
|
1127
|
+
)
|
|
1128
|
+
|
|
1129
|
+
def synthesis_started(self):
|
|
1130
|
+
"""Display synthesis phase starting."""
|
|
1131
|
+
identity = self.registry.get_identity("coordinator")
|
|
1132
|
+
self.console.print()
|
|
1133
|
+
self.console.print(
|
|
1134
|
+
f"[{identity.color}]{identity.emoji}[/] "
|
|
1135
|
+
f"[{identity.color} bold]Synthesizing results...[/]"
|
|
1136
|
+
)
|
|
1137
|
+
|
|
1138
|
+
def orchestration_complete(self, success: bool, metrics: Dict[str, Any]):
|
|
1139
|
+
"""Display final orchestration summary."""
|
|
1140
|
+
self.console.print()
|
|
1141
|
+
|
|
1142
|
+
# Calculate duration
|
|
1143
|
+
duration = (datetime.now() - self.start_time).total_seconds() if self.start_time else 0
|
|
1144
|
+
|
|
1145
|
+
# Status
|
|
1146
|
+
status_color = AgentColorPalette.SUCCESS if success else AgentColorPalette.ERROR
|
|
1147
|
+
status_icon = "✅" if success else "⚠️"
|
|
1148
|
+
status_text = "Complete" if success else "Incomplete"
|
|
1149
|
+
|
|
1150
|
+
# Summary content
|
|
1151
|
+
summary_lines = [
|
|
1152
|
+
f"Duration: {duration:.1f}s",
|
|
1153
|
+
f"Agents used: {metrics.get('num_agents', 'N/A')}",
|
|
1154
|
+
f"Tasks completed: {metrics.get('tasks_completed', 'N/A')}",
|
|
1155
|
+
f"Parallelization: {metrics.get('parallelization_factor', 1.0):.1f}x",
|
|
1156
|
+
]
|
|
1157
|
+
|
|
1158
|
+
if metrics.get('tasks_failed', 0) > 0:
|
|
1159
|
+
summary_lines.append(f"Tasks failed: {metrics['tasks_failed']}")
|
|
1160
|
+
|
|
1161
|
+
self.console.print(Panel(
|
|
1162
|
+
"\n".join(summary_lines),
|
|
1163
|
+
title=f"{status_icon} Orchestration {status_text}",
|
|
1164
|
+
border_style=status_color,
|
|
1165
|
+
box=DOUBLE,
|
|
1166
|
+
))
|
|
1167
|
+
|
|
1168
|
+
def parallel_status_display(self, agent_statuses: Dict[str, Dict[str, str]]):
|
|
1169
|
+
"""
|
|
1170
|
+
Display parallel agent status in a live-updating grid.
|
|
1171
|
+
|
|
1172
|
+
agent_statuses: {agent_id: {"status": str, "progress": str}}
|
|
1173
|
+
"""
|
|
1174
|
+
columns = []
|
|
1175
|
+
for agent_id, status_info in agent_statuses.items():
|
|
1176
|
+
identity = self.registry.get_identity(agent_id)
|
|
1177
|
+
|
|
1178
|
+
status = status_info.get("status", "idle")
|
|
1179
|
+
progress = status_info.get("progress", "")
|
|
1180
|
+
|
|
1181
|
+
# Status indicator
|
|
1182
|
+
if status == "working":
|
|
1183
|
+
indicator = "⏳"
|
|
1184
|
+
elif status == "complete":
|
|
1185
|
+
indicator = "✓"
|
|
1186
|
+
elif status == "failed":
|
|
1187
|
+
indicator = "✗"
|
|
1188
|
+
else:
|
|
1189
|
+
indicator = "○"
|
|
1190
|
+
|
|
1191
|
+
content = f"{indicator} {progress}" if progress else indicator
|
|
1192
|
+
|
|
1193
|
+
columns.append(Panel(
|
|
1194
|
+
f"[{identity.color}]{content}[/]",
|
|
1195
|
+
title=f"{identity.emoji} {identity.name}",
|
|
1196
|
+
border_style=identity.color,
|
|
1197
|
+
width=20,
|
|
1198
|
+
height=3,
|
|
1199
|
+
))
|
|
1200
|
+
|
|
1201
|
+
self.console.print(Columns(columns, equal=True, expand=True))
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+
# =============================================================================
|
|
1205
|
+
# CLI COMMANDS
|
|
1206
|
+
# =============================================================================
|
|
1207
|
+
|
|
1208
|
+
import click
|
|
1209
|
+
|
|
1210
|
+
@click.group(name="agents")
|
|
1211
|
+
def agents_cli():
|
|
1212
|
+
"""Manage agent identities and seed prompts."""
|
|
1213
|
+
pass
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
@agents_cli.command("list")
|
|
1217
|
+
@click.option("--format", "output_format", type=click.Choice(["table", "json", "simple"]),
|
|
1218
|
+
default="table", help="Output format")
|
|
1219
|
+
def list_agents(output_format: str):
|
|
1220
|
+
"""List all available agents with their visual identities."""
|
|
1221
|
+
console = Console()
|
|
1222
|
+
registry = AgentRegistry()
|
|
1223
|
+
|
|
1224
|
+
if output_format == "json":
|
|
1225
|
+
output = {}
|
|
1226
|
+
for agent_id in registry.list_agents():
|
|
1227
|
+
identity = registry.get_identity(agent_id)
|
|
1228
|
+
output[agent_id] = {
|
|
1229
|
+
"name": identity.name,
|
|
1230
|
+
"emoji": identity.emoji,
|
|
1231
|
+
"color": identity.color,
|
|
1232
|
+
"role": identity.role_title,
|
|
1233
|
+
}
|
|
1234
|
+
click.echo(json.dumps(output, indent=2))
|
|
1235
|
+
return
|
|
1236
|
+
|
|
1237
|
+
if output_format == "simple":
|
|
1238
|
+
for agent_id in sorted(registry.list_agents()):
|
|
1239
|
+
identity = registry.get_identity(agent_id)
|
|
1240
|
+
click.echo(f"{identity.emoji} {identity.name} ({agent_id})")
|
|
1241
|
+
return
|
|
1242
|
+
|
|
1243
|
+
# Table format
|
|
1244
|
+
table = Table(
|
|
1245
|
+
title="🤖 Available Agents",
|
|
1246
|
+
show_header=True,
|
|
1247
|
+
header_style="bold white",
|
|
1248
|
+
border_style="dim",
|
|
1249
|
+
)
|
|
1250
|
+
table.add_column("Agent", style="bold")
|
|
1251
|
+
table.add_column("Role", style="dim")
|
|
1252
|
+
table.add_column("Style", justify="center")
|
|
1253
|
+
table.add_column("Temp", justify="right")
|
|
1254
|
+
|
|
1255
|
+
for agent_id in sorted(registry.list_agents()):
|
|
1256
|
+
identity = registry.get_identity(agent_id)
|
|
1257
|
+
|
|
1258
|
+
# Agent name with color
|
|
1259
|
+
name_text = Text(f"{identity.emoji} {identity.name}", style=identity.color)
|
|
1260
|
+
|
|
1261
|
+
# Role
|
|
1262
|
+
role = identity.role_title[:35] + "..." if len(identity.role_title) > 35 else identity.role_title
|
|
1263
|
+
|
|
1264
|
+
# Color swatch
|
|
1265
|
+
color_text = Text("███", style=identity.color)
|
|
1266
|
+
|
|
1267
|
+
table.add_row(
|
|
1268
|
+
name_text,
|
|
1269
|
+
role,
|
|
1270
|
+
color_text,
|
|
1271
|
+
f"{identity.temperature}",
|
|
1272
|
+
)
|
|
1273
|
+
|
|
1274
|
+
console.print(table)
|
|
1275
|
+
|
|
1276
|
+
|
|
1277
|
+
@agents_cli.command("show")
|
|
1278
|
+
@click.argument("agent_id")
|
|
1279
|
+
@click.option("--prompt", "show_prompt", is_flag=True, help="Show full seed prompt")
|
|
1280
|
+
@click.option("--json-output", is_flag=True, help="Output as JSON")
|
|
1281
|
+
def show_agent(agent_id: str, show_prompt: bool, json_output: bool):
|
|
1282
|
+
"""Show detailed information for a specific agent."""
|
|
1283
|
+
console = Console()
|
|
1284
|
+
registry = AgentRegistry()
|
|
1285
|
+
|
|
1286
|
+
if agent_id not in registry.list_agents():
|
|
1287
|
+
raise click.ClickException(f"Unknown agent: {agent_id}")
|
|
1288
|
+
|
|
1289
|
+
identity = registry.get_identity(agent_id)
|
|
1290
|
+
prompt = registry.get_prompt(agent_id)
|
|
1291
|
+
|
|
1292
|
+
if json_output:
|
|
1293
|
+
output = {
|
|
1294
|
+
"identity": {
|
|
1295
|
+
"id": identity.id,
|
|
1296
|
+
"name": identity.name,
|
|
1297
|
+
"color": identity.color,
|
|
1298
|
+
"emoji": identity.emoji,
|
|
1299
|
+
"role_title": identity.role_title,
|
|
1300
|
+
"expertise": identity.expertise,
|
|
1301
|
+
"temperature": identity.temperature,
|
|
1302
|
+
},
|
|
1303
|
+
"prompt": prompt.to_dict() if prompt else None,
|
|
1304
|
+
}
|
|
1305
|
+
click.echo(json.dumps(output, indent=2))
|
|
1306
|
+
return
|
|
1307
|
+
|
|
1308
|
+
# Identity panel
|
|
1309
|
+
identity_content = f"""[bold]Role:[/] {identity.role_title}
|
|
1310
|
+
[bold]Color:[/] {identity.color}
|
|
1311
|
+
[bold]Emoji:[/] {identity.emoji} / {identity.secondary_emoji or '—'}
|
|
1312
|
+
[bold]Temperature:[/] {identity.temperature}
|
|
1313
|
+
[bold]Thinking Style:[/] {identity.thinking_style}
|
|
1314
|
+
|
|
1315
|
+
[bold]Expertise:[/]
|
|
1316
|
+
""" + "\n".join(f" • {e}" for e in identity.expertise)
|
|
1317
|
+
|
|
1318
|
+
console.print(Panel(
|
|
1319
|
+
identity_content,
|
|
1320
|
+
title=f"{identity.emoji} {identity.name}",
|
|
1321
|
+
border_style=identity.color,
|
|
1322
|
+
box=DOUBLE,
|
|
1323
|
+
))
|
|
1324
|
+
|
|
1325
|
+
if prompt:
|
|
1326
|
+
if show_prompt:
|
|
1327
|
+
console.print(Panel(
|
|
1328
|
+
prompt.to_system_prompt(),
|
|
1329
|
+
title="Seed Prompt",
|
|
1330
|
+
border_style="dim",
|
|
1331
|
+
))
|
|
1332
|
+
else:
|
|
1333
|
+
console.print(f"\n[dim]Use --prompt to see the full seed prompt[/]")
|
|
1334
|
+
|
|
1335
|
+
|
|
1336
|
+
@agents_cli.command("create")
|
|
1337
|
+
@click.option("--interactive", "-i", is_flag=True, help="Interactive creation wizard")
|
|
1338
|
+
@click.option("--from-yaml", type=click.Path(exists=True), help="Create from YAML file")
|
|
1339
|
+
@click.option("--template", "-t", help="Base on existing agent")
|
|
1340
|
+
def create_agent(interactive: bool, from_yaml: Optional[str], template: Optional[str]):
|
|
1341
|
+
"""Create a new custom agent."""
|
|
1342
|
+
console = Console()
|
|
1343
|
+
registry = AgentRegistry()
|
|
1344
|
+
|
|
1345
|
+
if from_yaml:
|
|
1346
|
+
with open(from_yaml) as f:
|
|
1347
|
+
data = yaml.safe_load(f)
|
|
1348
|
+
|
|
1349
|
+
identity = AgentIdentity(**data.get("identity", {}))
|
|
1350
|
+
prompt = SeedPrompt(**data.get("prompt", {}))
|
|
1351
|
+
|
|
1352
|
+
registry.save_custom_agent(identity, prompt)
|
|
1353
|
+
console.print(f"[green]✅ Agent '{identity.name}' created from {from_yaml}[/]")
|
|
1354
|
+
return
|
|
1355
|
+
|
|
1356
|
+
if interactive:
|
|
1357
|
+
console.print("[bold]Create Custom Agent[/]\n")
|
|
1358
|
+
|
|
1359
|
+
# Basic info
|
|
1360
|
+
agent_id = click.prompt("Agent ID (lowercase)", type=str).lower()
|
|
1361
|
+
name = click.prompt("Display name", default=agent_id.title())
|
|
1362
|
+
emoji = click.prompt("Emoji", default="🤖")
|
|
1363
|
+
color = click.prompt("Color (hex)", default="#74B9FF")
|
|
1364
|
+
role = click.prompt("Role title")
|
|
1365
|
+
|
|
1366
|
+
# Use template as base if provided
|
|
1367
|
+
base_prompt = registry.get_prompt(template) if template else None
|
|
1368
|
+
|
|
1369
|
+
# Create identity
|
|
1370
|
+
identity = AgentIdentity(
|
|
1371
|
+
id=agent_id,
|
|
1372
|
+
name=name,
|
|
1373
|
+
color=color,
|
|
1374
|
+
emoji=emoji,
|
|
1375
|
+
role_title=role,
|
|
1376
|
+
)
|
|
1377
|
+
|
|
1378
|
+
# Create prompt (simplified for interactive)
|
|
1379
|
+
prompt = SeedPrompt(
|
|
1380
|
+
agent_id=agent_id,
|
|
1381
|
+
role_description=role,
|
|
1382
|
+
personality=click.prompt("Personality description"),
|
|
1383
|
+
expertise_areas=click.prompt("Expertise (comma-separated)").split(","),
|
|
1384
|
+
communication_style=click.prompt("Communication style"),
|
|
1385
|
+
key_responsibilities=click.prompt("Key responsibilities (comma-separated)").split(","),
|
|
1386
|
+
constraints=[],
|
|
1387
|
+
output_format="",
|
|
1388
|
+
)
|
|
1389
|
+
|
|
1390
|
+
registry.save_custom_agent(identity, prompt)
|
|
1391
|
+
console.print(f"\n[green]✅ Agent '{name}' created![/]")
|
|
1392
|
+
console.print(f"[dim]Saved to: {registry.config_dir}[/]")
|
|
1393
|
+
else:
|
|
1394
|
+
console.print("Use --interactive or --from-yaml to create an agent")
|
|
1395
|
+
console.print("Example: ainative agents create --interactive")
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
@agents_cli.command("export")
|
|
1399
|
+
@click.argument("agent_id")
|
|
1400
|
+
@click.option("--output", "-o", type=click.Path(), help="Output file")
|
|
1401
|
+
def export_agent(agent_id: str, output: Optional[str]):
|
|
1402
|
+
"""Export agent definition to YAML."""
|
|
1403
|
+
registry = AgentRegistry()
|
|
1404
|
+
|
|
1405
|
+
if agent_id not in registry.list_agents():
|
|
1406
|
+
raise click.ClickException(f"Unknown agent: {agent_id}")
|
|
1407
|
+
|
|
1408
|
+
identity = registry.get_identity(agent_id)
|
|
1409
|
+
prompt = registry.get_prompt(agent_id)
|
|
1410
|
+
|
|
1411
|
+
export_data = {
|
|
1412
|
+
"identity": {
|
|
1413
|
+
"id": identity.id,
|
|
1414
|
+
"name": identity.name,
|
|
1415
|
+
"color": identity.color,
|
|
1416
|
+
"emoji": identity.emoji,
|
|
1417
|
+
"secondary_emoji": identity.secondary_emoji,
|
|
1418
|
+
"border_style": identity.border_style,
|
|
1419
|
+
"role_title": identity.role_title,
|
|
1420
|
+
"expertise": identity.expertise,
|
|
1421
|
+
"temperature": identity.temperature,
|
|
1422
|
+
"thinking_style": identity.thinking_style,
|
|
1423
|
+
},
|
|
1424
|
+
"prompt": prompt.to_dict() if prompt else None,
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
yaml_output = yaml.dump(export_data, default_flow_style=False, sort_keys=False)
|
|
1428
|
+
|
|
1429
|
+
if output:
|
|
1430
|
+
with open(output, "w") as f:
|
|
1431
|
+
f.write(yaml_output)
|
|
1432
|
+
click.echo(f"Exported to {output}")
|
|
1433
|
+
else:
|
|
1434
|
+
click.echo(yaml_output)
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
@agents_cli.command("preview")
|
|
1438
|
+
@click.argument("agent_id")
|
|
1439
|
+
def preview_agent(agent_id: str):
|
|
1440
|
+
"""Preview how an agent appears in swarm output."""
|
|
1441
|
+
console = Console()
|
|
1442
|
+
registry = AgentRegistry()
|
|
1443
|
+
|
|
1444
|
+
if agent_id not in registry.list_agents():
|
|
1445
|
+
raise click.ClickException(f"Unknown agent: {agent_id}")
|
|
1446
|
+
|
|
1447
|
+
identity = registry.get_identity(agent_id)
|
|
1448
|
+
|
|
1449
|
+
console.print(f"\n[bold]Preview: {identity.name}[/]\n")
|
|
1450
|
+
|
|
1451
|
+
# Status line
|
|
1452
|
+
console.print(
|
|
1453
|
+
f" [{identity.color}]{identity.emoji}[/] "
|
|
1454
|
+
f"[{identity.color}]{identity.name}[/] → "
|
|
1455
|
+
f"Processing task..."
|
|
1456
|
+
)
|
|
1457
|
+
|
|
1458
|
+
# Progress
|
|
1459
|
+
console.print(
|
|
1460
|
+
f" [{identity.color}]{identity.secondary_emoji or '→'}[/] "
|
|
1461
|
+
f"[dim]Analyzing requirements...[/]"
|
|
1462
|
+
)
|
|
1463
|
+
|
|
1464
|
+
# Completion
|
|
1465
|
+
console.print(
|
|
1466
|
+
f" [{identity.color}]{identity.emoji}[/] "
|
|
1467
|
+
f"[{identity.color}]{identity.name}[/] "
|
|
1468
|
+
f"[{AgentColorPalette.SUCCESS}]✓[/] "
|
|
1469
|
+
f"[dim]Task completed successfully[/]"
|
|
1470
|
+
)
|
|
1471
|
+
|
|
1472
|
+
# Output panel
|
|
1473
|
+
console.print()
|
|
1474
|
+
console.print(identity.create_panel(
|
|
1475
|
+
"This is sample output from the agent.\nIt demonstrates the styled panel.",
|
|
1476
|
+
title="Sample Output"
|
|
1477
|
+
))
|
|
1478
|
+
|
|
1479
|
+
|
|
1480
|
+
# =============================================================================
|
|
1481
|
+
# DEMO FUNCTION
|
|
1482
|
+
# =============================================================================
|
|
1483
|
+
|
|
1484
|
+
def demo_parallel_execution():
|
|
1485
|
+
"""Demonstrate parallel agent execution visualization."""
|
|
1486
|
+
console = Console()
|
|
1487
|
+
renderer = SwarmStreamRenderer(console)
|
|
1488
|
+
|
|
1489
|
+
# Simulate orchestration
|
|
1490
|
+
renderer.start_orchestration(
|
|
1491
|
+
task="Build a REST API for user management with authentication",
|
|
1492
|
+
agents=["coordinator", "database", "api", "backend", "security", "testing"],
|
|
1493
|
+
max_iterations=5,
|
|
1494
|
+
)
|
|
1495
|
+
|
|
1496
|
+
# Coordinator planning
|
|
1497
|
+
renderer.coordinator_thinking("Analyzing requirements... This is a multi-component system requiring database schema, API endpoints, business logic, security review, and tests.")
|
|
1498
|
+
|
|
1499
|
+
renderer.coordinator_plan(
|
|
1500
|
+
"Parallel execution in 2 waves",
|
|
1501
|
+
tasks=[
|
|
1502
|
+
{"agent": "database", "description": "Design user schema with auth tables"},
|
|
1503
|
+
{"agent": "api", "description": "Define REST endpoints for users"},
|
|
1504
|
+
{"agent": "backend", "description": "Implement user service logic"},
|
|
1505
|
+
{"agent": "security", "description": "Review auth flow and token handling"},
|
|
1506
|
+
{"agent": "testing", "description": "Write test cases for user operations"},
|
|
1507
|
+
]
|
|
1508
|
+
)
|
|
1509
|
+
|
|
1510
|
+
# Wave 1 - Foundation
|
|
1511
|
+
import time
|
|
1512
|
+
renderer.start_wave(1, ["database", "api"])
|
|
1513
|
+
|
|
1514
|
+
renderer.agent_started("database", "Design user and auth_token tables")
|
|
1515
|
+
renderer.agent_progress("database", "Creating users table with constraints...")
|
|
1516
|
+
time.sleep(0.5)
|
|
1517
|
+
renderer.agent_completed("database", True, "Schema with 2 tables, 3 indexes")
|
|
1518
|
+
|
|
1519
|
+
renderer.agent_started("api", "Define CRUD endpoints for /users")
|
|
1520
|
+
renderer.agent_progress("api", "Designing request/response models...")
|
|
1521
|
+
time.sleep(0.3)
|
|
1522
|
+
renderer.agent_completed("api", True, "5 endpoints with OpenAPI spec")
|
|
1523
|
+
|
|
1524
|
+
# Wave 2 - Implementation
|
|
1525
|
+
renderer.start_wave(2, ["backend", "security", "testing"])
|
|
1526
|
+
|
|
1527
|
+
renderer.agent_started("backend", "Implement UserService class")
|
|
1528
|
+
renderer.agent_started("security", "Review authentication flow")
|
|
1529
|
+
renderer.agent_started("testing", "Create test fixtures")
|
|
1530
|
+
|
|
1531
|
+
time.sleep(0.5)
|
|
1532
|
+
renderer.agent_progress("backend", "Implementing password hashing...")
|
|
1533
|
+
renderer.agent_progress("security", "Checking JWT configuration...")
|
|
1534
|
+
renderer.agent_progress("testing", "Writing user creation tests...")
|
|
1535
|
+
|
|
1536
|
+
time.sleep(0.5)
|
|
1537
|
+
renderer.agent_completed("backend", True, "UserService with 8 methods")
|
|
1538
|
+
renderer.agent_completed("security", True, "No critical issues found")
|
|
1539
|
+
renderer.agent_completed("testing", True, "15 test cases, 92% coverage")
|
|
1540
|
+
|
|
1541
|
+
# Synthesis
|
|
1542
|
+
renderer.synthesis_started()
|
|
1543
|
+
time.sleep(0.3)
|
|
1544
|
+
|
|
1545
|
+
# Sample output
|
|
1546
|
+
renderer.agent_output(
|
|
1547
|
+
"backend",
|
|
1548
|
+
'''class UserService:
|
|
1549
|
+
async def create_user(self, data: UserCreate) -> User:
|
|
1550
|
+
"""Create a new user with hashed password."""
|
|
1551
|
+
hashed = self.hash_password(data.password)
|
|
1552
|
+
return await self.repo.create(data, hashed)''',
|
|
1553
|
+
title="Generated Code"
|
|
1554
|
+
)
|
|
1555
|
+
|
|
1556
|
+
# Complete
|
|
1557
|
+
renderer.orchestration_complete(True, {
|
|
1558
|
+
"num_agents": 5,
|
|
1559
|
+
"tasks_completed": 5,
|
|
1560
|
+
"tasks_failed": 0,
|
|
1561
|
+
"parallelization_factor": 2.3,
|
|
1562
|
+
})
|
|
1563
|
+
|
|
1564
|
+
|
|
1565
|
+
if __name__ == "__main__":
|
|
1566
|
+
demo_parallel_execution()
|