6ExampleProvider — minimal :class:`ProviderPlugin` implementation.
10Every abstract method is implemented with the simplest body that
11satisfies the contract: no provider-specific quirks, no
12``extra_body`` shaping, no message transformation. When porting to a
13real provider, replace each method body in turn — the comments mark
14every DeepSeek-specific pattern that does *not* belong in a generic
19- :class:`ExampleProvider` — implement every abstract method on
20 :class:`ProviderPlugin` with the minimal body needed.
21- :meth:`build_client` — return an :class:`ExampleClient`.
22- :meth:`models` / :meth:`tier` — surface the static registries.
23- :meth:`build_extra_body` — always return ``None`` (no thinking
25- :meth:`transform_outgoing_messages` — pass-through (no schema
27- :meth:`parse_usage` — defer to the shared
28 :func:`usage_prompt_cache_hit_miss` helper.
40- The example bundle stays dependency-free — no SDK imports, no
42- ``build_extra_body`` returns ``None`` regardless of model
43 capabilities (no thinking shape needed for stubs).
44- ``transform_outgoing_messages`` is a true pass-through (no
45 sentinel embedding) — the example provider exists to prove the
46 contract works without provider-specific transforms.
47- All abstract surface lives here; everything else in the bundle is
52- oc_diagnostics (structured debug logging via _dbg)
53- option_c_agent_contracts (ProviderPlugin base class and the ModelCaps, UsageStats and BaseClient types)
54- providers.example.client (ExampleClient returned by build_client)
55- providers.example.models (MODELS and TIER_MAP registries)
57from __future__
import annotations
59from oc_diagnostics
import _dbg
61from option_c_agent_contracts
import (
68from .client
import ExampleClient
69from .models
import MODELS, TIER_MAP
75 api_key_env_var =
"EXAMPLE_API_KEY"
76 base_url_env_var =
"EXAMPLE_BASE_URL"
78 default_model =
"example-echo"
84 _dbg(
"OC_CHAT.CLIENT", func, f
"ExampleProvider base_url={base_url!r}", 4)
89 def models(self) -> dict[str, ModelCaps]:
95 return client.list_models()
101 supports_thinking=
False,
102 supports_reasoning=
False,
104 max_context_tokens=4096,
109 def tier(self, name: str) -> str |
None:
110 return TIER_MAP.get(name)
118 enable_thinking: bool,
121 """No provider-specific ``extra_body`` payload.
123 DeepSeek returns ``{"thinking": {"type": "enabled"}}`` here when
124 thinking is requested and the model supports it; other providers
125 with no equivalent concept return ``None``.
131 messages: list[dict],
132 tool_schemas: list[dict] |
None,
134 """No-op — return messages unchanged.
136 DeepSeek embeds JSON tool schemas into the system prompt for
137 prefix-cache stability and appends a sentinel comment. Providers
138 without prefix caching (or with server-side automatic caching)
139 return the messages unchanged.
146 if not isinstance(usage, dict):
149 prompt_tokens=int(usage.get(
"prompt_tokens")
or 0),
150 completion_tokens=int(usage.get(
"completion_tokens")
or 0),
151 total_tokens=int(usage.get(
"total_tokens")
or 0),
UsageStats parse_usage(self, dict usage)
dict|None build_extra_body(self, str model, *, bool enable_thinking, str|None effort)
list[dict] transform_outgoing_messages(self, list[dict] messages, list[dict]|None tool_schemas)
str|None tier(self, str name)
ModelCaps default_caps(self)
BaseClient build_client(self, str api_key, str base_url)
list[str] fetch_live_models(self, BaseClient client)