Spaces:
Running
Running
| """ | |
| ERNIE 5.1 Browser-Sourced Manual Callback Adapter | |
| ERNIE has no API — this adapter bridges browser output to NEXUS OS. | |
| Usage pattern: | |
| 1. User manually copies ERNIE browser output to clipboard/file | |
| 2. ERNIEAdapter reads the file and returns structured evidence | |
| 3. Adapter normalizes scores to [0,1] for μ_ret compatibility | |
| Fallback: If no manual input available, adapter degrades gracefully | |
| with empty evidence and warns the router to use parametric-only mode. | |
| """ | |
| import json | |
| import os | |
| import re | |
| from typing import List, Dict, Optional, Any | |
| from dataclasses import dataclass | |
| from pathlib import Path | |
| class ERNIEEvidence: | |
| text: str | |
| confidence: float # Normalized 0-1 | |
| source: str # "ernie_browser" | |
| timestamp: Optional[str] = None | |
| raw_score: Optional[float] = None # Original ERNIE score if parsed | |
| class ERNIEAdapter: | |
| """ | |
| Manual callback adapter for Baidu ERNIE 5.1 (no public API). | |
| ERNIE 5.1 is browser-only — all interaction happens through: | |
| https://yiyan.baidu.com (Chinese interface) | |
| https://ernie.baidu.com (International) | |
| This adapter reads manually-captured ERNIE outputs from: | |
| - A watched file (ERNIE_OUTPUT_PATH env var) | |
| - A JSON clipboard dump | |
| - A structured text export | |
| """ | |
| DEFAULT_WATCH_PATH = "./ernie_output.json" | |
| SCORE_PATTERN = re.compile(r'(置信度|confidence|可信度)[::]\s*(\d+\.?\d*)', re.I) | |
| def __init__(self, watch_path: Optional[str] = None): | |
| self.watch_path = Path(watch_path or os.environ.get("ERNIE_OUTPUT_PATH", self.DEFAULT_WATCH_PATH)) | |
| self._last_read_mtime: Optional[float] = None | |
| self._cache: List[ERNIEEvidence] = [] | |
| def _parse_raw_text(self, raw: str) -> List[ERNIEEvidence]: | |
| """Parse unstructured ERNIE browser output into evidence chunks.""" | |
| # Split by numbered items or paragraph breaks | |
| chunks = re.split(r'\n\n+|\d+\.\s+', raw) | |
| evidence = [] | |
| for chunk in chunks: | |
| chunk = chunk.strip() | |
| if len(chunk) < 10: | |
| continue | |
| # Try to extract confidence score | |
| match = self.SCORE_PATTERN.search(chunk) | |
| raw_score = float(match.group(2)) if match else None | |
| confidence = raw_score / 100.0 if raw_score and raw_score > 1.0 else (raw_score or 0.7) | |
| evidence.append(ERNIEEvidence( | |
| text=chunk, | |
| confidence=min(max(confidence, 0.0), 1.0), | |
| source="ernie_browser", | |
| raw_score=raw_score, | |
| )) | |
| return evidence | |
| def _read_file(self) -> Optional[str]: | |
| """Read watch file if it exists and has been modified.""" | |
| if not self.watch_path.exists(): | |
| return None | |
| mtime = self.watch_path.stat().st_mtime | |
| if self._last_read_mtime and mtime <= self._last_read_mtime: | |
| return None # Not modified | |
| self._last_read_mtime = mtime | |
| return self.watch_path.read_text(encoding="utf-8") | |
| def poll(self) -> List[ERNIEEvidence]: | |
| """Poll for new ERNIE browser output. Returns [] if none available.""" | |
| raw = self._read_file() | |
| if raw is None: | |
| return self._cache # Return cached if no new data | |
| # Try JSON first | |
| try: | |
| data = json.loads(raw) | |
| if isinstance(data, list): | |
| self._cache = [ | |
| ERNIEEvidence( | |
| text=item.get("text", item.get("answer", str(item))), | |
| confidence=item.get("confidence", 0.7), | |
| source="ernie_browser", | |
| timestamp=item.get("timestamp"), | |
| ) | |
| for item in data | |
| ] | |
| elif isinstance(data, dict): | |
| self._cache = [ERNIEEvidence( | |
| text=data.get("text", data.get("answer", str(data))), | |
| confidence=data.get("confidence", 0.7), | |
| source="ernie_browser", | |
| timestamp=data.get("timestamp"), | |
| )] | |
| except json.JSONDecodeError: | |
| # Parse as raw text | |
| self._cache = self._parse_raw_text(raw) | |
| return self._cache | |
| def get_evidence(self, query: str) -> List[Dict[str, Any]]: | |
| """Format ERNIE evidence for CK-PLUG / TWAVE consumption.""" | |
| evidence = self.poll() | |
| return [ | |
| { | |
| "text": e.text, | |
| "relevance": e.confidence, # Maps to μ_ret scale | |
| "source": e.source, | |
| "timestamp": e.timestamp, | |
| } | |
| for e in evidence | |
| ] | |
| def is_available(self) -> bool: | |
| """Check if ERNIE evidence is currently available.""" | |
| return len(self.poll()) > 0 | |
| def get_status(self) -> Dict[str, Any]: | |
| """Return adapter status for monitoring.""" | |
| evidence = self.poll() | |
| return { | |
| "available": len(evidence) > 0, | |
| "watch_path": str(self.watch_path), | |
| "evidence_count": len(evidence), | |
| "avg_confidence": sum(e.confidence for e in evidence) / len(evidence) if evidence else 0.0, | |
| "sources": list(set(e.source for e in evidence)), | |
| } | |
| class MockERNIEAdapter: | |
| """Mock adapter that returns synthetic ERNIE evidence for testing.""" | |
| def __init__(self): | |
| self._mock_evidence = [ | |
| ERNIEEvidence( | |
| text="ERNIE 5.1 confirms: The thermodynamic BEC analogy for LLM reasoning is structurally valid when applied to internal effective temperature, not sampling temperature.", | |
| confidence=0.91, | |
| source="ernie_browser", | |
| ), | |
| ERNIEEvidence( | |
| text="ERNIE 5.1 analysis: Claude Opus 4.7 and GPT-5.5 use internal thermostat regulation decoupled from user-facing temperature controls.", | |
| confidence=0.85, | |
| source="ernie_browser", | |
| ), | |
| ERNIEEvidence( | |
| text="ERNIE 5.1 observation: Jarzynski equality has not been applied to autoregressive LLM generation in published literature as of May 2026.", | |
| confidence=0.78, | |
| source="ernie_browser", | |
| ), | |
| ] | |
| def poll(self) -> List[ERNIEEvidence]: | |
| return self._mock_evidence | |
| def get_evidence(self, query: str) -> List[Dict[str, Any]]: | |
| return [{"text": e.text, "relevance": e.confidence, "source": e.source} for e in self._mock_evidence] | |
| def is_available(self) -> bool: | |
| return True | |
| def get_status(self) -> Dict[str, Any]: | |
| return { | |
| "available": True, | |
| "watch_path": "mock://ernie", | |
| "evidence_count": len(self._mock_evidence), | |
| "avg_confidence": sum(e.confidence for e in self._mock_evidence) / len(self._mock_evidence), | |
| "sources": ["ernie_browser"], | |
| } | |