simbiot-harness/tests/test_events_context.py
Simbiot Harness 4e57de63bd t-261017110430: подача событий EventStore в контекст тика (policy events_context)
- scheduler: _events_digest() — содержательные события стора за ~90 мин
  (Message/Reply/Tasks/Escalations/AUM/MCP), шум (CycleTicked/Tool*/) отсечён;
  секция «СОБЫТИЯ ХАРНЕСА» в build_context по policy.events_context=on
- commands/cli: policy --events-context on|off (переключатель, одобрен Alex)
- tests/test_events_context.py: 9 hermetic-проверок (on/off/дефолт/пустой стор)
2026-10-17 13:03:14 +00:00

87 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""t-261017110430: подача событий EventStore в контекст тика (hermetic, без LLM).
Запуск: ./venv/bin/python tests/test_events_context.py
Проверяет: policy.events_context=on — в контексте мин/час/день появляется
секция «СОБЫТИЯ ХАРНЕСА» с содержательными событиями (MessageReceived,
TaskClaimed, …) и БЕЗ механического шума (CycleTicked/ToolCalled/…);
policy off (и дефолт) — секции нет. Выжимка не валит контекст при пустом
сторе.
"""
import os
import sys
sys.path.insert(0, "/root/simbiot-harness")
# изоляция стора (как test_gate.py): тест не пишет в боевой стор
import tempfile as _iso_tf # noqa: E402
os.environ["SIMBIOT_DB"] = os.path.join(
_iso_tf.mkdtemp(prefix="simbiot_test_evt_"), "harness.db")
from harness import es, scheduler # noqa: E402
from harness.levels import LEVELS # noqa: E402
fails = []
def check(name, cond, extra=""):
print(("PASS" if cond else "FAIL"), name, ("| " + extra) if not cond else "")
if not cond:
fails.append(name)
es.init_db()
es.append_event("tg", "m-1", "MessageReceived", {"text": "привет, как дела?"})
es.append_event("tg", "m-1", "ReplySent", {"text": "привет! всё ровно"})
es.append_event("harness", "t-1", "TaskClaimed", {"level": "min"})
# механический шум — его в контексте быть не должно
es.append_event("cycle", "x", "CycleTicked", {"level": "min"})
es.append_event("trace", "y", "ToolCalled", {"tool": "shell"})
def ctx(policy):
model = {"tasks": {}, "inbox": {}, "escalations": {}, "digests": {},
"policy": policy if policy is not None else {}}
return scheduler.build_context(LEVELS["min"], model, batch=[])
on = ctx({"events_context": "on"})
check("on: секция СОБЫТИЯ ХАРНЕСА в контексте", "СОБЫТИЯ ХАРНЕСА" in on)
check("on: входящее с текстом",
"входящее [m-1]: привет, как дела?" in on)
check("on: ответ в чат", "ответ в чат [m-1]: привет! всё ровно" in on)
check("on: задача взята с уровнем", "задача взята [t-1]: уровнем min" in on)
check("on: шум CycleTicked/ToolCalled отсечён",
"CycleTicked" not in on and "ToolCalled" not in on)
off = ctx({"events_context": "off"})
check("off: секции нет", "СОБЫТИЯ ХАРНЕСА" not in off)
default = ctx(None)
check("дефолт (нет policy): секции нет", "СОБЫТИЯ ХАРНЕСА" not in default)
# пустой стор (lookback 90 мин): не падает и не добавляет секцию.
# es.DB_PATH кешируется на импорте — смена SIMBIOT_DB после импорта не
# действует, поэтому патчим модульный глобал напрямую (с возвратом).
_db_backup, es.DB_PATH = es.DB_PATH, os.path.join(
_iso_tf.mkdtemp(prefix="simbiot_test_evt2_"), "harness.db")
try:
es.init_db()
empty = ctx({"events_context": "on"})
check("пустой стор: контекст собран, секции нет",
isinstance(empty, str) and "СОБЫТИЯ ХАРНЕСА" not in empty)
finally:
es.DB_PATH = _db_backup
# часовой уровень: секция там тоже (тот же build_context)
on_hour = scheduler.build_context(
LEVELS["hour"], {"tasks": {}, "inbox": {}, "escalations": {}, "digests": {},
"policy": {"events_context": "on"}}, batch=[])
check("hour: секция в контексте", "СОБЫТИЯ ХАРНЕСА" in on_hour)
print()
if fails:
print("FAILED:", len(fails), fails)
sys.exit(1)
print("OK: все проверки прошли")