Agentic Architecture Pattern: Code Generation Agent

Written by

in


    """
Pattern 238: Code Generation Agent

Purpose: AI-powered code generation with language detection, testing, and documentation.
Generates code from natural language descriptions with quality checks and best practices.
"""

from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
import re


class ProgrammingLanguage(Enum):
    """Supported programming languages."""
    PYTHON = "python"
    JAVASCRIPT = "javascript"
    TYPESCRIPT = "typescript"
    JAVA = "java"
    CSHARP = "csharp"
    CPP = "cpp"
    GO = "go"
    RUST = "rust"
    RUBY = "ruby"
    PHP = "php"


class CodeQuality(Enum):
    """Code quality levels."""
    QUICK = "quick"  # Fast generation, basic functionality
    STANDARD = "standard"  # Good quality with comments
    PRODUCTION = "production"  # High quality, well-documented
    ENTERPRISE = "enterprise"  # Best practices, fully tested


@dataclass
class CodeRequest:
    """Code generation request."""
    description: str
    language: ProgrammingLanguage
    quality: CodeQuality = CodeQuality.STANDARD
    include_tests: bool = False
    include_docs: bool = True
    requirements: List[str] = field(default_factory=list)


@dataclass
class GeneratedCode:
    """Generated code result."""
    request: CodeRequest
    code: str
    tests: Optional[str] = None
    documentation: Optional[str] = None
    language: ProgrammingLanguage = ProgrammingLanguage.PYTHON
    complexity_score: float = 0.0
    line_count: int = 0
    has_error_handling: bool = False
    best_practices_applied: List[str] = field(default_factory=list)


class CodeGenerationAgent:
    """
    Code Generation Agent - AI-powered code synthesis.
    
    Features:
    - Natural language to code translation
    - Multi-language support
    - Test generation
    - Documentation generation
    - Code quality levels
    - Best practices enforcement
    - Error handling
    - Complexity analysis
    """
    
    def __init__(self, name: str, default_language: ProgrammingLanguage = ProgrammingLanguage.PYTHON):
        self.name = name
        self.default_language = default_language
        self.llm = ChatOpenAI(model="gpt-4", temperature=0.2)
        
        # Statistics
        self.statistics: Dict[str, Any] = {
            "total_generations": 0,
            "languages_used": {lang.value: 0 for lang in ProgrammingLanguage},
            "quality_distribution": {q.value: 0 for q in CodeQuality},
            "avg_line_count": 0,
            "tests_generated": 0
        }
    
    def generate(self, request: CodeRequest) -> GeneratedCode:
        """Generate code from request."""
        
        # Generate main code
        code = self._generate_code(request)
        
        # Generate tests if requested
        tests = None
        if request.include_tests:
            tests = self._generate_tests(code, request)
            self.statistics["tests_generated"] += 1
        
        # Generate documentation if requested
        documentation = None
        if request.include_docs:
            documentation = self._generate_documentation(code, request)
        
        # Analyze code
        line_count = len(code.split('\n'))
        complexity_score = self._calculate_complexity(code)
        has_error_handling = self._check_error_handling(code, request.language)
        best_practices = self._identify_best_practices(code, request.language)
        
        # Update statistics
        self.statistics["total_generations"] += 1
        self.statistics["languages_used"][request.language.value] += 1
        self.statistics["quality_distribution"][request.quality.value] += 1
        
        old_avg = self.statistics["avg_line_count"]
        total = self.statistics["total_generations"]
        self.statistics["avg_line_count"] = (old_avg * (total - 1) + line_count) / total
        
        return GeneratedCode(
            request=request,
            code=code,
            tests=tests,
            documentation=documentation,
            language=request.language,
            complexity_score=complexity_score,
            line_count=line_count,
            has_error_handling=has_error_handling,
            best_practices_applied=best_practices
        )
    
    def _generate_code(self, request: CodeRequest) -> str:
        """Generate code from description."""
        
        quality_instructions = {
            CodeQuality.QUICK: "Generate working code quickly. Basic functionality is sufficient.",
            CodeQuality.STANDARD: "Generate clean, readable code with inline comments.",
            CodeQuality.PRODUCTION: "Generate production-quality code with comprehensive error handling, "
                                   "logging, and documentation.",
            CodeQuality.ENTERPRISE: "Generate enterprise-grade code following all best practices, "
                                   "with complete error handling, logging, type hints, and comprehensive documentation."
        }
        
        requirements_text = ""
        if request.requirements:
            requirements_text = f"\n\nSpecific requirements:\n" + "\n".join(f"- {req}" for req in request.requirements)
        
        prompt = ChatPromptTemplate.from_messages([
            ("system", f"You are an expert {request.language.value} developer. "
                      f"Generate high-quality, idiomatic code. "
                      f"{quality_instructions.get(request.quality, '')} "
                      f"Include appropriate error handling and follow best practices. "
                      f"Return ONLY the code, no explanations."),
            ("human", f"Generate {request.language.value} code for:\n\n{request.description}{requirements_text}")
        ])
        
        chain = prompt | self.llm
        response = chain.invoke({})
        
        # Extract code from response
        code = str(response.content).strip()
        code = self._extract_code_block(code)
        
        return code
    
    def _generate_tests(self, code: str, request: CodeRequest) -> str:
        """Generate unit tests for code."""
        
        test_frameworks = {
            ProgrammingLanguage.PYTHON: "pytest",
            ProgrammingLanguage.JAVASCRIPT: "Jest",
            ProgrammingLanguage.TYPESCRIPT: "Jest",
            ProgrammingLanguage.JAVA: "JUnit",
            ProgrammingLanguage.CSHARP: "xUnit",
            ProgrammingLanguage.GO: "testing package",
            ProgrammingLanguage.RUST: "Rust testing framework"
        }
        
        framework = test_frameworks.get(request.language, "standard testing framework")
        
        prompt = ChatPromptTemplate.from_messages([
            ("system", f"You are an expert in {request.language.value} testing. "
                      f"Generate comprehensive unit tests using {framework}. "
                      f"Include edge cases and error scenarios. "
                      f"Return ONLY the test code, no explanations."),
            ("human", f"Generate tests for this code:\n\n{code}")
        ])
        
        chain = prompt | self.llm
        response = chain.invoke({})
        
        tests = str(response.content).strip()
        tests = self._extract_code_block(tests)
        
        return tests
    
    def _generate_documentation(self, code: str, request: CodeRequest) -> str:
        """Generate documentation for code."""
        
        prompt = ChatPromptTemplate.from_messages([
            ("system", f"Generate clear, comprehensive documentation for {request.language.value} code. "
                      f"Include: purpose, parameters, return values, usage examples, and edge cases."),
            ("human", f"Document this code:\n\n{code}")
        ])
        
        chain = prompt | self.llm
        response = chain.invoke({})
        
        return str(response.content).strip()
    
    def _extract_code_block(self, text: str) -> str:
        """Extract code from markdown code blocks."""
        # Try to find code block with language specifier
        pattern = r'```(?:\w+)?\n(.*?)```'
        matches = re.findall(pattern, text, re.DOTALL)
        
        if matches:
            return matches[0].strip()
        
        # If no code block found, return as is
        return text
    
    def _calculate_complexity(self, code: str) -> float:
        """Calculate code complexity score (simplified)."""
        lines = [line for line in code.split('\n') if line.strip() and not line.strip().startswith('#')]
        
        # Count complexity indicators
        complexity = 0
        complexity += len(re.findall(r'\bif\b|\bfor\b|\bwhile\b', code)) * 2
        complexity += len(re.findall(r'\bdef\b|\bclass\b|\bfunction\b', code)) * 3
        complexity += len(re.findall(r'\btry\b|\bcatch\b|\bexcept\b', code)) * 1
        complexity += len(re.findall(r'\band\b|\bor\b|\b&&\b|\b\|\|\b', code)) * 1
        
        # Normalize by line count
        if lines:
            return min(10.0, complexity / len(lines) * 10)
        return 0.0
    
    def _check_error_handling(self, code: str, language: ProgrammingLanguage) -> bool:
        """Check if code includes error handling."""
        error_keywords = {
            ProgrammingLanguage.PYTHON: ['try', 'except', 'raise', 'finally'],
            ProgrammingLanguage.JAVASCRIPT: ['try', 'catch', 'throw', 'finally'],
            ProgrammingLanguage.JAVA: ['try', 'catch', 'throw', 'throws'],
            ProgrammingLanguage.CSHARP: ['try', 'catch', 'throw', 'finally'],
            ProgrammingLanguage.GO: ['defer', 'panic', 'recover', 'error'],
            ProgrammingLanguage.RUST: ['Result', 'Option', 'unwrap', 'expect']
        }
        
        keywords = error_keywords.get(language, ['try', 'catch', 'error'])
        return any(keyword in code for keyword in keywords)
    
    def _identify_best_practices(self, code: str, language: ProgrammingLanguage) -> List[str]:
        """Identify applied best practices."""
        practices = []
        
        # Common practices
        if re.search(r'""".*?"""', code, re.DOTALL) or re.search(r'/\*\*.*?\*/', code, re.DOTALL):
            practices.append("Documentation strings")
        
        if self._check_error_handling(code, language):
            practices.append("Error handling")
        
        if re.search(r'#.*|//.*', code):
            practices.append("Inline comments")
        
        if language == ProgrammingLanguage.PYTHON:
            if 'def ' in code and '->' in code:
                practices.append("Type hints")
            if 'logging' in code:
                practices.append("Logging")
        
        if 'test' in code.lower() or 'assert' in code:
            practices.append("Testing utilities")
        
        return practices
    
    def generate_from_description(self, description: str, language: Optional[ProgrammingLanguage] = None) -> GeneratedCode:
        """Quick generation from description."""
        request = CodeRequest(
            description=description,
            language=language or self.default_language,
            quality=CodeQuality.STANDARD,
            include_tests=False,
            include_docs=True
        )
        return self.generate(request)
    
    def get_statistics(self) -> Dict[str, Any]:
        """Get generation statistics."""
        return {
            "name": self.name,
            "default_language": self.default_language.value,
            **self.statistics
        }


class CodeGenerationPattern:
    """
    Code Generation Pattern - Manage code generation agents.
    
    Coordinates multiple agents for different languages and purposes.
    """
    
    def __init__(self):
        self.agents: Dict[str, CodeGenerationAgent] = {}
    
    def create_agent(self, name: str, default_language: ProgrammingLanguage = ProgrammingLanguage.PYTHON) -> CodeGenerationAgent:
        """Create a new code generation agent."""
        agent = CodeGenerationAgent(name, default_language)
        self.agents[name] = agent
        print(f"   Created code generation agent: {name} ({default_language.value})")
        return agent
    
    def run(self, agent_name: str, request: CodeRequest) -> Dict[str, Any]:
        """Generate code using specified agent."""
        if agent_name not in self.agents:
            return {"error": f"Agent {agent_name} not found"}
        
        agent = self.agents[agent_name]
        result = agent.generate(request)
        
        print(f"\n=== Code Generated by {agent_name} ===")
        print(f"Language: {result.language.value}")
        print(f"Quality: {result.request.quality.value}")
        print(f"Lines: {result.line_count} | Complexity: {result.complexity_score:.1f}/10")
        print(f"Error Handling: {'✓' if result.has_error_handling else '✗'}")
        
        if result.best_practices_applied:
            print(f"Best Practices: {', '.join(result.best_practices_applied)}")
        
        print(f"\nGenerated Code:\n{result.code[:300]}...")
        
        if result.tests:
            print(f"\nTests Generated: ✓ ({len(result.tests.split(chr(10)))} lines)")
        
        if result.documentation:
            print(f"\nDocumentation: {result.documentation[:150]}...")
        
        return {
            "agent": agent_name,
            "language": result.language.value,
            "line_count": result.line_count,
            "complexity": result.complexity_score,
            "statistics": agent.get_statistics()
        }


# Example usage
if __name__ == "__main__":
    print("=== Code Generation Agent Pattern Demo ===\n")
    
    # Create pattern
    pattern = CodeGenerationPattern()
    
    # Create agents
    print("1. Setting up code generation agents...")
    
    python_agent = pattern.create_agent("PythonCodeGen", ProgrammingLanguage.PYTHON)
    js_agent = pattern.create_agent("JSCodeGen", ProgrammingLanguage.JAVASCRIPT)
    
    # Generate code examples
    print("\n2. Generating code...")
    
    # Python function
    request1 = CodeRequest(
        description="Create a function to calculate the Fibonacci sequence up to n terms using memoization",
        language=ProgrammingLanguage.PYTHON,
        quality=CodeQuality.PRODUCTION,
        include_tests=True,
        include_docs=True
    )
    result1 = pattern.run("PythonCodeGen", request1)
    
    print("\n" + "="*60 + "\n")
    
    # JavaScript class
    request2 = CodeRequest(
        description="Create a Task class with methods to add, complete, and list tasks",
        language=ProgrammingLanguage.JAVASCRIPT,
        quality=CodeQuality.STANDARD,
        include_tests=False,
        include_docs=True
    )
    result2 = pattern.run("JSCodeGen", request2)
    
    print("\n" + "="*60 + "\n")
    
    # Python data processing
    request3 = CodeRequest(
        description="Create a function to parse CSV data and calculate statistics (mean, median, std dev)",
        language=ProgrammingLanguage.PYTHON,
        quality=CodeQuality.PRODUCTION,
        include_tests=True,
        requirements=["Handle missing values", "Return dict with statistics"]
    )
    result3 = pattern.run("PythonCodeGen", request3)
    
    # Print statistics
    print("\n" + "="*60)
    print("\n3. Code Generation Statistics:")
    stats = result3["statistics"]
    for key, value in stats.items():
        print(f"   {key}: {value}")
    
    print("\n✓ AI-powered code generation with quality checks complete!")

    

Agentic Architecture Pattern: Code Generation Agent

Pattern 238: 238 Code Generation Agent – Line-by-Line Explanation

Overview

Pattern 238: Code Generation Agent

Purpose: AI-powered code generation with language detection, testing, and documentation. Generates code from natural language descriptions with quality checks and best practices.


Code Structure Analysis

File Information

  • Pattern Number: 238
  • Pattern Name: 238 Code Generation Agent
  • File Path: patterns\domain_specific\238_code_generation_agent.py
  • Total Lines: 412

Detailed Code Explanation

Module Docstring

"""
Pattern 238: Code Generation Agent

Purpose: AI-powered code generation with language detection, testing, and documentation.
Generates code from natural language descriptions with quality checks and best practices.
"""

Explanation: This module docstring describes the purpose and key features of the 238 Code Generation Agent pattern.


Imports Section

from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
import re  # First 20 imports shown

Explanation: The module imports necessary dependencies: – from typing import Dict, Any, List, Optional: Type hints for better code documentation – from dataclasses import dataclass, field: Data class decorators for clean data structures – from datetime import datetime: Date and time utilities – from enum import Enum: Enumeration support for fixed sets of values – from langchain_core.prompts import ChatPromptTemplate: LangChain framework integration – from langchain_openai import ChatOpenAI: LangChain framework integration


Enumerations

ProgrammingLanguage (Line 17)

class ProgrammingLanguage(Enum):
    PYTHON
    JAVASCRIPT
    TYPESCRIPT
    JAVA
    CSHARP
    CPP
    GO
    RUST
    RUBY
    PHP

Purpose: Supported programming languages.

Values: – PYTHON: Represents python – JAVASCRIPT: Represents javascript – TYPESCRIPT: Represents typescript – JAVA: Represents java – CSHARP: Represents csharp – CPP: Represents cpp – GO: Represents go – RUST: Represents rust – RUBY: Represents ruby – PHP: Represents php

CodeQuality (Line 31)

class CodeQuality(Enum):
    QUICK
    STANDARD
    PRODUCTION
    ENTERPRISE

Purpose: Code quality levels.

Values: – QUICK: Represents quick – STANDARD: Represents standard – PRODUCTION: Represents production – ENTERPRISE: Represents enterprise


Classes

ProgrammingLanguage (Line 17)

Description: Supported programming languages.

CodeQuality (Line 31)

Description: Code quality levels.

CodeRequest (Line 40)

Description: Code generation request.

GeneratedCode (Line 51)

Description: Generated code result.

CodeGenerationAgent (Line 64)

Description: Code Generation Agent – AI-powered code synthesis.

Features: – Natural language to code translation – Multi-language support – Test generation – Documentation generation – Code quality levels – Best practices enforcement – Error handling – Complexity analysis

Methods:

__init__ (Line 79)
def __init__(self, name, default_language):
    """No method docstring."""

Purpose: No method docstring.

Parameters: – self: Instance reference – name: Identifier or label – default_language: Parameter for default_language

generate (Line 93)
def generate(self, request):
    """Generate code from request."""

Purpose: Generate code from request.

Parameters: – self: Instance reference – request: Parameter for request

_generate_code (Line 137)
def _generate_code(self, request):
    """Generate code from description."""

Purpose: Generate code from description.

Parameters: – self: Instance reference – request: Parameter for request

_generate_tests (Line 171)
def _generate_tests(self, code, request):
    """Generate unit tests for code."""

Purpose: Generate unit tests for code.

Parameters: – self: Instance reference – code: Parameter for code – request: Parameter for request

_generate_documentation (Line 202)
def _generate_documentation(self, code, request):
    """Generate documentation for code."""

Purpose: Generate documentation for code.

Parameters: – self: Instance reference – code: Parameter for code – request: Parameter for request

_extract_code_block (Line 216)
def _extract_code_block(self, text):
    """Extract code from markdown code blocks."""

Purpose: Extract code from markdown code blocks.

Parameters: – self: Instance reference – text: Parameter for text

_calculate_complexity (Line 228)
def _calculate_complexity(self, code):
    """Calculate code complexity score (simplified)."""

Purpose: Calculate code complexity score (simplified).

Parameters: – self: Instance reference – code: Parameter for code

_check_error_handling (Line 244)
def _check_error_handling(self, code, language):
    """Check if code includes error handling."""

Purpose: Check if code includes error handling.

Parameters: – self: Instance reference – code: Parameter for code – language: Parameter for language

_identify_best_practices (Line 258)
def _identify_best_practices(self, code, language):
    """Identify applied best practices."""

Purpose: Identify applied best practices.

Parameters: – self: Instance reference – code: Parameter for code – language: Parameter for language

generate_from_description (Line 283)
def generate_from_description(self, description, language):
    """Quick generation from description."""

Purpose: Quick generation from description.

Parameters: – self: Instance reference – description: Parameter for description – language: Parameter for language

get_statistics (Line 294)
def get_statistics(self):
    """Get generation statistics."""

Purpose: Get generation statistics.

Parameters: – self: Instance reference

CodeGenerationPattern (Line 303)

Description: Code Generation Pattern – Manage code generation agents.

Coordinates multiple agents for different languages and purposes.

Methods:

__init__ (Line 310)
def __init__(self):
    """No method docstring."""

Purpose: No method docstring.

Parameters: – self: Instance reference

create_agent (Line 313)
def create_agent(self, name, default_language):
    """Create a new code generation agent."""

Purpose: Create a new code generation agent.

Parameters: – self: Instance reference – name: Identifier or label – default_language: Parameter for default_language

run (Line 320)
def run(self, agent_name, request):
    """Generate code using specified agent."""

Purpose: Generate code using specified agent.

Parameters: – self: Instance reference – agent_name: Parameter for agent_name – request: Parameter for request


Design Patterns Used

  • Strategy Pattern: Different execution strategies for various scenarios
  • State Pattern: Managing different states in the workflow
  • Chain of Responsibility: Sequential processing through workflow nodes
  • Observer Pattern: Tracking and monitoring pattern execution
  • Factory Pattern: Creating instances with proper configuration

Usage Example

# Initialize the pattern
pattern = ProgrammingLanguage(name="example", model_name="gpt-4")

# Configure and execute
result = pattern.execute(data={"key": "value"})

# Check results
print(result)

Key Concepts

  • LLM Integration: Uses LangChain/OpenAI for intelligent decision-making
  • Workflow Orchestration: LangGraph manages execution flow through nodes
  • State Management: TypedDict defines workflow state structure
  • Error Handling: Comprehensive error handling and fallback mechanisms
  • Extensibility: Designed for easy customization and extension

Extension Points

This pattern can be extended by: 1. Adding custom workflow nodes 2. Implementing additional validation logic 3. Integrating with external services 4. Customizing LLM prompts and responses 5. Adding monitoring and logging capabilities

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *