Overuse may indicate design issues; consider polymorphism
if not isinstance(profile, dict):
1"""Model profile types and utilities."""23import logging4import warnings5from typing import get_type_hints67from pydantic import ConfigDict8from typing_extensions import TypedDict910logger = logging.getLogger(__name__)111213class ModelProfile(TypedDict, total=False):14 """Description of a chat model's capabilities, exposed via `model.profile`.1516 See the17 [model profiles guide](https://docs.langchain.com/oss/python/langchain/models#model-profiles)18 for concepts and usage. Data is sourced from19 [models.dev](https://github.com/sst/models.dev), augmented with additional20 fields, and generated by the21 [`langchain-model-profiles`](https://github.com/langchain-ai/langchain/tree/master/libs/model-profiles)22 package (via its `langchain-profiles` CLI).2324 !!! warning "Beta feature"2526 Fields and format are subject to change. This is a `total=False`27 `TypedDict`, so any field may be absent — guard accesses with `.get()`.28 """2930 __pydantic_config__ = ConfigDict(extra="allow") # type: ignore[misc]3132 # --- Model metadata ---3334 name: str35 """Human-readable model name (e.g., `'GPT-5'`)."""3637 status: str38 """Model lifecycle status (e.g., `'active'`, `'deprecated'`)."""3940 release_date: str41 """Model release date (ISO 8601 format, e.g., `'2025-06-01'`)."""4243 last_updated: str44 """Date the model was last updated (ISO 8601 format)."""4546 open_weights: bool47 """Whether the model weights are openly available."""4849 # --- Input constraints ---5051 max_input_tokens: int52 """Maximum context window (tokens)."""5354 text_inputs: bool55 """Whether text inputs are supported."""5657 image_inputs: bool58 """Whether image inputs are supported."""59 # TODO: add more detail about formats?6061 image_url_inputs: bool62 """Whether [image URL inputs](https://docs.langchain.com/oss/python/langchain/models#multimodal)63 are supported."""6465 pdf_inputs: bool66 """Whether [PDF inputs](https://docs.langchain.com/oss/python/langchain/models#multimodal)67 are supported."""68 # TODO: add more detail about formats? e.g. bytes or base646970 audio_inputs: bool71 """Whether [audio inputs](https://docs.langchain.com/oss/python/langchain/models#multimodal)72 are supported."""73 # TODO: add more detail about formats? e.g. bytes or base647475 video_inputs: bool76 """Whether [video inputs](https://docs.langchain.com/oss/python/langchain/models#multimodal)77 are supported."""78 # TODO: add more detail about formats? e.g. bytes or base647980 image_tool_message: bool81 """Whether images can be included in `ToolMessage` content."""8283 pdf_tool_message: bool84 """Whether PDFs can be included in `ToolMessage` content."""8586 # --- Output constraints ---8788 max_output_tokens: int89 """Maximum output tokens."""9091 reasoning_output: bool92 """Whether the model supports [reasoning / chain-of-thought](https://docs.langchain.com/oss/python/langchain/models#reasoning)."""9394 reasoning_effort_levels: list[str]95 """Supported reasoning-effort levels (e.g. `['low', 'medium', 'high']`).9697 Absent or empty if the model does not support a configurable reasoning98 effort. Only meaningful when `reasoning_output` is `True`.99 """100101 reasoning_effort_default: str102 """The provider's documented default reasoning-effort level, if known.103104 Absent when no default is documented. Only meaningful when105 `reasoning_effort_levels` is non-empty; not necessarily a member of106 `reasoning_effort_levels` itself (a model may default to unconfigurable107 behavior distinct from any explicit level).108 """109110 text_outputs: bool111 """Whether text outputs are supported."""112113 image_outputs: bool114 """Whether [image outputs](https://docs.langchain.com/oss/python/langchain/models#multimodal)115 are supported."""116117 audio_outputs: bool118 """Whether [audio outputs](https://docs.langchain.com/oss/python/langchain/models#multimodal)119 are supported."""120121 video_outputs: bool122 """Whether [video outputs](https://docs.langchain.com/oss/python/langchain/models#multimodal)123 are supported."""124125 # --- Tool calling ---126 tool_calling: bool127 """Whether the model supports [tool calling](https://docs.langchain.com/oss/python/langchain/models#tool-calling)."""128129 tool_choice: bool130 """Whether the model supports [tool choice](https://docs.langchain.com/oss/python/langchain/models#forcing-tool-calls)."""131132 tool_call_streaming: bool133 """Whether the model returns properly structured `tool_call_chunks` when streaming.134135 Only meaningful when `tool_calling` is `True`.136 """137138 # --- Structured output ---139 structured_output: bool140 """Whether the model supports native [structured output](https://docs.langchain.com/oss/python/langchain/models#structured-outputs)."""141142 # --- Other capabilities ---143144 attachment: bool145 """Whether the model supports file attachments."""146147 temperature: bool148 """Whether the model supports a temperature parameter."""149150151ModelProfileRegistry = dict[str, ModelProfile]152"""Registry mapping model identifiers or names to their ModelProfile."""153154155def _warn_unknown_profile_keys(profile: ModelProfile) -> None:156 """Warn if `profile` contains keys not declared on `ModelProfile`.157158 Args:159 profile: The model profile dict to check for undeclared keys.160 """161 if not isinstance(profile, dict):162 return # type: ignore[unreachable]163164 try:165 declared = frozenset(get_type_hints(ModelProfile).keys())166 except (TypeError, NameError):167 # get_type_hints raises NameError on unresolvable forward refs and168 # TypeError when annotations evaluate to non-type objects.169 logger.debug(170 "Could not resolve type hints for ModelProfile; "171 "skipping unknown-key check.",172 exc_info=True,173 )174 return175176 extra = sorted(set(profile) - declared)177 if extra:178 warnings.warn(179 f"Unrecognized keys in model profile: {extra}. "180 f"This may indicate a version mismatch between langchain-core "181 f"and your provider package. Consider upgrading langchain-core.",182 stacklevel=2,183 )
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.