26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
108 lines
3.6 KiB
Python
108 lines
3.6 KiB
Python
"""Live integration against a real lean-ctx daemon.
|
|
|
|
Skipped unless ``LEANCTX_LIVE_URL`` is set (no mocks — these hit a real daemon).
|
|
Run locally / in CI with::
|
|
|
|
LEANCTX_LIVE_URL=http://127.0.0.1:<port> \
|
|
LEANCTX_LIVE_TOKEN=<token> \
|
|
python -m pytest integrations/hermes-lean-ctx/tests/test_live_daemon.py -v
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
|
|
import pytest
|
|
|
|
LIVE_URL = os.environ.get("LEANCTX_LIVE_URL", "").strip()
|
|
LIVE_TOKEN = os.environ.get("LEANCTX_LIVE_TOKEN", "").strip() or None
|
|
|
|
pytestmark = pytest.mark.skipif(not LIVE_URL, reason="LEANCTX_LIVE_URL not set")
|
|
|
|
|
|
def _engine():
|
|
from hermes_lean_ctx.config import LeanCtxConfig
|
|
from hermes_lean_ctx.engine import LeanCtxEngine
|
|
|
|
cfg = LeanCtxConfig(base_url=LIVE_URL, token=LIVE_TOKEN, timeout=15.0)
|
|
return LeanCtxEngine(config=cfg)
|
|
|
|
|
|
def test_daemon_reachable():
|
|
engine = _engine()
|
|
assert engine._gateway.is_available(force=True) is True
|
|
|
|
|
|
def test_status_includes_daemon_metrics():
|
|
status = _engine().get_status()
|
|
assert status["daemon_available"] is True
|
|
assert status["base_url"] == LIVE_URL
|
|
|
|
|
|
def test_native_tool_dispatch_real():
|
|
engine = _engine()
|
|
out = engine.handle_tool_call("ctx_search", {"pattern": "fn ", "max_results": 3})
|
|
assert isinstance(out, str) and out
|
|
# not the daemon-down error envelope
|
|
try:
|
|
payload = json.loads(out)
|
|
assert "unavailable" not in str(payload)
|
|
except json.JSONDecodeError:
|
|
pass # plain text result is expected and fine
|
|
|
|
|
|
def test_compress_offloads_real():
|
|
from tests._helpers import make_messages
|
|
|
|
engine = _engine()
|
|
engine._config = engine._config.with_context_length(8_000)
|
|
out = engine.compress(make_messages(40))
|
|
from hermes_lean_ctx import compaction
|
|
|
|
assert compaction.tool_pairing_errors(out) == []
|
|
assert len(out) < 81
|
|
|
|
|
|
def test_transcript_compact_core_tool_real():
|
|
"""The Rust core tool over /v1 returns a valid, reduced message array."""
|
|
from hermes_lean_ctx import compaction
|
|
from tests._helpers import make_messages
|
|
|
|
engine = _engine()
|
|
msgs = make_messages(40)
|
|
raw = engine._gateway.call_text(
|
|
"ctx_transcript_compact",
|
|
{"messages": msgs, "fresh_tail_tokens": 500, "protect_min_messages": 4},
|
|
)
|
|
assert raw, "daemon must support ctx_transcript_compact"
|
|
payload = json.loads(raw)
|
|
assert isinstance(payload, dict)
|
|
new_messages = payload["messages"]
|
|
assert isinstance(new_messages, list) and new_messages
|
|
assert all(isinstance(m, dict) for m in new_messages)
|
|
assert compaction.tool_pairing_errors(new_messages) == []
|
|
assert len(new_messages) < len(msgs)
|
|
stats = payload.get("stats", {})
|
|
assert stats.get("compacted") is True
|
|
assert stats.get("saved_tokens", 0) >= 0
|
|
# determinism: same input → byte-identical output (AGENTS.md #498)
|
|
raw2 = engine._gateway.call_text(
|
|
"ctx_transcript_compact",
|
|
{"messages": msgs, "fresh_tail_tokens": 500, "protect_min_messages": 4},
|
|
)
|
|
assert raw2 == raw
|
|
|
|
|
|
def test_lifecycle_hooks_real():
|
|
"""Session lifecycle hooks drive real daemon tools without raising."""
|
|
engine = _engine()
|
|
# resume on start, summary + handoff on end — must reach the daemon.
|
|
assert engine._gateway.call_text("ctx_session", {"action": "resume"}) is not None
|
|
assert engine._gateway.call_text("ctx_handoff", {"action": "create"}) is not None
|
|
engine.on_session_start("hermes-live-itest")
|
|
engine.on_session_end("hermes-live-itest", [])
|
|
status = engine.get_status()
|
|
assert status["daemon_available"] is True
|
|
assert status["session_id"] == "hermes-live-itest"
|