mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-07-09 21:58:41 +02:00
Feat/gt analytics openclaw (#392)
* feat(telegram): auto-translate OSINT channel posts to English Cherry-picked from @Bobpick PR #391 (telegram-only slice): server-side translation during fetch, SHOW ORIGINAL toggle in TelegramOsintPopup, and on-demand /api/telegram-feed?lang=. Co-authored-by: Robert Pickett <bobpickettsr@yahoo.com> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(gt): experimental Derived OSINT analytics with lean-node safeguards Cherry-picked from @Bobpick PR #391 (GT + OpenClaw slice): Bayesian strategic-risk engine, map overlay, OpenClaw commands, and telegram_rhetoric watchdog. Off by default (GT_ANALYTICS_ENABLED=false, gt_risk layer false). 1 vCPU nodes get cgroup detection, UI warning on layer toggle, and lean profile that skips scheduled ingest/Louvain unless GT_ANALYTICS_ACK_LOW_CPU=true. Backtest HUD removed from dashboard (OpenClaw/API regression only). Co-authored-by: Robert Pickett <bobpickettsr@yahoo.com> Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Robert Pickett <bobpickettsr@yahoo.com> Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
"""Container-aware runtime limits for fleet vs desktop deployments."""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
def _read_first_int(path: Path) -> int | None:
|
||||
try:
|
||||
raw = path.read_text(encoding="utf-8").strip().split()[0]
|
||||
return int(raw)
|
||||
except (OSError, ValueError, IndexError):
|
||||
return None
|
||||
|
||||
|
||||
def detect_cpu_limit() -> float | None:
|
||||
"""Effective CPU cores from cgroup quota (Docker ``cpus:``), else host count."""
|
||||
cgroup_v2 = Path("/sys/fs/cgroup/cpu.max")
|
||||
if cgroup_v2.is_file():
|
||||
try:
|
||||
parts = cgroup_v2.read_text(encoding="utf-8").strip().split()
|
||||
if len(parts) >= 2 and parts[0] != "max":
|
||||
quota = int(parts[0])
|
||||
period = int(parts[1])
|
||||
if quota > 0 and period > 0:
|
||||
return round(quota / period, 3)
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
|
||||
cgroup_v1_quota = Path("/sys/fs/cgroup/cpu/cpu.cfs_quota_us")
|
||||
cgroup_v1_period = Path("/sys/fs/cgroup/cpu/cpu.cfs_period_us")
|
||||
if cgroup_v1_quota.is_file() and cgroup_v1_period.is_file():
|
||||
quota = _read_first_int(cgroup_v1_quota)
|
||||
period = _read_first_int(cgroup_v1_period)
|
||||
if quota is not None and period and quota > 0:
|
||||
return round(quota / period, 3)
|
||||
|
||||
try:
|
||||
import os as _os
|
||||
|
||||
count = _os.cpu_count()
|
||||
return float(count) if count else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def detect_memory_limit_mb() -> int | None:
|
||||
cgroup_v2 = Path("/sys/fs/cgroup/memory.max")
|
||||
if cgroup_v2.is_file():
|
||||
try:
|
||||
raw = cgroup_v2.read_text(encoding="utf-8").strip()
|
||||
if raw and raw != "max":
|
||||
return int(int(raw) / (1024 * 1024))
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
|
||||
cgroup_v1 = Path("/sys/fs/cgroup/memory/memory.limit_in_bytes")
|
||||
if cgroup_v1.is_file():
|
||||
try:
|
||||
raw = _read_first_int(cgroup_v1)
|
||||
if raw is not None and raw < (1 << 62):
|
||||
return int(raw / (1024 * 1024))
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def resolve_profile_name() -> str:
|
||||
explicit = str(os.environ.get("GT_ANALYTICS_PROFILE", "")).strip().lower()
|
||||
if explicit in {"lean", "standard"}:
|
||||
return explicit
|
||||
cpu = detect_cpu_limit()
|
||||
if cpu is not None and cpu <= 1.0:
|
||||
return "lean"
|
||||
return "standard"
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def get_runtime_profile() -> dict[str, Any]:
|
||||
cpu_limit = detect_cpu_limit()
|
||||
memory_mb = detect_memory_limit_mb()
|
||||
profile = resolve_profile_name()
|
||||
lean = profile == "lean"
|
||||
return {
|
||||
"profile": profile,
|
||||
"cpu_limit": cpu_limit,
|
||||
"memory_limit_mb": memory_mb,
|
||||
"gt_analytics": {
|
||||
"recommended": not lean,
|
||||
"lean_node": lean,
|
||||
"warning": (
|
||||
"This node is capped at 1 vCPU. Enabling Strategic Risk (Derived OSINT) "
|
||||
"may slow Telegram, GDELT, and other OSINT fetches. Set "
|
||||
"GT_ANALYTICS_ACK_LOW_CPU=true after enabling GT_ANALYTICS_ENABLED to run "
|
||||
"the full engine on lean hardware."
|
||||
if lean
|
||||
else None
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def clear_runtime_profile_cache() -> None:
|
||||
get_runtime_profile.cache_clear()
|
||||
Reference in New Issue
Block a user