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.
@@ -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()