#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary.
"""LLM extractor: captures knowledge that regex misses (~70% of agent responses)."""
import logging
from datetime import datetime, timezone

from pulse.daemons.distiller.extractors.base import BaseExtractor

log = logging.getLogger('pulse.distiller.llm')


class LLMExtractor(BaseExtractor):
    """Runs LLM extraction on every pair — no gating — to reach ~85% extraction rate."""

    def __init__(self):
        super().__init__('llm', 'lessons')

    def extract(self, user_text: str, agent_text: str, metadata: dict) -> list:
        """Call extract_with_llm on combined text; always runs regardless of other yields."""
        try:
            from pulse.daemons.bridge.llm_extraction import extract_with_llm
        except ImportError:
            return []

        ts = metadata.get('timestamp', datetime.now(timezone.utc).isoformat())
        domain = metadata.get('domain', 'general')
        combined = user_text + '\n' + agent_text if agent_text else user_text

        try:
            items = extract_with_llm(combined, domain, ts)
        except Exception as exc:
            log.debug('extract_with_llm failed: %s', exc)
            return []

        source = metadata.get('source', 'distiller')
        for item in items:
            item.setdefault('_source', source)

        return items or []

    def write(self, items: list) -> int:
        """Route items through bridge routing (JSONL + SQLite)."""
        if not items:
            return 0
        try:
            from pulse.daemons.bridge.bridge_routing import route_knowledge
        except ImportError:
            return 0

        source = items[0].get('_source', 'distiller') if items else 'distiller'
        clean = [{k: v for k, v in it.items() if not k.startswith('_')} for it in items]
        try:
            route_knowledge(clean, source)
        except Exception as exc:
            log.debug('route_knowledge (llm) failed: %s', exc)
            return 0
        self.extracted_count += len(clean)
        return len(clean)
