Spaces:
Sleeping
Sleeping
| """Base Domain Plugin Interface""" | |
| from abc import ABC, abstractmethod | |
| from typing import Dict, Tuple, List, Optional | |
| from dataclasses import dataclass | |
| class DomainScore: | |
| """Standardized domain scoring output""" | |
| domain_type: str | |
| score: float # 0-1 | |
| confidence: float # 0-1 | |
| raw_features: Dict # Raw feature values for explainability | |
| processing_time_ms: float | |
| def to_dict(self): | |
| return { | |
| 'domain_type': self.domain_type, | |
| 'score': round(self.score, 3), | |
| 'confidence': round(self.confidence, 3), | |
| 'raw_features': self.raw_features, | |
| 'processing_time_ms': round(self.processing_time_ms, 2) | |
| } | |
| class BaseDomainPlugin(ABC): | |
| """Abstract base class for all domain plugins""" | |
| def __init__(self): | |
| self.domain_type = self._get_domain_type() | |
| self.feature_weights = self._get_feature_weights() | |
| def _get_domain_type(self) -> str: | |
| """Return domain identifier (e.g., 'tech', 'business')""" | |
| pass | |
| def _get_feature_weights(self) -> Dict[str, float]: | |
| """Return feature name to weight mapping""" | |
| pass | |
| def get_required_fields(self) -> List[str]: | |
| """Return list of required input fields for this domain""" | |
| pass | |
| def get_optional_fields(self) -> List[str]: | |
| """Return list of optional input fields""" | |
| pass | |
| def validate_inputs(self, evidence_data: Dict) -> Tuple[bool, Optional[str]]: | |
| """ | |
| Validate input data completeness | |
| Returns: (is_valid, error_message) | |
| """ | |
| required = self.get_required_fields() | |
| missing = [f for f in required if not evidence_data.get(f)] | |
| if missing: | |
| return False, f"Missing required fields: {', '.join(missing)}" | |
| return True, None | |
| def score(self, evidence_data: Dict) -> DomainScore: | |
| """ | |
| Main scoring method - must be implemented by each plugin | |
| Args: | |
| evidence_data: Dictionary containing domain-specific inputs | |
| Returns: | |
| DomainScore object with score, confidence, and features | |
| """ | |
| pass | |
| def explain(self, features: Dict) -> Dict: | |
| """Generate human-readable explanation of scoring""" | |
| explanations = { | |
| 'top_features': [], | |
| 'recommendations': [] | |
| } | |
| # Sort features by value | |
| sorted_features = sorted(features.items(), key=lambda x: x[1], reverse=True) | |
| # Top 3 features | |
| for feat, val in sorted_features[:3]: | |
| if val > 0.3: | |
| explanations['top_features'].append({ | |
| 'feature': feat, | |
| 'value': round(val, 2), | |
| 'weight': self.feature_weights.get(feat, 0) | |
| }) | |
| return explanations | |
| def calculate_confidence(self, evidence_data: Dict) -> float: | |
| """ | |
| Calculate confidence based on data completeness and quality | |
| Returns: 0-1 confidence score | |
| """ | |
| required_fields = self.get_required_fields() | |
| optional_fields = self.get_optional_fields() | |
| total_fields = len(required_fields) + len(optional_fields) | |
| filled_required = sum(1 for f in required_fields if evidence_data.get(f)) | |
| filled_optional = sum(1 for f in optional_fields if evidence_data.get(f)) | |
| # Base confidence from required fields (70%) | |
| required_confidence = (filled_required / len(required_fields)) * 0.7 if required_fields else 0.7 | |
| # Bonus from optional fields (30%) | |
| optional_confidence = (filled_optional / len(optional_fields)) * 0.3 if optional_fields else 0.3 | |
| return min(required_confidence + optional_confidence, 1.0) | |