core: Inventar/Placement, Konfig-Validierung, CLI, HTTP-API, LiteLLM-Konfiguration, Beispiel-Skills

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 00:47:13 +02:00
co-authored by Claude Opus 5.5
parent f2da893f71
commit 4cbe313c62
20 changed files with 1085 additions and 19 deletions
+10 -9
View File
@@ -41,7 +41,7 @@ def make_runner(registry, library, embedder, store, fake_chat, classifiers):
def test_weak_success_records_case(make_runner, store):
runner = make_runner(**{"rechnungen-v1": lambda m: GOOD})
runner = make_runner(**{"tier1-general/rechnungen-v1": lambda m: GOOD})
res = runner.run(RECHNUNG)
assert res.status == "ok" and res.stage == 1 and res.escalations == 0
cases = store.list_cases()
@@ -51,7 +51,7 @@ def test_weak_success_records_case(make_runner, store):
def test_schema_failure_escalates_and_creates_pair(make_runner, store):
runner = make_runner(**{
"rechnungen-v1": lambda m: json.dumps({"nummer": "4711"}), # betrag fehlt
"tier1-general/rechnungen-v1": lambda m: json.dumps({"nummer": "4711"}), # betrag fehlt
"tier0-strong": lambda m: GOOD,
})
res = runner.run(RECHNUNG)
@@ -63,7 +63,7 @@ def test_schema_failure_escalates_and_creates_pair(make_runner, store):
def test_invalid_json_signal(make_runner, store):
runner = make_runner(**{"rechnungen-v1": lambda m: "kein json", "tier0-strong": lambda m: GOOD})
runner = make_runner(**{"tier1-general/rechnungen-v1": lambda m: "kein json", "tier0-strong": lambda m: GOOD})
res = runner.run(RECHNUNG)
assert Signal.INVALID_FORMAT in res.attempts[0].execution.signals
assert res.stage == 0
@@ -74,7 +74,7 @@ def test_endpoint_error_uses_fallback_slot_without_case(make_runner, store):
def boom(m):
raise EndpointError("down")
runner = make_runner(**{"rechnungen-v1": boom})
runner = make_runner(**{"tier1-general/rechnungen-v1": boom})
# Fallback-Slot tier1-flex hat dieselbe Basis → gleicher Adapter-Name; daher Fehler nur einmal
calls = {"n": 0}
@@ -84,7 +84,8 @@ def test_endpoint_error_uses_fallback_slot_without_case(make_runner, store):
raise EndpointError("down")
return GOOD
runner.executor.chat.handlers["rechnungen-v1"] = flaky
runner.executor.chat.handlers["tier1-general/rechnungen-v1"] = flaky
runner.executor.chat.handlers["tier1-flex/rechnungen-v1"] = lambda m: GOOD
res = runner.run(RECHNUNG)
assert res.status == "ok"
assert [a.decision.slot for a in res.attempts] == ["tier1-general", "tier1-flex"]
@@ -96,7 +97,7 @@ def test_context_overflow_detected(make_runner):
def overflow(m):
raise ContextOverflowError("maximum context length")
runner = make_runner(**{"rechnungen-v1": overflow, "tier0-strong": lambda m: GOOD})
runner = make_runner(**{"tier1-general/rechnungen-v1": overflow, "tier0-strong": lambda m: GOOD})
res = runner.run(RECHNUNG)
assert res.attempts[0].execution.signals == [Signal.CONTEXT_OVERFLOW]
assert res.status == "ok"
@@ -105,7 +106,7 @@ def test_context_overflow_detected(make_runner):
def test_truncated_and_degenerate(make_runner):
loop = " ".join(["immer wieder das gleiche"] * 30)
runner = make_runner(**{
"rechnungen-v1": lambda m: ChatResult(content=loop, finish_reason="length"),
"tier1-general/rechnungen-v1": lambda m: ChatResult(content=loop, finish_reason="length"),
"tier0-strong": lambda m: GOOD,
})
res = runner.run(RECHNUNG)
@@ -114,7 +115,7 @@ def test_truncated_and_degenerate(make_runner):
def test_total_failure(make_runner):
runner = make_runner(**{"rechnungen-v1": lambda m: "x", "tier0-strong": lambda m: "y"})
runner = make_runner(**{"tier1-general/rechnungen-v1": lambda m: "x", "tier0-strong": lambda m: "y"})
res = runner.run(RECHNUNG)
assert res.status == "failed"
@@ -193,7 +194,7 @@ def test_split_is_deterministic():
def test_exports(make_runner, store):
runner = make_runner(**{"rechnungen-v1": lambda m: '{"nummer": "1"}', "tier0-strong": lambda m: GOOD})
runner = make_runner(**{"tier1-general/rechnungen-v1": lambda m: '{"nummer": "1"}', "tier0-strong": lambda m: GOOD})
for i in range(30):
runner.run(f"{RECHNUNG} Nr {i}")
train = list(export_sft(store, cluster="rechnungen", split="train"))