Profiles & models¶
lm15.profiles.ProviderProfile / EndpointProfile are deprecated (1.0.0rc2) and removed in 1.0.0; see the migration table in Using model profiles. The compatibility policies and the request-level hatch stay.
lm15.profiles — provider endpoint profiles (DEPRECATED) and the Responses compat resolution that survives them.
ProviderProfile / EndpointProfile / OpenAILM.from_profile /
OpenAILM(profile=...) are deprecated as of 1.0.0rc2 and removed in
1.0.0 (contract changes/2026-09-11-job-handles-live-turns-profiles.md
§ 3). Everything they expressed has one home now:
- an endpoint's address and wire policy:
OpenAILM(compat="ollama")(a preset name supplies its own address) orcompat=+base_url=; - a per-model policy: the chat dialect's
OpenAIChatCompat.model_overrides, or per requestConfig.extensions["openai_responses_compat"]; - a compat guessed from the base URL: nothing — say
compat="openrouter".
What stays, in lm15.compat where it belongs: the partial-compat
semantics (None inherits, "auto" is the adapter default),
merge_openai_responses_compat, and the request-level hatch
(:func:openai_responses_compat_from_extensions). ModelInfo and
ModelRegistry were never profiles; they live in lm15.models.
OpenAIChatCompat
dataclass
¶
Partial compatibility policy for OpenAI Chat Completions-family APIs.
This class is consumed by OpenAIChatLM (lm15.providers.openai_chat); it is kept separate so profiles can describe chat-completions style endpoints without overloading OpenAIResponsesCompat.
for_model(model: str) -> 'OpenAIChatCompat'
¶
This compat with the first matching model_overrides entry applied.
preset(name: str) -> 'OpenAIChatCompat'
classmethod
¶
The named server dialect from :data:OPENAI_CHAT_PRESETS.
Accepts the permanent spelling aliases (lm-studio, z.ai,
openai_chat); raises ValueError for an unknown name.
OpenAIResponsesCompat
dataclass
¶
Partial compatibility policy for OpenAI Responses-family APIs.
None means "inherit". Non-None values override parent profiles. The value "auto" means "explicitly use adapter auto-detection".
preset(name: str) -> 'OpenAIResponsesCompat'
classmethod
¶
The named server dialect from :data:OPENAI_RESPONSES_PRESETS.
Accepts the permanent spelling aliases (responses, lm-studio,
z.ai); raises ValueError for an unknown name.
ResolvedOpenAIResponsesCompat
dataclass
¶
Fully resolved OpenAI Responses compatibility policy.
InferencePricing
dataclass
¶
A model's list prices, per million tokens, and estimate.
Rates are per million tokens of each billing bucket of MAP-19:
uncached input (input_tokens - cache_read_tokens - cache_write_tokens),
cache reads, cache writes, output (reasoning included). An absent rate
is unknown, never zero: a catalog that knows a bucket costs the same as
plain input states that rate. tiers (ascending by threshold) reprice
long prompts; dimensions is opaque catalog data that estimate
does not read.
estimate(usage: 'Usage') -> float | None
¶
The list-price cost of one call, or None when it is not known.
Exact or nothing (spec/types.md, InferencePricing): the result is
the sum, in this order, of uncached input, cache reads, cache writes
and output, each tokens * rate / 1_000_000, at the base rates or
at the highest tier whose above_input_tokens the call's
input_tokens exceeds. None when:
input_tokensoroutput_tokensis unknown;- a cache counter is unknown and its rate differs from the input rate (or either rate is unknown), so the split would change the price;
- a bucket with tokens has no rate;
- the call has audio tokens (audio has its own prices, which these rates do not carry).
Not covered, and never guessed: the price differences lm15 cannot
see in Usage: service tiers (flex, priority, batch), regional
multipliers, a cache write's longer lifetime, server-side tool
fees. The number is the standard list price of the tokens reported.
ModelRegistry
dataclass
¶
from_dicts(dicts: Iterable[dict]) -> 'ModelRegistry'
classmethod
¶
Build a registry from canonical ModelInfo dicts.
Each dict is validated through serde.model_info_from_dict; the
ModelInfo constructors reject junk (negative prices, empty modality
names, missing id/provider) by raising ValueError/TypeError.
discover(*, group: str = 'lm15.model_catalogs') -> 'ModelRegistry'
classmethod
¶
Hydrate a registry from installed entry-point catalogs.
Each entry point in group must load to a zero-argument callable
returning an iterable of canonical ModelInfo dicts
(docs/model-hydration.md). Catalogs are processed sorted by
entry-point name; on duplicate (provider, id) keys the FIRST
occurrence wins. A catalog that raises is skipped with a warning —
discovery never crashes the host application.
Hydrated data is ADVISORY metadata only: it must never change what build_request produces.
EndpointProfile
dataclass
¶
DEPRECATED (1.0.0rc2; removed in 1.0.0). See the module docstring.
ProviderProfile
dataclass
¶
DEPRECATED (1.0.0rc2; removed in 1.0.0). See the module docstring.
openai_responses_compat_from_extensions(extensions: JsonObject | None) -> OpenAIResponsesCompat | None
¶
Read request-level OpenAI Responses compat from Config.extensions.
Supported shapes:
{"openai_responses_compat": {...}}
{"openai_compat": {...}} # backwards-friendly alias
{"compat": {"openai_responses": {...}}}
{"compat": {"openai": {...}}} # generic OpenAI alias
The per-request hatch: the one place a Responses-dialect policy can
differ per model after profiles are gone. Normal configuration is
OpenAILM(compat=...).
resolve_openai_responses_compat(*, base_url: str, model: str, profile: ProviderProfile | None, request_extensions: JsonObject | None, base: OpenAIResponsesCompat | None = None) -> ResolvedOpenAIResponsesCompat
¶
Resolve effective OpenAI Responses compatibility policy.
Layering:
bound compat (``OpenAILM(compat=...)``), else the base URL default
< endpoint compat (deprecated with profiles)
< model compat (deprecated with profiles)
< request extension override
The base-URL default is a guess about the server and is deprecated
with the profiles: when it would pick anything but OpenAI's own
policy it warns, naming the compat= spelling that says the same
thing explicitly.
lm15.models — Optional model metadata and registry utilities.
The canonical inference request remains Request(model="..."). ModelInfo and
ModelRegistry are optional helpers for model discovery, validation, routing, and
cost estimation. Model capabilities are endpoint-specific (inference today)
so new endpoint families can be described later without breaking the
inference model. Fine-tune PROVENANCE stays describable through ModelOrigin
(type, base_model) — lm15 does inference with tuned models, not training.
PricingTier
dataclass
¶
The rates of a call whose prompt is longer than above_input_tokens.
A tier reprices the WHOLE call, not only the tokens past the threshold:
a call with Usage.input_tokens > above_input_tokens pays every rate
from the highest such tier (OpenAI: "Long context: >272K input tokens";
Anthropic Haiku 5.5: "a request whose prompt is over 100,000 tokens pays
higher prices", cache reads and writes included). input_tokens is the
whole prompt (MAP-19), which is what both providers count. A rate absent
from a tier is unknown at that tier; it is never taken from the base
rates.
InferencePricing
dataclass
¶
A model's list prices, per million tokens, and estimate.
Rates are per million tokens of each billing bucket of MAP-19:
uncached input (input_tokens - cache_read_tokens - cache_write_tokens),
cache reads, cache writes, output (reasoning included). An absent rate
is unknown, never zero: a catalog that knows a bucket costs the same as
plain input states that rate. tiers (ascending by threshold) reprice
long prompts; dimensions is opaque catalog data that estimate
does not read.
estimate(usage: 'Usage') -> float | None
¶
The list-price cost of one call, or None when it is not known.
Exact or nothing (spec/types.md, InferencePricing): the result is
the sum, in this order, of uncached input, cache reads, cache writes
and output, each tokens * rate / 1_000_000, at the base rates or
at the highest tier whose above_input_tokens the call's
input_tokens exceeds. None when:
input_tokensoroutput_tokensis unknown;- a cache counter is unknown and its rate differs from the input rate (or either rate is unknown), so the split would change the price;
- a bucket with tokens has no rate;
- the call has audio tokens (audio has its own prices, which these rates do not carry).
Not covered, and never guessed: the price differences lm15 cannot
see in Usage: service tiers (flex, priority, batch), regional
multipliers, a cache write's longer lifetime, server-side tool
fees. The number is the standard list price of the tokens reported.
ModelRegistry
dataclass
¶
from_dicts(dicts: Iterable[dict]) -> 'ModelRegistry'
classmethod
¶
Build a registry from canonical ModelInfo dicts.
Each dict is validated through serde.model_info_from_dict; the
ModelInfo constructors reject junk (negative prices, empty modality
names, missing id/provider) by raising ValueError/TypeError.
discover(*, group: str = 'lm15.model_catalogs') -> 'ModelRegistry'
classmethod
¶
Hydrate a registry from installed entry-point catalogs.
Each entry point in group must load to a zero-argument callable
returning an iterable of canonical ModelInfo dicts
(docs/model-hydration.md). Catalogs are processed sorted by
entry-point name; on duplicate (provider, id) keys the FIRST
occurrence wins. A catalog that raises is skipped with a warning —
discovery never crashes the host application.
Hydrated data is ADVISORY metadata only: it must never change what build_request produces.
Compatibility policies¶
For a worked Chat Completions example, see Connect an unlisted OpenAI-compatible server. Preset strings must be recognized names; use a typed policy object for an unlisted server's format differences.
Partial compatibility policy for OpenAI Chat Completions-family APIs.
This class is consumed by OpenAIChatLM (lm15.providers.openai_chat); it is kept separate so profiles can describe chat-completions style endpoints without overloading OpenAIResponsesCompat.
for_model(model: str) -> 'OpenAIChatCompat'
¶
This compat with the first matching model_overrides entry applied.
preset(name: str) -> 'OpenAIChatCompat'
classmethod
¶
The named server dialect from :data:OPENAI_CHAT_PRESETS.
Accepts the permanent spelling aliases (lm-studio, z.ai,
openai_chat); raises ValueError for an unknown name.
Partial compatibility policy for OpenAI Responses-family APIs.
None means "inherit". Non-None values override parent profiles. The value "auto" means "explicitly use adapter auto-detection".
preset(name: str) -> 'OpenAIResponsesCompat'
classmethod
¶
The named server dialect from :data:OPENAI_RESPONSES_PRESETS.
Accepts the permanent spelling aliases (responses, lm-studio,
z.ai); raises ValueError for an unknown name.