File size: 6,494 Bytes
4aec5bd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#!/usr/bin/env python3
"""
Advanced multi-agent workflow for complex programming projects.

This orchestrates multiple specialized agents:
- architect: Designs system architecture
- coder: Writes implementation code  
- tester: Writes and runs tests
- reviewer: Reviews code quality and standards compliance

Usage:
    python agents/multiagent_workflow.py "Build a JWT authentication system"
"""

import argparse
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

from smolagents import CodeAgent, OpenAIModel, HfApiModel, ToolCollection
from smolagents.default_tools import WebSearchTool


class ProjectWorkflow:
    """Orchestrates a team of AI agents to build a software project."""

    def __init__(self, model, project_name: str = "Untitled"):
        self.model = model
        self.project_name = project_name
        self.agents = self._create_agents()

    def _create_agents(self):
        """Create specialized agents for different roles."""

        architect = CodeAgent(
            tools=[WebSearchTool()],
            model=self.model,
            name="architect",
            description="""Designs system architecture. Reads PRD.md and creates:
- File structure plan
- Data models
- API contract design
- Technology choices with justification""",
            max_steps=8,
        )

        coder = CodeAgent(
            tools=[],
            model=self.model,
            name="coder",
            description="""Writes production code. Requirements:
- Type hints on ALL functions
- Google docstrings
- Error handling with specific exceptions
- Follows architecture from architect agent
- No business logic in route handlers""",
            max_steps=12,
        )

        tester = CodeAgent(
            tools=[],
            model=self.model,
            name="tester",
            description="""Writes comprehensive tests. Must:
- Test happy paths and edge cases
- Test error conditions
- Use pytest fixtures from conftest.py
- Target 80%+ coverage
- Mock external APIs""",
            max_steps=8,
        )

        reviewer = CodeAgent(
            tools=[],
            model=self.model,
            name="reviewer",
            description="""Reviews code against standards. Checks:
- Type hints present?
- Docstrings complete?
- Error handling specific?
- No business logic in routes?
- Tests exist for all functions?
- No forbidden patterns (print, bare except, hardcoded values)?""",
            max_steps=6,
        )

        return {
            "architect": architect,
            "coder": coder,
            "tester": tester,
            "reviewer": reviewer,
        }

    def run(self, task: str) -> dict:
        """Execute the full workflow: architect → coder → tester → reviewer."""

        results = {}

        # Phase 1: Architecture
        print("\n" + "="*60)
        print("PHASE 1: Architecture Design")
        print("="*60)
        arch_prompt = f"""Design the architecture for this task: {task}

Read docs/PRD.md if it exists for requirements.
Create a detailed plan including:
1. File structure (which files in which directories)
2. Data models with field types
3. API endpoints with request/response schemas
4. Technology choices and why

Return your plan as structured markdown."""

        results["architecture"] = self.agents["architect"].run(arch_prompt)
        print(results["architecture"])

        # Phase 2: Implementation
        print("\n" + "="*60)
        print("PHASE 2: Code Implementation")
        print("="*60)
        code_prompt = f"""Implement the code based on this architecture:

{results['architecture']}

Task: {task}

Write production-ready code following these rules:
- Full type annotations on all functions
- Google-style docstrings
- Specific exception handling
- Business logic in services/, thin routes
- Read docs/CONTEXT.md for coding standards

Create or modify the necessary files."""

        results["code"] = self.agents["coder"].run(code_prompt)
        print(results["code"])

        # Phase 3: Testing
        print("\n" + "="*60)
        print("PHASE 3: Test Writing")
        print("="*60)
        test_prompt = f"""Write comprehensive tests for the code that was just written.

Task: {task}

Requirements:
- Create tests in tests/ mirroring src/ structure
- Test all functions including edge cases
- Use pytest fixtures
- Mock external dependencies
- Target 80%+ line coverage
- Include both unit and integration tests

Read existing tests for style consistency."""

        results["tests"] = self.agents["tester"].run(test_prompt)
        print(results["tests"])

        # Phase 4: Review
        print("\n" + "="*60)
        print("PHASE 4: Code Review")
        print("="*60)
        review_prompt = f"""Review all the code and tests produced for this task.

Task: {task}

Check against these standards from docs/CONTEXT.md:
1. All functions have type hints?
2. All public functions have Google docstrings?
3. Business logic is in services/ not routes?
4. No print() statements — only logging?
5. No bare except: clauses?
6. No hardcoded values?
7. Tests exist for all new functions?
8. Error handling is specific?

Report any issues found and suggest fixes."""

        results["review"] = self.agents["reviewer"].run(review_prompt)
        print(results["review"])

        return results


def main():
    parser = argparse.ArgumentParser(description="Multi-agent project workflow")
    parser.add_argument("task", help="The project task to execute")
    parser.add_argument("--model", default="gemma4:4b")
    parser.add_argument("--api-base", default="http://localhost:11434/v1")
    parser.add_argument("--hf", action="store_true", help="Use Hugging Face model")
    args = parser.parse_args()

    if args.hf:
        model = HfApiModel(model_id=args.model)
    else:
        model = OpenAIModel(
            model_id=args.model,
            api_base=args.api_base,
            api_key="ollama",
        )

    workflow = ProjectWorkflow(model, project_name=args.task[:50])
    results = workflow.run(args.task)

    # Save results
    output_dir = Path("agent_outputs")
    output_dir.mkdir(exist_ok=True)

    for phase, content in results.items():
        (output_dir / f"{phase}.md").write_text(str(content))

    print(f"\n✓ Results saved to {output_dir}/")
    print("  - architecture.md")
    print("  - code.md")
    print("  - tests.md")
    print("  - review.md")


if __name__ == "__main__":
    main()