diff --git a/libs/langchain/langchain/schema/runnable/configurable.py b/libs/langchain/langchain/schema/runnable/configurable.py index bf45e4c004a..760ca2e6473 100644 --- a/libs/langchain/langchain/schema/runnable/configurable.py +++ b/libs/langchain/langchain/schema/runnable/configurable.py @@ -1,6 +1,7 @@ from __future__ import annotations import enum +import threading from abc import abstractmethod from typing import ( Any, @@ -270,6 +271,8 @@ _enums_for_spec: WeakValueDictionary[ Type[StrEnum], ] = WeakValueDictionary() +_enums_for_spec_lock = threading.Lock() + class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]): which: ConfigurableField @@ -280,14 +283,18 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]): @property def config_specs(self) -> Sequence[ConfigurableFieldSpec]: - if which_enum := _enums_for_spec.get(self.which): - pass - else: - which_enum = StrEnum( # type: ignore[call-overload] - self.which.name or self.which.id, - ((v, v) for v in list(self.alternatives.keys()) + [self.default_key]), - ) - _enums_for_spec[self.which] = cast(Type[StrEnum], which_enum) + with _enums_for_spec_lock: + if which_enum := _enums_for_spec.get(self.which): + pass + else: + which_enum = StrEnum( # type: ignore[call-overload] + self.which.name or self.which.id, + ( + (v, v) + for v in list(self.alternatives.keys()) + [self.default_key] + ), + ) + _enums_for_spec[self.which] = cast(Type[StrEnum], which_enum) return [ ConfigurableFieldSpec( id=self.which.id, @@ -325,14 +332,15 @@ def make_options_spec( spec: Union[ConfigurableFieldSingleOption, ConfigurableFieldMultiOption], description: Optional[str], ) -> ConfigurableFieldSpec: - if enum := _enums_for_spec.get(spec): - pass - else: - enum = StrEnum( # type: ignore[call-overload] - spec.name or spec.id, - ((v, v) for v in list(spec.options.keys())), - ) - _enums_for_spec[spec] = cast(Type[StrEnum], enum) + with _enums_for_spec_lock: + if enum := _enums_for_spec.get(spec): + pass + else: + enum = StrEnum( # type: ignore[call-overload] + spec.name or spec.id, + ((v, v) for v in list(spec.options.keys())), + ) + _enums_for_spec[spec] = cast(Type[StrEnum], enum) if isinstance(spec, ConfigurableFieldSingleOption): return ConfigurableFieldSpec( id=spec.id,