Files
cluster-knaster/core/tests/test_registry_skills.py

79 lines
3.2 KiB
Python

from knaster.registry import AdapterSpec, Registry
from knaster.skills import compact_body, parse_skill
def test_slot_effective_context_prefers_calibration(registry):
slot = registry.slot("tier1-general")
assert slot.effective_context == 2000
registry.set_calibrated_context("tier1-general", 1500)
assert registry.slot("tier1-general").effective_context == 1500
def test_effective_context_never_exceeds_max(registry):
registry.set_calibrated_context("tier1-general", 999999)
assert registry.slot("tier1-general").effective_context == 8192
def test_status_and_strong_slot(registry):
registry.set_status("tier1-general", "degraded", reason="test", set_by="healer")
slot = registry.slot("tier1-general")
assert not slot.available and slot.set_by == "healer"
assert registry.strong_slot().name == "tier0-strong"
def test_unknown_fallback_rejected(store):
import pytest
with pytest.raises(ValueError):
Registry.from_dict({"slots": {"a": {"tier": 1, "litellm_model": "a", "base_model": "b",
"max_context": 10, "fallbacks": ["x"]}}}, store)
def test_adapter_overlay_and_active(registry):
assert registry.active_adapter("base-14b", "rechnungen").name == "rechnungen-v1"
registry.set_adapter(AdapterSpec(name="rechnungen-v2", base_model="base-14b", cluster="rechnungen",
version=2, status="active"))
assert registry.active_adapter("base-14b", "rechnungen").name == "rechnungen-v2"
registry.set_adapter(AdapterSpec(name="rechnungen-v2", base_model="base-14b", cluster="rechnungen",
version=2, status="retired"))
assert registry.active_adapter("base-14b", "rechnungen").name == "rechnungen-v1"
assert registry.active_adapter("other-base", "rechnungen") is None
def test_base_model_override_and_export(registry):
registry.set_base_model("tier1-general", "new-base")
assert registry.slot("tier1-general").base_model == "new-base"
exported = registry.export()
assert exported["slots"]["tier1-general"]["base_model"] == "new-base"
def test_parse_skill_and_compact(library):
skill = library.get("rechnung-extrahieren")
assert skill.cluster == "rechnungen"
assert skill.meta.output.format == "json"
assert "Beispiele" in skill.prompt("full")
assert "Beispiele" not in skill.prompt("compact")
assert "Lies Nummer" in skill.prompt("compact")
def test_compact_body_keeps_following_sections():
body = "# T\nA\n## Beispiele\nx\ny\n## Regeln\nR\n"
assert compact_body(body) == "# T\nA\n## Regeln\nR"
def test_parse_skill_requires_fields():
import pytest
with pytest.raises(ValueError):
parse_skill("---\nname: x\n---\nbody")
with pytest.raises(ValueError):
parse_skill("kein frontmatter")
def test_routable_and_state_overlay(library):
names = {s.name for s in library.routable()}
assert "entwurf" not in names and "vertrag-pruefen" in names
library.set_state("rechnung-extrahieren", status="demoted", reason="drift")
assert library.get("rechnung-extrahieren").meta.status == "demoted"
assert library.get("rechnung-extrahieren").meta.stage == 1