44 lines
1.5 KiB
Python
44 lines
1.5 KiB
Python
"""The opt-in gate — every expensive move calls ``ensure_enabled()`` first.
|
|
|
|
Two independent locks must both be open:
|
|
1. ``RM_E2E_MONITOR=1`` in the environment (deliberate enable), and
|
|
2. a usable LLM key/provider is configured (same rule the eval harness uses).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
|
|
class MonitorDisabled(RuntimeError):
|
|
"""Raised when a move is invoked without the monitor being enabled."""
|
|
|
|
|
|
def _key_is_configured() -> bool:
|
|
"""True when a usable key/provider is set (mirrors the eval ``_needs_key``)."""
|
|
try:
|
|
from app.llm import get_llm_config
|
|
|
|
cfg = get_llm_config()
|
|
except Exception:
|
|
return False
|
|
return bool(cfg.api_key) or cfg.provider in ("ollama", "openai_compatible")
|
|
|
|
|
|
def ensure_enabled(*, require_key: bool = True) -> None:
|
|
"""Raise ``MonitorDisabled`` unless both locks are open.
|
|
|
|
When ``require_key=False`` the LLM key check is skipped (use for offline
|
|
moves such as ``update-baseline`` that need no LLM calls).
|
|
"""
|
|
if os.environ.get("RM_E2E_MONITOR") != "1":
|
|
raise MonitorDisabled(
|
|
"e2e monitor is disabled by default — it makes real, billed LLM calls "
|
|
"and boots servers. Set RM_E2E_MONITOR=1 to enable."
|
|
)
|
|
if require_key and not _key_is_configured():
|
|
raise MonitorDisabled(
|
|
"no usable LLM key/provider configured (set one in data/config.json or "
|
|
"the Settings UI, or point at a local provider)."
|
|
)
|