"""LLMProvider port — 大语言模型能力契约。""" from collections.abc import AsyncIterator from typing import Protocol, runtime_checkable @runtime_checkable class LLMProvider(Protocol): async def complete( self, messages: list[dict], *, temperature: float = 0.7, model: str | None = None, max_tokens: int | None = None, ) -> str: """Single-turn completion, returns full response text. Implementations MUST wrap underlying SDK calls with their own telemetry (e.g. ``langchain_invoke_span``) so callers such as ``LlmGateway`` can invoke ``complete()`` without adding a second observability layer. ``max_tokens`` when set is passed to the underlying chat API (adapter-specific). """ ... def stream( self, messages: list[dict], *, temperature: float = 0.7, model: str | None = None, max_tokens: int | None = None, ) -> AsyncIterator[str]: """Streaming completion, yields text chunks (async generator).""" ...