Files
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

219 lines
7.3 KiB
Python

"""Hugging Face Hub helpers: stream ``query_alerts`` JSON and cache telemetry CSV trees."""
from __future__ import annotations
import copy
import importlib
import json
import os
import re
from collections.abc import Iterator
from pathlib import Path
from typing import Any
from integrations.opensre.constants import OPENSRE_HF_DATASET_ID
_MONTH_RE = re.compile(
r"\b(January|February|March|April|May|June|July|August|September|October|November|December)"
r"\s+(\d{1,2}),\s*(\d{4})\b",
re.IGNORECASE,
)
_ISO_DATE_RE = re.compile(r"\b(\d{4})-(\d{2})-(\d{2})\b")
_MONTHS: dict[str, int] = {
"january": 1,
"february": 2,
"march": 3,
"april": 4,
"may": 5,
"june": 6,
"july": 7,
"august": 8,
"september": 9,
"october": 10,
"november": 11,
"december": 12,
}
def _hub_import_error(name: str) -> ImportError:
return ImportError(
f"{name} is required for Hugging Face OpenSRE helpers. "
"Install with: pip install 'opensre[opensre-hub]'"
)
def _load_dataset_loader() -> Any:
try:
module = importlib.import_module("datasets")
except ImportError as e:
raise _hub_import_error("datasets") from e
loader = getattr(module, "load_dataset", None)
if loader is None:
raise _hub_import_error("datasets")
return loader
def _load_snapshot_download() -> Any:
try:
module = importlib.import_module("huggingface_hub")
except ImportError as e:
raise _hub_import_error("huggingface_hub") from e
downloader = getattr(module, "snapshot_download", None)
if downloader is None:
raise _hub_import_error("huggingface_hub")
return downloader
def hub_repo_prefix_from_pipeline(pipeline_name: str) -> str:
"""Map alert ``pipeline_name`` to a dataset path prefix (e.g. ``market/cloudbed-1`` → ``Market/cloudbed-1``)."""
parts = [p for p in pipeline_name.strip("/").split("/") if p]
if not parts:
return ""
parts[0] = parts[0][:1].upper() + parts[0][1:]
return "/".join(parts)
def telemetry_date_folder_from_text(*texts: str) -> str | None:
"""Return ``YYYY_MM_DD`` for the first calendar date found across ``texts``."""
blob = "\n".join(t for t in texts if t)
if not blob:
return None
m = _MONTH_RE.search(blob)
if m:
month = _MONTHS[m.group(1).lower()]
day = int(m.group(2))
year = int(m.group(3))
return f"{year:04d}_{month:02d}_{day:02d}"
m2 = _ISO_DATE_RE.search(blob)
if m2:
y, mo, d = int(m2.group(1)), int(m2.group(2)), int(m2.group(3))
return f"{y:04d}_{mo:02d}_{d:02d}"
return None
def infer_opensre_telemetry_relative(raw_alert: dict[str, Any]) -> str | None:
"""Derive ``<Prefix>/telemetry/YYYY_MM_DD`` when annotations omit ``*_telemetry_relative``."""
labels_raw = raw_alert.get("commonLabels")
labels: dict[str, Any] = labels_raw if isinstance(labels_raw, dict) else {}
pipeline = str(labels.get("pipeline_name") or raw_alert.get("pipeline_name") or "").strip()
if not pipeline:
return None
prefix = hub_repo_prefix_from_pipeline(pipeline)
ann = raw_alert.get("commonAnnotations") or {}
if not isinstance(ann, dict):
ann = {}
texts = [
str(raw_alert.get("message") or ""),
str(raw_alert.get("text") or ""),
str(ann.get("summary") or ""),
str(ann.get("query") or ""),
]
day = telemetry_date_folder_from_text(*texts)
if not day:
return None
return f"{prefix}/telemetry/{day}"
def strip_scoring_points_from_alert(alert: dict[str, Any]) -> dict[str, Any]:
"""Drop ``scoring_points`` from annotations so agent runs do not see rubric text."""
out = copy.deepcopy(alert)
for key in ("commonAnnotations", "annotations"):
nested = out.get(key)
if isinstance(nested, dict) and "scoring_points" in nested:
out[key] = {k: v for k, v in nested.items() if k != "scoring_points"}
return out
def extract_scoring_points(alert: dict[str, Any]) -> str:
"""
Collect ``scoring_points`` from ``commonAnnotations`` and ``annotations``.
Used for offline LLM judges; the investigation agent should not see this text
(use :func:`strip_scoring_points_from_alert` on the alert passed into the graph).
"""
chunks: list[str] = []
for block_name in ("commonAnnotations", "annotations"):
block = alert.get(block_name)
if not isinstance(block, dict):
continue
raw = block.get("scoring_points")
if raw is None or raw == "":
continue
if isinstance(raw, str):
text = raw.strip()
else:
try:
text = json.dumps(raw, indent=2)
except (TypeError, ValueError):
text = str(raw)
chunks.append(f"## {block_name}.scoring_points\n{text}")
return "\n\n".join(chunks).strip()
def stream_opensre_query_alerts(
*,
query_alerts_prefix: str,
dataset_id: str | None = None,
revision: str | None = None,
strip_scoring_points: bool = False,
) -> Iterator[dict[str, Any]]:
"""Yield alert dicts from ``<prefix>/*.json`` using Hugging Face ``datasets`` streaming.
By default **does not** strip ``scoring_points`` so saved alerts work with
``opensre investigate --evaluate``. Pass ``strip_scoring_points=True`` for a stream
with rubric removed (e.g. publishing blind fixtures). Investigations still strip
rubric from the in-graph ``raw_alert`` when ``--evaluate`` is off — see
:func:`tools.investigation.state_factory.make_initial_state`.
"""
load_dataset = _load_dataset_loader()
repo = (dataset_id or OPENSRE_HF_DATASET_ID).strip()
rev = (revision or os.environ.get("OPENSRE_HF_REVISION") or "main").strip()
prefix = query_alerts_prefix.strip().strip("/")
url = f"hf://datasets/{repo}@{rev}/{prefix}/*.json"
ds = load_dataset("json", data_files=url, streaming=True, split="train")
for row in ds:
row_dict = dict(row)
if strip_scoring_points:
row_dict = strip_scoring_points_from_alert(row_dict)
yield row_dict
def default_hf_cache_dir() -> Path:
root = os.environ.get("OPENSRE_HF_CACHE", "").strip()
if root:
return Path(root).expanduser()
return Path.home() / ".cache" / "opensre" / "hf"
def materialize_opensre_telemetry_from_hub(
*,
dataset_id: str,
telemetry_relative: str,
revision: str | None = None,
cache_dir: Path | None = None,
) -> Path:
"""Download only ``telemetry_relative/**`` from the dataset repo into a persistent cache."""
snapshot_download = _load_snapshot_download()
rel = telemetry_relative.strip().strip("/")
if not rel:
raise ValueError("telemetry_relative must be non-empty")
rev = (revision or os.environ.get("OPENSRE_HF_REVISION") or "main").strip()
base = cache_dir or default_hf_cache_dir()
dest = (base / dataset_id.replace("/", "__") / rev).resolve()
dest.mkdir(parents=True, exist_ok=True)
pattern = f"{rel}/**"
snapshot_download(
repo_id=dataset_id,
repo_type="dataset",
revision=rev,
local_dir=str(dest),
allow_patterns=[pattern],
)
out = (dest / rel).resolve()
if not out.is_dir():
raise FileNotFoundError(f"Telemetry path missing after Hub download: {out}")
return out