From 2319fdc9788e526103f079bde9acecfe4a6a3958 Mon Sep 17 00:00:00 2001 From: Tanushree <87711021+tanushree-sharma@users.noreply.github.com> Date: Wed, 18 Mar 2026 08:24:08 -0700 Subject: [PATCH] feat: Add LangSmith integration metadata to create_agent and init_chat_model (#35810) --- .../langchain_core/language_models/base.py | 18 ++++++++++++++++++ .../language_models/chat_models.py | 18 ++++++++++++++---- .../langchain_core/language_models/llms.py | 12 ++++++------ libs/langchain_v1/langchain/agents/factory.py | 3 ++- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/libs/core/langchain_core/language_models/base.py b/libs/core/langchain_core/language_models/base.py index 55ca3a5d24e..570076290e0 100644 --- a/libs/core/langchain_core/language_models/base.py +++ b/libs/core/langchain_core/language_models/base.py @@ -69,6 +69,8 @@ class LangSmithParams(TypedDict, total=False): ls_stop: list[str] | None """Stop words for generation.""" + ls_integration: str + """Integration that created the trace.""" @cache # Cache the tokenizer @@ -299,6 +301,22 @@ class BaseLanguageModel( # generate responses that match a given schema. raise NotImplementedError + def _get_ls_params( + self, + stop: list[str] | None = None, # noqa: ARG002 + **kwargs: Any, # noqa: ARG002 + ) -> LangSmithParams: + """Get standard params for tracing.""" + return LangSmithParams() + + def _get_ls_params_with_defaults( + self, + stop: list[str] | None = None, + **kwargs: Any, + ) -> LangSmithParams: + """Wrap _get_ls_params to include any additional default parameters.""" + return self._get_ls_params(stop=stop, **kwargs) + @property def _identifying_params(self) -> Mapping[str, Any]: """Get the identifying parameters.""" diff --git a/libs/core/langchain_core/language_models/chat_models.py b/libs/core/langchain_core/language_models/chat_models.py index 32f198532e6..25dc2dd16f3 100644 --- a/libs/core/langchain_core/language_models/chat_models.py +++ b/libs/core/langchain_core/language_models/chat_models.py @@ -505,7 +505,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC): options = {"stop": stop, **kwargs, **ls_structured_output_format_dict} inheritable_metadata = { **(config.get("metadata") or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } callback_manager = CallbackManager.configure( config.get("callbacks"), @@ -633,7 +633,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC): options = {"stop": stop, **kwargs, **ls_structured_output_format_dict} inheritable_metadata = { **(config.get("metadata") or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } callback_manager = AsyncCallbackManager.configure( config.get("callbacks"), @@ -827,6 +827,16 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC): return ls_params + def _get_ls_params_with_defaults( + self, + stop: list[str] | None = None, + **kwargs: Any, + ) -> LangSmithParams: + """Wrap _get_ls_params to always include ls_integration.""" + ls_params = self._get_ls_params(stop=stop, **kwargs) + ls_params["ls_integration"] = "langchain_chat_model" + return ls_params + def _get_llm_string(self, stop: list[str] | None = None, **kwargs: Any) -> str: if self.is_lc_serializable(): params = {**kwargs, "stop": stop} @@ -899,7 +909,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC): options = {"stop": stop, **ls_structured_output_format_dict} inheritable_metadata = { **(metadata or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } callback_manager = CallbackManager.configure( @@ -1022,7 +1032,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC): options = {"stop": stop, **ls_structured_output_format_dict} inheritable_metadata = { **(metadata or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } callback_manager = AsyncCallbackManager.configure( diff --git a/libs/core/langchain_core/language_models/llms.py b/libs/core/langchain_core/language_models/llms.py index fa034675d89..e5400d16d4d 100644 --- a/libs/core/langchain_core/language_models/llms.py +++ b/libs/core/langchain_core/language_models/llms.py @@ -527,7 +527,7 @@ class BaseLLM(BaseLanguageModel[str], ABC): options = {"stop": stop} inheritable_metadata = { **(config.get("metadata") or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } callback_manager = CallbackManager.configure( config.get("callbacks"), @@ -597,7 +597,7 @@ class BaseLLM(BaseLanguageModel[str], ABC): options = {"stop": stop} inheritable_metadata = { **(config.get("metadata") or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } callback_manager = AsyncCallbackManager.configure( config.get("callbacks"), @@ -906,14 +906,14 @@ class BaseLLM(BaseLanguageModel[str], ABC): metadata = [ { **(meta or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } for meta in metadata ] elif isinstance(metadata, dict): metadata = { **(metadata or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } if ( isinstance(callbacks, list) @@ -1173,14 +1173,14 @@ class BaseLLM(BaseLanguageModel[str], ABC): metadata = [ { **(meta or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } for meta in metadata ] elif isinstance(metadata, dict): metadata = { **(metadata or {}), - **self._get_ls_params(stop=stop, **kwargs), + **self._get_ls_params_with_defaults(stop=stop, **kwargs), } # Create callback managers if isinstance(callbacks, list) and ( diff --git a/libs/langchain_v1/langchain/agents/factory.py b/libs/langchain_v1/langchain/agents/factory.py index e57075cb860..1d7e8d279be 100644 --- a/libs/langchain_v1/langchain/agents/factory.py +++ b/libs/langchain_v1/langchain/agents/factory.py @@ -1630,8 +1630,9 @@ def create_agent( ) config: RunnableConfig = {"recursion_limit": 10_000} + config["metadata"] = {"ls_integration": "langchain_create_agent"} if name: - config["metadata"] = {"lc_agent_name": name} + config["metadata"]["lc_agent_name"] = name return graph.compile( checkpointer=checkpointer,