Tag: ai

  • Agentic Architecture Pattern: Peer Review

    
        """
    Pattern 213: Peer Review Pattern
    
    Agents review each other's work collaboratively
    Implements feedback and improvement mechanisms using LangChain/LangGraph.
    """
    
    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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict
    
    
    class FeedbackType(Enum):
        """Types of feedback."""
        POSITIVE = "positive"
        NEGATIVE = "negative"
        CONSTRUCTIVE = "constructive"
        NEUTRAL = "neutral"
    
    
    @dataclass
    class FeedbackItem:
        """Represents a feedback item."""
        source: str
        content: str
        feedback_type: FeedbackType
        score: float = 0.0  # 0.0 to 1.0
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    @dataclass
    class EvaluationResult:
        """Result of evaluation."""
        score: float
        feedback: List[FeedbackItem]
        improvements: List[str]
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    class PeerreviewPattern:
        """
        Peer Review Pattern - Agents review each other's work collaboratively
        
        Provides peer_review capabilities for continuous improvement
        and quality enhancement in agentic systems.
        """
        
        def __init__(self, model_name: str = "gpt-4"):
            self.llm = ChatOpenAI(model=model_name, temperature=0.3)
            self.history: List[EvaluationResult] = []
            self.feedback_log: List[FeedbackItem] = []
        
        def evaluate(self, output: str, criteria: List[str]) -> EvaluationResult:
            """Evaluate output against criteria."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", """You are an expert evaluator for Peer Review. 
                Evaluate the output against the criteria and provide:
                1. Overall score (0.0 to 1.0)
                2. Specific feedback points
                3. Improvement suggestions"""),
                ("human", """Output to evaluate:
    {output}
    
    Criteria:
    {criteria}
    
    Provide evaluation.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "output": output,
                "criteria": "\n".join(f"- {c}" for c in criteria)
            })
            
            content = str(response.content)
            
            # Parse response
            score = 0.75  # Default score
            if "score:" in content.lower():
                try:
                    score_text = content.lower().split("score:")[1].split("\n")[0].strip()
                    score = float(score_text.split()[0].replace("/1.0", "").replace(":", ""))
                except:
                    pass
            
            feedback_items = [
                FeedbackItem(
                    source=self.__class__.__name__,
                    content=content,
                    feedback_type=FeedbackType.CONSTRUCTIVE,
                    score=score
                )
            ]
            
            improvements = [
                line.strip("- ").strip() 
                for line in content.split("\n") 
                if line.strip().startswith("-") or "improve" in line.lower()
            ][:3]
            
            result = EvaluationResult(
                score=score,
                feedback=feedback_items,
                improvements=improvements
            )
            
            self.history.append(result)
            self.feedback_log.extend(feedback_items)
            
            return result
        
        def provide_feedback(self, output: str) -> Dict[str, Any]:
            """Provide feedback on output."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are providing constructive feedback using Peer Review pattern."),
                ("human", "{output}")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"output": output})
            
            feedback = FeedbackItem(
                source="feedback_provider",
                content=str(response.content),
                feedback_type=FeedbackType.CONSTRUCTIVE,
                score=0.8
            )
            
            self.feedback_log.append(feedback)
            
            return {
                "feedback": feedback.content,
                "score": feedback.score,
                "type": feedback.feedback_type.value
            }
        
        def run(self, output: str, criteria: Optional[List[str]] = None) -> Dict[str, Any]:
            """Main execution method."""
            if criteria is None:
                criteria = ["clarity", "accuracy", "completeness"]
            
            result = self.evaluate(output, criteria)
            
            return {
                "pattern": "Peer Review",
                "score": result.score,
                "feedback_count": len(result.feedback),
                "improvements": result.improvements,
                "total_evaluations": len(self.history)
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Peer Review Pattern Demo ===\n")
        
        pattern = PeerreviewPattern()
        
        # Example evaluation
        test_output = "This is a sample output that demonstrates the peer_review functionality."
        result = pattern.run(test_output, ["clarity", "usefulness", "accuracy"])
        
        print(f"Pattern: {result['pattern']}")
        print(f"Score: {result['score']:.2f}")
        print(f"Improvements suggested: {len(result['improvements'])}")
        if result['improvements']:
            print("\nSuggestions:")
            for i, imp in enumerate(result['improvements'][:3], 1):
                print(f"  {i}. {imp}")
        
        print(f"\nTotal evaluations: {result['total_evaluations']}")
        print(f"Total feedback items: {len(pattern.feedback_log)}")
    
        

    Agentic Architecture Pattern: Peer Review

    Pattern 213: 213 Peer Review – Line-by-Line Explanation

    Overview

    Pattern 213: Peer Review Pattern

    Agents review each other’s work collaboratively Implements feedback and improvement mechanisms using LangChain/LangGraph.


    Code Structure Analysis

    File Information

    • Pattern Number: 213
    • Pattern Name: 213 Peer Review
    • File Path: patterns\feedback_improvement\213_peer_review.py
    • Total Lines: 179

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 213: Peer Review Pattern
    
    Agents review each other's work collaboratively
    Implements feedback and improvement mechanisms using LangChain/LangGraph.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 213 Peer Review 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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict  # 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 – from langgraph.graph import StateGraph, END: LangGraph for workflow orchestration – from typing_extensions import TypedDict: Type hints for better code documentation


    Enumerations

    FeedbackType (Line 18)

    class FeedbackType(Enum):
        POSITIVE
        NEGATIVE
        CONSTRUCTIVE
        NEUTRAL
    

    Purpose: Types of feedback.

    Values: – POSITIVE: Represents positive – NEGATIVE: Represents negative – CONSTRUCTIVE: Represents constructive – NEUTRAL: Represents neutral


    Classes

    FeedbackType (Line 18)

    Description: Types of feedback.

    FeedbackItem (Line 27)

    Description: Represents a feedback item.

    EvaluationResult (Line 37)

    Description: Result of evaluation.

    PeerreviewPattern (Line 45)

    Description: Peer Review Pattern – Agents review each other’s work collaboratively

    Provides peer_review capabilities for continuous improvement and quality enhancement in agentic systems.

    Methods:

    __init__ (Line 53)
    def __init__(self, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – model_name: LLM model to use (e.g., “gpt-4”)

    evaluate (Line 58)
    def evaluate(self, output, criteria):
        """Evaluate output against criteria."""
    

    Purpose: Evaluate output against criteria.

    Parameters: – self: Instance reference – output: Parameter for output – criteria: Parameter for criteria

    provide_feedback (Line 118)
    def provide_feedback(self, output):
        """Provide feedback on output."""
    

    Purpose: Provide feedback on output.

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

    run (Line 143)
    def run(self, output, criteria):
        """Main execution method."""
    

    Purpose: Main execution method.

    Parameters: – self: Instance reference – output: Parameter for output – criteria: Parameter for criteria


    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 = FeedbackType(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

  • Agentic Architecture Pattern: Self Evaluation

    
        """
    Pattern 212: Self-Evaluation Pattern
    
    Agent evaluates its own performance and outputs
    Implements feedback and improvement mechanisms using LangChain/LangGraph.
    """
    
    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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict
    
    
    class FeedbackType(Enum):
        """Types of feedback."""
        POSITIVE = "positive"
        NEGATIVE = "negative"
        CONSTRUCTIVE = "constructive"
        NEUTRAL = "neutral"
    
    
    @dataclass
    class FeedbackItem:
        """Represents a feedback item."""
        source: str
        content: str
        feedback_type: FeedbackType
        score: float = 0.0  # 0.0 to 1.0
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    @dataclass
    class EvaluationResult:
        """Result of evaluation."""
        score: float
        feedback: List[FeedbackItem]
        improvements: List[str]
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    class SelfEvaluationPattern:
        """
        Self-Evaluation Pattern - Agent evaluates its own performance and outputs
        
        Provides self_evaluation capabilities for continuous improvement
        and quality enhancement in agentic systems.
        """
        
        def __init__(self, model_name: str = "gpt-4"):
            self.llm = ChatOpenAI(model=model_name, temperature=0.3)
            self.history: List[EvaluationResult] = []
            self.feedback_log: List[FeedbackItem] = []
        
        def evaluate(self, output: str, criteria: List[str]) -> EvaluationResult:
            """Evaluate output against criteria."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", """You are an expert evaluator for Self-Evaluation. 
                Evaluate the output against the criteria and provide:
                1. Overall score (0.0 to 1.0)
                2. Specific feedback points
                3. Improvement suggestions"""),
                ("human", """Output to evaluate:
    {output}
    
    Criteria:
    {criteria}
    
    Provide evaluation.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "output": output,
                "criteria": "\n".join(f"- {c}" for c in criteria)
            })
            
            content = str(response.content)
            
            # Parse response
            score = 0.75  # Default score
            if "score:" in content.lower():
                try:
                    score_text = content.lower().split("score:")[1].split("\n")[0].strip()
                    score = float(score_text.split()[0].replace("/1.0", "").replace(":", ""))
                except:
                    pass
            
            feedback_items = [
                FeedbackItem(
                    source=self.__class__.__name__,
                    content=content,
                    feedback_type=FeedbackType.CONSTRUCTIVE,
                    score=score
                )
            ]
            
            improvements = [
                line.strip("- ").strip() 
                for line in content.split("\n") 
                if line.strip().startswith("-") or "improve" in line.lower()
            ][:3]
            
            result = EvaluationResult(
                score=score,
                feedback=feedback_items,
                improvements=improvements
            )
            
            self.history.append(result)
            self.feedback_log.extend(feedback_items)
            
            return result
        
        def provide_feedback(self, output: str) -> Dict[str, Any]:
            """Provide feedback on output."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are providing constructive feedback using Self-Evaluation pattern."),
                ("human", "{output}")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"output": output})
            
            feedback = FeedbackItem(
                source="feedback_provider",
                content=str(response.content),
                feedback_type=FeedbackType.CONSTRUCTIVE,
                score=0.8
            )
            
            self.feedback_log.append(feedback)
            
            return {
                "feedback": feedback.content,
                "score": feedback.score,
                "type": feedback.feedback_type.value
            }
        
        def run(self, output: str, criteria: Optional[List[str]] = None) -> Dict[str, Any]:
            """Main execution method."""
            if criteria is None:
                criteria = ["clarity", "accuracy", "completeness"]
            
            result = self.evaluate(output, criteria)
            
            return {
                "pattern": "Self-Evaluation",
                "score": result.score,
                "feedback_count": len(result.feedback),
                "improvements": result.improvements,
                "total_evaluations": len(self.history)
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Self-Evaluation Pattern Demo ===\n")
        
        pattern = SelfEvaluationPattern()
        
        # Example evaluation
        test_output = "This is a sample output that demonstrates the self_evaluation functionality."
        result = pattern.run(test_output, ["clarity", "usefulness", "accuracy"])
        
        print(f"Pattern: {result['pattern']}")
        print(f"Score: {result['score']:.2f}")
        print(f"Improvements suggested: {len(result['improvements'])}")
        if result['improvements']:
            print("\nSuggestions:")
            for i, imp in enumerate(result['improvements'][:3], 1):
                print(f"  {i}. {imp}")
        
        print(f"\nTotal evaluations: {result['total_evaluations']}")
        print(f"Total feedback items: {len(pattern.feedback_log)}")
    
        

    Agentic Architecture Pattern: Self Evaluation

    Pattern 212: 212 Self Evaluation – Line-by-Line Explanation

    Overview

    Pattern 212: Self-Evaluation Pattern

    Agent evaluates its own performance and outputs Implements feedback and improvement mechanisms using LangChain/LangGraph.


    Code Structure Analysis

    File Information

    • Pattern Number: 212
    • Pattern Name: 212 Self Evaluation
    • File Path: patterns\feedback_improvement\212_self_evaluation.py
    • Total Lines: 179

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 212: Self-Evaluation Pattern
    
    Agent evaluates its own performance and outputs
    Implements feedback and improvement mechanisms using LangChain/LangGraph.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 212 Self Evaluation 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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict  # 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 – from langgraph.graph import StateGraph, END: LangGraph for workflow orchestration – from typing_extensions import TypedDict: Type hints for better code documentation


    Enumerations

    FeedbackType (Line 18)

    class FeedbackType(Enum):
        POSITIVE
        NEGATIVE
        CONSTRUCTIVE
        NEUTRAL
    

    Purpose: Types of feedback.

    Values: – POSITIVE: Represents positive – NEGATIVE: Represents negative – CONSTRUCTIVE: Represents constructive – NEUTRAL: Represents neutral


    Classes

    FeedbackType (Line 18)

    Description: Types of feedback.

    FeedbackItem (Line 27)

    Description: Represents a feedback item.

    EvaluationResult (Line 37)

    Description: Result of evaluation.

    SelfEvaluationPattern (Line 45)

    Description: Self-Evaluation Pattern – Agent evaluates its own performance and outputs

    Provides self_evaluation capabilities for continuous improvement and quality enhancement in agentic systems.

    Methods:

    __init__ (Line 53)
    def __init__(self, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – model_name: LLM model to use (e.g., “gpt-4”)

    evaluate (Line 58)
    def evaluate(self, output, criteria):
        """Evaluate output against criteria."""
    

    Purpose: Evaluate output against criteria.

    Parameters: – self: Instance reference – output: Parameter for output – criteria: Parameter for criteria

    provide_feedback (Line 118)
    def provide_feedback(self, output):
        """Provide feedback on output."""
    

    Purpose: Provide feedback on output.

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

    run (Line 143)
    def run(self, output, criteria):
        """Main execution method."""
    

    Purpose: Main execution method.

    Parameters: – self: Instance reference – output: Parameter for output – criteria: Parameter for criteria


    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 = FeedbackType(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

  • Agentic Architecture Pattern: Feedback Loop

    
        """
    Pattern 211: Feedback Loop Pattern
    
    Implements continuous improvement through iterative feedback cycles.
    Features feedback collection, analysis, and action application.
    """
    
    from typing import Dict, Any, List, Optional, Callable
    from dataclasses import dataclass, field
    from datetime import datetime
    from enum import Enum
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    
    
    class FeedbackType(Enum):
        """Types of feedback."""
        POSITIVE = "positive"
        NEGATIVE = "negative"
        NEUTRAL = "neutral"
        SUGGESTION = "suggestion"
    
    
    @dataclass
    class Feedback:
        """Represents feedback from evaluation."""
        feedback_id: str
        content: str
        feedback_type: FeedbackType
        score: float  # -1.0 to 1.0
        source: str
        iteration: int
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    @dataclass
    class Iteration:
        """Represents one iteration in the feedback loop."""
        iteration_number: int
        input_data: Any
        output: Any
        feedbacks: List[Feedback] = field(default_factory=list)
        improvements_applied: List[str] = field(default_factory=list)
        quality_score: float = 0.0
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    class FeedbackCollector:
        """Collects and analyzes feedback."""
        
        def __init__(self, llm: ChatOpenAI):
            self.llm = llm
            self.all_feedback: List[Feedback] = []
        
        def collect_feedback(self, output: Any, iteration: int) -> List[Feedback]:
            """Collect feedback on output using LLM."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are a critic providing constructive feedback. "
                          "Analyze the output and provide specific, actionable feedback."),
                ("human", """Output to evaluate:
    {output}
    
    Provide feedback in the following format:
    1. List 2-3 specific strengths
    2. List 2-3 specific areas for improvement  
    3. Overall quality score (0.0 to 1.0)
    
    Be specific and actionable.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"output": str(output)})
            
            # Parse feedback (simplified)
            feedback_items = []
            
            # Positive feedback
            feedback_items.append(Feedback(
                feedback_id=f"fb_{iteration}_pos",
                content=f"Positive aspects from iteration {iteration}",
                feedback_type=FeedbackType.POSITIVE,
                score=0.7,
                source="llm_critic",
                iteration=iteration
            ))
            
            # Improvement suggestions
            feedback_items.append(Feedback(
                feedback_id=f"fb_{iteration}_improve",
                content=response.content,
                feedback_type=FeedbackType.SUGGESTION,
                score=0.0,
                source="llm_critic",
                iteration=iteration
            ))
            
            self.all_feedback.extend(feedback_items)
            return feedback_items
    
    
    class FeedbackLoopAgent:
        """Agent that improves through feedback loops."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.7)
            self.feedback_collector = FeedbackCollector(self.llm)
            self.iterations: List[Iteration] = []
            self.current_best_output: Optional[Any] = None
            self.best_score: float = 0.0
        
        def execute_with_feedback(self, task: str, max_iterations: int = 3) -> Dict[str, Any]:
            """Execute task with iterative feedback and improvement."""
            print(f"\n   {self.name}: Starting feedback loop for task")
            print(f"   Max iterations: {max_iterations}")
            
            current_input = task
            
            for iteration_num in range(1, max_iterations + 1):
                print(f"\n   === Iteration {iteration_num}/{max_iterations} ===")
                
                # Generate output
                output = self._generate_output(current_input, iteration_num)
                print(f"   Output generated: {str(output)[:80]}...")
                
                # Collect feedback
                feedbacks = self.feedback_collector.collect_feedback(output, iteration_num)
                print(f"   Collected {len(feedbacks)} feedback items")
                
                # Calculate quality score
                quality_score = self._calculate_quality(feedbacks)
                print(f"   Quality score: {quality_score:.3f}")
                
                # Record iteration
                improvements = self._identify_improvements(feedbacks)
                iteration = Iteration(
                    iteration_number=iteration_num,
                    input_data=current_input,
                    output=output,
                    feedbacks=feedbacks,
                    improvements_applied=improvements,
                    quality_score=quality_score
                )
                self.iterations.append(iteration)
                
                # Update best output
                if quality_score > self.best_score:
                    self.best_score = quality_score
                    self.current_best_output = output
                    print(f"   ✓ New best output!")
                
                # Check convergence
                if quality_score >= 0.9:
                    print(f"   ✓ Quality threshold reached!")
                    break
                
                # Apply improvements for next iteration
                if iteration_num  str:
            """Generate output for current iteration."""
            context = ""
            if iteration > 1:
                prev_feedback = self.iterations[-1].feedbacks
                context = f"\nPrevious feedback: {prev_feedback[0].content[:200] if prev_feedback else 'None'}"
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", f"You are {self.name}. Generate high-quality output. "
                          f"This is iteration {iteration}. Apply previous feedback if available."),
                ("human", "Task: {task}{context}\n\nGenerate output:")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"task": str(input_data), "context": context})
            return response.content
        
        def _calculate_quality(self, feedbacks: List[Feedback]) -> float:
            """Calculate overall quality score from feedback."""
            if not feedbacks:
                return 0.5
            
            # Simple average of feedback scores (normalized to 0-1)
            positive_count = sum(1 for f in feedbacks if f.feedback_type == FeedbackType.POSITIVE)
            total = len(feedbacks)
            return min(1.0, 0.3 + (positive_count / total) * 0.7)
        
        def _identify_improvements(self, feedbacks: List[Feedback]) -> List[str]:
            """Identify improvements from feedback."""
            improvements = []
            for feedback in feedbacks:
                if feedback.feedback_type in [FeedbackType.NEGATIVE, FeedbackType.SUGGESTION]:
                    improvements.append(f"Address: {feedback.content[:50]}...")
            return improvements
        
        def _apply_improvements(self, original_task: str, feedbacks: List[Feedback], 
                               previous_output: Any) -> str:
            """Apply improvements for next iteration."""
            suggestions = [f.content for f in feedbacks 
                          if f.feedback_type == FeedbackType.SUGGESTION]
            
            improved_task = f"{original_task}\n\nPrevious attempt had these issues:\n"
            improved_task += "\n".join(suggestions[:2])  # Top 2 suggestions
            
            return improved_task
    
    
    class FeedbackLoopPattern:
        """
        Feedback Loop Pattern - Continuous improvement through feedback.
        
        Implements iterative refinement where agents improve their outputs
        based on collected feedback.
        """
        
        def __init__(self):
            self.agents: Dict[str, FeedbackLoopAgent] = {}
        
        def register_agent(self, agent: FeedbackLoopAgent):
            """Register feedback loop agent."""
            self.agents[agent.name] = agent
        
        def run(self, tasks: List[Dict[str, Any]]) -> Dict[str, Any]:
            """Execute feedback loop on tasks."""
            print("=== Feedback Loop Pattern Demo ===\n")
            
            results = []
            for task_info in tasks:
                print(f"\nTask: {task_info.get('description', 'Unknown')}")
                
                agent_name = task_info.get("agent")
                if agent_name not in self.agents:
                    continue
                
                agent = self.agents[agent_name]
                task = task_info.get("task")
                max_iterations = task_info.get("max_iterations", 3)
                
                result = agent.execute_with_feedback(task, max_iterations)
                results.append(result)
            
            # Statistics
            total_iterations = sum(r["total_iterations"] for r in results)
            avg_score = sum(r["best_score"] for r in results) / len(results) if results else 0
            
            return {
                "pattern": "FeedbackLoop",
                "total_agents": len(self.agents),
                "tasks_completed": len(results),
                "total_iterations": total_iterations,
                "average_best_score": avg_score
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Feedback Loop Pattern Demo ===\n")
        
        # Create pattern
        pattern = FeedbackLoopPattern()
        
        # Create agent
        print("1. Creating feedback loop agent...")
        agent = FeedbackLoopAgent("WriterAgent")
        pattern.register_agent(agent)
        
        # Define tasks
        print("\n2. Defining tasks for iterative improvement...")
        
        tasks = [
            {
                "description": "Write product description",
                "agent": "WriterAgent",
                "task": "Write a compelling product description for a smart watch",
                "max_iterations": 3
            },
            {
                "description": "Create email subject line",
                "agent": "WriterAgent",
                "task": "Create an engaging email subject line for a summer sale",
                "max_iterations": 2
            }
        ]
        
        # Execute
        print("\n3. Executing with feedback loops...")
        summary = pattern.run(tasks)
        
        print(f"\n4. Summary:")
        print(f"   Tasks Completed: {summary['tasks_completed']}")
        print(f"   Total Iterations: {summary['total_iterations']}")
        print(f"   Average Best Score: {summary['average_best_score']:.3f}")
        
        print("\n5. Iteration History:")
        for i, iteration in enumerate(agent.iterations, 1):
            print(f"   Iteration {iteration.iteration_number}:")
            print(f"     Quality: {iteration.quality_score:.3f}")
            print(f"     Improvements: {len(iteration.improvements_applied)}")
            print(f"     Feedback items: {len(iteration.feedbacks)}")
        
        print(f"\n6. Best Output:")
        if agent.current_best_output:
            print(f"   {str(agent.current_best_output)[:200]}...")
            print(f"   Score: {agent.best_score:.3f}")
        
        print("\n✓ Feedback loop enabled continuous improvement!")
    
        

    Agentic Architecture Pattern: Feedback Loop

    Pattern 211: 211 Feedback Loop – Line-by-Line Explanation

    Overview

    Pattern 211: Feedback Loop Pattern

    Implements continuous improvement through iterative feedback cycles. Features feedback collection, analysis, and action application.


    Code Structure Analysis

    File Information

    • Pattern Number: 211
    • Pattern Name: 211 Feedback Loop
    • File Path: patterns\feedback_improvement\211_feedback_loop.py
    • Total Lines: 314

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 211: Feedback Loop Pattern
    
    Implements continuous improvement through iterative feedback cycles.
    Features feedback collection, analysis, and action application.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 211 Feedback Loop pattern.


    Imports Section

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

    Explanation: The module imports necessary dependencies: – from typing import Dict, Any, List, Optional, Callable: 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

    FeedbackType (Line 16)

    class FeedbackType(Enum):
        POSITIVE
        NEGATIVE
        NEUTRAL
        SUGGESTION
    

    Purpose: Types of feedback.

    Values: – POSITIVE: Represents positive – NEGATIVE: Represents negative – NEUTRAL: Represents neutral – SUGGESTION: Represents suggestion


    Classes

    FeedbackType (Line 16)

    Description: Types of feedback.

    Feedback (Line 25)

    Description: Represents feedback from evaluation.

    Iteration (Line 37)

    Description: Represents one iteration in the feedback loop.

    FeedbackCollector (Line 48)

    Description: Collects and analyzes feedback.

    Methods:

    __init__ (Line 51)
    def __init__(self, llm):
        """No method docstring."""
    

    Purpose: No method docstring.

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

    collect_feedback (Line 55)
    def collect_feedback(self, output, iteration):
        """Collect feedback on output using LLM."""
    

    Purpose: Collect feedback on output using LLM.

    Parameters: – self: Instance reference – output: Parameter for output – iteration: Parameter for iteration

    FeedbackLoopAgent (Line 101)

    Description: Agent that improves through feedback loops.

    Methods:

    __init__ (Line 104)
    def __init__(self, name, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – model_name: LLM model to use (e.g., “gpt-4”)

    execute_with_feedback (Line 112)
    def execute_with_feedback(self, task, max_iterations):
        """Execute task with iterative feedback and improvement."""
    

    Purpose: Execute task with iterative feedback and improvement.

    Parameters: – self: Instance reference – task: Parameter for task – max_iterations: Parameter for max_iterations

    _generate_output (Line 168)
    def _generate_output(self, input_data, iteration):
        """Generate output for current iteration."""
    

    Purpose: Generate output for current iteration.

    Parameters: – self: Instance reference – input_data: Parameter for input_data – iteration: Parameter for iteration

    _calculate_quality (Line 185)
    def _calculate_quality(self, feedbacks):
        """Calculate overall quality score from feedback."""
    

    Purpose: Calculate overall quality score from feedback.

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

    _identify_improvements (Line 195)
    def _identify_improvements(self, feedbacks):
        """Identify improvements from feedback."""
    

    Purpose: Identify improvements from feedback.

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

    _apply_improvements (Line 203)
    def _apply_improvements(self, original_task, feedbacks, previous_output):
        """Apply improvements for next iteration."""
    

    Purpose: Apply improvements for next iteration.

    Parameters: – self: Instance reference – original_task: Parameter for original_task – feedbacks: Parameter for feedbacks – previous_output: Parameter for previous_output

    FeedbackLoopPattern (Line 215)

    Description: Feedback Loop Pattern – Continuous improvement through feedback.

    Implements iterative refinement where agents improve their outputs based on collected feedback.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 226)
    def register_agent(self, agent):
        """Register feedback loop agent."""
    

    Purpose: Register feedback loop agent.

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

    run (Line 230)
    def run(self, tasks):
        """Execute feedback loop on tasks."""
    

    Purpose: Execute feedback loop on tasks.

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


    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 = FeedbackType(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

  • Agentic Architecture Pattern: Counterfactual Reasoning

    
        """
    Pattern 210: Counterfactual Reasoning Pattern
    
    Reasons about "what if" scenarios and alternative possibilities.
    Explores hypothetical situations contrary to actual facts.
    """
    
    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
    
    
    class CounterfactualType(Enum):
        """Types of counterfactual reasoning."""
        WHAT_IF = "what_if"  # What if X had happened?
        IF_ONLY = "if_only"  # If only X had been different
        ALTERNATIVE = "alternative"  # Alternative possible outcomes
        MINIMAL_CHANGE = "minimal_change"  # Minimal change for different outcome
    
    
    @dataclass
    class ActualWorld:
        """The actual state of affairs."""
        facts: List[str]
        outcome: str
        context: Dict[str, Any] = field(default_factory=dict)
    
    
    @dataclass
    class CounterfactualWorld:
        """A hypothetical alternative world."""
        change: str  # What's different from actual
        predicted_facts: List[str]
        predicted_outcome: str
        plausibility: float = 0.5  # 0.0 to 1.0
        reasoning: str = ""
    
    
    @dataclass
    class CounterfactualQuery:
        """Query about counterfactual scenario."""
        actual_world: ActualWorld
        counterfactual_change: str
        question: str
    
    
    class CounterfactualReasoningAgent:
        """Agent that performs counterfactual reasoning."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.7)
            self.scenarios: List[CounterfactualWorld] = []
        
        def generate_counterfactual(self, actual: ActualWorld, 
                                   change: str) -> CounterfactualWorld:
            """Generate counterfactual scenario with change."""
            print(f"\n  {self.name}: Generating counterfactual: '{change}'...")
            
            actual_facts = "\n".join([f"- {fact}" for fact in actual.facts])
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are a counterfactual reasoning expert. Imagine alternative "
                          "scenarios and predict consequences."),
                ("human", """Actual World:
    Facts: 
    {facts}
    Outcome: {outcome}
    
    Counterfactual Change: {change}
    
    If this change had occurred, what would be different?
    Provide:
    1. New facts (what changes)
    2. Alternative outcome
    3. Plausibility (0.0-1.0)
    4. Reasoning chain
    
    Format:
    FACTS: 
    OUTCOME: 
    PLAUSIBILITY: 
    REASONING: """)
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "facts": actual_facts,
                "outcome": actual.outcome,
                "change": change
            })
            
            # Parse response
            new_facts = []
            new_outcome = ""
            plausibility = 0.5
            reasoning = ""
            
            current_section = None
            for line in response.content.split("\n"):
                line = line.strip()
                if line.startswith("FACTS:"):
                    current_section = "facts"
                    continue
                elif line.startswith("OUTCOME:"):
                    new_outcome = line.replace("OUTCOME:", "").strip()
                    current_section = "outcome"
                    continue
                elif line.startswith("PLAUSIBILITY:"):
                    try:
                        plausibility = float(line.replace("PLAUSIBILITY:", "").strip())
                    except:
                        plausibility = 0.5
                    current_section = "plausibility"
                    continue
                elif line.startswith("REASONING:"):
                    current_section = "reasoning"
                    reasoning = line.replace("REASONING:", "").strip()
                    continue
                
                if current_section == "facts" and line.startswith("-"):
                    new_facts.append(line.lstrip("- "))
                elif current_section == "reasoning" and line:
                    reasoning += " " + line
            
            counterfactual = CounterfactualWorld(
                change=change,
                predicted_facts=new_facts if new_facts else ["Unknown changes"],
                predicted_outcome=new_outcome or "Unknown outcome",
                plausibility=plausibility,
                reasoning=reasoning.strip() or "Hypothetical alternative"
            )
            
            self.scenarios.append(counterfactual)
            
            print(f"  Predicted outcome: {counterfactual.predicted_outcome[:80]}...")
            print(f"  Plausibility: {counterfactual.plausibility}")
            
            return counterfactual
        
        def compare_worlds(self, actual: ActualWorld, 
                          counterfactual: CounterfactualWorld) -> Dict[str, Any]:
            """Compare actual and counterfactual worlds."""
            print(f"\n  {self.name}: Comparing worlds...")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Compare actual and counterfactual scenarios."),
                ("human", """Actual Outcome: {actual_outcome}
    Counterfactual Outcome: {counterfactual_outcome}
    
    What are the key differences? What insights does this comparison reveal?""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "actual_outcome": actual.outcome,
                "counterfactual_outcome": counterfactual.predicted_outcome
            })
            
            comparison = {
                "actual": actual.outcome,
                "counterfactual": counterfactual.predicted_outcome,
                "analysis": response.content,
                "change": counterfactual.change
            }
            
            return comparison
        
        def identify_critical_factors(self, actual: ActualWorld) -> List[str]:
            """Identify factors critical to the actual outcome."""
            print(f"\n  {self.name}: Identifying critical factors...")
            
            facts_text = "\n".join(actual.facts)
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Identify which factors were most critical to the outcome."),
                ("human", """Facts:
    {facts}
    
    Outcome: {outcome}
    
    Which factors were most critical? List 2-3 key factors.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "facts": facts_text,
                "outcome": actual.outcome
            })
            
            factors = [line.strip().lstrip("0123456789.-) ")
                      for line in response.content.split("\n")
                      if line.strip()]
            
            print(f"  Identified {len(factors)} critical factors")
            return factors[:3]
        
        def explore_minimal_changes(self, actual: ActualWorld, 
                                   desired_outcome: str) -> CounterfactualWorld:
            """Find minimal change needed for desired outcome."""
            print(f"\n  {self.name}: Finding minimal change for desired outcome...")
            
            facts_text = "\n".join(actual.facts)
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Find the minimal change that would lead to desired outcome."),
                ("human", """Current Facts:
    {facts}
    
    Current Outcome: {current_outcome}
    Desired Outcome: {desired_outcome}
    
    What is the SMALLEST change that would lead to the desired outcome?
    Explain the change and why it would work.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "facts": facts_text,
                "current_outcome": actual.outcome,
                "desired_outcome": desired_outcome
            })
            
            minimal_change = CounterfactualWorld(
                change=response.content.split("\n")[0],
                predicted_facts=[],
                predicted_outcome=desired_outcome,
                plausibility=0.7,
                reasoning=response.content
            )
            
            print(f"  Minimal change: {minimal_change.change[:80]}...")
            
            return minimal_change
    
    
    class CounterfactualReasoningPattern:
        """
        Counterfactual Reasoning Pattern - Explore "what if" scenarios.
        
        Generates alternative scenarios, compares outcomes, identifies
        critical factors, and explores minimal changes.
        """
        
        def __init__(self):
            self.agents: Dict[str, CounterfactualReasoningAgent] = {}
        
        def register_agent(self, agent: CounterfactualReasoningAgent):
            """Register counterfactual reasoning agent."""
            self.agents[agent.name] = agent
        
        def run(self, queries: List[CounterfactualQuery]) -> Dict[str, Any]:
            """Execute counterfactual reasoning queries."""
            print("=== Counterfactual Reasoning Pattern ===\n")
            
            comparisons = []
            for agent in self.agents.values():
                for query in queries:
                    # Generate counterfactual
                    counterfactual = agent.generate_counterfactual(
                        query.actual_world,
                        query.counterfactual_change
                    )
                    
                    # Compare worlds
                    comparison = agent.compare_worlds(
                        query.actual_world,
                        counterfactual
                    )
                    comparisons.append(comparison)
            
            return {
                "pattern": "CounterfactualReasoning",
                "agents": len(self.agents),
                "queries_processed": len(queries),
                "scenarios_explored": sum(len(a.scenarios) for a in self.agents.values()),
                "comparisons": comparisons
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Counterfactual Reasoning Pattern Demo ===\n")
        
        # Create pattern and agent
        pattern = CounterfactualReasoningPattern()
        agent = CounterfactualReasoningAgent("WhatIfAnalyst")
        pattern.register_agent(agent)
        
        # Actual world scenarios
        print("1. Defining actual world scenarios...\n")
        
        # Scenario 1: Historical event
        actual1 = ActualWorld(
            facts=[
                "Columbus sailed west in 1492",
                "He had support from Spanish monarchy",
                "Navigation technology was available"
            ],
            outcome="European discovery of the Americas in 1492"
        )
        
        # Scenario 2: Business decision
        actual2 = ActualWorld(
            facts=[
                "Company invested heavily in mobile apps",
                "Market shifted to mobile-first",
                "Competitors were slow to adapt"
            ],
            outcome="Company became market leader in mobile space"
        )
        
        # Counterfactual queries
        print("2. Exploring counterfactual scenarios...\n")
        queries = [
            CounterfactualQuery(
                actual_world=actual1,
                counterfactual_change="What if the Spanish monarchy had refused funding?",
                question="Would the Americas still be discovered in 1492?"
            ),
            CounterfactualQuery(
                actual_world=actual2,
                counterfactual_change="What if the company had focused on desktop instead?",
                question="Would they still be market leader?"
            )
        ]
        
        # Run counterfactual reasoning
        summary = pattern.run(queries)
        
        print(f"\n=== Summary ===")
        print(f"Queries processed: {summary['queries_processed']}")
        print(f"Scenarios explored: {summary['scenarios_explored']}")
        
        print(f"\n=== Counterfactual Analysis ===")
        for i, comp in enumerate(summary['comparisons'], 1):
            print(f"\nScenario {i}:")
            print(f"  Change: {comp['change'][:60]}...")
            print(f"  Actual: {comp['actual'][:60]}...")
            print(f"  Counterfactual: {comp['counterfactual'][:60]}...")
        
        # Additional: Identify critical factors
        print(f"\n=== Critical Factors ===")
        critical = agent.identify_critical_factors(actual1)
        for factor in critical:
            print(f"  - {factor}")
        
        print("\n✓ Counterfactual reasoning: exploring alternative realities!")
    
        

    Agentic Architecture Pattern: Counterfactual Reasoning

    Pattern 210: 210 Counterfactual Reasoning Pattern – Line-by-Line Explanation

    Overview

    Pattern 210: Counterfactual Reasoning Pattern

    Reasons about “what if” scenarios and alternative possibilities. Explores hypothetical situations contrary to actual facts.


    Code Structure Analysis

    File Information

    • Pattern Number: 210
    • Pattern Name: 210 Counterfactual Reasoning Pattern
    • File Path: patterns\advanced_reasoning\210_counterfactual_reasoning_pattern.py
    • Total Lines: 352

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 210: Counterfactual Reasoning Pattern
    
    Reasons about "what if" scenarios and alternative possibilities.
    Explores hypothetical situations contrary to actual facts.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 210 Counterfactual Reasoning Pattern 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  # 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

    CounterfactualType (Line 16)

    class CounterfactualType(Enum):
        WHAT_IF
        IF_ONLY
        ALTERNATIVE
        MINIMAL_CHANGE
    

    Purpose: Types of counterfactual reasoning.

    Values: – WHAT_IF: Represents what if – IF_ONLY: Represents if only – ALTERNATIVE: Represents alternative – MINIMAL_CHANGE: Represents minimal change


    Classes

    CounterfactualType (Line 16)

    Description: Types of counterfactual reasoning.

    ActualWorld (Line 25)

    Description: The actual state of affairs.

    CounterfactualWorld (Line 33)

    Description: A hypothetical alternative world.

    CounterfactualQuery (Line 43)

    Description: Query about counterfactual scenario.

    CounterfactualReasoningAgent (Line 50)

    Description: Agent that performs counterfactual reasoning.

    Methods:

    __init__ (Line 53)
    def __init__(self, name, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – model_name: LLM model to use (e.g., “gpt-4”)

    generate_counterfactual (Line 58)
    def generate_counterfactual(self, actual, change):
        """Generate counterfactual scenario with change."""
    

    Purpose: Generate counterfactual scenario with change.

    Parameters: – self: Instance reference – actual: Parameter for actual – change: Parameter for change

    compare_worlds (Line 144)
    def compare_worlds(self, actual, counterfactual):
        """Compare actual and counterfactual worlds."""
    

    Purpose: Compare actual and counterfactual worlds.

    Parameters: – self: Instance reference – actual: Parameter for actual – counterfactual: Parameter for counterfactual

    identify_critical_factors (Line 172)
    def identify_critical_factors(self, actual):
        """Identify factors critical to the actual outcome."""
    

    Purpose: Identify factors critical to the actual outcome.

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

    explore_minimal_changes (Line 201)
    def explore_minimal_changes(self, actual, desired_outcome):
        """Find minimal change needed for desired outcome."""
    

    Purpose: Find minimal change needed for desired outcome.

    Parameters: – self: Instance reference – actual: Parameter for actual – desired_outcome: Parameter for desired_outcome

    CounterfactualReasoningPattern (Line 240)

    Description: Counterfactual Reasoning Pattern – Explore “what if” scenarios.

    Generates alternative scenarios, compares outcomes, identifies critical factors, and explores minimal changes.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 251)
    def register_agent(self, agent):
        """Register counterfactual reasoning agent."""
    

    Purpose: Register counterfactual reasoning agent.

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

    run (Line 255)
    def run(self, queries):
        """Execute counterfactual reasoning queries."""
    

    Purpose: Execute counterfactual reasoning queries.

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


    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 = CounterfactualType(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

  • Agentic Architecture Pattern: Logical Reasoning

    
        """
    Pattern 209: Logical Reasoning Pattern
    
    Applies formal logic, propositional and predicate logic to derive conclusions.
    Handles logical operators (AND, OR, NOT), quantifiers, and logical proofs.
    """
    
    from typing import Dict, Any, List, Optional, Set
    from dataclasses import dataclass, field
    from enum import Enum
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    
    
    class LogicalOperator(Enum):
        """Logical operators."""
        AND = "AND"
        OR = "OR"
        NOT = "NOT"
        IMPLIES = "=>"
        IFF = ""  # if and only if
    
    
    @dataclass
    class Proposition:
        """Logical proposition."""
        statement: str
        truth_value: Optional[bool] = None
        variables: Set[str] = field(default_factory=set)
    
    
    @dataclass
    class LogicalRule:
        """Logical inference rule."""
        premises: List[str]
        conclusion: str
        rule_name: str = "modus_ponens"
    
    
    @dataclass
    class LogicalArgument:
        """Complete logical argument."""
        premises: List[Proposition]
        conclusion: Proposition
        is_valid: Optional[bool] = None
        proof_steps: List[str] = field(default_factory=list)
    
    
    class LogicalReasoningAgent:
        """Agent that performs logical reasoning."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.1)  # Low temp for logic
            self.knowledge_base: List[Proposition] = []
            self.rules: List[LogicalRule] = []
        
        def add_proposition(self, prop: Proposition):
            """Add proposition to knowledge base."""
            self.knowledge_base.append(prop)
            print(f"  Added: {prop.statement} = {prop.truth_value}")
        
        def evaluate_logical_expression(self, expression: str, 
                                        context: Dict[str, bool]) -> bool:
            """Evaluate logical expression given variable values."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Evaluate logical expression. Answer only TRUE or FALSE."),
                ("human", """Expression: {expression}
    Variable values: {context}
    
    What is the truth value? (TRUE or FALSE)""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "expression": expression,
                "context": str(context)
            })
            
            return "TRUE" in response.content.upper()
        
        def check_validity(self, argument: LogicalArgument) -> bool:
            """Check if logical argument is valid."""
            print(f"\n  {self.name}: Checking argument validity...")
            
            premises_text = "\n".join([f"- {p.statement}" for p in argument.premises])
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are a logic expert. Determine if the conclusion follows "
                          "logically from the premises."),
                ("human", """Premises:
    {premises}
    
    Conclusion: {conclusion}
    
    Is this argument logically valid? Answer YES or NO and explain why.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "premises": premises_text,
                "conclusion": argument.conclusion.statement
            })
            
            is_valid = "YES" in response.content.split("\n")[0].upper()
            argument.is_valid = is_valid
            
            print(f"  Argument is {'valid' if is_valid else 'invalid'}")
            return is_valid
        
        def construct_proof(self, premises: List[str], conclusion: str) -> List[str]:
            """Construct logical proof from premises to conclusion."""
            print(f"\n  {self.name}: Constructing proof...")
            
            premises_text = "\n".join([f"{i+1}. {p}" for i, p in enumerate(premises)])
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Construct a step-by-step logical proof."),
                ("human", """Given premises:
    {premises}
    
    Prove: {conclusion}
    
    Provide proof steps, each on a new line, showing logical progression.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "premises": premises_text,
                "conclusion": conclusion
            })
            
            proof_steps = [line.strip() for line in response.content.split("\n") 
                          if line.strip() and not line.strip().startswith("Prove")]
            
            print(f"  Proof constructed with {len(proof_steps)} steps")
            return proof_steps
        
        def apply_modus_ponens(self, conditional: str, antecedent: str) -> Optional[str]:
            """Apply modus ponens: If P then Q, P, therefore Q."""
            print(f"\n  Applying modus ponens...")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Apply modus ponens rule."),
                ("human", """Rule: {conditional}
    Fact: {antecedent}
    
    What conclusion follows? (Just state the conclusion)""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "conditional": conditional,
                "antecedent": antecedent
            })
            
            conclusion = response.content.strip()
            print(f"  Conclusion: {conclusion}")
            return conclusion
        
        def check_consistency(self) -> bool:
            """Check if knowledge base is logically consistent."""
            if len(self.knowledge_base)  str:
            """Solve logic puzzle using reasoning."""
            print(f"\n  {self.name}: Solving logic puzzle...")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Solve this logic puzzle step-by-step using logical reasoning."),
                ("human", "{puzzle}")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"puzzle": puzzle})
            
            return response.content
    
    
    class LogicalReasoningPattern:
        """
        Logical Reasoning Pattern - Apply formal logic.
        
        Handles logical operators, validates arguments, constructs proofs,
        and applies inference rules.
        """
        
        def __init__(self):
            self.agents: Dict[str, LogicalReasoningAgent] = {}
        
        def register_agent(self, agent: LogicalReasoningAgent):
            """Register logical reasoning agent."""
            self.agents[agent.name] = agent
        
        def run(self, scenarios: List[Dict[str, Any]]) -> Dict[str, Any]:
            """Execute logical reasoning scenarios."""
            print("=== Logical Reasoning Pattern ===\n")
            
            results = []
            for agent in self.agents.values():
                for scenario in scenarios:
                    scenario_type = scenario.get("type", "argument")
                    
                    if scenario_type == "argument":
                        argument = LogicalArgument(
                            premises=[Proposition(p) for p in scenario["premises"]],
                            conclusion=Proposition(scenario["conclusion"])
                        )
                        is_valid = agent.check_validity(argument)
                        results.append({"type": "argument", "valid": is_valid})
                    
                    elif scenario_type == "proof":
                        proof = agent.construct_proof(
                            scenario["premises"],
                            scenario["conclusion"]
                        )
                        results.append({"type": "proof", "steps": len(proof)})
                    
                    elif scenario_type == "modus_ponens":
                        conclusion = agent.apply_modus_ponens(
                            scenario["conditional"],
                            scenario["antecedent"]
                        )
                        results.append({"type": "inference", "conclusion": conclusion})
                    
                    elif scenario_type == "puzzle":
                        solution = agent.solve_logic_puzzle(scenario["puzzle"])
                        results.append({"type": "puzzle", "solution": solution[:100]})
            
            return {
                "pattern": "LogicalReasoning",
                "agents": len(self.agents),
                "scenarios_processed": len(scenarios),
                "results": results
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Logical Reasoning Pattern Demo ===\n")
        
        # Create pattern and agent
        pattern = LogicalReasoningPattern()
        agent = LogicalReasoningAgent("Logician")
        pattern.register_agent(agent)
        
        # Logical reasoning scenarios
        print("1. Testing logical reasoning capabilities...\n")
        scenarios = [
            {
                "type": "argument",
                "premises": [
                    "All humans are mortal",
                    "Socrates is a human"
                ],
                "conclusion": "Socrates is mortal"
            },
            {
                "type": "proof",
                "premises": [
                    "If it rains, the ground gets wet",
                    "It is raining"
                ],
                "conclusion": "The ground is wet"
            },
            {
                "type": "modus_ponens",
                "conditional": "If it's sunny, we go to the beach",
                "antecedent": "It's sunny"
            },
            {
                "type": "puzzle",
                "puzzle": "Three people: Alice, Bob, and Carol. One always tells truth, "
                         "one always lies, one alternates. Alice says 'I am not the liar'. "
                         "Bob says 'Alice is the liar'. Who is who?"
            }
        ]
        
        # Run logical reasoning
        summary = pattern.run(scenarios)
        
        print(f"\n=== Summary ===")
        print(f"Scenarios processed: {summary['scenarios_processed']}")
        print(f"Results: {len(summary['results'])} logical operations completed")
        
        print("\n✓ Logical reasoning: applying formal logic!")
    
        

    Agentic Architecture Pattern: Logical Reasoning

    Pattern 209: 209 Logical Reasoning Pattern – Line-by-Line Explanation

    Overview

    Pattern 209: Logical Reasoning Pattern

    Applies formal logic, propositional and predicate logic to derive conclusions. Handles logical operators (AND, OR, NOT), quantifiers, and logical proofs.


    Code Structure Analysis

    File Information

    • Pattern Number: 209
    • Pattern Name: 209 Logical Reasoning Pattern
    • File Path: patterns\advanced_reasoning\209_logical_reasoning_pattern.py
    • Total Lines: 304

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 209: Logical Reasoning Pattern
    
    Applies formal logic, propositional and predicate logic to derive conclusions.
    Handles logical operators (AND, OR, NOT), quantifiers, and logical proofs.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 209 Logical Reasoning Pattern pattern.


    Imports Section

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

    Explanation: The module imports necessary dependencies: – from typing import Dict, Any, List, Optional, Set: Type hints for better code documentation – from dataclasses import dataclass, field: Data class decorators for clean data structures – 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

    LogicalOperator (Line 15)

    class LogicalOperator(Enum):
        AND
        OR
        NOT
        IMPLIES
        IFF
    

    Purpose: Logical operators.

    Values: – AND: Represents and – OR: Represents or – NOT: Represents not – IMPLIES: Represents implies – IFF: Represents iff


    Classes

    LogicalOperator (Line 15)

    Description: Logical operators.

    Proposition (Line 25)

    Description: Logical proposition.

    LogicalRule (Line 33)

    Description: Logical inference rule.

    LogicalArgument (Line 41)

    Description: Complete logical argument.

    LogicalReasoningAgent (Line 49)

    Description: Agent that performs logical reasoning.

    Methods:

    __init__ (Line 52)
    def __init__(self, name, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – model_name: LLM model to use (e.g., “gpt-4”)

    add_proposition (Line 58)
    def add_proposition(self, prop):
        """Add proposition to knowledge base."""
    

    Purpose: Add proposition to knowledge base.

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

    evaluate_logical_expression (Line 63)
    def evaluate_logical_expression(self, expression, context):
        """Evaluate logical expression given variable values."""
    

    Purpose: Evaluate logical expression given variable values.

    Parameters: – self: Instance reference – expression: Parameter for expression – context: Parameter for context

    check_validity (Line 82)
    def check_validity(self, argument):
        """Check if logical argument is valid."""
    

    Purpose: Check if logical argument is valid.

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

    construct_proof (Line 111)
    def construct_proof(self, premises, conclusion):
        """Construct logical proof from premises to conclusion."""
    

    Purpose: Construct logical proof from premises to conclusion.

    Parameters: – self: Instance reference – premises: Parameter for premises – conclusion: Parameter for conclusion

    apply_modus_ponens (Line 139)
    def apply_modus_ponens(self, conditional, antecedent):
        """Apply modus ponens: If P then Q, P, therefore Q."""
    

    Purpose: Apply modus ponens: If P then Q, P, therefore Q.

    Parameters: – self: Instance reference – conditional: Parameter for conditional – antecedent: Parameter for antecedent

    check_consistency (Line 161)
    def check_consistency(self):
        """Check if knowledge base is logically consistent."""
    

    Purpose: Check if knowledge base is logically consistent.

    Parameters: – self: Instance reference

    solve_logic_puzzle (Line 182)
    def solve_logic_puzzle(self, puzzle):
        """Solve logic puzzle using reasoning."""
    

    Purpose: Solve logic puzzle using reasoning.

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

    LogicalReasoningPattern (Line 197)

    Description: Logical Reasoning Pattern – Apply formal logic.

    Handles logical operators, validates arguments, constructs proofs, and applies inference rules.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 208)
    def register_agent(self, agent):
        """Register logical reasoning agent."""
    

    Purpose: Register logical reasoning agent.

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

    run (Line 212)
    def run(self, scenarios):
        """Execute logical reasoning scenarios."""
    

    Purpose: Execute logical reasoning scenarios.

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


    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 = LogicalOperator(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

  • Agentic Architecture Pattern: Spatial Reasoning

    
        """
    Pattern 208: Spatial Reasoning Pattern
    
    Reasons about spatial relationships, locations, distances, orientations,
    and navigation. Handles concepts like left/right, near/far, inside/outside.
    """
    
    from typing import Dict, Any, List, Optional, Tuple
    from dataclasses import dataclass
    from enum import Enum
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    
    
    class SpatialRelation(Enum):
        """Types of spatial relationships."""
        ABOVE = "above"
        BELOW = "below"
        LEFT_OF = "left_of"
        RIGHT_OF = "right_of"
        IN_FRONT_OF = "in_front_of"
        BEHIND = "behind"
        INSIDE = "inside"
        OUTSIDE = "outside"
        NEAR = "near"
        FAR = "far"
        TOUCHING = "touching"
        ADJACENT = "adjacent"
    
    
    @dataclass
    class SpatialObject:
        """Object with spatial properties."""
        name: str
        location: Tuple[float, float, float]  # x, y, z coordinates
        size: Tuple[float, float, float]  # width, height, depth
        orientation: float = 0.0  # degrees
    
    
    @dataclass
    class SpatialQuery:
        """Query about spatial relationships."""
        query_text: str
        objects_involved: List[str]
        query_type: str  # "relation", "path", "distance", "visibility"
    
    
    class SpatialReasoningAgent:
        """Agent that performs spatial reasoning."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.3)
            self.objects: Dict[str, SpatialObject] = {}
        
        def add_object(self, obj: SpatialObject):
            """Add object to spatial environment."""
            self.objects[obj.name] = obj
        
        def determine_relation(self, obj1_name: str, obj2_name: str) -> str:
            """Determine spatial relation between two objects."""
            if obj1_name not in self.objects or obj2_name not in self.objects:
                return "unknown"
            
            obj1 = self.objects[obj1_name]
            obj2 = self.objects[obj2_name]
            
            dx = obj2.location[0] - obj1.location[0]
            dy = obj2.location[1] - obj1.location[1]
            dz = obj2.location[2] - obj1.location[2]
            
            # Simple spatial reasoning based on coordinates
            relations = []
            if dz > 0.5:
                relations.append("above")
            elif dz  0.5:
                relations.append("right of")
            elif dx  0.5:
                relations.append("in front of")
            elif dy < -0.5:
                relations.append("behind")
            
            distance = (dx**2 + dy**2 + dz**2) ** 0.5
            if distance  5.0:
                relations.append("far from")
            
            return ", ".join(relations) if relations else "at similar location"
        
        def calculate_distance(self, obj1_name: str, obj2_name: str) -> float:
            """Calculate Euclidean distance between objects."""
            if obj1_name not in self.objects or obj2_name not in self.objects:
                return -1.0
            
            obj1 = self.objects[obj1_name]
            obj2 = self.objects[obj2_name]
            
            dx = obj2.location[0] - obj1.location[0]
            dy = obj2.location[1] - obj1.location[1]
            dz = obj2.location[2] - obj1.location[2]
            
            return (dx**2 + dy**2 + dz**2) ** 0.5
        
        def find_path(self, start: str, goal: str, obstacles: List[str] = None) -> List[str]:
            """Find path from start to goal avoiding obstacles."""
            print(f"\n  {self.name}: Finding path from {start} to {goal}...")
            
            if start not in self.objects or goal not in self.objects:
                return []
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Plan a path from start to goal in 3D space."),
                ("human", """Start location: {start}
    Goal location: {goal}
    Obstacles: {obstacles}
    
    Describe a path as a sequence of waypoints.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "start": str(self.objects[start].location),
                "goal": str(self.objects[goal].location),
                "obstacles": str([self.objects[o].location for o in (obstacles or [])])
            })
            
            waypoints = [line.strip() for line in response.content.split("\n") if line.strip()]
            print(f"  Path: {len(waypoints)} waypoints")
            return waypoints
        
        def check_visibility(self, observer: str, target: str) -> bool:
            """Check if target is visible from observer."""
            if observer not in self.objects or target not in self.objects:
                return False
            
            obs = self.objects[observer]
            tgt = self.objects[target]
            
            # Simple line-of-sight check (no obstacles for now)
            distance = self.calculate_distance(observer, target)
            return distance  Dict[str, Any]:
            """Reason about spatial scene from natural language."""
            print(f"\n  {self.name}: Reasoning about scene...")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Analyze spatial relationships in scene description."),
                ("human", """Scene: {scene}
    
    Identify:
    1. Objects and their locations
    2. Spatial relationships between objects
    3. Possible navigation paths
    
    Provide structured analysis.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"scene": scene_description})
            
            return {
                "scene": scene_description,
                "analysis": response.content,
                "object_count": len(self.objects)
            }
    
    
    class SpatialReasoningPattern:
        """
        Spatial Reasoning Pattern - Understand space and location.
        
        Handles spatial relationships, distances, paths, visibility,
        and scene understanding.
        """
        
        def __init__(self):
            self.agents: Dict[str, SpatialReasoningAgent] = {}
        
        def register_agent(self, agent: SpatialReasoningAgent):
            """Register spatial reasoning agent."""
            self.agents[agent.name] = agent
        
        def run(self, queries: List[SpatialQuery]) -> Dict[str, Any]:
            """Execute spatial reasoning queries."""
            print("=== Spatial Reasoning Pattern ===\n")
            
            for agent in self.agents.values():
                for query in queries:
                    if query.query_type == "relation" and len(query.objects_involved) >= 2:
                        relation = agent.determine_relation(
                            query.objects_involved[0],
                            query.objects_involved[1]
                        )
                        print(f"\n  Relation: {query.objects_involved[0]} is {relation} {query.objects_involved[1]}")
                    
                    elif query.query_type == "distance" and len(query.objects_involved) >= 2:
                        distance = agent.calculate_distance(
                            query.objects_involved[0],
                            query.objects_involved[1]
                        )
                        print(f"\n  Distance: {distance:.2f} units")
                    
                    elif query.query_type == "path" and len(query.objects_involved) >= 2:
                        agent.find_path(
                            query.objects_involved[0],
                            query.objects_involved[1]
                        )
                    
                    elif query.query_type == "scene":
                        agent.reason_about_scene(query.query_text)
            
            return {
                "pattern": "SpatialReasoning",
                "agents": len(self.agents),
                "queries_processed": len(queries)
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Spatial Reasoning Pattern Demo ===\n")
        
        # Create pattern and agent
        pattern = SpatialReasoningPattern()
        agent = SpatialReasoningAgent("Navigator")
        pattern.register_agent(agent)
        
        # Add objects to spatial environment
        print("1. Setting up spatial environment...\n")
        agent.add_object(SpatialObject("Table", (0.0, 0.0, 0.0), (2.0, 1.0, 0.8)))
        agent.add_object(SpatialObject("Chair", (-1.0, 0.0, 0.0), (0.5, 0.5, 1.0)))
        agent.add_object(SpatialObject("Lamp", (0.0, 0.0, 1.5), (0.2, 0.2, 0.5)))
        agent.add_object(SpatialObject("Door", (5.0, 0.0, 0.0), (1.0, 0.1, 2.0)))
        agent.add_object(SpatialObject("Window", (0.0, 3.0, 1.0), (1.5, 0.1, 1.5)))
        
        # Spatial reasoning queries
        print("2. Executing spatial reasoning queries...\n")
        queries = [
            SpatialQuery(
                "Where is the lamp relative to the table?",
                ["Lamp", "Table"],
                "relation"
            ),
            SpatialQuery(
                "How far is the door from the chair?",
                ["Door", "Chair"],
                "distance"
            ),
            SpatialQuery(
                "Find path from chair to door",
                ["Chair", "Door"],
                "path"
            ),
            SpatialQuery(
                "The room has a table in the center with a lamp on it. "
                "A chair is to the left, and a door is on the right wall.",
                [],
                "scene"
            )
        ]
        
        # Run spatial reasoning
        summary = pattern.run(queries)
        
        print(f"\n=== Summary ===")
        print(f"Queries processed: {summary['queries_processed']}")
        print(f"Objects in environment: {len(agent.objects)}")
        
        print("\n✓ Spatial reasoning: understanding locations and relationships!")
    
        

    Agentic Architecture Pattern: Spatial Reasoning

    Pattern 208: 208 Spatial Reasoning Pattern – Line-by-Line Explanation

    Overview

    Pattern 208: Spatial Reasoning Pattern

    Reasons about spatial relationships, locations, distances, orientations, and navigation. Handles concepts like left/right, near/far, inside/outside.


    Code Structure Analysis

    File Information

    • Pattern Number: 208
    • Pattern Name: 208 Spatial Reasoning Pattern
    • File Path: patterns\advanced_reasoning\208_spatial_reasoning_pattern.py
    • Total Lines: 278

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 208: Spatial Reasoning Pattern
    
    Reasons about spatial relationships, locations, distances, orientations,
    and navigation. Handles concepts like left/right, near/far, inside/outside.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 208 Spatial Reasoning Pattern pattern.


    Imports Section

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

    Explanation: The module imports necessary dependencies: – from typing import Dict, Any, List, Optional, Tuple: Type hints for better code documentation – from dataclasses import dataclass: Data class decorators for clean data structures – 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

    SpatialRelation (Line 15)

    class SpatialRelation(Enum):
        ABOVE
        BELOW
        LEFT_OF
        RIGHT_OF
        IN_FRONT_OF
        BEHIND
        INSIDE
        OUTSIDE
        NEAR
        FAR
        TOUCHING
        ADJACENT
    

    Purpose: Types of spatial relationships.

    Values: – ABOVE: Represents above – BELOW: Represents below – LEFT_OF: Represents left of – RIGHT_OF: Represents right of – IN_FRONT_OF: Represents in front of – BEHIND: Represents behind – INSIDE: Represents inside – OUTSIDE: Represents outside – NEAR: Represents near – FAR: Represents far – TOUCHING: Represents touching – ADJACENT: Represents adjacent


    Classes

    SpatialRelation (Line 15)

    Description: Types of spatial relationships.

    SpatialObject (Line 32)

    Description: Object with spatial properties.

    SpatialQuery (Line 41)

    Description: Query about spatial relationships.

    SpatialReasoningAgent (Line 48)

    Description: Agent that performs spatial reasoning.

    Methods:

    __init__ (Line 51)
    def __init__(self, name, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – model_name: LLM model to use (e.g., “gpt-4”)

    add_object (Line 56)
    def add_object(self, obj):
        """Add object to spatial environment."""
    

    Purpose: Add object to spatial environment.

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

    determine_relation (Line 60)
    def determine_relation(self, obj1_name, obj2_name):
        """Determine spatial relation between two objects."""
    

    Purpose: Determine spatial relation between two objects.

    Parameters: – self: Instance reference – obj1_name: Parameter for obj1_name – obj2_name: Parameter for obj2_name

    calculate_distance (Line 97)
    def calculate_distance(self, obj1_name, obj2_name):
        """Calculate Euclidean distance between objects."""
    

    Purpose: Calculate Euclidean distance between objects.

    Parameters: – self: Instance reference – obj1_name: Parameter for obj1_name – obj2_name: Parameter for obj2_name

    find_path (Line 111)
    def find_path(self, start, goal, obstacles):
        """Find path from start to goal avoiding obstacles."""
    

    Purpose: Find path from start to goal avoiding obstacles.

    Parameters: – self: Instance reference – start: Parameter for start – goal: Parameter for goal – obstacles: Parameter for obstacles

    check_visibility (Line 138)
    def check_visibility(self, observer, target):
        """Check if target is visible from observer."""
    

    Purpose: Check if target is visible from observer.

    Parameters: – self: Instance reference – observer: Parameter for observer – target: Parameter for target

    reason_about_scene (Line 150)
    def reason_about_scene(self, scene_description):
        """Reason about spatial scene from natural language."""
    

    Purpose: Reason about spatial scene from natural language.

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

    SpatialReasoningPattern (Line 176)

    Description: Spatial Reasoning Pattern – Understand space and location.

    Handles spatial relationships, distances, paths, visibility, and scene understanding.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 187)
    def register_agent(self, agent):
        """Register spatial reasoning agent."""
    

    Purpose: Register spatial reasoning agent.

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

    run (Line 191)
    def run(self, queries):
        """Execute spatial reasoning queries."""
    

    Purpose: Execute spatial reasoning queries.

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


    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 = SpatialRelation(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

  • Agentic Architecture Pattern: Temporal Reasoning

    
        """
    Pattern 207: Temporal Reasoning Pattern
    
    Reasons about time, temporal sequences, durations, and temporal constraints.
    Handles before/after relationships, concurrency, and time-based planning.
    """
    
    from typing import Dict, Any, List, Optional
    from dataclasses import dataclass, field
    from datetime import datetime, timedelta
    from enum import Enum
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    
    
    class TemporalRelation(Enum):
        """Allen's interval algebra relations."""
        BEFORE = "before"
        AFTER = "after"
        MEETS = "meets"
        OVERLAPS = "overlaps"
        DURING = "during"
        STARTS = "starts"
        FINISHES = "finishes"
        EQUALS = "equals"
    
    
    @dataclass
    class TemporalEvent:
        """Event with temporal information."""
        name: str
        start_time: Optional[datetime] = None
        end_time: Optional[datetime] = None
        duration: Optional[timedelta] = None
        description: str = ""
    
    
    @dataclass
    class TemporalConstraint:
        """Constraint between temporal events."""
        event1: str
        event2: str
        relation: TemporalRelation
        description: str = ""
    
    
    class TemporalReasoningAgent:
        """Agent that performs temporal reasoning."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.3)
            self.events: List[TemporalEvent] = []
            self.constraints: List[TemporalConstraint] = []
        
        def add_event(self, event: TemporalEvent):
            """Add temporal event."""
            self.events.append(event)
        
        def infer_temporal_order(self, events_description: str) -> List[str]:
            """Infer temporal ordering of events from description."""
            print(f"\n  {self.name}: Inferring temporal order...")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Analyze text and determine temporal order of events."),
                ("human", """Text: {text}
    
    List the events in chronological order (earliest to latest).
    Format: one event per line.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"text": events_description})
            
            ordered_events = [line.strip().lstrip("0123456789.-) ") 
                             for line in response.content.split("\n") 
                             if line.strip()]
            
            print(f"  Ordered {len(ordered_events)} events")
            return ordered_events
        
        def calculate_duration(self, event_description: str) -> timedelta:
            """Estimate duration of an event."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Estimate typical duration in minutes for the event."),
                ("human", "Event: {event}\n\nTypical duration in minutes (just the number):")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"event": event_description})
            
            try:
                minutes = int(response.content.strip().split()[0])
                return timedelta(minutes=minutes)
            except:
                return timedelta(hours=1)  # Default
        
        def check_temporal_consistency(self) -> Dict[str, Any]:
            """Check if temporal constraints are consistent."""
            print(f"\n  {self.name}: Checking temporal consistency...")
            
            if len(self.events)  List[TemporalEvent]:
            """Plan schedule for tasks."""
            print(f"\n  {self.name}: Planning schedule for {len(tasks)} tasks...")
            
            schedule = []
            current_time = start_time
            
            for task in tasks:
                duration = self.calculate_duration(task)
                event = TemporalEvent(
                    name=task,
                    start_time=current_time,
                    end_time=current_time + duration,
                    duration=duration
                )
                schedule.append(event)
                self.events.append(event)
                current_time = event.end_time
                
                print(f"    {task}: {event.start_time.strftime('%H:%M')} - "
                      f"{event.end_time.strftime('%H:%M')} ({duration})")
            
            return schedule
        
        def reason_about_deadline(self, task: str, deadline: datetime,
                                 current_time: datetime) -> Dict[str, Any]:
            """Reason about meeting a deadline."""
            time_remaining = deadline - current_time
            duration = self.calculate_duration(task)
            
            can_meet = time_remaining >= duration
            buffer = time_remaining - duration if can_meet else timedelta(0)
            
            return {
                "task": task,
                "deadline": deadline,
                "estimated_duration": duration,
                "time_remaining": time_remaining,
                "can_meet_deadline": can_meet,
                "buffer_time": buffer
            }
    
    
    class TemporalReasoningPattern:
        """
        Temporal Reasoning Pattern - Reason about time.
        
        Handles temporal ordering, durations, constraints, scheduling,
        and deadline reasoning.
        """
        
        def __init__(self):
            self.agents: Dict[str, TemporalReasoningAgent] = {}
        
        def register_agent(self, agent: TemporalReasoningAgent):
            """Register temporal reasoning agent."""
            self.agents[agent.name] = agent
        
        def run(self, scenarios: List[Dict[str, Any]]) -> Dict[str, Any]:
            """Execute temporal reasoning scenarios."""
            print("=== Temporal Reasoning Pattern ===\n")
            
            for agent in self.agents.values():
                for scenario in scenarios:
                    scenario_type = scenario.get("type", "order")
                    
                    if scenario_type == "order":
                        agent.infer_temporal_order(scenario["text"])
                    elif scenario_type == "schedule":
                        agent.plan_schedule(
                            scenario["tasks"],
                            scenario.get("start_time", datetime.now())
                        )
                    elif scenario_type == "deadline":
                        result = agent.reason_about_deadline(
                            scenario["task"],
                            scenario["deadline"],
                            scenario.get("current_time", datetime.now())
                        )
                        print(f"\n  Deadline analysis:")
                        print(f"    Can meet: {result['can_meet_deadline']}")
                        print(f"    Buffer: {result['buffer_time']}")
            
            return {
                "pattern": "TemporalReasoning",
                "agents": len(self.agents),
                "scenarios_processed": len(scenarios),
                "events_tracked": sum(len(a.events) for a in self.agents.values())
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Temporal Reasoning Pattern Demo ===\n")
        
        # Create pattern and agent
        pattern = TemporalReasoningPattern()
        agent = TemporalReasoningAgent("TimeKeeper")
        pattern.register_agent(agent)
        
        # Temporal reasoning scenarios
        print("1. Temporal ordering scenario...")
        scenarios = [
            {
                "type": "order",
                "text": "First, I woke up. Then I had breakfast. After that, I went to work. "
                       "During lunch, I met a friend. Finally, I came home in the evening."
            },
            {
                "type": "schedule",
                "tasks": ["Morning meeting", "Code review", "Lunch break", "Development work"],
                "start_time": datetime.now().replace(hour=9, minute=0, second=0, microsecond=0)
            },
            {
                "type": "deadline",
                "task": "Write project report",
                "deadline": datetime.now() + timedelta(hours=4),
                "current_time": datetime.now()
            }
        ]
        
        # Run temporal reasoning
        summary = pattern.run(scenarios)
        
        print(f"\n=== Summary ===")
        print(f"Scenarios processed: {summary['scenarios_processed']}")
        print(f"Events tracked: {summary['events_tracked']}")
        
        print("\n✓ Temporal reasoning: understanding time and sequences!")
    
        

    Agentic Architecture Pattern: Temporal Reasoning

    Pattern 207: 207 Temporal Reasoning Pattern – Line-by-Line Explanation

    Overview

    Pattern 207: Temporal Reasoning Pattern

    Reasons about time, temporal sequences, durations, and temporal constraints. Handles before/after relationships, concurrency, and time-based planning.


    Code Structure Analysis

    File Information

    • Pattern Number: 207
    • Pattern Name: 207 Temporal Reasoning Pattern
    • File Path: patterns\advanced_reasoning\207_temporal_reasoning_pattern.py
    • Total Lines: 258

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 207: Temporal Reasoning Pattern
    
    Reasons about time, temporal sequences, durations, and temporal constraints.
    Handles before/after relationships, concurrency, and time-based planning.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 207 Temporal Reasoning Pattern pattern.


    Imports Section

    from typing import Dict, Any, List, Optional
    from dataclasses import dataclass, field
    from datetime import datetime, timedelta
    from enum import Enum
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI  # 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, timedelta: 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

    TemporalRelation (Line 16)

    class TemporalRelation(Enum):
        BEFORE
        AFTER
        MEETS
        OVERLAPS
        DURING
        STARTS
        FINISHES
        EQUALS
    

    Purpose: Allen’s interval algebra relations.

    Values: – BEFORE: Represents before – AFTER: Represents after – MEETS: Represents meets – OVERLAPS: Represents overlaps – DURING: Represents during – STARTS: Represents starts – FINISHES: Represents finishes – EQUALS: Represents equals


    Classes

    TemporalRelation (Line 16)

    Description: Allen’s interval algebra relations.

    TemporalEvent (Line 29)

    Description: Event with temporal information.

    TemporalConstraint (Line 39)

    Description: Constraint between temporal events.

    TemporalReasoningAgent (Line 47)

    Description: Agent that performs temporal reasoning.

    Methods:

    __init__ (Line 50)
    def __init__(self, name, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – model_name: LLM model to use (e.g., “gpt-4”)

    add_event (Line 56)
    def add_event(self, event):
        """Add temporal event."""
    

    Purpose: Add temporal event.

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

    infer_temporal_order (Line 60)
    def infer_temporal_order(self, events_description):
        """Infer temporal ordering of events from description."""
    

    Purpose: Infer temporal ordering of events from description.

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

    calculate_duration (Line 82)
    def calculate_duration(self, event_description):
        """Estimate duration of an event."""
    

    Purpose: Estimate duration of an event.

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

    check_temporal_consistency (Line 98)
    def check_temporal_consistency(self):
        """Check if temporal constraints are consistent."""
    

    Purpose: Check if temporal constraints are consistent.

    Parameters: – self: Instance reference

    plan_schedule (Line 128)
    def plan_schedule(self, tasks, start_time):
        """Plan schedule for tasks."""
    

    Purpose: Plan schedule for tasks.

    Parameters: – self: Instance reference – tasks: Parameter for tasks – start_time: Parameter for start_time

    reason_about_deadline (Line 153)
    def reason_about_deadline(self, task, deadline, current_time):
        """Reason about meeting a deadline."""
    

    Purpose: Reason about meeting a deadline.

    Parameters: – self: Instance reference – task: Parameter for task – deadline: Parameter for deadline – current_time: Parameter for current_time

    TemporalReasoningPattern (Line 172)

    Description: Temporal Reasoning Pattern – Reason about time.

    Handles temporal ordering, durations, constraints, scheduling, and deadline reasoning.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 183)
    def register_agent(self, agent):
        """Register temporal reasoning agent."""
    

    Purpose: Register temporal reasoning agent.

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

    run (Line 187)
    def run(self, scenarios):
        """Execute temporal reasoning scenarios."""
    

    Purpose: Execute temporal reasoning scenarios.

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


    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 = TemporalRelation(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

  • Agentic Architecture Pattern: Causal Reasoning

    
        """
    Pattern 206: Causal Reasoning Pattern
    
    Identifies cause-and-effect relationships, understands causal chains,
    and predicts outcomes based on causal mechanisms.
    """
    
    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
    
    
    class CausalRelationType(Enum):
        """Types of causal relationships."""
        DIRECT = "direct"  # A directly causes B
        INDIRECT = "indirect"  # A causes B through intermediary C
        CONTRIBUTORY = "contributory"  # A contributes to B
        PREVENTIVE = "preventive"  # A prevents B
        NECESSARY = "necessary"  # A is necessary for B
        SUFFICIENT = "sufficient"  # A is sufficient for B
    
    
    @dataclass
    class CausalRelation:
        """Represents a cause-effect relationship."""
        cause: str
        effect: str
        relation_type: CausalRelationType
        strength: float = 0.8  # 0.0 to 1.0
        mechanism: str = ""  # How cause leads to effect
        intermediaries: List[str] = field(default_factory=list)
    
    
    @dataclass
    class CausalQuery:
        """Query about causal relationships."""
        question: str
        context: Dict[str, Any]
        query_type: str  # "cause", "effect", "mechanism", "intervention"
    
    
    class CausalReasoningAgent:
        """Agent that performs causal reasoning."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.3)
            self.causal_graph: List[CausalRelation] = []
            self.interventions: List[Dict[str, Any]] = []
        
        def identify_cause(self, effect: str, context: Dict[str, Any]) -> List[str]:
            """Identify possible causes of an effect."""
            print(f"\n  {self.name}: Identifying causes of '{effect}'...")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are a causal reasoning expert. Identify likely causes."),
                ("human", """Effect: {effect}
    Context: {context}
    
    What are the most likely causes? List 2-3 primary causes, one per line.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"effect": effect, "context": str(context)})
            
            causes = [line.strip().lstrip("0123456789.-) ") 
                     for line in response.content.split("\n") 
                     if line.strip()]
            
            print(f"  Identified {len(causes)} potential causes")
            return causes[:3]
        
        def predict_effect(self, cause: str, context: Dict[str, Any]) -> List[str]:
            """Predict effects of a cause."""
            print(f"\n  {self.name}: Predicting effects of '{cause}'...")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are a causal reasoning expert. Predict likely effects."),
                ("human", """Cause: {cause}
    Context: {context}
    
    What effects will this cause? List 2-3 primary effects, one per line.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"cause": cause, "context": str(context)})
            
            effects = [line.strip().lstrip("0123456789.-) ") 
                      for line in response.content.split("\n") 
                      if line.strip()]
            
            print(f"  Predicted {len(effects)} effects")
            return effects[:3]
        
        def explain_mechanism(self, cause: str, effect: str) -> str:
            """Explain causal mechanism linking cause to effect."""
            print(f"\n  {self.name}: Explaining mechanism: {cause} → {effect}")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Explain the causal mechanism - how does the cause lead to the effect?"),
                ("human", "Cause: {cause}\nEffect: {effect}\n\nExplain the causal mechanism:")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"cause": cause, "effect": effect})
            
            mechanism = response.content.strip()
            print(f"  Mechanism: {mechanism[:80]}...")
            return mechanism
        
        def build_causal_chain(self, initial_cause: str, 
                              context: Dict[str, Any]) -> List[CausalRelation]:
            """Build a causal chain from initial cause."""
            print(f"\n  {self.name}: Building causal chain from '{initial_cause}'...")
            
            chain = []
            current_cause = initial_cause
            
            for step in range(3):  # Max 3 steps
                effects = self.predict_effect(current_cause, context)
                if not effects:
                    break
                
                primary_effect = effects[0]
                mechanism = self.explain_mechanism(current_cause, primary_effect)
                
                relation = CausalRelation(
                    cause=current_cause,
                    effect=primary_effect,
                    relation_type=CausalRelationType.DIRECT,
                    mechanism=mechanism,
                    strength=0.8 - (step * 0.1)  # Strength decreases with distance
                )
                
                chain.append(relation)
                self.causal_graph.append(relation)
                current_cause = primary_effect
            
            print(f"  Built chain with {len(chain)} causal links")
            return chain
        
        def simulate_intervention(self, intervention: str, 
                                target_effect: str) -> Dict[str, Any]:
            """Simulate effect of intervention."""
            print(f"\n  {self.name}: Simulating intervention: {intervention}")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Analyze causal impact of intervention."),
                ("human", """Intervention: {intervention}
    Target Effect: {target_effect}
    
    Will this intervention affect the target effect? How?
    Provide: IMPACT (increase/decrease/no_change) and CONFIDENCE (0.0-1.0)""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "intervention": intervention,
                "target_effect": target_effect
            })
            
            result = {
                "intervention": intervention,
                "target_effect": target_effect,
                "prediction": response.content,
                "confidence": 0.7
            }
            
            self.interventions.append(result)
            return result
    
    
    class CausalReasoningPattern:
        """
        Causal Reasoning Pattern - Understand cause and effect.
        
        Identifies causes, predicts effects, explains mechanisms,
        builds causal chains, and simulates interventions.
        """
        
        def __init__(self):
            self.agents: Dict[str, CausalReasoningAgent] = {}
        
        def register_agent(self, agent: CausalReasoningAgent):
            """Register causal reasoning agent."""
            self.agents[agent.name] = agent
        
        def run(self, queries: List[CausalQuery]) -> Dict[str, Any]:
            """Execute causal reasoning on queries."""
            print("=== Causal Reasoning Pattern ===\n")
            
            for agent in self.agents.values():
                for query in queries:
                    context = query.context
                    
                    if query.query_type == "cause":
                        agent.identify_cause(query.question, context)
                    elif query.query_type == "effect":
                        agent.predict_effect(query.question, context)
                    elif query.query_type == "chain":
                        agent.build_causal_chain(query.question, context)
                    elif query.query_type == "intervention":
                        agent.simulate_intervention(
                            query.question, 
                            context.get("target_effect", "unknown")
                        )
            
            return {
                "pattern": "CausalReasoning",
                "agents": len(self.agents),
                "queries_processed": len(queries),
                "causal_relations": sum(len(a.causal_graph) for a in self.agents.values())
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Causal Reasoning Pattern Demo ===\n")
        
        # Create pattern and agent
        pattern = CausalReasoningPattern()
        agent = CausalReasoningAgent("CausalAnalyst")
        pattern.register_agent(agent)
        
        # Causal reasoning queries
        queries = [
            CausalQuery(
                question="Global temperature increase",
                context={"domain": "climate"},
                query_type="cause"
            ),
            CausalQuery(
                question="Increased carbon emissions",
                context={"domain": "climate"},
                query_type="effect"
            ),
            CausalQuery(
                question="Poor sleep quality",
                context={"person": "adult", "lifestyle": "busy"},
                query_type="chain"
            ),
            CausalQuery(
                question="Regular exercise routine",
                context={"target_effect": "improved health"},
                query_type="intervention"
            ),
        ]
        
        # Run causal reasoning
        summary = pattern.run(queries)
        
        print(f"\n=== Summary ===")
        print(f"Queries processed: {summary['queries_processed']}")
        print(f"Causal relations identified: {summary['causal_relations']}")
        
        print(f"\n=== Causal Graph ===")
        for relation in agent.causal_graph:
            print(f"{relation.cause} → {relation.effect}")
            print(f"  Type: {relation.relation_type.value}, Strength: {relation.strength}")
        
        print("\n✓ Causal reasoning: understanding cause and effect!")
    
        

    Agentic Architecture Pattern: Causal Reasoning

    Pattern 206: 206 Causal Reasoning Pattern – Line-by-Line Explanation

    Overview

    Pattern 206: Causal Reasoning Pattern

    Identifies cause-and-effect relationships, understands causal chains, and predicts outcomes based on causal mechanisms.


    Code Structure Analysis

    File Information

    • Pattern Number: 206
    • Pattern Name: 206 Causal Reasoning Pattern
    • File Path: patterns\advanced_reasoning\206_causal_reasoning_pattern.py
    • Total Lines: 265

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 206: Causal Reasoning Pattern
    
    Identifies cause-and-effect relationships, understands causal chains,
    and predicts outcomes based on causal mechanisms.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 206 Causal Reasoning Pattern 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  # 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

    CausalRelationType (Line 16)

    class CausalRelationType(Enum):
        DIRECT
        INDIRECT
        CONTRIBUTORY
        PREVENTIVE
        NECESSARY
        SUFFICIENT
    

    Purpose: Types of causal relationships.

    Values: – DIRECT: Represents direct – INDIRECT: Represents indirect – CONTRIBUTORY: Represents contributory – PREVENTIVE: Represents preventive – NECESSARY: Represents necessary – SUFFICIENT: Represents sufficient


    Classes

    CausalRelationType (Line 16)

    Description: Types of causal relationships.

    CausalRelation (Line 27)

    Description: Represents a cause-effect relationship.

    CausalQuery (Line 38)

    Description: Query about causal relationships.

    CausalReasoningAgent (Line 45)

    Description: Agent that performs causal reasoning.

    Methods:

    __init__ (Line 48)
    def __init__(self, name, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – model_name: LLM model to use (e.g., “gpt-4”)

    identify_cause (Line 54)
    def identify_cause(self, effect, context):
        """Identify possible causes of an effect."""
    

    Purpose: Identify possible causes of an effect.

    Parameters: – self: Instance reference – effect: Parameter for effect – context: Parameter for context

    predict_effect (Line 76)
    def predict_effect(self, cause, context):
        """Predict effects of a cause."""
    

    Purpose: Predict effects of a cause.

    Parameters: – self: Instance reference – cause: Parameter for cause – context: Parameter for context

    explain_mechanism (Line 98)
    def explain_mechanism(self, cause, effect):
        """Explain causal mechanism linking cause to effect."""
    

    Purpose: Explain causal mechanism linking cause to effect.

    Parameters: – self: Instance reference – cause: Parameter for cause – effect: Parameter for effect

    build_causal_chain (Line 114)
    def build_causal_chain(self, initial_cause, context):
        """Build a causal chain from initial cause."""
    

    Purpose: Build a causal chain from initial cause.

    Parameters: – self: Instance reference – initial_cause: Parameter for initial_cause – context: Parameter for context

    simulate_intervention (Line 145)
    def simulate_intervention(self, intervention, target_effect):
        """Simulate effect of intervention."""
    

    Purpose: Simulate effect of intervention.

    Parameters: – self: Instance reference – intervention: Parameter for intervention – target_effect: Parameter for target_effect

    CausalReasoningPattern (Line 176)

    Description: Causal Reasoning Pattern – Understand cause and effect.

    Identifies causes, predicts effects, explains mechanisms, builds causal chains, and simulates interventions.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 187)
    def register_agent(self, agent):
        """Register causal reasoning agent."""
    

    Purpose: Register causal reasoning agent.

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

    run (Line 191)
    def run(self, queries):
        """Execute causal reasoning on queries."""
    

    Purpose: Execute causal reasoning on queries.

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


    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 = CausalRelationType(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

  • Agentic Architecture Pattern: Commonsense Reasoning

    
        """
    Pattern 205: Commonsense Reasoning Pattern
    
    Applies everyday knowledge and intuitive understanding to reason about
    situations. Handles implicit knowledge that humans take for granted.
    """
    
    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
    
    
    class KnowledgeType(Enum):
        """Types of commonsense knowledge."""
        PHYSICAL = "physical"  # Gravity, objects fall
        SOCIAL = "social"  # People have feelings
        TEMPORAL = "temporal"  # Time flows forward
        SPATIAL = "spatial"  # Objects have location
        CAUSAL = "causal"  # Actions have consequences
        FUNCTIONAL = "functional"  # Objects have purposes
    
    
    @dataclass
    class CommonsenseKnowledge:
        """Piece of commonsense knowledge."""
        statement: str
        knowledge_type: KnowledgeType
        confidence: float = 0.9
        source: str = "general"
    
    
    @dataclass
    class ReasoningQuery:
        """Query requiring commonsense reasoning."""
        question: str
        context: Dict[str, Any]
        requires_knowledge: List[KnowledgeType] = field(default_factory=list)
    
    
    @dataclass
    class CommonsenseAnswer:
        """Answer based on commonsense reasoning."""
        query: str
        answer: str
        reasoning: str
        knowledge_used: List[CommonsenseKnowledge]
        confidence: float
    
    
    class CommonsenseKnowledgeBase:
        """Storage for commonsense knowledge."""
        
        def __init__(self):
            self.knowledge: List[CommonsenseKnowledge] = []
            self._populate_basic_knowledge()
        
        def _populate_basic_knowledge(self):
            """Populate with basic commonsense knowledge."""
            basic_knowledge = [
                CommonsenseKnowledge("Objects fall down due to gravity", KnowledgeType.PHYSICAL),
                CommonsenseKnowledge("People need food and water to survive", KnowledgeType.PHYSICAL),
                CommonsenseKnowledge("Time moves forward, not backward", KnowledgeType.TEMPORAL),
                CommonsenseKnowledge("People feel pain when hurt", KnowledgeType.SOCIAL),
                CommonsenseKnowledge("Tools are used to accomplish tasks", KnowledgeType.FUNCTIONAL),
                CommonsenseKnowledge("Actions have consequences", KnowledgeType.CAUSAL),
            ]
            self.knowledge.extend(basic_knowledge)
        
        def get_relevant_knowledge(self, knowledge_types: List[KnowledgeType]) -> List[CommonsenseKnowledge]:
            """Get knowledge relevant to types."""
            if not knowledge_types:
                return self.knowledge
            return [k for k in self.knowledge if k.knowledge_type in knowledge_types]
        
        def add_knowledge(self, knowledge: CommonsenseKnowledge):
            """Add new commonsense knowledge."""
            self.knowledge.append(knowledge)
    
    
    class CommonsenseReasoningAgent:
        """Agent that applies commonsense reasoning."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.5)
            self.knowledge_base = CommonsenseKnowledgeBase()
            self.answers: List[CommonsenseAnswer] = []
        
        def reason(self, query: ReasoningQuery) -> CommonsenseAnswer:
            """Apply commonsense reasoning to query."""
            print(f"\n  {self.name}: Reasoning about: {query.question[:60]}...")
            
            # Get relevant knowledge
            relevant_knowledge = self.knowledge_base.get_relevant_knowledge(
                query.requires_knowledge
            )
            
            knowledge_text = "\n".join([
                f"- {k.statement} ({k.knowledge_type.value})"
                for k in relevant_knowledge
            ])
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are applying commonsense reasoning. Use everyday knowledge "
                          "that people typically understand intuitively."),
                ("human", """Question: {question}
    
    Context: {context}
    
    Relevant Commonsense Knowledge:
    {knowledge}
    
    Provide:
    1. A direct answer
    2. Step-by-step reasoning showing commonsense logic
    3. Confidence level (0.0-1.0)
    
    Format:
    ANSWER: 
    REASONING: 
    CONFIDENCE: """)
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "question": query.question,
                "context": str(query.context),
                "knowledge": knowledge_text
            })
            
            # Parse response
            answer_text = ""
            reasoning_text = ""
            confidence = 0.8
            
            for line in response.content.split("\n"):
                if line.startswith("ANSWER:"):
                    answer_text = line.replace("ANSWER:", "").strip()
                elif line.startswith("REASONING:"):
                    reasoning_text = line.replace("REASONING:", "").strip()
                elif line.startswith("CONFIDENCE:"):
                    try:
                        confidence = float(line.replace("CONFIDENCE:", "").strip())
                    except:
                        confidence = 0.8
            
            if not answer_text:
                answer_text = response.content[:200]
            if not reasoning_text:
                reasoning_text = "Applied commonsense reasoning"
            
            answer = CommonsenseAnswer(
                query=query.question,
                answer=answer_text,
                reasoning=reasoning_text,
                knowledge_used=relevant_knowledge,
                confidence=confidence
            )
            
            self.answers.append(answer)
            print(f"  Answer: {answer_text[:80]}...")
            print(f"  Confidence: {confidence}")
            
            return answer
    
    
    class CommonsenseReasoningPattern:
        """
        Commonsense Reasoning Pattern - Apply everyday knowledge.
        
        Uses intuitive, everyday knowledge to reason about situations
        that require implicit understanding.
        """
        
        def __init__(self):
            self.agents: Dict[str, CommonsenseReasoningAgent] = {}
        
        def register_agent(self, agent: CommonsenseReasoningAgent):
            """Register commonsense reasoning agent."""
            self.agents[agent.name] = agent
        
        def run(self, queries: List[ReasoningQuery]) -> Dict[str, Any]:
            """Execute commonsense reasoning on queries."""
            print("=== Commonsense Reasoning Pattern ===\n")
            
            for agent in self.agents.values():
                print(f"{agent.name}: Processing {len(queries)} queries...")
                for query in queries:
                    agent.reason(query)
            
            return {
                "pattern": "CommonsenseReasoning",
                "agents": len(self.agents),
                "queries_processed": len(queries),
                "total_answers": sum(len(a.answers) for a in self.agents.values())
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Commonsense Reasoning Pattern Demo ===\n")
        
        # Create pattern and agent
        pattern = CommonsenseReasoningPattern()
        agent = CommonsenseReasoningAgent("CommonSenseBot")
        pattern.register_agent(agent)
        
        # Queries requiring commonsense
        print("1. Creating queries requiring commonsense reasoning...\n")
        queries = [
            ReasoningQuery(
                question="If I drop a glass on a hard floor, what will likely happen?",
                context={"object": "glass", "surface": "hard floor", "action": "drop"},
                requires_knowledge=[KnowledgeType.PHYSICAL, KnowledgeType.CAUSAL]
            ),
            ReasoningQuery(
                question="If someone hasn't eaten all day, what should I offer them?",
                context={"person": "hungry", "time_without_food": "all day"},
                requires_knowledge=[KnowledgeType.PHYSICAL, KnowledgeType.SOCIAL]
            ),
            ReasoningQuery(
                question="Why would someone use an umbrella on a rainy day?",
                context={"weather": "rainy", "object": "umbrella"},
                requires_knowledge=[KnowledgeType.FUNCTIONAL, KnowledgeType.PHYSICAL]
            ),
            ReasoningQuery(
                question="If I'm late for an important meeting, how should I communicate?",
                context={"situation": "late", "event": "important meeting"},
                requires_knowledge=[KnowledgeType.SOCIAL, KnowledgeType.TEMPORAL]
            ),
        ]
        
        # Run reasoning
        summary = pattern.run(queries)
        
        print(f"\n2. Summary:")
        print(f"   Queries processed: {summary['queries_processed']}")
        print(f"   Total answers: {summary['total_answers']}")
        
        print(f"\n3. Answers with Reasoning:")
        for i, answer in enumerate(agent.answers, 1):
            print(f"\n   Query {i}: {answer.query[:50]}...")
            print(f"   Answer: {answer.answer}")
            print(f"   Reasoning: {answer.reasoning[:100]}...")
            print(f"   Knowledge types used: {len(answer.knowledge_used)}")
        
        print("\n✓ Commonsense reasoning applied everyday knowledge!")
    
        

    Agentic Architecture Pattern: Commonsense Reasoning

    Pattern 205: 205 Commonsense Reasoning Pattern – Line-by-Line Explanation

    Overview

    Pattern 205: Commonsense Reasoning Pattern

    Applies everyday knowledge and intuitive understanding to reason about situations. Handles implicit knowledge that humans take for granted.


    Code Structure Analysis

    File Information

    • Pattern Number: 205
    • Pattern Name: 205 Commonsense Reasoning Pattern
    • File Path: patterns\advanced_reasoning\205_commonsense_reasoning_pattern.py
    • Total Lines: 251

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 205: Commonsense Reasoning Pattern
    
    Applies everyday knowledge and intuitive understanding to reason about
    situations. Handles implicit knowledge that humans take for granted.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 205 Commonsense Reasoning Pattern 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  # 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

    KnowledgeType (Line 16)

    class KnowledgeType(Enum):
        PHYSICAL
        SOCIAL
        TEMPORAL
        SPATIAL
        CAUSAL
        FUNCTIONAL
    

    Purpose: Types of commonsense knowledge.

    Values: – PHYSICAL: Represents physical – SOCIAL: Represents social – TEMPORAL: Represents temporal – SPATIAL: Represents spatial – CAUSAL: Represents causal – FUNCTIONAL: Represents functional


    Classes

    KnowledgeType (Line 16)

    Description: Types of commonsense knowledge.

    CommonsenseKnowledge (Line 27)

    Description: Piece of commonsense knowledge.

    ReasoningQuery (Line 36)

    Description: Query requiring commonsense reasoning.

    CommonsenseAnswer (Line 44)

    Description: Answer based on commonsense reasoning.

    CommonsenseKnowledgeBase (Line 53)

    Description: Storage for commonsense knowledge.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    _populate_basic_knowledge (Line 60)
    def _populate_basic_knowledge(self):
        """Populate with basic commonsense knowledge."""
    

    Purpose: Populate with basic commonsense knowledge.

    Parameters: – self: Instance reference

    get_relevant_knowledge (Line 72)
    def get_relevant_knowledge(self, knowledge_types):
        """Get knowledge relevant to types."""
    

    Purpose: Get knowledge relevant to types.

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

    add_knowledge (Line 78)
    def add_knowledge(self, knowledge):
        """Add new commonsense knowledge."""
    

    Purpose: Add new commonsense knowledge.

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

    CommonsenseReasoningAgent (Line 83)

    Description: Agent that applies commonsense reasoning.

    Methods:

    __init__ (Line 86)
    def __init__(self, name, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – model_name: LLM model to use (e.g., “gpt-4”)

    reason (Line 92)
    def reason(self, query):
        """Apply commonsense reasoning to query."""
    

    Purpose: Apply commonsense reasoning to query.

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

    CommonsenseReasoningPattern (Line 170)

    Description: Commonsense Reasoning Pattern – Apply everyday knowledge.

    Uses intuitive, everyday knowledge to reason about situations that require implicit understanding.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 181)
    def register_agent(self, agent):
        """Register commonsense reasoning agent."""
    

    Purpose: Register commonsense reasoning agent.

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

    run (Line 185)
    def run(self, queries):
        """Execute commonsense reasoning on queries."""
    

    Purpose: Execute commonsense reasoning on queries.

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


    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 = KnowledgeType(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

  • Agentic Architecture Pattern: Inductive Reasoning

    
        """
    Pattern 204: Inductive Reasoning Pattern
    
    Reasons from specific observations to general principles through pattern
    recognition and generalization. Infers general rules from examples.
    """
    
    from typing import Dict, Any, List, Optional
    from dataclasses import dataclass, field
    from datetime import datetime
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    
    
    @dataclass
    class Observation:
        """Single observation/example."""
        description: str
        attributes: Dict[str, Any]
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    @dataclass
    class GeneralPrinciple:
        """Inferred general principle."""
        principle: str
        confidence: float  # 0.0 to 1.0
        supporting_observations: List[Observation]
        counter_examples: List[Observation] = field(default_factory=list)
    
    
    class InductiveReasoningAgent:
        """Agent that performs inductive reasoning."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.3)
            self.observations: List[Observation] = []
            self.principles: List[GeneralPrinciple] = []
        
        def add_observation(self, observation: Observation):
            """Add new observation."""
            self.observations.append(observation)
            print(f"  {self.name}: Added observation - {observation.description}")
        
        def induce_principles(self) -> List[GeneralPrinciple]:
            """Induce general principles from observations."""
            print(f"\n  {self.name}: Inducing principles from {len(self.observations)} observations...")
            
            if len(self.observations)  2 else ""
                        
                        # Parse supporting observation indices
                        supporting_obs = []
                        for idx_str in indices_str.split(","):
                            try:
                                idx = int(idx_str.strip()) - 1
                                if 0 <= idx  bool:
            """Test if principle applies to new observation."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Determine if a general principle applies to a new observation."),
                ("human", """General Principle: {principle}
    
    New Observation: {observation}
    Attributes: {attributes}
    
    Does this principle apply? Answer YES or NO with brief explanation.""")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "principle": principle.principle,
                "observation": test_observation.description,
                "attributes": str(test_observation.attributes)
            })
            
            result = "YES" in response.content.upper()
            if result:
                principle.supporting_observations.append(test_observation)
            else:
                principle.counter_examples.append(test_observation)
            
            return result
    
    
    class InductiveReasoningPattern:
        """
        Inductive Reasoning Pattern - From specific to general.
        
        Collects observations, identifies patterns, induces general principles,
        and tests them against new observations.
        """
        
        def __init__(self):
            self.agents: Dict[str, InductiveReasoningAgent] = {}
        
        def register_agent(self, agent: InductiveReasoningAgent):
            """Register inductive reasoning agent."""
            self.agents[agent.name] = agent
        
        def run(self, observations: List[Observation], 
                test_cases: Optional[List[Observation]] = None) -> Dict[str, Any]:
            """Execute inductive reasoning process."""
            print("=== Inductive Reasoning Pattern ===\n")
            
            for agent in self.agents.values():
                # Add observations
                print(f"{agent.name}: Collecting observations...")
                for obs in observations:
                    agent.add_observation(obs)
                
                # Induce principles
                principles = agent.induce_principles()
                
                # Test principles if test cases provided
                if test_cases:
                    print(f"\n  Testing principles with new observations...")
                    for test_obs in test_cases:
                        print(f"\n  Test: {test_obs.description}")
                        for i, principle in enumerate(principles, 1):
                            result = agent.test_principle(principle, test_obs)
                            print(f"    Principle {i}: {'✓ Applies' if result else '✗ Does not apply'}")
            
            return {
                "pattern": "InductiveReasoning",
                "agents": len(self.agents),
                "total_observations": sum(len(a.observations) for a in self.agents.values()),
                "total_principles": sum(len(a.principles) for a in self.agents.values())
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Inductive Reasoning Pattern Demo ===\n")
        
        # Create pattern and agent
        pattern = InductiveReasoningPattern()
        agent = InductiveReasoningAgent("Scientist")
        pattern.register_agent(agent)
        
        # Training observations (specific examples)
        print("1. Collecting specific observations...\n")
        observations = [
            Observation("The swan in the park is white", {"color": "white", "animal": "swan"}),
            Observation("Another swan at the lake is white", {"color": "white", "animal": "swan"}),
            Observation("The swan at the zoo is also white", {"color": "white", "animal": "swan"}),
            Observation("Swans in the book pictures are white", {"color": "white", "animal": "swan"}),
            Observation("Heated metal expands", {"temperature": "hot", "material": "metal", "state": "expanded"}),
            Observation("Heated water expands", {"temperature": "hot", "material": "water", "state": "expanded"}),
            Observation("Heated air expands", {"temperature": "hot", "material": "air", "state": "expanded"}),
        ]
        
        # Test cases (new observations)
        test_cases = [
            Observation("A black swan in Australia", {"color": "black", "animal": "swan"}),
            Observation("Heated plastic expands", {"temperature": "hot", "material": "plastic", "state": "expanded"}),
        ]
        
        # Run inductive reasoning
        summary = pattern.run(observations, test_cases)
        
        print(f"\n2. Summary:")
        print(f"   Total observations: {summary['total_observations']}")
        print(f"   Principles induced: {summary['total_principles']}")
        
        print(f"\n3. Induced Principles:")
        for i, principle in enumerate(agent.principles, 1):
            print(f"   {i}. {principle.principle}")
            print(f"      Confidence: {principle.confidence}")
            print(f"      Supported by: {len(principle.supporting_observations)} observations")
            print(f"      Counter-examples: {len(principle.counter_examples)}")
        
        print("\n✓ Inductive reasoning: specific observations → general principles!")
    
        

    Agentic Architecture Pattern: Inductive Reasoning

    Pattern 204: 204 Inductive Reasoning Pattern – Line-by-Line Explanation

    Overview

    Pattern 204: Inductive Reasoning Pattern

    Reasons from specific observations to general principles through pattern recognition and generalization. Infers general rules from examples.


    Code Structure Analysis

    File Information

    • Pattern Number: 204
    • Pattern Name: 204 Inductive Reasoning Pattern
    • File Path: patterns\advanced_reasoning\204_inductive_reasoning_pattern.py
    • Total Lines: 231

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 204: Inductive Reasoning Pattern
    
    Reasons from specific observations to general principles through pattern
    recognition and generalization. Infers general rules from examples.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 204 Inductive Reasoning Pattern pattern.


    Imports Section

    from typing import Dict, Any, List, Optional
    from dataclasses import dataclass, field
    from datetime import datetime
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI  # 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 langchain_core.prompts import ChatPromptTemplate: LangChain framework integration – from langchain_openai import ChatOpenAI: LangChain framework integration


    Classes

    Observation (Line 16)

    Description: Single observation/example.

    GeneralPrinciple (Line 24)

    Description: Inferred general principle.

    InductiveReasoningAgent (Line 32)

    Description: Agent that performs inductive reasoning.

    Methods:

    __init__ (Line 35)
    def __init__(self, name, model_name):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – model_name: LLM model to use (e.g., “gpt-4”)

    add_observation (Line 41)
    def add_observation(self, observation):
        """Add new observation."""
    

    Purpose: Add new observation.

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

    induce_principles (Line 46)
    def induce_principles(self):
        """Induce general principles from observations."""
    

    Purpose: Induce general principles from observations.

    Parameters: – self: Instance reference

    test_principle (Line 114)
    def test_principle(self, principle, test_observation):
        """Test if principle applies to new observation."""
    

    Purpose: Test if principle applies to new observation.

    Parameters: – self: Instance reference – principle: Parameter for principle – test_observation: Parameter for test_observation

    InductiveReasoningPattern (Line 143)

    Description: Inductive Reasoning Pattern – From specific to general.

    Collects observations, identifies patterns, induces general principles, and tests them against new observations.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 154)
    def register_agent(self, agent):
        """Register inductive reasoning agent."""
    

    Purpose: Register inductive reasoning agent.

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

    run (Line 158)
    def run(self, observations, test_cases):
        """Execute inductive reasoning process."""
    

    Purpose: Execute inductive reasoning process.

    Parameters: – self: Instance reference – observations: Parameter for observations – test_cases: Parameter for test_cases


    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 = Observation(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