feat(platform): add new services, tools, tests and crews modules
New router intelligence modules (26 files): alert_ingest/store, audit_store, architecture_pressure, backlog_generator/store, cost_analyzer, data_governance, dependency_scanner, drift_analyzer, incident_* (5 files), llm_enrichment, platform_priority_digest, provider_budget, release_check_runner, risk_* (6 files), signature_state_store, sofiia_auto_router, tool_governance New services: - sofiia-console: Dockerfile, adapters/, monitor/nodes/ops/voice modules, launchd, react static - memory-service: integration_endpoints, integrations, voice_endpoints, static UI - aurora-service: full app suite (analysis, job_store, orchestrator, reporting, schemas, subagents) - sofiia-supervisor: new supervisor service - aistalk-bridge-lite: Telegram bridge lite - calendar-service: CalDAV calendar service with reminders - mlx-stt-service / mlx-tts-service: Apple Silicon speech services - binance-bot-monitor: market monitor service - node-worker: STT/TTS memory providers New tools (9): agent_email, browser_tool, contract_tool, observability_tool, oncall_tool, pr_reviewer_tool, repo_tool, safe_code_executor, secure_vault New crews: agromatrix_crew (10 modules: depth_classifier, doc_facts, doc_focus, farm_state, light_reply, llm_factory, memory_manager, proactivity, reflection_engine, session_context, style_adapter, telemetry) Tests: 85+ test files for all new modules Made-with: Cursor
This commit is contained in:
91
services/sofiia-supervisor/tests/test_state_backend.py
Normal file
91
services/sofiia-supervisor/tests/test_state_backend.py
Normal file
@@ -0,0 +1,91 @@
|
||||
"""Tests for in-memory state backend (Redis tested in integration)."""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
from tests.conftest import _run
|
||||
from app.models import EventType, RunEvent, RunRecord, RunStatus
|
||||
|
||||
|
||||
def _make_run(run_id: str = "gr_test_001") -> RunRecord:
|
||||
return RunRecord(
|
||||
run_id=run_id,
|
||||
graph="release_check",
|
||||
status=RunStatus.QUEUED,
|
||||
agent_id="sofiia",
|
||||
workspace_id="daarion",
|
||||
user_id="u_001",
|
||||
)
|
||||
|
||||
|
||||
class TestMemoryBackend:
|
||||
def test_save_and_get_run(self):
|
||||
from app.state_backend import MemoryStateBackend
|
||||
backend = MemoryStateBackend()
|
||||
run = _make_run("gr_001")
|
||||
_run(backend.save_run(run))
|
||||
fetched = _run(backend.get_run("gr_001"))
|
||||
assert fetched is not None
|
||||
assert fetched.run_id == "gr_001"
|
||||
assert fetched.status == RunStatus.QUEUED
|
||||
|
||||
def test_get_missing_run_returns_none(self):
|
||||
from app.state_backend import MemoryStateBackend
|
||||
backend = MemoryStateBackend()
|
||||
assert _run(backend.get_run("does_not_exist")) is None
|
||||
|
||||
def test_append_and_get_events(self):
|
||||
from app.state_backend import MemoryStateBackend
|
||||
backend = MemoryStateBackend()
|
||||
run = _make_run("gr_002")
|
||||
_run(backend.save_run(run))
|
||||
|
||||
ev1 = RunEvent(ts="2026-01-01T00:00:00Z", type=EventType.NODE_START, node="start_job")
|
||||
ev2 = RunEvent(ts="2026-01-01T00:00:01Z", type=EventType.TOOL_CALL, tool="job_orchestrator_tool",
|
||||
details={"hash": "abc123", "size": 200})
|
||||
_run(backend.append_event("gr_002", ev1))
|
||||
_run(backend.append_event("gr_002", ev2))
|
||||
|
||||
events = _run(backend.get_events("gr_002"))
|
||||
assert len(events) == 2
|
||||
assert events[0].type == EventType.NODE_START
|
||||
assert events[1].tool == "job_orchestrator_tool"
|
||||
# Events should NOT contain payload content
|
||||
assert "size" in events[1].details
|
||||
|
||||
def test_cancel_queued_run(self):
|
||||
from app.state_backend import MemoryStateBackend
|
||||
backend = MemoryStateBackend()
|
||||
run = _make_run("gr_003")
|
||||
_run(backend.save_run(run))
|
||||
|
||||
ok = _run(backend.cancel_run("gr_003"))
|
||||
assert ok is True
|
||||
fetched = _run(backend.get_run("gr_003"))
|
||||
assert fetched.status == RunStatus.CANCELLED
|
||||
|
||||
def test_cancel_completed_run_returns_false(self):
|
||||
from app.state_backend import MemoryStateBackend
|
||||
backend = MemoryStateBackend()
|
||||
run = _make_run("gr_004")
|
||||
run.status = RunStatus.SUCCEEDED
|
||||
_run(backend.save_run(run))
|
||||
|
||||
ok = _run(backend.cancel_run("gr_004"))
|
||||
assert ok is False
|
||||
|
||||
def test_update_run_status(self):
|
||||
from app.state_backend import MemoryStateBackend
|
||||
backend = MemoryStateBackend()
|
||||
run = _make_run("gr_005")
|
||||
_run(backend.save_run(run))
|
||||
|
||||
run.status = RunStatus.RUNNING
|
||||
run.started_at = "2026-01-01T00:00:00Z"
|
||||
_run(backend.save_run(run))
|
||||
|
||||
fetched = _run(backend.get_run("gr_005"))
|
||||
assert fetched.status == RunStatus.RUNNING
|
||||
assert fetched.started_at == "2026-01-01T00:00:00Z"
|
||||
Reference in New Issue
Block a user