""" TechScout Configuration Central configuration for all components. """ from dataclasses import dataclass, field from typing import List, Optional from pathlib import Path @dataclass class OllamaConfig: """Ollama LLM configuration.""" base_url: str = "http://localhost:11434" fast_model: str = "llama3.2:latest" # Quick decomposition default_model: str = "mistral-nemo:12b" # Standard analysis quality_model: str = "qwen2.5:14b" # Deep analysis temperature: float = 0.1 max_tokens: int = 4096 @dataclass class SearchConfig: """Search configuration.""" max_results_per_source: int = 20 request_delay: float = 1.0 # Rate limiting timeout: int = 30 # Source weights for scoring source_weights: dict = field(default_factory=lambda: { "sbir_sttr": 1.2, # High relevance for defense tech "uspto": 1.1, # Patents indicate innovation "usaspending": 1.0, # Contract history "defense_news": 0.9, # News/press "web_search": 0.8, # General web "arxiv": 1.0, # Academic research }) @dataclass class ScoringConfig: """Scoring and ranking configuration.""" # Weights for different scoring factors technical_relevance_weight: float = 0.35 trl_match_weight: float = 0.20 recency_weight: float = 0.15 source_authority_weight: float = 0.15 funding_indicator_weight: float = 0.15 # TRL preferences (target TRL range) target_trl_min: int = 4 target_trl_max: int = 7 # Recency decay (years) recency_half_life: float = 2.0 @dataclass class TechScoutConfig: """Main TechScout configuration.""" # Paths base_dir: Path = field(default_factory=lambda: Path(__file__).parent.parent) personas_dir: Path = field(default_factory=lambda: Path(__file__).parent.parent / "personas") analyses_dir: Path = field(default_factory=lambda: Path(__file__).parent.parent / "analyses") exports_dir: Path = field(default_factory=lambda: Path(__file__).parent.parent / "exports") # Sub-configs ollama: OllamaConfig = field(default_factory=OllamaConfig) search: SearchConfig = field(default_factory=SearchConfig) scoring: ScoringConfig = field(default_factory=ScoringConfig) # Analysis settings max_phase1_results: int = 50 max_phase2_candidates: int = 10 def __post_init__(self): """Ensure directories exist.""" self.analyses_dir.mkdir(parents=True, exist_ok=True) self.exports_dir.mkdir(parents=True, exist_ok=True) # Global config instance config = TechScoutConfig()