# Coding Agents

Agents specialized for software development: code generation, refactoring, testing, and repository understanding.

---

## Coding Agent Capabilities

| Capability | Description | Tools |
|---|---|---|
| **Code Generation** | Write new code from specs | LSP, templates, snippets |
| **Refactoring** | Restructure without behavior change | AST, codemods, LSP |
| **Code Review** | Find bugs, style, security issues | Linters, SAST, LLMs |
| **Testing** | Generate, run, debug tests | pytest, jest, coverage |
| **Debugging** | Trace, breakpoint, inspect | Debugger, logs, REPL |
| **Repository Understanding** | Navigate, search, analyze | Git, grep, LSP, embeddings |
| **Documentation** | Generate, update docs | Docstrings, markdown |
| **Dependency Management** | Update, audit, resolve | Package managers, lockfiles |
| **CI/CD Integration** | Pipeline, deploy, rollback | GitHub Actions, GitLab CI |
| **Architecture** | Design, diagram, decision records | ADR, C4, Mermaid |

---

## Agent Architectures for Coding

### 1. Repository-Aware Agent
```python
class RepoAwareCodingAgent:
    def __init__(self, repo_path: str):
        self.repo_path = Path(repo_path)
        self.index = self._build_index()
    
    def _build_index(self) -> RepoIndex:
        return RepoIndex(
            files=self._discover_files(),
            symbols=self._extract_symbols(),
            dependencies=self._analyze_dependencies(),
            git_history=self._analyze_git_history()
        )
    
    async def answer_question(self, question: str) -> Answer:
        # Retrieve relevant context
        context = self.index.retrieve(question, k=10)
        
        # Generate answer with citations
        return await self.llm.generate(
            prompt=f"Question: {question}\n\nContext:\n{context}\n\nAnswer with file references:",
            tools=[self.index.get_file, self.index.get_symbol]
        )
```

### 2. Test-Driven Agent
```python
class TDDAgent:
    def __init__(self, project_root: Path):
        self.project_root = project_root
        self.test_runner = TestRunner(project_root)
    
    async def implement_feature(self, spec: FeatureSpec) -> Implementation:
        # 1. Generate failing tests from spec
        tests = await self.generate_tests(spec)
        await self.write_tests(tests)
        
        # 2. Run tests (should fail)
        result = await self.test_runner.run(tests)
        assert not result.passed
        
        # 3. Implement code to pass tests
        code = await self.generate_code(tests, spec)
        
        # 4. Iterate until passing
        for attempt in range(5):
            await self.write_code(code)
            result = await self.test_runner.run(tests)
            if result.passed:
                break
            code = await self.fix_code(code, result.failures)
        
        # 5. Refactor
        code = await self.refactor(code, tests)
        
        return Implementation(code=code, tests=tests)
```

### 3. Code Review Agent
```python
class CodeReviewAgent:
    def __init__(self, repo: GitRepo):
        self.repo = repo
        self.linters = self._setup_linters()
        self.security_scanner = SecurityScanner()
    
    async def review_pr(self, pr_number: int) -> ReviewResult:
        pr = self.repo.get_pr(pr_number)
        diff = pr.get_diff()
        
        # Parallel analysis
        results = await asyncio.gather(
            self.check_style(diff),
            self.check_types(diff),
            self.check_security(diff),
            self.check_performance(diff),
            self.check_tests(diff),
            self.check_docs(diff),
            self.suggest_improvements(diff)
        )
        
        return ReviewResult(
            style_issues=results[0],
            type_issues=results[1],
            security_issues=results[2],
            performance_issues=results[3],
            test_gaps=results[4],
            doc_gaps=results[5],
            suggestions=results[6]
        )
```

---

## Core Tools for Coding Agents

### Language Server Protocol (LSP)
```python
class LSPClient:
    def __init__(self, language: str, project_root: Path):
        self.language = language
        self.project_root = project_root
        self.server = self._start_server()
    
    def _start_server(self) -> LSPServer:
        servers = {
            "python": ["pyright-langserver", "--stdio"],
            "typescript": ["typescript-language-server", "--stdio"],
            "go": ["gopls"],
            "rust": ["rust-analyzer"],
            "java": ["jdtls"],
            "cpp": ["clangd"]
        }
        return LSPServer(servers[self.language])
    
    async def goto_definition(self, file: str, line: int, col: int) -> Location:
        return await self.server.request("textDocument/definition", {
            "textDocument": {"uri": f"file://{file}"},
            "position": {"line": line, "character": col}
        })
    
    async def find_references(self, file: str, line: int, col: int) -> list[Location]:
        return await self.server.request("textDocument/references", {...})
    
    async def get_hover(self, file: str, line: int, col: int) -> Hover:
        return await self.server.request("textDocument/hover", {...})
    
    async def get_diagnostics(self, file: str) -> list[Diagnostic]:
        return await self.server.request("textDocument/publishDiagnostics", {...})
```

### Code Search & Navigation
```python
class CodeNavigator:
    def __init__(self, project_root: Path):
        self.project_root = project_root
        self.embeddings = CodeEmbeddings(project_root)
    
    async def search(self, query: str, k: int = 10) -> list[CodeSnippet]:
        # Semantic search
        semantic_results = await self.embeddings.search(query, k)
        
        # Keyword search (grep)
        keyword_results = await self.grep_search(query, k)
        
        # Merge & rerank
        return self.rerank(semantic_results + keyword_results, query)
    
    async def grep_search(self, pattern: str, k: int) -> list[CodeSnippet]:
        # Use ripgrep for fast keyword search
        result = subprocess.run(
            ["rg", "--json", pattern, str(self.project_root)],
            capture_output=True, text=True
        )
        return self._parse_rg_output(result.stdout)[:k]
```

### Code Execution & Testing
```python
class CodeExecutor:
    def __init__(self, sandbox: Sandbox):
        self.sandbox = sandbox
    
    async def run_tests(self, test_files: list[Path]) -> TestResult:
        return await self.sandbox.run(
            f"pytest {' '.join(str(f) for f in test_files)} -v --json-report"
        )
    
    async def run_linter(self, files: list[Path]) -> LintResult:
        return await self.sandbox.run(f"ruff check {' '.join(str(f) for f in files)}")
    
    async def run_type_check(self, files: list[Path]) -> TypeCheckResult:
        return await self.sandbox.run(f"mypy {' '.join(str(f) for f in files)}")
    
    async def run_code(self, code: str, language: str = "python") -> ExecutionResult:
        return await self.sandbox.run_code(code, language)
```

### Git Operations
```python
class GitOperator:
    def __init__(self, repo_path: Path):
        self.repo = git.Repo(repo_path)
    
    def get_diff(self, base: str = "HEAD", target: str = None) -> str:
        if target:
            return self.repo.git.diff(base, target)
        return self.repo.git.diff(base)
    
    def get_changed_files(self, base: str = "HEAD") -> list[str]:
        return [item.a_path for item in self.repo.index.diff(base)]
    
    def create_branch(self, name: str, base: str = "HEAD"):
        self.repo.git.checkout("-b", name, base)
    
    def commit(self, message: str, files: list[str] = None):
        if files:
            self.repo.index.add(files)
        self.repo.index.commit(message)
    
    def create_pr(self, title: str, body: str, base: str = "main") -> PR:
        return self.github.create_pr(title, body, self.repo.active_branch.name, base)
```

---

## Specialized Coding Agents

### 1. Frontend Agent
```python
class FrontendAgent:
    def __init__(self, project_root: Path):
        self.project_root = project_root
        self.framework = self._detect_framework()
    
    def _detect_framework(self) -> str:
        package_json = self.project_root / "package.json"
        if package_json.exists():
            deps = json.loads(package_json.read_text()).get("dependencies", {})
            if "react" in deps: return "react"
            if "vue" in deps: return "vue"
            if "svelte" in deps: return "svelte"
            if "next" in deps: return "nextjs"
        return "vanilla"
    
    async def create_component(self, spec: ComponentSpec) -> Component:
        # Generate component with framework conventions
        template = self.get_template(self.framework, spec.type)
        code = template.render(spec.props)
        
        # Add styles
        if spec.styling == "css-modules":
            styles = self.generate_css_modules(spec)
        elif spec.styling == "tailwind":
            styles = self.generate_tailwind(spec)
        
        # Add tests
        test_code = self.generate_component_test(spec)
        
        return Component(
            code=code,
            styles=styles,
            test=test_code,
            storybook=spec.include_storybook
        )
```

### 2. Backend Agent
```python
class BackendAgent:
    def __init__(self, project_root: Path):
        self.project_root = project_root
        self.framework = self._detect_framework()
        self.orm = self._detect_orm()
    
    async def create_api_endpoint(self, spec: APISpec) -> Endpoint:
        # Generate route
        route_code = self.generate_route(spec)
        
        # Generate schema (Pydantic/Zod)
        schema_code = self.generate_schema(spec.request, spec.response)
        
        # Generate service layer
        service_code = self.generate_service(spec)
        
        # Generate tests
        test_code = self.generate_tests(spec)
        
        # Generate OpenAPI docs
        openapi_code = self.generate_openapi(spec)
        
        return Endpoint(
            route=route_code,
            schema=schema_code,
            service=service_code,
            tests=test_code,
            docs=openapi_code
        )
```

### 3. Database Agent
```python
class DatabaseAgent:
    def __init__(self, connection_string: str):
        self.engine = create_engine(connection_string)
        self.inspector = inspect(self.engine)
    
    async def generate_migrations(self, schema_changes: list[SchemaChange]) -> Migration:
        # Generate Alembic migration
        ops = []
        for change in schema_changes:
            if change.type == "create_table":
                ops.append(CreateTableOp(change.table))
            elif change.type == "add_column":
                ops.append(AddColumnOp(change.table, change.column))
            elif change.type == "create_index":
                ops.append(CreateIndexOp(change.table, change.columns))
        
        return Migration(operations=ops)
    
    async def optimize_query(self, query: str) -> OptimizationResult:
        # Analyze query plan
        plan = await self.explain_query(query)
        
        # Suggest optimizations
        suggestions = []
        if plan.has_seq_scan:
            suggestions.append("Add index for sequential scan")
        if plan.has_nested_loop:
            suggestions.append("Consider hash join or materialized view")
        
        return OptimizationResult(plan=plan, suggestions=suggestions)
```

### 4. DevOps Agent
```python
class DevOpsAgent:
    def __init__(self, repo: GitRepo, kubeconfig: str = None):
        self.repo = repo
        self.k8s = KubernetesClient(kubeconfig) if kubeconfig else None
    
    async def setup_ci_cd(self, spec: CICDSpec) -> Pipeline:
        # Generate pipeline config
        if spec.platform == "github":
            config = self.generate_github_actions(spec)
        elif spec.platform == "gitlab":
            config = self.generate_gitlab_ci(spec)
        elif spec.platform == "jenkins":
            config = self.generate_jenkinsfile(spec)
        
        # Add security scanning
        config = self.add_security_scanning(config)
        
        # Add deployment
        if spec.deploy_target:
            config = self.add_deployment(config, spec.deploy_target)
        
        return Pipeline(config=config)
    
    async def deploy(self, environment: str, version: str) -> DeploymentResult:
        if self.k8s:
            return await self.k8s.deploy(environment, version)
        # ... other deployment targets
```

---

## Coding Benchmarks

### SWE-bench
```python
# Real GitHub issues from popular repos
# Task: Fix issue given repo + issue description
# Metrics: Pass rate, patch quality

class SWEBenchEvaluator:
    def __init__(self, dataset_path: str):
        self.dataset = load_dataset(dataset_path)
    
    async def evaluate(self, agent: CodingAgent) -> EvaluationResult:
        results = []
        for instance in self.dataset:
            # Setup repo at commit before fix
            repo = self.setup_repo(instance)
            
            # Agent attempts fix
            patch = await agent.generate_fix(
                repo=repo,
                issue=instance.issue_text
            )
            
            # Apply patch & test
            result = self.apply_and_test(repo, patch, instance.tests)
            results.append(result)
        
        return EvaluationResult(
            pass_rate=sum(r.passed for r in results) / len(results),
            avg_patch_size=statistics.mean(len(r.patch) for r in results)
        )
```

### HumanEval / MBPP
```python
class CodeGenerationEvaluator:
    def __init__(self, dataset: str = "humaneval"):
        self.dataset = load_dataset(dataset)
    
    async def evaluate(self, agent: CodingAgent) -> EvaluationResult:
        results = []
        for problem in self.dataset:
            # Generate solution
            solution = await agent.generate_code(
                prompt=problem.prompt,
                signature=problem.signature
            )
            
            # Execute tests
            result = await self.execute_tests(solution, problem.tests)
            results.append(result)
        
        return EvaluationResult(
            pass_at_1=pass_at_k(results, k=1),
            pass_at_10=pass_at_k(results, k=10),
            pass_at_100=pass_at_k(results, k=100)
        )
```

---

## Best Practices

### Code Quality
1. **Always run linters/type checkers** before committing
2. **Generate tests first** (TDD)
3. **Small, focused changes** - easier to review
4. **Self-consistency** - generate multiple solutions, pick best
4. **Verify in sandbox** - never trust generated code blindly

### Repository Navigation
1. **Use LSP** for accurate navigation
2. **Embeddings + grep** for semantic + keyword search
3. **Git history** for context on why code exists
4. **Dependency graphs** for impact analysis

### Testing
1. **Test in sandbox** - never run untrusted code on host
2. **Run full test suite** before declaring done
3. **Property-based testing** for edge cases
4. **Mutation testing** for test quality

### Security
1. **Never commit secrets** - use env vars, secret managers
2. **Scan dependencies** - SCA tools in CI
3. **Validate inputs** - never trust generated code
4. **Least privilege** - sandbox all execution

---

## Related Notes

- [[Tools/Code-Execution.md]] — Sandbox execution
- [[ToolUse/Function-Calling.md]] — Code as tool
- [[ToolUse/MCP-Protocol.md]] — Code tools via MCP
- [[ToolUse/Code-Execution.md]] — Execution environments
- [[ToolUse/API-Integration.md]] — API integration
- [[DevOps/CI-CD-Best-Practices.md]] — CI/CD for code
- [[DevOps/Observability.md]] — Code observability
- [[Security/Secure-Coding.md]] — Secure coding
- [[Security/Supply-Chain-Security.md]] — Dependency security
- [[Testing/Test-Pyramid.md]] — Testing strategy
- [[Testing/Test-Driven-Development.md]] — TDD
- [[Patterns/Design-Patterns.md]] — Patterns in code
- [[Architecture/Domain-Driven-Design.md]] — DDD in code
- [[Architecture/Architecture-Decision-Records.md]] — ADRs for code

---

*Sources: SWE-bench, HumanEval, MBPP, OpenAI Codex, GitHub Copilot, Cursor, Devin, Cody, Tabnine, Codeium, SWE-agent, OpenDevin, Aider, language server protocol, Tree-sitter, ripgrep, pytest, ruff, mypy, E2B, Modal, Daytona, GitHub Actions, GitLab CI, ArgoCD, Argo Workflows, Tekton, Dagger, Earthly.*