ExampleClient — deterministic stub that satisfies :class:`BaseClient`.
Purpose
-------
SDK-free and network-free. ``stream_chat`` and ``one_shot`` build a
fake response from the last user message ("echo: <text>"). Useful as
a template for new provider clients and as a test harness for code
that needs a working :class:`BaseClient` without hitting a real API.
``oc_diagnostics`` is the only external import — it's first-party
Option C tooling, not a foreign SDK.
When porting this file to a real provider:
1. Replace the constructor body with the SDK client construction
(e.g. ``self._sdk = OpenAI(api_key=..., base_url=...)``).
2. Replace ``stream_chat`` with a real streaming loop that yields
``("reasoning", str)``, ``("content", str)``,
``("tool_call", dict)``, and ``("usage", dict)`` chunks as the
SDK produces them. See ``providers/deepseek/client.py`` for the
canonical shape.
3. Replace ``one_shot`` with a non-streaming completion call.
4. Replace ``list_models`` with a real API call returning model ids.
Responsibilities
----------------
- :class:`ExampleClient` — :class:`BaseClient` stub with no I/O.
- :func:`_last_user_text` — pluck the most recent user message
content from the messages list.
- Deterministic fake usage block (constant token counts) so tests
can assert on it.
Diagnostics
-----------
Domain: OC_CHAT.CLIENT
Levels:
L2 — lifecycle events
L3 — semantic details
L4 — deep tracing
Contracts
---------
- ``stream_chat`` always yields exactly one ``("content", str)``
chunk and one ``("usage", dict)`` chunk — no reasoning, no tool
calls.
- ``one_shot`` returns a plain ``str`` — never ``None``.
- ``list_models`` returns the static :data:`MODELS` keys.
- No exceptions are raised under normal use; the stub is meant to
be reliable in tests.
Dependencies
------------
- oc_diagnostics (structured debug logging via _dbg)
- providers.example.models (MODELS registry whose keys list_models returns)
- option_c_agent_contracts (lazy; SupportsCancellation type of the stream_chat cancellation token)