69 lines
3.7 KiB
Python
69 lines
3.7 KiB
Python
"""Centralized configuration for the AI Research Oracle.
|
|
|
|
Single source of truth for all paths, defaults, and constants.
|
|
"""
|
|
import os
|
|
from pathlib import Path
|
|
|
|
# ── Paths ──────────────────────────────────────────────────────────────────
|
|
ROOT = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
DB_PATH = ROOT / "oracle.db"
|
|
SCHEMA_PATH = ROOT / "schema.sql"
|
|
|
|
# ── Web output ─────────────────────────────────────────────────────────────
|
|
WEBROOT = "/var/www/preprod2"
|
|
FALLBACK_WEBROOT = ROOT / "site"
|
|
SEEN_JSON = ROOT.parent / "ai-oracle-site" / "seen_urls.json"
|
|
|
|
# ── Pipeline defaults ──────────────────────────────────────────────────────
|
|
ENABLED_SOURCES = ["github", "arxiv", "reddit", "hackernews", "huggingface", "rss"]
|
|
DEFAULT_LIMIT = 20
|
|
|
|
# ── Source tiers (World Monitor pattern) ───────────────────────────────────
|
|
# Tier 1: Primary trusted sources (official releases, peer-reviewed)
|
|
# Tier 2: Secondary credible sources (curated communities, major outlets)
|
|
# Tier 3: Tertiary noise sources (user-generated, unverified)
|
|
SOURCE_TIERS = {
|
|
"arxiv": {"tier": 1, "label": "PRIMARY", "description": "Peer-reviewed research"},
|
|
"github": {"tier": 1, "label": "PRIMARY", "description": "Official code releases"},
|
|
"huggingface": {"tier": 1, "label": "PRIMARY", "description": "Model registry"},
|
|
"rss": {"tier": 2, "label": "SECONDARY", "description": "Curated tech media"},
|
|
"hackernews": {"tier": 2, "label": "SECONDARY", "description": "Curated community"},
|
|
"reddit": {"tier": 3, "label": "TERTIARY", "description": "User-generated discussion"},
|
|
}
|
|
|
|
# Tier-based signal score bonus/penalty (applied to final_score)
|
|
TIER_BONUS = {1: 0.05, 2: 0.0, 3: -0.05}
|
|
|
|
# Freshness SLA per tier (hours after which a source is flagged stale)
|
|
FRESHNESS_SLA_H = {1: 48, 2: 24, 3: 12}
|
|
|
|
# ── Composite verdict thresholds ───────────────────────────────────────────
|
|
# PUBLISH: High score + fresh, goes to top
|
|
# WATCH: Medium score, monitor for follow-ups
|
|
# ARCHIVE: Low score or aged out, move to archive
|
|
# DROP: Junk score, ignore
|
|
VERDICT_THRESHOLDS = {
|
|
"PUBLISH": {"min_score": 5.0, "max_age_h": 48},
|
|
"WATCH": {"min_score": 4.0, "max_age_h": 168}, # 7 days
|
|
"ARCHIVE": {"min_score": 2.0, "max_age_h": 720}, # 30 days
|
|
"DROP": {"min_score": 0.0, "max_age_h": 999999}, # catch-all
|
|
}
|
|
|
|
# ── Content hash dedup ─────────────────────────────────────────────────────
|
|
CONTENT_HASH_PREFIX = "sha256"
|
|
HASH_LENGTH = 16 # characters
|
|
|
|
# ── Clickability weights ───────────────────────────────────────────────────
|
|
VEL_W = 0.50
|
|
ENG_W = 0.50
|
|
SIG_W = 0.0
|
|
HALF_LIFE_H = 18.0
|
|
|
|
# ── Render ─────────────────────────────────────────────────────────────────
|
|
TOP_N = 8
|
|
|
|
# ── Archive ────────────────────────────────────────────────────────────────
|
|
ARCHIVE_DAYS = 30
|
|
ARCHIVE_CAP = 5000
|