Spaces:
Running
Running
| """ | |
| Base class for all reasoning agents in the forge. | |
| Each agent must implement analyze() and get_analysis_templates(). | |
| The base class provides keyword matching and template selection utilities. | |
| """ | |
| from abc import ABC, abstractmethod | |
| import random | |
| import re | |
| class ReasoningAgent(ABC): | |
| """Abstract base class for all reasoning agents.""" | |
| name: str = "BaseAgent" | |
| perspective: str = "general" | |
| def __init__(self): | |
| self._templates = self.get_analysis_templates() | |
| self._keyword_map = self.get_keyword_map() | |
| def analyze(self, concept: str) -> str: | |
| """Analyze a concept from this agent's perspective. | |
| Args: | |
| concept: The concept text to analyze. | |
| Returns: | |
| A substantive analysis string from this agent's perspective. | |
| """ | |
| raise NotImplementedError | |
| def get_analysis_templates(self) -> list[str]: | |
| """Return diverse analysis templates. | |
| Each template should contain {concept} placeholder and produce | |
| genuine expert-level reasoning, not placeholder text. | |
| Returns: | |
| List of template strings. | |
| """ | |
| raise NotImplementedError | |
| def get_keyword_map(self) -> dict[str, list[int]]: | |
| """Return a mapping of keywords to preferred template indices. | |
| Override in subclasses to steer template selection based on | |
| concept content. Keys are lowercase keywords/phrases, values | |
| are lists of template indices that work well for that keyword. | |
| Returns: | |
| Dictionary mapping keywords to template index lists. | |
| """ | |
| return {} | |
| def select_template(self, concept: str) -> str: | |
| """Select the best template for the given concept. | |
| Uses keyword matching to find relevant templates. Falls back | |
| to random selection if no keywords match. | |
| Args: | |
| concept: The concept text. | |
| Returns: | |
| A single template string. | |
| """ | |
| concept_lower = concept.lower() | |
| scored_indices: dict[int, int] = {} | |
| for keyword, indices in self._keyword_map.items(): | |
| if keyword in concept_lower: | |
| for idx in indices: | |
| if 0 <= idx < len(self._templates): | |
| scored_indices[idx] = scored_indices.get(idx, 0) + 1 | |
| if scored_indices: | |
| max_score = max(scored_indices.values()) | |
| best = [i for i, s in scored_indices.items() if s == max_score] | |
| chosen = random.choice(best) | |
| return self._templates[chosen] | |
| return random.choice(self._templates) | |
| def extract_key_terms(self, concept: str) -> list[str]: | |
| """Extract significant terms from the concept for template filling. | |
| Args: | |
| concept: The concept text. | |
| Returns: | |
| List of key terms found in the concept. | |
| """ | |
| stop_words = { | |
| "the", "a", "an", "is", "are", "was", "were", "be", "been", | |
| "being", "have", "has", "had", "do", "does", "did", "will", | |
| "would", "could", "should", "may", "might", "can", "shall", | |
| "of", "in", "to", "for", "with", "on", "at", "from", "by", | |
| "about", "as", "into", "through", "during", "before", "after", | |
| "above", "below", "between", "and", "but", "or", "nor", "not", | |
| "so", "yet", "both", "either", "neither", "each", "every", | |
| "this", "that", "these", "those", "it", "its", "they", "them", | |
| "their", "we", "our", "you", "your", "he", "she", "his", "her", | |
| "how", "what", "when", "where", "which", "who", "why", | |
| } | |
| words = re.findall(r'\b[a-zA-Z]{3,}\b', concept.lower()) | |
| return [w for w in words if w not in stop_words] | |
| def __repr__(self) -> str: | |
| return f"{self.__class__.__name__}(name={self.name!r}, perspective={self.perspective!r})" | |