langchain-core 1.0.0a2__py3-none-any.whl → 1.0.0a4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of langchain-core might be problematic. Click here for more details.

Files changed (130) hide show
  1. langchain_core/_api/beta_decorator.py +17 -40
  2. langchain_core/_api/deprecation.py +20 -7
  3. langchain_core/_api/path.py +19 -2
  4. langchain_core/_import_utils.py +7 -0
  5. langchain_core/agents.py +10 -6
  6. langchain_core/callbacks/base.py +28 -15
  7. langchain_core/callbacks/manager.py +81 -69
  8. langchain_core/callbacks/usage.py +4 -2
  9. langchain_core/chat_history.py +29 -21
  10. langchain_core/document_loaders/base.py +34 -9
  11. langchain_core/document_loaders/langsmith.py +3 -0
  12. langchain_core/documents/base.py +35 -10
  13. langchain_core/documents/transformers.py +4 -2
  14. langchain_core/embeddings/fake.py +8 -5
  15. langchain_core/env.py +2 -3
  16. langchain_core/example_selectors/base.py +12 -0
  17. langchain_core/exceptions.py +7 -0
  18. langchain_core/globals.py +17 -28
  19. langchain_core/indexing/api.py +57 -45
  20. langchain_core/indexing/base.py +5 -8
  21. langchain_core/indexing/in_memory.py +23 -3
  22. langchain_core/language_models/__init__.py +6 -2
  23. langchain_core/language_models/_utils.py +27 -5
  24. langchain_core/language_models/base.py +33 -21
  25. langchain_core/language_models/chat_models.py +104 -31
  26. langchain_core/language_models/fake_chat_models.py +5 -7
  27. langchain_core/language_models/llms.py +54 -20
  28. langchain_core/load/dump.py +2 -3
  29. langchain_core/load/load.py +15 -1
  30. langchain_core/load/serializable.py +38 -43
  31. langchain_core/memory.py +7 -3
  32. langchain_core/messages/__init__.py +1 -1
  33. langchain_core/messages/ai.py +41 -34
  34. langchain_core/messages/base.py +20 -7
  35. langchain_core/messages/block_translators/__init__.py +10 -8
  36. langchain_core/messages/block_translators/anthropic.py +11 -7
  37. langchain_core/messages/block_translators/bedrock.py +76 -27
  38. langchain_core/messages/block_translators/bedrock_converse.py +259 -23
  39. langchain_core/messages/block_translators/google_genai.py +3 -1
  40. langchain_core/messages/block_translators/google_vertexai.py +3 -1
  41. langchain_core/messages/block_translators/groq.py +3 -1
  42. langchain_core/messages/block_translators/ollama.py +3 -1
  43. langchain_core/messages/block_translators/openai.py +50 -20
  44. langchain_core/messages/content.py +23 -13
  45. langchain_core/messages/human.py +2 -13
  46. langchain_core/messages/system.py +2 -6
  47. langchain_core/messages/tool.py +34 -14
  48. langchain_core/messages/utils.py +186 -73
  49. langchain_core/output_parsers/base.py +5 -2
  50. langchain_core/output_parsers/json.py +4 -4
  51. langchain_core/output_parsers/list.py +7 -22
  52. langchain_core/output_parsers/openai_functions.py +3 -0
  53. langchain_core/output_parsers/openai_tools.py +6 -1
  54. langchain_core/output_parsers/pydantic.py +4 -0
  55. langchain_core/output_parsers/string.py +5 -1
  56. langchain_core/output_parsers/xml.py +19 -19
  57. langchain_core/outputs/chat_generation.py +18 -7
  58. langchain_core/outputs/generation.py +14 -3
  59. langchain_core/outputs/llm_result.py +8 -1
  60. langchain_core/prompt_values.py +10 -4
  61. langchain_core/prompts/base.py +6 -11
  62. langchain_core/prompts/chat.py +88 -60
  63. langchain_core/prompts/dict.py +16 -8
  64. langchain_core/prompts/few_shot.py +9 -11
  65. langchain_core/prompts/few_shot_with_templates.py +5 -1
  66. langchain_core/prompts/image.py +12 -5
  67. langchain_core/prompts/loading.py +2 -2
  68. langchain_core/prompts/message.py +5 -6
  69. langchain_core/prompts/pipeline.py +13 -8
  70. langchain_core/prompts/prompt.py +22 -8
  71. langchain_core/prompts/string.py +18 -10
  72. langchain_core/prompts/structured.py +7 -2
  73. langchain_core/rate_limiters.py +2 -2
  74. langchain_core/retrievers.py +7 -6
  75. langchain_core/runnables/base.py +387 -246
  76. langchain_core/runnables/branch.py +11 -28
  77. langchain_core/runnables/config.py +20 -17
  78. langchain_core/runnables/configurable.py +34 -19
  79. langchain_core/runnables/fallbacks.py +20 -13
  80. langchain_core/runnables/graph.py +48 -38
  81. langchain_core/runnables/graph_ascii.py +40 -17
  82. langchain_core/runnables/graph_mermaid.py +54 -25
  83. langchain_core/runnables/graph_png.py +27 -31
  84. langchain_core/runnables/history.py +55 -58
  85. langchain_core/runnables/passthrough.py +44 -21
  86. langchain_core/runnables/retry.py +44 -23
  87. langchain_core/runnables/router.py +9 -8
  88. langchain_core/runnables/schema.py +9 -0
  89. langchain_core/runnables/utils.py +53 -90
  90. langchain_core/stores.py +19 -31
  91. langchain_core/sys_info.py +9 -8
  92. langchain_core/tools/base.py +36 -27
  93. langchain_core/tools/convert.py +25 -14
  94. langchain_core/tools/simple.py +36 -8
  95. langchain_core/tools/structured.py +25 -12
  96. langchain_core/tracers/base.py +2 -2
  97. langchain_core/tracers/context.py +5 -1
  98. langchain_core/tracers/core.py +110 -46
  99. langchain_core/tracers/evaluation.py +22 -26
  100. langchain_core/tracers/event_stream.py +97 -42
  101. langchain_core/tracers/langchain.py +12 -3
  102. langchain_core/tracers/langchain_v1.py +10 -2
  103. langchain_core/tracers/log_stream.py +56 -17
  104. langchain_core/tracers/root_listeners.py +4 -20
  105. langchain_core/tracers/run_collector.py +6 -16
  106. langchain_core/tracers/schemas.py +5 -1
  107. langchain_core/utils/aiter.py +14 -6
  108. langchain_core/utils/env.py +3 -0
  109. langchain_core/utils/function_calling.py +46 -20
  110. langchain_core/utils/interactive_env.py +6 -2
  111. langchain_core/utils/iter.py +12 -5
  112. langchain_core/utils/json.py +12 -3
  113. langchain_core/utils/json_schema.py +156 -40
  114. langchain_core/utils/loading.py +5 -1
  115. langchain_core/utils/mustache.py +25 -16
  116. langchain_core/utils/pydantic.py +38 -9
  117. langchain_core/utils/utils.py +25 -9
  118. langchain_core/vectorstores/base.py +7 -20
  119. langchain_core/vectorstores/in_memory.py +20 -14
  120. langchain_core/vectorstores/utils.py +18 -12
  121. langchain_core/version.py +1 -1
  122. langchain_core-1.0.0a4.dist-info/METADATA +77 -0
  123. langchain_core-1.0.0a4.dist-info/RECORD +181 -0
  124. langchain_core/beta/__init__.py +0 -1
  125. langchain_core/beta/runnables/__init__.py +0 -1
  126. langchain_core/beta/runnables/context.py +0 -448
  127. langchain_core-1.0.0a2.dist-info/METADATA +0 -106
  128. langchain_core-1.0.0a2.dist-info/RECORD +0 -184
  129. {langchain_core-1.0.0a2.dist-info → langchain_core-1.0.0a4.dist-info}/WHEEL +0 -0
  130. {langchain_core-1.0.0a2.dist-info → langchain_core-1.0.0a4.dist-info}/entry_points.txt +0 -0
@@ -28,8 +28,18 @@ from langchain_core.callbacks.base import (
28
28
  ToolManagerMixin,
29
29
  )
30
30
  from langchain_core.callbacks.stdout import StdOutCallbackHandler
31
+ from langchain_core.globals import get_debug
31
32
  from langchain_core.messages import BaseMessage, get_buffer_string
33
+ from langchain_core.tracers.context import (
34
+ _configure_hooks,
35
+ _get_trace_callbacks,
36
+ _get_tracer_project,
37
+ _tracing_v2_is_enabled,
38
+ tracing_v2_callback_var,
39
+ )
40
+ from langchain_core.tracers.langchain import LangChainTracer
32
41
  from langchain_core.tracers.schemas import Run
42
+ from langchain_core.tracers.stdout import ConsoleCallbackHandler
33
43
  from langchain_core.utils.env import env_var_is_set
34
44
 
35
45
  if TYPE_CHECKING:
@@ -46,8 +56,6 @@ logger = logging.getLogger(__name__)
46
56
 
47
57
 
48
58
  def _get_debug() -> bool:
49
- from langchain_core.globals import get_debug
50
-
51
59
  return get_debug()
52
60
 
53
61
 
@@ -85,23 +93,24 @@ def trace_as_chain_group(
85
93
  Defaults to None.
86
94
 
87
95
  .. note:
88
- Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in LangSmith.
96
+ Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in
97
+ LangSmith.
89
98
 
90
- Returns:
91
- CallbackManagerForChainGroup: The callback manager for the chain group.
99
+ Yields:
100
+ The callback manager for the chain group.
92
101
 
93
102
  Example:
94
103
  .. code-block:: python
95
104
 
96
105
  llm_input = "Foo"
97
- with trace_as_chain_group("group_name", inputs={"input": llm_input}) as manager:
106
+ with trace_as_chain_group(
107
+ "group_name", inputs={"input": llm_input}
108
+ ) as manager:
98
109
  # Use the callback manager for the chain group
99
110
  res = llm.invoke(llm_input, {"callbacks": manager})
100
111
  manager.on_chain_end({"output": res})
101
112
 
102
- """ # noqa: E501
103
- from langchain_core.tracers.context import _get_trace_callbacks
104
-
113
+ """
105
114
  cb = _get_trace_callbacks(
106
115
  project_name, example_id, callback_manager=callback_manager
107
116
  )
@@ -153,8 +162,8 @@ async def atrace_as_chain_group(
153
162
 
154
163
  Args:
155
164
  group_name (str): The name of the chain group.
156
- callback_manager (AsyncCallbackManager, optional): The async callback manager to use,
157
- which manages tracing and other callback behavior. Defaults to None.
165
+ callback_manager (AsyncCallbackManager, optional): The async callback manager
166
+ to use, which manages tracing and other callback behavior. Defaults to None.
158
167
  inputs (dict[str, Any], optional): The inputs to the chain group.
159
168
  Defaults to None.
160
169
  project_name (str, optional): The name of the project.
@@ -167,24 +176,25 @@ async def atrace_as_chain_group(
167
176
  metadata (dict[str, Any], optional): The metadata to apply to all runs.
168
177
  Defaults to None.
169
178
 
170
- Returns:
171
- AsyncCallbackManager: The async callback manager for the chain group.
179
+ Yields:
180
+ The async callback manager for the chain group.
172
181
 
173
182
  .. note:
174
- Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in LangSmith.
183
+ Must have ``LANGCHAIN_TRACING_V2`` env var set to true to see the trace in
184
+ LangSmith.
175
185
 
176
186
  Example:
177
187
  .. code-block:: python
178
188
 
179
189
  llm_input = "Foo"
180
- async with atrace_as_chain_group("group_name", inputs={"input": llm_input}) as manager:
190
+ async with atrace_as_chain_group(
191
+ "group_name", inputs={"input": llm_input}
192
+ ) as manager:
181
193
  # Use the async callback manager for the chain group
182
194
  res = await llm.ainvoke(llm_input, {"callbacks": manager})
183
195
  await manager.on_chain_end({"output": res})
184
196
 
185
- """ # noqa: E501
186
- from langchain_core.tracers.context import _get_trace_callbacks
187
-
197
+ """
188
198
  cb = _get_trace_callbacks(
189
199
  project_name, example_id, callback_manager=callback_manager
190
200
  )
@@ -513,15 +523,12 @@ class RunManager(BaseRunManager):
513
523
  self,
514
524
  text: str,
515
525
  **kwargs: Any,
516
- ) -> Any:
526
+ ) -> None:
517
527
  """Run when a text is received.
518
528
 
519
529
  Args:
520
530
  text (str): The received text.
521
531
  **kwargs (Any): Additional keyword arguments.
522
-
523
- Returns:
524
- Any: The result of the callback.
525
532
  """
526
533
  if not self.handlers:
527
534
  return
@@ -601,16 +608,12 @@ class AsyncRunManager(BaseRunManager, ABC):
601
608
  self,
602
609
  text: str,
603
610
  **kwargs: Any,
604
- ) -> Any:
611
+ ) -> None:
605
612
  """Run when a text is received.
606
613
 
607
614
  Args:
608
615
  text (str): The received text.
609
616
  **kwargs (Any): Additional keyword arguments.
610
-
611
- Returns:
612
- Any: The result of the callback.
613
-
614
617
  """
615
618
  if not self.handlers:
616
619
  return
@@ -908,16 +911,12 @@ class CallbackManagerForChainRun(ParentRunManager, ChainManagerMixin):
908
911
  **kwargs,
909
912
  )
910
913
 
911
- def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
914
+ def on_agent_action(self, action: AgentAction, **kwargs: Any) -> None:
912
915
  """Run when agent action is received.
913
916
 
914
917
  Args:
915
918
  action (AgentAction): The agent action.
916
919
  **kwargs (Any): Additional keyword arguments.
917
-
918
- Returns:
919
- Any: The result of the callback.
920
-
921
920
  """
922
921
  if not self.handlers:
923
922
  return
@@ -932,16 +931,12 @@ class CallbackManagerForChainRun(ParentRunManager, ChainManagerMixin):
932
931
  **kwargs,
933
932
  )
934
933
 
935
- def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> Any:
934
+ def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> None:
936
935
  """Run when agent finish is received.
937
936
 
938
937
  Args:
939
938
  finish (AgentFinish): The agent finish.
940
939
  **kwargs (Any): Additional keyword arguments.
941
-
942
- Returns:
943
- Any: The result of the callback.
944
-
945
940
  """
946
941
  if not self.handlers:
947
942
  return
@@ -1027,16 +1022,12 @@ class AsyncCallbackManagerForChainRun(AsyncParentRunManager, ChainManagerMixin):
1027
1022
  **kwargs,
1028
1023
  )
1029
1024
 
1030
- async def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
1025
+ async def on_agent_action(self, action: AgentAction, **kwargs: Any) -> None:
1031
1026
  """Run when agent action is received.
1032
1027
 
1033
1028
  Args:
1034
1029
  action (AgentAction): The agent action.
1035
1030
  **kwargs (Any): Additional keyword arguments.
1036
-
1037
- Returns:
1038
- Any: The result of the callback.
1039
-
1040
1031
  """
1041
1032
  if not self.handlers:
1042
1033
  return
@@ -1051,16 +1042,12 @@ class AsyncCallbackManagerForChainRun(AsyncParentRunManager, ChainManagerMixin):
1051
1042
  **kwargs,
1052
1043
  )
1053
1044
 
1054
- async def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> Any:
1045
+ async def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> None:
1055
1046
  """Run when agent finish is received.
1056
1047
 
1057
1048
  Args:
1058
1049
  finish (AgentFinish): The agent finish.
1059
1050
  **kwargs (Any): Additional keyword arguments.
1060
-
1061
- Returns:
1062
- Any: The result of the callback.
1063
-
1064
1051
  """
1065
1052
  if not self.handlers:
1066
1053
  return
@@ -1556,6 +1543,8 @@ class CallbackManager(BaseCallbackManager):
1556
1543
  parent_run_id (UUID, optional): The ID of the parent run. Defaults to None.
1557
1544
  **kwargs (Any): Additional keyword arguments.
1558
1545
 
1546
+ Returns:
1547
+ The callback manager for the retriever run.
1559
1548
  """
1560
1549
  if run_id is None:
1561
1550
  run_id = uuid.uuid4()
@@ -1602,6 +1591,9 @@ class CallbackManager(BaseCallbackManager):
1602
1591
  data: The data for the adhoc event.
1603
1592
  run_id: The ID of the run. Defaults to None.
1604
1593
 
1594
+ Raises:
1595
+ ValueError: If additional keyword arguments are passed.
1596
+
1605
1597
  .. versionadded:: 0.2.14
1606
1598
 
1607
1599
  """
@@ -1704,8 +1696,8 @@ class CallbackManagerForChainGroup(CallbackManager):
1704
1696
  self.parent_run_manager = parent_run_manager
1705
1697
  self.ended = False
1706
1698
 
1699
+ @override
1707
1700
  def copy(self) -> CallbackManagerForChainGroup:
1708
- """Copy the callback manager."""
1709
1701
  return self.__class__(
1710
1702
  handlers=self.handlers.copy(),
1711
1703
  inheritable_handlers=self.inheritable_handlers.copy(),
@@ -1734,11 +1726,18 @@ class CallbackManagerForChainGroup(CallbackManager):
1734
1726
 
1735
1727
  .. code-block:: python
1736
1728
 
1737
- from langchain_core.callbacks.manager import CallbackManager, trace_as_chain_group
1729
+ from langchain_core.callbacks.manager import (
1730
+ CallbackManager,
1731
+ trace_as_chain_group,
1732
+ )
1738
1733
  from langchain_core.callbacks.stdout import StdOutCallbackHandler
1739
1734
 
1740
- manager = CallbackManager(handlers=[StdOutCallbackHandler()], tags=["tag2"])
1741
- with trace_as_chain_group("My Group Name", tags=["tag1"]) as group_manager:
1735
+ manager = CallbackManager(
1736
+ handlers=[StdOutCallbackHandler()], tags=["tag2"]
1737
+ )
1738
+ with trace_as_chain_group(
1739
+ "My Group Name", tags=["tag1"]
1740
+ ) as group_manager:
1742
1741
  merged_manager = group_manager.merge(manager)
1743
1742
  print(type(merged_manager))
1744
1743
  # <class 'langchain_core.callbacks.manager.CallbackManagerForChainGroup'>
@@ -2086,6 +2085,9 @@ class AsyncCallbackManager(BaseCallbackManager):
2086
2085
  data: The data for the adhoc event.
2087
2086
  run_id: The ID of the run. Defaults to None.
2088
2087
 
2088
+ Raises:
2089
+ ValueError: If additional keyword arguments are passed.
2090
+
2089
2091
  .. versionadded:: 0.2.14
2090
2092
  """
2091
2093
  if not self.handlers:
@@ -2236,7 +2238,7 @@ class AsyncCallbackManagerForChainGroup(AsyncCallbackManager):
2236
2238
  self.ended = False
2237
2239
 
2238
2240
  def copy(self) -> AsyncCallbackManagerForChainGroup:
2239
- """Copy the async callback manager."""
2241
+ """Return a copy the async callback manager."""
2240
2242
  return self.__class__(
2241
2243
  handlers=self.handlers.copy(),
2242
2244
  inheritable_handlers=self.inheritable_handlers.copy(),
@@ -2258,18 +2260,25 @@ class AsyncCallbackManagerForChainGroup(AsyncCallbackManager):
2258
2260
  from the current object.
2259
2261
 
2260
2262
  Returns:
2261
- AsyncCallbackManagerForChainGroup: A copy of the current AsyncCallbackManagerForChainGroup
2262
- with the handlers, tags, etc. of the other callback manager merged in.
2263
+ A copy of the current AsyncCallbackManagerForChainGroup
2264
+ with the handlers, tags, etc. of the other callback manager merged in.
2263
2265
 
2264
2266
  Example: Merging two callback managers.
2265
2267
 
2266
2268
  .. code-block:: python
2267
2269
 
2268
- from langchain_core.callbacks.manager import CallbackManager, atrace_as_chain_group
2270
+ from langchain_core.callbacks.manager import (
2271
+ CallbackManager,
2272
+ atrace_as_chain_group,
2273
+ )
2269
2274
  from langchain_core.callbacks.stdout import StdOutCallbackHandler
2270
2275
 
2271
- manager = CallbackManager(handlers=[StdOutCallbackHandler()], tags=["tag2"])
2272
- async with atrace_as_chain_group("My Group Name", tags=["tag1"]) as group_manager:
2276
+ manager = CallbackManager(
2277
+ handlers=[StdOutCallbackHandler()], tags=["tag2"]
2278
+ )
2279
+ async with atrace_as_chain_group(
2280
+ "My Group Name", tags=["tag1"]
2281
+ ) as group_manager:
2273
2282
  merged_manager = group_manager.merge(manager)
2274
2283
  print(type(merged_manager))
2275
2284
  # <class 'langchain_core.callbacks.manager.AsyncCallbackManagerForChainGroup'>
@@ -2365,16 +2374,12 @@ def _configure(
2365
2374
  local_metadata (Optional[dict[str, Any]], optional): The local metadata.
2366
2375
  Defaults to None.
2367
2376
 
2377
+ Raises:
2378
+ RuntimeError: If `LANGCHAIN_TRACING` is set but `LANGCHAIN_TRACING_V2` is not.
2379
+
2368
2380
  Returns:
2369
2381
  T: The configured callback manager.
2370
2382
  """
2371
- from langchain_core.tracers.context import (
2372
- _configure_hooks,
2373
- _get_tracer_project,
2374
- _tracing_v2_is_enabled,
2375
- tracing_v2_callback_var,
2376
- )
2377
-
2378
2383
  tracing_context = get_tracing_context()
2379
2384
  tracing_metadata = tracing_context["metadata"]
2380
2385
  tracing_tags = tracing_context["tags"]
@@ -2451,9 +2456,6 @@ def _configure(
2451
2456
  tracer_project = _get_tracer_project()
2452
2457
  debug = _get_debug()
2453
2458
  if verbose or debug or tracing_v2_enabled_:
2454
- from langchain_core.tracers.langchain import LangChainTracer
2455
- from langchain_core.tracers.stdout import ConsoleCallbackHandler
2456
-
2457
2459
  if verbose and not any(
2458
2460
  isinstance(handler, StdOutCallbackHandler)
2459
2461
  for handler in callback_manager.handlers
@@ -2537,6 +2539,10 @@ async def adispatch_custom_event(
2537
2539
  this is not enforced.
2538
2540
  config: Optional config object. Mirrors the async API but not strictly needed.
2539
2541
 
2542
+ Raises:
2543
+ RuntimeError: If there is no parent run ID available to associate
2544
+ the event with.
2545
+
2540
2546
  Example:
2541
2547
 
2542
2548
  .. code-block:: python
@@ -2618,7 +2624,8 @@ async def adispatch_custom_event(
2618
2624
  .. versionadded:: 0.2.15
2619
2625
 
2620
2626
  """
2621
- from langchain_core.runnables.config import (
2627
+ # Import locally to prevent circular imports.
2628
+ from langchain_core.runnables.config import ( # noqa: PLC0415
2622
2629
  ensure_config,
2623
2630
  get_async_callback_manager_for_config,
2624
2631
  )
@@ -2658,6 +2665,10 @@ def dispatch_custom_event(
2658
2665
  this is not enforced.
2659
2666
  config: Optional config object. Mirrors the async API but not strictly needed.
2660
2667
 
2668
+ Raises:
2669
+ RuntimeError: If there is no parent run ID available to associate
2670
+ the event with.
2671
+
2661
2672
  Example:
2662
2673
 
2663
2674
  .. code-block:: python
@@ -2689,7 +2700,8 @@ def dispatch_custom_event(
2689
2700
  .. versionadded:: 0.2.15
2690
2701
 
2691
2702
  """
2692
- from langchain_core.runnables.config import (
2703
+ # Import locally to prevent circular imports.
2704
+ from langchain_core.runnables.config import ( # noqa: PLC0415
2693
2705
  ensure_config,
2694
2706
  get_callback_manager_for_config,
2695
2707
  )
@@ -12,6 +12,7 @@ from langchain_core.callbacks import BaseCallbackHandler
12
12
  from langchain_core.messages import AIMessage
13
13
  from langchain_core.messages.ai import UsageMetadata, add_usage
14
14
  from langchain_core.outputs import ChatGeneration, LLMResult
15
+ from langchain_core.tracers.context import register_configure_hook
15
16
 
16
17
 
17
18
  class UsageMetadataCallbackHandler(BaseCallbackHandler):
@@ -101,6 +102,9 @@ def get_usage_metadata_callback(
101
102
  name (str): The name of the context variable. Defaults to
102
103
  ``'usage_metadata_callback'``.
103
104
 
105
+ Yields:
106
+ The usage metadata callback.
107
+
104
108
  Example:
105
109
  .. code-block:: python
106
110
 
@@ -130,8 +134,6 @@ def get_usage_metadata_callback(
130
134
  .. versionadded:: 0.3.49
131
135
 
132
136
  """
133
- from langchain_core.tracers.context import register_configure_hook
134
-
135
137
  usage_metadata_callback_var: ContextVar[Optional[UsageMetadataCallbackHandler]] = (
136
138
  ContextVar(name, default=None)
137
139
  )
@@ -27,6 +27,7 @@ from langchain_core.messages import (
27
27
  HumanMessage,
28
28
  get_buffer_string,
29
29
  )
30
+ from langchain_core.runnables.config import run_in_executor
30
31
 
31
32
  if TYPE_CHECKING:
32
33
  from collections.abc import Sequence
@@ -64,33 +65,43 @@ class BaseChatMessageHistory(ABC):
64
65
 
65
66
  .. code-block:: python
66
67
 
68
+ import json
69
+ import os
70
+ from langchain_core.messages import messages_from_dict, message_to_dict
71
+
72
+
67
73
  class FileChatMessageHistory(BaseChatMessageHistory):
68
74
  storage_path: str
69
75
  session_id: str
70
76
 
71
77
  @property
72
- def messages(self):
73
- with open(
74
- os.path.join(storage_path, session_id),
75
- "r",
76
- encoding="utf-8",
77
- ) as f:
78
- messages = json.loads(f.read())
79
- return messages_from_dict(messages)
78
+ def messages(self) -> list[BaseMessage]:
79
+ try:
80
+ with open(
81
+ os.path.join(self.storage_path, self.session_id),
82
+ "r",
83
+ encoding="utf-8",
84
+ ) as f:
85
+ messages_data = json.load(f)
86
+ return messages_from_dict(messages_data)
87
+ except FileNotFoundError:
88
+ return []
80
89
 
81
90
  def add_messages(self, messages: Sequence[BaseMessage]) -> None:
82
91
  all_messages = list(self.messages) # Existing messages
83
92
  all_messages.extend(messages) # Add new messages
84
93
 
85
94
  serialized = [message_to_dict(message) for message in all_messages]
86
- # Can be further optimized by only writing new messages
87
- # using append mode.
88
- with open(os.path.join(storage_path, session_id), "w") as f:
89
- json.dump(messages, f)
95
+ file_path = os.path.join(self.storage_path, self.session_id)
96
+ os.makedirs(os.path.dirname(file_path), exist_ok=True)
97
+ with open(file_path, "w", encoding="utf-8") as f:
98
+ json.dump(serialized, f)
90
99
 
91
- def clear(self):
92
- with open(os.path.join(storage_path, session_id), "w") as f:
93
- f.write("[]")
100
+ def clear(self) -> None:
101
+ file_path = os.path.join(self.storage_path, self.session_id)
102
+ os.makedirs(os.path.dirname(file_path), exist_ok=True)
103
+ with open(file_path, "w", encoding="utf-8") as f:
104
+ json.dump([], f)
94
105
 
95
106
  """
96
107
 
@@ -109,9 +120,10 @@ class BaseChatMessageHistory(ABC):
109
120
 
110
121
  In general, fetching messages may involve IO to the underlying
111
122
  persistence layer.
112
- """
113
- from langchain_core.runnables.config import run_in_executor
114
123
 
124
+ Returns:
125
+ The messages.
126
+ """
115
127
  return await run_in_executor(None, lambda: self.messages)
116
128
 
117
129
  def add_user_message(self, message: Union[HumanMessage, str]) -> None:
@@ -187,8 +199,6 @@ class BaseChatMessageHistory(ABC):
187
199
  Args:
188
200
  messages: A sequence of BaseMessage objects to store.
189
201
  """
190
- from langchain_core.runnables.config import run_in_executor
191
-
192
202
  await run_in_executor(None, self.add_messages, messages)
193
203
 
194
204
  @abstractmethod
@@ -197,8 +207,6 @@ class BaseChatMessageHistory(ABC):
197
207
 
198
208
  async def aclear(self) -> None:
199
209
  """Async remove all messages from the store."""
200
- from langchain_core.runnables.config import run_in_executor
201
-
202
210
  await run_in_executor(None, self.clear)
203
211
 
204
212
  def __str__(self) -> str:
@@ -15,6 +15,13 @@ if TYPE_CHECKING:
15
15
  from langchain_core.documents import Document
16
16
  from langchain_core.documents.base import Blob
17
17
 
18
+ try:
19
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
20
+
21
+ _HAS_TEXT_SPLITTERS = True
22
+ except ImportError:
23
+ _HAS_TEXT_SPLITTERS = False
24
+
18
25
 
19
26
  class BaseLoader(ABC): # noqa: B024
20
27
  """Interface for Document Loader.
@@ -28,11 +35,19 @@ class BaseLoader(ABC): # noqa: B024
28
35
  # Sub-classes should not implement this method directly. Instead, they
29
36
  # should implement the lazy load method.
30
37
  def load(self) -> list[Document]:
31
- """Load data into Document objects."""
38
+ """Load data into Document objects.
39
+
40
+ Returns:
41
+ the documents.
42
+ """
32
43
  return list(self.lazy_load())
33
44
 
34
45
  async def aload(self) -> list[Document]:
35
- """Load data into Document objects."""
46
+ """Load data into Document objects.
47
+
48
+ Returns:
49
+ the documents.
50
+ """
36
51
  return [document async for document in self.alazy_load()]
37
52
 
38
53
  def load_and_split(
@@ -44,21 +59,23 @@ class BaseLoader(ABC): # noqa: B024
44
59
 
45
60
  Args:
46
61
  text_splitter: TextSplitter instance to use for splitting documents.
47
- Defaults to RecursiveCharacterTextSplitter.
62
+ Defaults to RecursiveCharacterTextSplitter.
63
+
64
+ Raises:
65
+ ImportError: If langchain-text-splitters is not installed
66
+ and no text_splitter is provided.
48
67
 
49
68
  Returns:
50
69
  List of Documents.
51
70
  """
52
71
  if text_splitter is None:
53
- try:
54
- from langchain_text_splitters import RecursiveCharacterTextSplitter
55
- except ImportError as e:
72
+ if not _HAS_TEXT_SPLITTERS:
56
73
  msg = (
57
74
  "Unable to import from langchain_text_splitters. Please specify "
58
75
  "text_splitter or install langchain_text_splitters with "
59
76
  "`pip install -U langchain-text-splitters`."
60
77
  )
61
- raise ImportError(msg) from e
78
+ raise ImportError(msg)
62
79
 
63
80
  text_splitter_: TextSplitter = RecursiveCharacterTextSplitter()
64
81
  else:
@@ -69,14 +86,22 @@ class BaseLoader(ABC): # noqa: B024
69
86
  # Attention: This method will be upgraded into an abstractmethod once it's
70
87
  # implemented in all the existing subclasses.
71
88
  def lazy_load(self) -> Iterator[Document]:
72
- """A lazy loader for Documents."""
89
+ """A lazy loader for Documents.
90
+
91
+ Yields:
92
+ the documents.
93
+ """
73
94
  if type(self).load != BaseLoader.load:
74
95
  return iter(self.load())
75
96
  msg = f"{self.__class__.__name__} does not implement lazy_load()"
76
97
  raise NotImplementedError(msg)
77
98
 
78
99
  async def alazy_load(self) -> AsyncIterator[Document]:
79
- """A lazy loader for Documents."""
100
+ """A lazy loader for Documents.
101
+
102
+ Yields:
103
+ the documents.
104
+ """
80
105
  iterator = await run_in_executor(None, self.lazy_load)
81
106
  done = object()
82
107
  while True:
@@ -84,6 +84,9 @@ class LangSmithLoader(BaseLoader):
84
84
  client: LangSmith Client. If not provided will be initialized from below args.
85
85
  client_kwargs: Keyword args to pass to LangSmith client init. Should only be
86
86
  specified if ``client`` isn't.
87
+
88
+ Raises:
89
+ ValueError: If both ``client`` and ``client_kwargs`` are provided.
87
90
  """ # noqa: E501
88
91
  if client and client_kwargs:
89
92
  raise ValueError