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
+9 -10
View File
@@ -4,11 +4,16 @@ from __future__ import annotations
import asyncio
import uuid
from typing import Any
from typing import Any, Self
from aicc.errors import (
AICCError,
ConnectionError_,
ProtocolError,
ToolError,
)
from aicc.protocol import (
PROTOCOL_VERSION,
ErrorCode,
EventMessage,
MessageType,
SessionClose,
@@ -16,12 +21,6 @@ from aicc.protocol import (
ToolCall,
ToolResult,
)
from aicc.errors import (
AICCError,
ConnectionError_,
ProtocolError,
ToolError,
)
from aicc.transport.base import Transport
@@ -56,14 +55,14 @@ class AICCClient:
# ---------- Lifecycle ----------
async def __aenter__(self) -> "AICCClient":
async def __aenter__(self) -> Self:
await self._transport.connect()
return self
async def __aexit__(self, exc_type, exc, tb) -> None:
await self.close()
async def connect(self) -> "AICCClient":
async def connect(self) -> AICCClient:
await self._transport.connect()
return self