Ensure functions have docstrings for documentation
def init_chat_model(
1from __future__ import annotations23import warnings4from collections.abc import AsyncIterator, Callable, Iterator, Sequence5from importlib import util6from typing import Any, Literal, TypeAlias, cast, overload78from langchain_core._api import deprecated9from langchain_core.language_models import (10 BaseChatModel,11 LanguageModelInput,12 SimpleChatModel,13)14from langchain_core.language_models.chat_models import (15 agenerate_from_stream,16 generate_from_stream,17)18from langchain_core.messages import AIMessage, AnyMessage19from langchain_core.runnables import Runnable, RunnableConfig, ensure_config20from langchain_core.runnables.schema import StreamEvent21from langchain_core.tools import BaseTool22from langchain_core.tracers import RunLog, RunLogPatch23from pydantic import BaseModel24from typing_extensions import override2526__all__ = [27 # For backwards compatibility28 "BaseChatModel",29 "SimpleChatModel",30 "agenerate_from_stream",31 "generate_from_stream",32 "init_chat_model",33]343536@overload37def init_chat_model(38 model: str,39 *,40 model_provider: str | None = None,41 configurable_fields: None = None,42 config_prefix: str | None = None,43 **kwargs: Any,44) -> BaseChatModel: ...454647@overload48def init_chat_model(49 model: None = None,50 *,51 model_provider: str | None = None,52 configurable_fields: None = None,53 config_prefix: str | None = None,54 **kwargs: Any,55) -> _ConfigurableModel: ...565758@overload59def init_chat_model(60 model: str | None = None,61 *,62 model_provider: str | None = None,63 configurable_fields: Literal["any"] | list[str] | tuple[str, ...] = ...,64 config_prefix: str | None = None,65 **kwargs: Any,66) -> _ConfigurableModel: ...676869# FOR CONTRIBUTORS: If adding support for a new provider, please append the provider70# name to the supported list in the docstring below. Do *not* change the order of the71# existing providers.72@deprecated(73 since="1.0.5",74 removal="2.0.0",75 alternative="langchain.chat_models.init_chat_model",76 addendum=(77 "Maintained in `langchain`; `langchain-classic` retains this entry point "78 "for import-compatibility only."79 ),80)81def init_chat_model(82 model: str | None = None,83 *,84 model_provider: str | None = None,85 configurable_fields: Literal["any"] | list[str] | tuple[str, ...] | None = None,86 config_prefix: str | None = None,87 **kwargs: Any,88) -> BaseChatModel | _ConfigurableModel:89 """Initialize a chat model from any supported provider using a unified interface.9091 !!! warning "Use `langchain.chat_models.init_chat_model` instead"9293 This function lives in `langchain-classic` and is no longer actively94 maintained. New features and fixes land in the `langchain` package.9596 Update your imports:9798 ```python99 # Don't do this:100 from langchain.chat_models import init_chat_model101102 # Do this instead:103 from langchain.chat_models import init_chat_model104 ```105106 **Two main use cases:**107108 1. **Fixed model** – specify the model upfront and get a109 ready-to-use chat model.110 2. **Configurable model** – choose to specify parameters111 (including model name) at runtime via `config`. Makes it easy to112 switch between models/providers without changing your code113114 !!! note "Installation requirements"115116 Requires the integration package for the chosen model provider to117 be installed.118119 See the `model_provider` parameter below for specific package names120 (e.g., `pip install langchain-openai`).121122 Refer to the [provider integration's API reference](https://docs.langchain.com/oss/python/integrations/providers)123 for supported model parameters to use as `**kwargs`.124125 Args:126 model: Name of the model to use, with provider prefix — e.g.,127 `'openai:gpt-5.5'`.128129 A bare model name (e.g., `'claude-opus-4-7'`) is also accepted; we130 will attempt to infer the provider from the prefix using the mapping131 below. Inference is best-effort and not guaranteed, so prefer132 the prefixed form when possible.133134 Prefer pinned model IDs over moving aliases (e.g.,135 `'claude-haiku-4-5-20251001'` rather than `'claude-haiku-4-5'`)136 so behavior does not drift if the alias is repointed upstream.137138 Inferred providers by prefix (case-insensitive):139140 - `gpt-...` | `o1...` | `o3...` -> `openai`141 - `claude...` -> `anthropic`142 - `amazon....` | `anthropic....` | `meta....` -> `bedrock`143 - `gemini...` -> `google_vertexai`144 - `command...` -> `cohere`145 - `accounts/fireworks...` -> `fireworks`146 - `mistral...` | `mixtral...` -> `mistralai`147 - `deepseek...` -> `deepseek`148 - `grok...` -> `xai`149 - `sonar...` -> `perplexity`150 - `solar...` -> `upstage`151 - `chatgpt...` | `text-davinci...` -> `openai` (legacy)152 model_provider: Provider of the model, passed separately instead of153 as a prefix on `model`.154155 Equivalent to the prefix form — e.g.,156 `model='claude-sonnet-4-5', model_provider='anthropic'` behaves157 the same as `model='anthropic:claude-sonnet-4-5'`.158159 Prefer the prefix form on `model` for most usage. Reach for this160 kwarg when:161162 - The provider is dynamic (read from config or an env var) and163 you'd otherwise concatenate strings.164 - You want `model` and `model_provider` to be independently165 swappable at runtime via `configurable_fields` (e.g., to route166 the same model name to a different host).167168 Supported values and the integration package each requires:169170 - `openai` -> [`langchain-openai`](https://docs.langchain.com/oss/python/integrations/providers/openai)171 - `anthropic` -> [`langchain-anthropic`](https://docs.langchain.com/oss/python/integrations/providers/anthropic)172 - `azure_openai` -> [`langchain-openai`](https://docs.langchain.com/oss/python/integrations/providers/openai)173 - `azure_ai` -> [`langchain-azure-ai`](https://docs.langchain.com/oss/python/integrations/providers/microsoft)174 - `google_vertexai` -> [`langchain-google-vertexai`](https://docs.langchain.com/oss/python/integrations/providers/google)175 - `google_genai` -> [`langchain-google-genai`](https://docs.langchain.com/oss/python/integrations/providers/google)176 - `bedrock` -> [`langchain-aws`](https://docs.langchain.com/oss/python/integrations/providers/aws)177 - `bedrock_converse` -> [`langchain-aws`](https://docs.langchain.com/oss/python/integrations/providers/aws)178 - `cohere` -> [`langchain-cohere`](https://docs.langchain.com/oss/python/integrations/providers/cohere)179 - `fireworks` -> [`langchain-fireworks`](https://docs.langchain.com/oss/python/integrations/providers/fireworks)180 - `together` -> [`langchain-together`](https://docs.langchain.com/oss/python/integrations/providers/together)181 - `mistralai` -> [`langchain-mistralai`](https://docs.langchain.com/oss/python/integrations/providers/mistralai)182 - `huggingface` -> [`langchain-huggingface`](https://docs.langchain.com/oss/python/integrations/providers/huggingface)183 - `groq` -> [`langchain-groq`](https://docs.langchain.com/oss/python/integrations/providers/groq)184 - `ollama` -> [`langchain-ollama`](https://docs.langchain.com/oss/python/integrations/providers/ollama)185 - `google_anthropic_vertex` -> [`langchain-google-vertexai`](https://docs.langchain.com/oss/python/integrations/providers/google)186 - `deepseek` -> [`langchain-deepseek`](https://docs.langchain.com/oss/python/integrations/providers/deepseek)187 - `ibm` -> [`langchain-ibm`](https://docs.langchain.com/oss/python/integrations/providers/ibm)188 - `nvidia` -> [`langchain-nvidia-ai-endpoints`](https://docs.langchain.com/oss/python/integrations/providers/nvidia)189 - `xai` -> [`langchain-xai`](https://docs.langchain.com/oss/python/integrations/providers/xai)190 - `perplexity` -> [`langchain-perplexity`](https://docs.langchain.com/oss/python/integrations/providers/perplexity)191 - `upstage` -> [`langchain-upstage`](https://docs.langchain.com/oss/python/integrations/providers/upstage)192 configurable_fields: Which model parameters are configurable at runtime:193194 - `None`: No configurable fields (i.e., a fixed model).195 - `'any'`: All fields are configurable. **See security note below.**196 - `list[str] | Tuple[str, ...]`: Specified fields are configurable.197198 Fields are assumed to have `config_prefix` stripped if a `config_prefix` is199 specified.200201 If `model` is specified, then defaults to `None`.202203 If `model` is not specified, then defaults to `("model", "model_provider")`.204205 !!! warning "Security note"206207 Setting `configurable_fields="any"` means fields like `api_key`,208 `base_url`, etc., can be altered at runtime, potentially redirecting209 model requests to a different service/user.210211 Make sure that if you're accepting untrusted configurations that you212 enumerate the `configurable_fields=(...)` explicitly.213214 config_prefix: Optional prefix for configuration keys.215216 Useful when you have multiple configurable models in the same application.217218 If `'config_prefix'` is a non-empty string then `model` will be configurable219 at runtime via the `config["configurable"]["{config_prefix}_{param}"]` keys.220 See examples below.221222 If `'config_prefix'` is an empty string then model will be configurable via223 `config["configurable"]["{param}"]`.224 **kwargs: Additional model-specific keyword args to pass to the underlying225 chat model's `__init__` method. Common parameters include:226227 - `temperature`: Model temperature for controlling randomness.228 - `max_tokens`: Maximum number of output tokens.229 - `timeout`: Maximum time (in seconds) to wait for a response.230 - `max_retries`: Maximum number of retry attempts for failed requests.231 - `base_url`: Custom API endpoint URL.232 - `rate_limiter`: A233 [`BaseRateLimiter`][langchain_core.rate_limiters.BaseRateLimiter]234 instance to control request rate.235236 Refer to the specific model provider's237 [integration reference](https://reference.langchain.com/python/integrations/)238 for all available parameters.239240 Returns:241 A [`BaseChatModel`][langchain_core.language_models.BaseChatModel] corresponding242 to the `model_name` and `model_provider` specified if configurability is243 inferred to be `False`.244 If configurable, a chat model emulator that initializes the245 underlying model at runtime once a config is passed in.246247 Raises:248 ValueError: If `model_provider` cannot be inferred or isn't supported.249 ImportError: If the model provider integration package is not installed.250251 ???+ example "Initialize a non-configurable model"252253 ```python254 # pip install langchain langchain-openai255256 from langchain.chat_models import init_chat_model257258 gpt_5 = init_chat_model("openai:gpt-5.5", temperature=0)259 gpt_5.invoke("what's your name")260 ```261262 ??? example "Partially configurable model with no default"263264 ```python265 # pip install langchain langchain-openai266267 from langchain.chat_models import init_chat_model268269 # (We don't need to specify configurable=True if a model isn't specified.)270 configurable_model = init_chat_model(temperature=0)271272 # Use GPT-5.5 to generate the response273 configurable_model.invoke(274 "what's your name",275 config={"configurable": {"model": "gpt-5.5"}},276 )277 ```278279 ??? example "Fully configurable model with a default"280281 ```python282 # pip install langchain langchain-openai langchain-anthropic283284 from langchain.chat_models import init_chat_model285286 configurable_model_with_default = init_chat_model(287 "openai:gpt-5.5",288 configurable_fields="any", # This allows us to configure other params like temperature, max_tokens, etc at runtime.289 config_prefix="foo",290 temperature=0,291 )292293 configurable_model_with_default.invoke("what's your name")294 # GPT-5.5 response with temperature 0 (as set in default)295296 # Invoke overriding model and temperature at runtime via config.297 # Note the use of the "foo_" prefix on the config keys, which matches298 # the config_prefix we set when initializing the model.299 configurable_model_with_default.invoke(300 "what's your name",301 config={302 "configurable": {303 "foo_model": "anthropic:claude-opus-4-7",304 "foo_temperature": 0.6,305 }306 },307 )308 ```309310 ??? example "Bind tools to a configurable model"311312 You can call any chat model declarative methods on a configurable model313 in the same way that you would with a normal model:314315 ```python316 # pip install langchain langchain-openai langchain-anthropic317318 from langchain.chat_models import init_chat_model319 from pydantic import BaseModel, Field320321322 class GetWeather(BaseModel):323 '''Get the current weather in a given location'''324325 location: str = Field(326 ..., description="The city and state, e.g. San Francisco, CA"327 )328329330 class GetPopulation(BaseModel):331 '''Get the current population in a given location'''332333 location: str = Field(334 ..., description="The city and state, e.g. San Francisco, CA"335 )336337338 configurable_model = init_chat_model(339 "gpt-5.5", configurable_fields=("model", "model_provider"), temperature=0340 )341342 configurable_model_with_tools = configurable_model.bind_tools(343 [344 GetWeather,345 GetPopulation,346 ]347 )348 configurable_model_with_tools.invoke(349 "Which city is hotter today and which is bigger: LA or NY?"350 )351 # Use GPT-5.5352353 configurable_model_with_tools.invoke(354 "Which city is hotter today and which is bigger: LA or NY?",355 config={"configurable": {"model": "claude-opus-4-7"}},356 )357 # Use Opus 4.7358 ```359360 """ # noqa: E501361 if not model and not configurable_fields:362 configurable_fields = ("model", "model_provider")363 config_prefix = config_prefix or ""364 if config_prefix and not configurable_fields:365 warnings.warn(366 f"{config_prefix=} has been set but no fields are configurable. Set "367 f"`configurable_fields=(...)` to specify the model params that are "368 f"configurable.",369 stacklevel=2,370 )371372 if not configurable_fields:373 return _init_chat_model_helper(374 cast("str", model),375 model_provider=model_provider,376 **kwargs,377 )378 if model:379 kwargs["model"] = model380 if model_provider:381 kwargs["model_provider"] = model_provider382 return _ConfigurableModel(383 default_config=kwargs,384 config_prefix=config_prefix,385 configurable_fields=configurable_fields,386 )387388389def _init_chat_model_helper(390 model: str,391 *,392 model_provider: str | None = None,393 **kwargs: Any,394) -> BaseChatModel:395 model, model_provider = _parse_model(model, model_provider)396 if model_provider == "openai":397 _check_pkg("langchain_openai", "ChatOpenAI")398 from langchain_openai import ChatOpenAI399400 return ChatOpenAI(model=model, **kwargs)401 if model_provider == "anthropic":402 _check_pkg("langchain_anthropic", "ChatAnthropic")403 from langchain_anthropic import ChatAnthropic404405 return ChatAnthropic(model=model, **kwargs) # type: ignore[call-arg,unused-ignore]406 if model_provider == "azure_openai":407 _check_pkg("langchain_openai", "AzureChatOpenAI")408 from langchain_openai import AzureChatOpenAI409410 return AzureChatOpenAI(model=model, **kwargs)411 if model_provider == "azure_ai":412 _check_pkg("langchain_azure_ai", "AzureAIOpenAIApiChatModel")413 from langchain_azure_ai.chat_models import AzureAIOpenAIApiChatModel414415 return AzureAIOpenAIApiChatModel(model=model, **kwargs)416 if model_provider == "cohere":417 _check_pkg("langchain_cohere", "ChatCohere")418 from langchain_cohere import ChatCohere419420 return ChatCohere(model=model, **kwargs)421 if model_provider == "google_vertexai":422 _check_pkg("langchain_google_vertexai", "ChatVertexAI")423 from langchain_google_vertexai import ChatVertexAI424425 return ChatVertexAI(model=model, **kwargs)426 if model_provider == "google_genai":427 _check_pkg("langchain_google_genai", "ChatGoogleGenerativeAI")428 from langchain_google_genai import ChatGoogleGenerativeAI429430 return ChatGoogleGenerativeAI(model=model, **kwargs)431 if model_provider == "fireworks":432 _check_pkg("langchain_fireworks", "ChatFireworks")433 from langchain_fireworks import ChatFireworks434435 return ChatFireworks(model=model, **kwargs)436 if model_provider == "ollama":437 try:438 _check_pkg("langchain_ollama", "ChatOllama")439 from langchain_ollama import ChatOllama440 except ImportError:441 # For backwards compatibility442 try:443 _check_pkg("langchain_community", "ChatOllama")444 from langchain_community.chat_models import ChatOllama445 except ImportError:446 # If both langchain-ollama and langchain-community aren't available,447 # raise an error related to langchain-ollama448 _check_pkg("langchain_ollama", "ChatOllama")449450 return ChatOllama(model=model, **kwargs)451 if model_provider == "together":452 _check_pkg("langchain_together", "ChatTogether")453 from langchain_together import ChatTogether454455 return ChatTogether(model=model, **kwargs)456 if model_provider == "mistralai":457 _check_pkg("langchain_mistralai", "ChatMistralAI")458 from langchain_mistralai import ChatMistralAI459460 return ChatMistralAI(model=model, **kwargs) # type: ignore[call-arg,unused-ignore]461462 if model_provider == "huggingface":463 _check_pkg("langchain_huggingface", "ChatHuggingFace")464 from langchain_huggingface import ChatHuggingFace465466 return ChatHuggingFace.from_model_id(model_id=model, **kwargs)467468 if model_provider == "groq":469 _check_pkg("langchain_groq", "ChatGroq")470 from langchain_groq import ChatGroq471472 return ChatGroq(model=model, **kwargs)473 if model_provider == "bedrock":474 _check_pkg("langchain_aws", "ChatBedrock")475 from langchain_aws import ChatBedrock476477 # TODO: update to use model= once ChatBedrock supports478 return ChatBedrock(model_id=model, **kwargs)479 if model_provider == "bedrock_converse":480 _check_pkg("langchain_aws", "ChatBedrockConverse")481 from langchain_aws import ChatBedrockConverse482483 return ChatBedrockConverse(model=model, **kwargs)484 if model_provider == "google_anthropic_vertex":485 _check_pkg("langchain_google_vertexai", "ChatAnthropicVertex")486 from langchain_google_vertexai.model_garden import ChatAnthropicVertex487488 return ChatAnthropicVertex(model=model, **kwargs)489 if model_provider == "deepseek":490 _check_pkg("langchain_deepseek", "ChatDeepSeek", pkg_kebab="langchain-deepseek")491 from langchain_deepseek import ChatDeepSeek492493 return ChatDeepSeek(model=model, **kwargs)494 if model_provider == "nvidia":495 _check_pkg("langchain_nvidia_ai_endpoints", "ChatNVIDIA")496 from langchain_nvidia_ai_endpoints import ChatNVIDIA497498 return ChatNVIDIA(model=model, **kwargs)499 if model_provider == "ibm":500 _check_pkg("langchain_ibm", "ChatWatsonx")501 from langchain_ibm import ChatWatsonx502503 return ChatWatsonx(model_id=model, **kwargs)504 if model_provider == "xai":505 _check_pkg("langchain_xai", "ChatXAI")506 from langchain_xai import ChatXAI507508 return ChatXAI(model=model, **kwargs)509 if model_provider == "perplexity":510 _check_pkg("langchain_perplexity", "ChatPerplexity")511 from langchain_perplexity import ChatPerplexity512513 return ChatPerplexity(model=model, **kwargs)514 if model_provider == "upstage":515 _check_pkg("langchain_upstage", "ChatUpstage")516 from langchain_upstage import ChatUpstage517518 return ChatUpstage(model=model, **kwargs)519 supported = ", ".join(_SUPPORTED_PROVIDERS)520 msg = (521 f"Unsupported {model_provider=}.\n\nSupported model providers are: {supported}"522 )523 raise ValueError(msg)524525526_SUPPORTED_PROVIDERS = {527 "openai",528 "anthropic",529 "azure_openai",530 "azure_ai",531 "cohere",532 "google_vertexai",533 "google_genai",534 "fireworks",535 "ollama",536 "together",537 "mistralai",538 "huggingface",539 "groq",540 "bedrock",541 "bedrock_converse",542 "google_anthropic_vertex",543 "deepseek",544 "ibm",545 "xai",546 "perplexity",547 "upstage",548}549550551def _attempt_infer_model_provider(model_name: str) -> str | None:552 """Attempt to infer model provider from model name.553554 Args:555 model_name: The name of the model to infer provider for.556557 Returns:558 The inferred provider name, or `None` if no provider could be inferred.559 """560 model_lower = model_name.lower()561562 # OpenAI models (including newer models and aliases)563 if any(564 model_lower.startswith(pre)565 for pre in (566 "gpt-",567 "o1",568 "o3",569 "chatgpt",570 "text-davinci",571 )572 ):573 return "openai"574575 # Anthropic models576 if model_lower.startswith("claude"):577 return "anthropic"578579 # Cohere models580 if model_lower.startswith("command"):581 return "cohere"582583 # Fireworks models584 if model_name.startswith("accounts/fireworks"):585 return "fireworks"586587 # Google models588 if model_lower.startswith("gemini"):589 return "google_vertexai"590591 # AWS Bedrock models592 if model_name.startswith("amazon.") or model_lower.startswith(593 (594 "anthropic.",595 "meta.",596 )597 ):598 return "bedrock"599600 # Mistral models601 if model_lower.startswith(("mistral", "mixtral")):602 return "mistralai"603604 # DeepSeek models605 if model_lower.startswith("deepseek"):606 return "deepseek"607608 # xAI models609 if model_lower.startswith("grok"):610 return "xai"611612 # Perplexity models613 if model_lower.startswith("sonar"):614 return "perplexity"615616 # Upstage models617 if model_lower.startswith("solar"):618 return "upstage"619620 return None621622623def _parse_model(model: str, model_provider: str | None) -> tuple[str, str]:624 """Parse model name and provider, inferring provider if necessary."""625 if not model_provider and ":" in model:626 prefix, suffix = model.split(":", 1)627 if prefix in _SUPPORTED_PROVIDERS:628 model_provider = prefix629 model = suffix630 else:631 inferred = _attempt_infer_model_provider(prefix)632 if inferred:633 model_provider = inferred634 model = suffix635636 model_provider = model_provider or _attempt_infer_model_provider(model)637 if not model_provider:638 supported_list = ", ".join(sorted(_SUPPORTED_PROVIDERS))639 msg = (640 f"Unable to infer model provider for {model=}. "641 f"Please specify 'model_provider' directly.\n\n"642 f"Supported providers: {supported_list}\n\n"643 f"For help with specific providers, see: "644 f"https://docs.langchain.com/oss/python/integrations/providers"645 )646 raise ValueError(msg)647648 # Normalize provider name649 model_provider = model_provider.replace("-", "_").lower()650 return model, model_provider651652653def _check_pkg(pkg: str, class_name: str, *, pkg_kebab: str | None = None) -> None:654 if not util.find_spec(pkg):655 pkg_kebab = pkg_kebab if pkg_kebab is not None else pkg.replace("_", "-")656 msg = (657 f"Initializing {class_name} requires the {pkg_kebab} package. "658 f"Please install it with `pip install {pkg_kebab}`"659 )660 raise ImportError(msg)661662663_DECLARATIVE_METHODS = ("bind_tools", "with_structured_output")664665666class _ConfigurableModel(Runnable[LanguageModelInput, Any]):667 def __init__(668 self,669 *,670 default_config: dict | None = None,671 configurable_fields: Literal["any"] | list[str] | tuple[str, ...] = "any",672 config_prefix: str = "",673 queued_declarative_operations: Sequence[tuple[str, tuple, dict]] = (),674 ) -> None:675 self._default_config: dict = default_config or {}676 self._configurable_fields: Literal["any"] | list[str] = (677 configurable_fields678 if configurable_fields == "any"679 else list(configurable_fields)680 )681 self._config_prefix = (682 config_prefix + "_"683 if config_prefix and not config_prefix.endswith("_")684 else config_prefix685 )686 self._queued_declarative_operations: list[tuple[str, tuple, dict]] = list(687 queued_declarative_operations,688 )689690 def __getattr__(self, name: str) -> Any:691 if name in _DECLARATIVE_METHODS:692 # Declarative operations that cannot be applied until after an actual model693 # object is instantiated. So instead of returning the actual operation,694 # we record the operation and its arguments in a queue. This queue is695 # then applied in order whenever we actually instantiate the model (in696 # self._model()).697 def queue(*args: Any, **kwargs: Any) -> _ConfigurableModel:698 queued_declarative_operations = list(699 self._queued_declarative_operations,700 )701 queued_declarative_operations.append((name, args, kwargs))702 return _ConfigurableModel(703 default_config=dict(self._default_config),704 configurable_fields=list(self._configurable_fields)705 if isinstance(self._configurable_fields, list)706 else self._configurable_fields,707 config_prefix=self._config_prefix,708 queued_declarative_operations=queued_declarative_operations,709 )710711 return queue712 if self._default_config and (model := self._model()) and hasattr(model, name):713 return getattr(model, name)714 msg = f"{name} is not a BaseChatModel attribute"715 if self._default_config:716 msg += " and is not implemented on the default model"717 msg += "."718 raise AttributeError(msg)719720 def _model(self, config: RunnableConfig | None = None) -> Runnable:721 params = {**self._default_config, **self._model_params(config)}722 model = _init_chat_model_helper(**params)723 for name, args, kwargs in self._queued_declarative_operations:724 model = getattr(model, name)(*args, **kwargs)725 return model726727 def _model_params(self, config: RunnableConfig | None) -> dict:728 config = ensure_config(config)729 model_params = {730 k.removeprefix(self._config_prefix): v731 for k, v in config.get("configurable", {}).items()732 if k.startswith(self._config_prefix)733 }734 if self._configurable_fields != "any":735 model_params = {736 k: v for k, v in model_params.items() if k in self._configurable_fields737 }738 return model_params739740 def with_config(741 self,742 config: RunnableConfig | None = None,743 **kwargs: Any,744 ) -> _ConfigurableModel:745 """Bind config to a `Runnable`, returning a new `Runnable`."""746 config = RunnableConfig(**(config or {}), **cast("RunnableConfig", kwargs))747 model_params = self._model_params(config)748 remaining_config = {k: v for k, v in config.items() if k != "configurable"}749 remaining_config["configurable"] = {750 k: v751 for k, v in config.get("configurable", {}).items()752 if k.removeprefix(self._config_prefix) not in model_params753 }754 queued_declarative_operations = list(self._queued_declarative_operations)755 if remaining_config:756 queued_declarative_operations.append(757 (758 "with_config",759 (),760 {"config": remaining_config},761 ),762 )763 return _ConfigurableModel(764 default_config={**self._default_config, **model_params},765 configurable_fields=list(self._configurable_fields)766 if isinstance(self._configurable_fields, list)767 else self._configurable_fields,768 config_prefix=self._config_prefix,769 queued_declarative_operations=queued_declarative_operations,770 )771772 @property773 @override774 def InputType(self) -> TypeAlias:775 """Get the input type for this `Runnable`."""776 from langchain_core.prompt_values import (777 ChatPromptValueConcrete,778 StringPromptValue,779 )780781 # This is a version of LanguageModelInput which replaces the abstract782 # base class BaseMessage with a union of its subclasses, which makes783 # for a much better schema.784 return str | StringPromptValue | ChatPromptValueConcrete | list[AnyMessage]785786 @override787 def invoke(788 self,789 input: LanguageModelInput,790 config: RunnableConfig | None = None,791 **kwargs: Any,792 ) -> Any:793 return self._model(config).invoke(input, config=config, **kwargs)794795 @override796 async def ainvoke(797 self,798 input: LanguageModelInput,799 config: RunnableConfig | None = None,800 **kwargs: Any,801 ) -> Any:802 return await self._model(config).ainvoke(input, config=config, **kwargs)803804 @override805 def stream(806 self,807 input: LanguageModelInput,808 config: RunnableConfig | None = None,809 **kwargs: Any | None,810 ) -> Iterator[Any]:811 yield from self._model(config).stream(input, config=config, **kwargs)812813 @override814 async def astream(815 self,816 input: LanguageModelInput,817 config: RunnableConfig | None = None,818 **kwargs: Any | None,819 ) -> AsyncIterator[Any]:820 async for x in self._model(config).astream(input, config=config, **kwargs):821 yield x822823 def batch(824 self,825 inputs: list[LanguageModelInput],826 config: RunnableConfig | list[RunnableConfig] | None = None,827 *,828 return_exceptions: bool = False,829 **kwargs: Any | None,830 ) -> list[Any]:831 config = config or None832 # If <= 1 config use the underlying models batch implementation.833 if config is None or isinstance(config, dict) or len(config) <= 1:834 if isinstance(config, list):835 config = config[0]836 return self._model(config).batch(837 inputs,838 config=config,839 return_exceptions=return_exceptions,840 **kwargs,841 )842 # If multiple configs default to Runnable.batch which uses executor to invoke843 # in parallel.844 return super().batch(845 inputs,846 config=config,847 return_exceptions=return_exceptions,848 **kwargs,849 )850851 async def abatch(852 self,853 inputs: list[LanguageModelInput],854 config: RunnableConfig | list[RunnableConfig] | None = None,855 *,856 return_exceptions: bool = False,857 **kwargs: Any | None,858 ) -> list[Any]:859 config = config or None860 # If <= 1 config use the underlying models batch implementation.861 if config is None or isinstance(config, dict) or len(config) <= 1:862 if isinstance(config, list):863 config = config[0]864 return await self._model(config).abatch(865 inputs,866 config=config,867 return_exceptions=return_exceptions,868 **kwargs,869 )870 # If multiple configs default to Runnable.batch which uses executor to invoke871 # in parallel.872 return await super().abatch(873 inputs,874 config=config,875 return_exceptions=return_exceptions,876 **kwargs,877 )878879 def batch_as_completed(880 self,881 inputs: Sequence[LanguageModelInput],882 config: RunnableConfig | Sequence[RunnableConfig] | None = None,883 *,884 return_exceptions: bool = False,885 **kwargs: Any,886 ) -> Iterator[tuple[int, Any | Exception]]:887 config = config or None888 # If <= 1 config use the underlying models batch implementation.889 if config is None or isinstance(config, dict) or len(config) <= 1:890 if isinstance(config, list):891 config = config[0]892 yield from self._model(cast("RunnableConfig", config)).batch_as_completed( # type: ignore[call-overload]893 inputs,894 config=config,895 return_exceptions=return_exceptions,896 **kwargs,897 )898 # If multiple configs default to Runnable.batch which uses executor to invoke899 # in parallel.900 else:901 yield from super().batch_as_completed( # type: ignore[call-overload]902 inputs,903 config=config,904 return_exceptions=return_exceptions,905 **kwargs,906 )907908 async def abatch_as_completed(909 self,910 inputs: Sequence[LanguageModelInput],911 config: RunnableConfig | Sequence[RunnableConfig] | None = None,912 *,913 return_exceptions: bool = False,914 **kwargs: Any,915 ) -> AsyncIterator[tuple[int, Any]]:916 config = config or None917 # If <= 1 config use the underlying models batch implementation.918 if config is None or isinstance(config, dict) or len(config) <= 1:919 if isinstance(config, list):920 config = config[0]921 async for x in self._model(922 cast("RunnableConfig", config),923 ).abatch_as_completed( # type: ignore[call-overload]924 inputs,925 config=config,926 return_exceptions=return_exceptions,927 **kwargs,928 ):929 yield x930 # If multiple configs default to Runnable.batch which uses executor to invoke931 # in parallel.932 else:933 async for x in super().abatch_as_completed( # type: ignore[call-overload]934 inputs,935 config=config,936 return_exceptions=return_exceptions,937 **kwargs,938 ):939 yield x940941 @override942 def transform(943 self,944 input: Iterator[LanguageModelInput],945 config: RunnableConfig | None = None,946 **kwargs: Any | None,947 ) -> Iterator[Any]:948 yield from self._model(config).transform(input, config=config, **kwargs)949950 @override951 async def atransform(952 self,953 input: AsyncIterator[LanguageModelInput],954 config: RunnableConfig | None = None,955 **kwargs: Any | None,956 ) -> AsyncIterator[Any]:957 async for x in self._model(config).atransform(input, config=config, **kwargs):958 yield x959960 @overload961 def astream_log(962 self,963 input: Any,964 config: RunnableConfig | None = None,965 *,966 diff: Literal[True] = True,967 with_streamed_output_list: bool = True,968 include_names: Sequence[str] | None = None,969 include_types: Sequence[str] | None = None,970 include_tags: Sequence[str] | None = None,971 exclude_names: Sequence[str] | None = None,972 exclude_types: Sequence[str] | None = None,973 exclude_tags: Sequence[str] | None = None,974 **kwargs: Any,975 ) -> AsyncIterator[RunLogPatch]: ...976977 @overload978 def astream_log(979 self,980 input: Any,981 config: RunnableConfig | None = None,982 *,983 diff: Literal[False],984 with_streamed_output_list: bool = True,985 include_names: Sequence[str] | None = None,986 include_types: Sequence[str] | None = None,987 include_tags: Sequence[str] | None = None,988 exclude_names: Sequence[str] | None = None,989 exclude_types: Sequence[str] | None = None,990 exclude_tags: Sequence[str] | None = None,991 **kwargs: Any,992 ) -> AsyncIterator[RunLog]: ...993994 @override995 async def astream_log(996 self,997 input: Any,998 config: RunnableConfig | None = None,999 *,1000 diff: bool = True,1001 with_streamed_output_list: bool = True,1002 include_names: Sequence[str] | None = None,1003 include_types: Sequence[str] | None = None,1004 include_tags: Sequence[str] | None = None,1005 exclude_names: Sequence[str] | None = None,1006 exclude_types: Sequence[str] | None = None,1007 exclude_tags: Sequence[str] | None = None,1008 **kwargs: Any,1009 ) -> AsyncIterator[RunLogPatch] | AsyncIterator[RunLog]:1010 async for x in self._model(config).astream_log( # type: ignore[call-overload, misc]1011 input,1012 config=config,1013 diff=diff,1014 with_streamed_output_list=with_streamed_output_list,1015 include_names=include_names,1016 include_types=include_types,1017 include_tags=include_tags,1018 exclude_tags=exclude_tags,1019 exclude_types=exclude_types,1020 exclude_names=exclude_names,1021 **kwargs,1022 ):1023 yield x10241025 @override1026 async def astream_events( # type: ignore[override]1027 self,1028 input: Any,1029 config: RunnableConfig | None = None,1030 *,1031 version: Literal["v1", "v2"] = "v2",1032 include_names: Sequence[str] | None = None,1033 include_types: Sequence[str] | None = None,1034 include_tags: Sequence[str] | None = None,1035 exclude_names: Sequence[str] | None = None,1036 exclude_types: Sequence[str] | None = None,1037 exclude_tags: Sequence[str] | None = None,1038 **kwargs: Any,1039 ) -> AsyncIterator[StreamEvent]:1040 async for x in self._model(config).astream_events(1041 input,1042 config=config,1043 version=version,1044 include_names=include_names,1045 include_types=include_types,1046 include_tags=include_tags,1047 exclude_tags=exclude_tags,1048 exclude_types=exclude_types,1049 exclude_names=exclude_names,1050 **kwargs,1051 ):1052 yield x10531054 # Explicitly added to satisfy downstream linters.1055 def bind_tools(1056 self,1057 tools: Sequence[dict[str, Any] | type[BaseModel] | Callable | BaseTool],1058 **kwargs: Any,1059 ) -> Runnable[LanguageModelInput, AIMessage]:1060 return self.__getattr__("bind_tools")(tools, **kwargs)10611062 # Explicitly added to satisfy downstream linters.1063 def with_structured_output(1064 self,1065 schema: dict | type[BaseModel],1066 **kwargs: Any,1067 ) -> Runnable[LanguageModelInput, dict | BaseModel]:1068 return self.__getattr__("with_structured_output")(schema, **kwargs)
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.