feat: conformance test runner + protocol fixes

- conformance.py: declarative scenario runner (subset matcher, $kind/$gt/
  $enum/$required assertions, call_id/session_id echo checks), reference
  bridge, CLI entry (python -m aicc.conformance)
- bridge.py: protocol version check before parsing (protocol_mismatch),
  session expiry handling (session_expired), malformed tool_call ->
  invalid_input, emit_event() for async events
- client.py: Self return type
- in_process.py: drain bridge event queue after response (event delivery),
  Self return type
- websocket.py: Self return type, best-effort shutdown
- tests: 14 passing (incl. conformance scenarios, 9/9 core scenarios)
- ruff: all checks pass
This commit is contained in:
Emil Shanaty
2026-08-08 03:27:14 +03:00
parent 0cfb4277b5
commit 1314314567
14 changed files with 470 additions and 68 deletions
+33
View File
@@ -0,0 +1,33 @@
"""Conformance runner tests: runs the declarative scenarios from the spec repo."""
from __future__ import annotations
from pathlib import Path
import pytest
from aicc.conformance import reference_bridge, run_scenarios, summarize
SCENARIOS = Path(__file__).resolve().parents[1] / ".." / "aicc-spec" / "conformance" / "scenarios"
@pytest.mark.asyncio
async def test_core_scenarios_pass():
if not SCENARIOS.exists():
pytest.skip("AICC-Protocol conformance scenarios not found on this machine")
bridge = reference_bridge()
results = await run_scenarios(bridge, SCENARIOS)
report = summarize(results)
assert all(r.passed for r in results), report
@pytest.mark.asyncio
async def test_runner_rejects_unknown_tool():
"""A bridge missing a required tool fails the corresponding scenario."""
from aicc import Bridge
bridge = Bridge(name="incomplete")
results = await run_scenarios(bridge, SCENARIOS)
by_id = {r.id: r for r in results}
# echo tool missing -> core-03 must fail
assert not by_id["core-03-tool-call-ok"].passed
-2
View File
@@ -2,8 +2,6 @@
from __future__ import annotations
import asyncio
import pytest
from aicc import AICCClient, Bridge, ToolClass
-2
View File
@@ -2,8 +2,6 @@
from __future__ import annotations
import asyncio
import pytest
from aicc import AICCClient, Bridge