blizzarman's picture
feat: M0 walking skeleton (app, service protocols, CI/CD, Space deploy)
00d5ae5
Raw
History Blame Contribute Delete
950 Bytes
"""LLM client contract.
Anything that can turn a chat into text satisfies `LLMClient` — the app, the
exercise generators and the evals only ever depend on this Protocol, never on
a vendor SDK (same pattern for ASR / TTS / storage).
"""
from collections.abc import Sequence
from typing import Literal, Protocol, runtime_checkable
from pydantic import BaseModel
Role = Literal["system", "user", "assistant"]
class ChatMessage(BaseModel):
role: Role
content: str
class LLMResponse(BaseModel):
text: str
model: str
input_tokens: int | None = None
output_tokens: int | None = None
class LLMError(RuntimeError):
"""A completion failed (network, auth, rate limit, provider error...)."""
@runtime_checkable
class LLMClient(Protocol):
async def complete(
self,
messages: Sequence[ChatMessage],
*,
temperature: float = 0.7,
max_tokens: int = 1024,
) -> LLMResponse: ...