langchain-core 1.0.0a1__py3-none-any.whl → 1.0.0a3__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 (131) 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 +28 -4
  24. langchain_core/language_models/base.py +33 -21
  25. langchain_core/language_models/chat_models.py +103 -29
  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 +7 -17
  33. langchain_core/messages/ai.py +41 -34
  34. langchain_core/messages/base.py +16 -7
  35. langchain_core/messages/block_translators/__init__.py +10 -8
  36. langchain_core/messages/block_translators/anthropic.py +3 -1
  37. langchain_core/messages/block_translators/bedrock.py +3 -1
  38. langchain_core/messages/block_translators/bedrock_converse.py +3 -1
  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/langchain_v0.py +3 -136
  43. langchain_core/messages/block_translators/ollama.py +3 -1
  44. langchain_core/messages/block_translators/openai.py +252 -10
  45. langchain_core/messages/content.py +26 -124
  46. langchain_core/messages/human.py +2 -13
  47. langchain_core/messages/system.py +2 -6
  48. langchain_core/messages/tool.py +34 -14
  49. langchain_core/messages/utils.py +189 -74
  50. langchain_core/output_parsers/base.py +5 -2
  51. langchain_core/output_parsers/json.py +4 -4
  52. langchain_core/output_parsers/list.py +7 -22
  53. langchain_core/output_parsers/openai_functions.py +3 -0
  54. langchain_core/output_parsers/openai_tools.py +6 -1
  55. langchain_core/output_parsers/pydantic.py +4 -0
  56. langchain_core/output_parsers/string.py +5 -1
  57. langchain_core/output_parsers/xml.py +19 -19
  58. langchain_core/outputs/chat_generation.py +18 -7
  59. langchain_core/outputs/generation.py +14 -3
  60. langchain_core/outputs/llm_result.py +8 -1
  61. langchain_core/prompt_values.py +10 -4
  62. langchain_core/prompts/base.py +6 -11
  63. langchain_core/prompts/chat.py +88 -60
  64. langchain_core/prompts/dict.py +16 -8
  65. langchain_core/prompts/few_shot.py +9 -11
  66. langchain_core/prompts/few_shot_with_templates.py +5 -1
  67. langchain_core/prompts/image.py +12 -5
  68. langchain_core/prompts/loading.py +2 -2
  69. langchain_core/prompts/message.py +5 -6
  70. langchain_core/prompts/pipeline.py +13 -8
  71. langchain_core/prompts/prompt.py +22 -8
  72. langchain_core/prompts/string.py +18 -10
  73. langchain_core/prompts/structured.py +7 -2
  74. langchain_core/rate_limiters.py +2 -2
  75. langchain_core/retrievers.py +7 -6
  76. langchain_core/runnables/base.py +387 -246
  77. langchain_core/runnables/branch.py +11 -28
  78. langchain_core/runnables/config.py +20 -17
  79. langchain_core/runnables/configurable.py +34 -19
  80. langchain_core/runnables/fallbacks.py +20 -13
  81. langchain_core/runnables/graph.py +48 -38
  82. langchain_core/runnables/graph_ascii.py +40 -17
  83. langchain_core/runnables/graph_mermaid.py +54 -25
  84. langchain_core/runnables/graph_png.py +27 -31
  85. langchain_core/runnables/history.py +55 -58
  86. langchain_core/runnables/passthrough.py +44 -21
  87. langchain_core/runnables/retry.py +44 -23
  88. langchain_core/runnables/router.py +9 -8
  89. langchain_core/runnables/schema.py +9 -0
  90. langchain_core/runnables/utils.py +53 -90
  91. langchain_core/stores.py +19 -31
  92. langchain_core/sys_info.py +9 -8
  93. langchain_core/tools/base.py +36 -27
  94. langchain_core/tools/convert.py +25 -14
  95. langchain_core/tools/simple.py +36 -8
  96. langchain_core/tools/structured.py +25 -12
  97. langchain_core/tracers/base.py +2 -2
  98. langchain_core/tracers/context.py +5 -1
  99. langchain_core/tracers/core.py +110 -46
  100. langchain_core/tracers/evaluation.py +22 -26
  101. langchain_core/tracers/event_stream.py +97 -42
  102. langchain_core/tracers/langchain.py +12 -3
  103. langchain_core/tracers/langchain_v1.py +10 -2
  104. langchain_core/tracers/log_stream.py +56 -17
  105. langchain_core/tracers/root_listeners.py +4 -20
  106. langchain_core/tracers/run_collector.py +6 -16
  107. langchain_core/tracers/schemas.py +5 -1
  108. langchain_core/utils/aiter.py +14 -6
  109. langchain_core/utils/env.py +3 -0
  110. langchain_core/utils/function_calling.py +46 -20
  111. langchain_core/utils/interactive_env.py +6 -2
  112. langchain_core/utils/iter.py +12 -5
  113. langchain_core/utils/json.py +12 -3
  114. langchain_core/utils/json_schema.py +156 -40
  115. langchain_core/utils/loading.py +5 -1
  116. langchain_core/utils/mustache.py +25 -16
  117. langchain_core/utils/pydantic.py +38 -9
  118. langchain_core/utils/utils.py +25 -9
  119. langchain_core/vectorstores/base.py +7 -20
  120. langchain_core/vectorstores/in_memory.py +20 -14
  121. langchain_core/vectorstores/utils.py +18 -12
  122. langchain_core/version.py +1 -1
  123. langchain_core-1.0.0a3.dist-info/METADATA +77 -0
  124. langchain_core-1.0.0a3.dist-info/RECORD +181 -0
  125. langchain_core/beta/__init__.py +0 -1
  126. langchain_core/beta/runnables/__init__.py +0 -1
  127. langchain_core/beta/runnables/context.py +0 -448
  128. langchain_core-1.0.0a1.dist-info/METADATA +0 -106
  129. langchain_core-1.0.0a1.dist-info/RECORD +0 -184
  130. {langchain_core-1.0.0a1.dist-info → langchain_core-1.0.0a3.dist-info}/WHEEL +0 -0
  131. {langchain_core-1.0.0a1.dist-info → langchain_core-1.0.0a3.dist-info}/entry_points.txt +0 -0
@@ -44,10 +44,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
44
44
 
45
45
  If no condition evaluates to True, the default branch is run on the input.
46
46
 
47
- Parameters:
48
- branches: A list of (condition, Runnable) pairs.
49
- default: A Runnable to run if no condition is met.
50
-
51
47
  Examples:
52
48
 
53
49
  .. code-block:: python
@@ -61,13 +57,15 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
61
57
  lambda x: "goodbye",
62
58
  )
63
59
 
64
- branch.invoke("hello") # "HELLO"
65
- branch.invoke(None) # "goodbye"
60
+ branch.invoke("hello") # "HELLO"
61
+ branch.invoke(None) # "goodbye"
66
62
 
67
63
  """
68
64
 
69
65
  branches: Sequence[tuple[Runnable[Input, bool], Runnable[Input, Output]]]
66
+ """A list of (condition, Runnable) pairs."""
70
67
  default: Runnable[Input, Output]
68
+ """A Runnable to run if no condition is met."""
71
69
 
72
70
  def __init__(
73
71
  self,
@@ -144,12 +142,17 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
144
142
 
145
143
  @classmethod
146
144
  def is_lc_serializable(cls) -> bool:
147
- """RunnableBranch is serializable if all its branches are serializable."""
145
+ """Return True as this class is serializable."""
148
146
  return True
149
147
 
150
148
  @classmethod
151
149
  @override
152
150
  def get_lc_namespace(cls) -> list[str]:
151
+ """Get the namespace of the langchain object.
152
+
153
+ Returns:
154
+ ``["langchain", "schema", "runnable"]``
155
+ """
153
156
  return ["langchain", "schema", "runnable"]
154
157
 
155
158
  @override
@@ -174,12 +177,7 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
174
177
  @property
175
178
  @override
176
179
  def config_specs(self) -> list[ConfigurableFieldSpec]:
177
- from langchain_core.beta.runnables.context import (
178
- CONTEXT_CONFIG_PREFIX,
179
- CONTEXT_CONFIG_SUFFIX_SET,
180
- )
181
-
182
- specs = get_unique_config_specs(
180
+ return get_unique_config_specs(
183
181
  spec
184
182
  for step in (
185
183
  [self.default]
@@ -188,14 +186,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
188
186
  )
189
187
  for spec in step.config_specs
190
188
  )
191
- if any(
192
- s.id.startswith(CONTEXT_CONFIG_PREFIX)
193
- and s.id.endswith(CONTEXT_CONFIG_SUFFIX_SET)
194
- for s in specs
195
- ):
196
- msg = "RunnableBranch cannot contain context setters."
197
- raise ValueError(msg)
198
- return specs
199
189
 
200
190
  @override
201
191
  def invoke(
@@ -260,7 +250,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
260
250
  async def ainvoke(
261
251
  self, input: Input, config: Optional[RunnableConfig] = None, **kwargs: Any
262
252
  ) -> Output:
263
- """Async version of invoke."""
264
253
  config = ensure_config(config)
265
254
  callback_manager = get_async_callback_manager_for_config(config)
266
255
  run_manager = await callback_manager.on_chain_start(
@@ -321,9 +310,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
321
310
 
322
311
  Yields:
323
312
  The output of the branch that was run.
324
-
325
- Raises:
326
- BaseException: If an error occurs during the execution of the Runnable.
327
313
  """
328
314
  config = ensure_config(config)
329
315
  callback_manager = get_callback_manager_for_config(config)
@@ -408,9 +394,6 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
408
394
 
409
395
  Yields:
410
396
  The output of the branch that was run.
411
-
412
- Raises:
413
- BaseException: If an error occurs during the execution of the Runnable.
414
397
  """
415
398
  config = ensure_config(config)
416
399
  callback_manager = get_async_callback_manager_for_config(config)
@@ -10,23 +10,33 @@ from concurrent.futures import Executor, Future, ThreadPoolExecutor
10
10
  from contextlib import contextmanager
11
11
  from contextvars import Context, ContextVar, Token, copy_context
12
12
  from functools import partial
13
- from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union, cast
13
+ from typing import (
14
+ TYPE_CHECKING,
15
+ Any,
16
+ Callable,
17
+ Optional,
18
+ ParamSpec,
19
+ TypeVar,
20
+ Union,
21
+ cast,
22
+ )
14
23
 
15
- from typing_extensions import ParamSpec, TypedDict
24
+ from langsmith.run_helpers import _set_tracing_context, get_tracing_context
25
+ from typing_extensions import TypedDict
16
26
 
27
+ from langchain_core.callbacks.manager import AsyncCallbackManager, CallbackManager
17
28
  from langchain_core.runnables.utils import (
18
29
  Input,
19
30
  Output,
20
31
  accepts_config,
21
32
  accepts_run_manager,
22
33
  )
34
+ from langchain_core.tracers.langchain import LangChainTracer
23
35
 
24
36
  if TYPE_CHECKING:
25
37
  from langchain_core.callbacks.base import BaseCallbackManager, Callbacks
26
38
  from langchain_core.callbacks.manager import (
27
- AsyncCallbackManager,
28
39
  AsyncCallbackManagerForChainRun,
29
- CallbackManager,
30
40
  CallbackManagerForChainRun,
31
41
  )
32
42
  else:
@@ -125,9 +135,10 @@ def _set_config_context(
125
135
 
126
136
  Args:
127
137
  config (RunnableConfig): The config to set.
128
- """
129
- from langchain_core.tracers.langchain import LangChainTracer
130
138
 
139
+ Returns:
140
+ The token to reset the config and the previous tracing context.
141
+ """
131
142
  config_token = var_child_runnable_config.set(config)
132
143
  current_context = None
133
144
  if (
@@ -147,8 +158,6 @@ def _set_config_context(
147
158
  )
148
159
  and (run := tracer.run_map.get(str(parent_run_id)))
149
160
  ):
150
- from langsmith.run_helpers import _set_tracing_context, get_tracing_context
151
-
152
161
  current_context = get_tracing_context()
153
162
  _set_tracing_context({"parent": run})
154
163
  return config_token, current_context
@@ -160,9 +169,10 @@ def set_config_context(config: RunnableConfig) -> Generator[Context, None, None]
160
169
 
161
170
  Args:
162
171
  config (RunnableConfig): The config to set.
163
- """
164
- from langsmith.run_helpers import _set_tracing_context
165
172
 
173
+ Yields:
174
+ The config context.
175
+ """
166
176
  ctx = copy_context()
167
177
  config_token, _ = ctx.run(_set_config_context, config)
168
178
  try:
@@ -475,8 +485,6 @@ def get_callback_manager_for_config(config: RunnableConfig) -> CallbackManager:
475
485
  Returns:
476
486
  CallbackManager: The callback manager.
477
487
  """
478
- from langchain_core.callbacks.manager import CallbackManager
479
-
480
488
  return CallbackManager.configure(
481
489
  inheritable_callbacks=config.get("callbacks"),
482
490
  inheritable_tags=config.get("tags"),
@@ -495,8 +503,6 @@ def get_async_callback_manager_for_config(
495
503
  Returns:
496
504
  AsyncCallbackManager: The async callback manager.
497
505
  """
498
- from langchain_core.callbacks.manager import AsyncCallbackManager
499
-
500
506
  return AsyncCallbackManager.configure(
501
507
  inheritable_callbacks=config.get("callbacks"),
502
508
  inheritable_tags=config.get("tags"),
@@ -598,9 +604,6 @@ async def run_in_executor(
598
604
 
599
605
  Returns:
600
606
  Output: The output of the function.
601
-
602
- Raises:
603
- RuntimeError: If the function raises a StopIteration.
604
607
  """
605
608
 
606
609
  def wrapper() -> T:
@@ -51,17 +51,15 @@ if TYPE_CHECKING:
51
51
  class DynamicRunnable(RunnableSerializable[Input, Output]):
52
52
  """Serializable Runnable that can be dynamically configured.
53
53
 
54
- A DynamicRunnable should be initiated using the `configurable_fields` or
55
- `configurable_alternatives` method of a Runnable.
56
-
57
- Parameters:
58
- default: The default Runnable to use.
59
- config: The configuration to use.
54
+ A DynamicRunnable should be initiated using the ``configurable_fields`` or
55
+ ``configurable_alternatives`` method of a Runnable.
60
56
  """
61
57
 
62
58
  default: RunnableSerializable[Input, Output]
59
+ """The default Runnable to use."""
63
60
 
64
61
  config: Optional[RunnableConfig] = None
62
+ """The configuration to use."""
65
63
 
66
64
  model_config = ConfigDict(
67
65
  arbitrary_types_allowed=True,
@@ -70,11 +68,17 @@ class DynamicRunnable(RunnableSerializable[Input, Output]):
70
68
  @classmethod
71
69
  @override
72
70
  def is_lc_serializable(cls) -> bool:
71
+ """Return True as this class is serializable."""
73
72
  return True
74
73
 
75
74
  @classmethod
76
75
  @override
77
76
  def get_lc_namespace(cls) -> list[str]:
77
+ """Get the namespace of the langchain object.
78
+
79
+ Returns:
80
+ ``["langchain", "schema", "runnable"]``
81
+ """
78
82
  return ["langchain", "schema", "runnable"]
79
83
 
80
84
  @property
@@ -322,9 +326,6 @@ class RunnableConfigurableFields(DynamicRunnable[Input, Output]):
322
326
  A RunnableConfigurableFields should be initiated using the
323
327
  `configurable_fields` method of a Runnable.
324
328
 
325
- Parameters:
326
- fields: The configurable fields to use.
327
-
328
329
  Here is an example of using a RunnableConfigurableFields with LLMs:
329
330
 
330
331
  .. code-block:: python
@@ -382,6 +383,7 @@ class RunnableConfigurableFields(DynamicRunnable[Input, Output]):
382
383
  """
383
384
 
384
385
  fields: dict[str, AnyConfigurableField]
386
+ """The configurable fields to use."""
385
387
 
386
388
  @property
387
389
  def config_specs(self) -> list[ConfigurableFieldSpec]:
@@ -501,7 +503,7 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]):
501
503
  ).configurable_alternatives(
502
504
  ConfigurableField(id="prompt"),
503
505
  default_key="joke",
504
- poem=PromptTemplate.from_template("Write a short poem about {topic}")
506
+ poem=PromptTemplate.from_template("Write a short poem about {topic}"),
505
507
  )
506
508
 
507
509
  # When invoking the created RunnableSequence, you can pass in the
@@ -511,7 +513,9 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]):
511
513
 
512
514
  # The `with_config` method brings in the desired Prompt Runnable in your
513
515
  # Runnable Sequence.
514
- chain.with_config(configurable={"prompt": "poem"}).invoke({"topic": "bears"})
516
+ chain.with_config(configurable={"prompt": "poem"}).invoke(
517
+ {"topic": "bears"}
518
+ )
515
519
 
516
520
 
517
521
  Equivalently, you can initialize RunnableConfigurableAlternatives directly
@@ -520,20 +524,28 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]):
520
524
  .. code-block:: python
521
525
 
522
526
  from langchain_core.runnables import ConfigurableField
523
- from langchain_core.runnables.configurable import RunnableConfigurableAlternatives
527
+ from langchain_core.runnables.configurable import (
528
+ RunnableConfigurableAlternatives,
529
+ )
524
530
  from langchain_openai import ChatOpenAI
525
531
 
526
532
  prompt = RunnableConfigurableAlternatives(
527
- which=ConfigurableField(id='prompt'),
533
+ which=ConfigurableField(id="prompt"),
528
534
  default=PromptTemplate.from_template("Tell me a joke about {topic}"),
529
- default_key='joke',
535
+ default_key="joke",
530
536
  prefix_keys=False,
531
- alternatives={"poem":PromptTemplate.from_template("Write a short poem about {topic}")}
537
+ alternatives={
538
+ "poem": PromptTemplate.from_template(
539
+ "Write a short poem about {topic}"
540
+ )
541
+ },
532
542
  )
533
543
  chain = prompt | ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
534
- chain.with_config(configurable={"prompt": "poem"}).invoke({"topic": "bears"})
544
+ chain.with_config(configurable={"prompt": "poem"}).invoke(
545
+ {"topic": "bears"}
546
+ )
535
547
 
536
- """ # noqa: E501
548
+ """
537
549
 
538
550
  which: ConfigurableField
539
551
  """The ConfigurableField to use to choose between alternatives."""
@@ -680,7 +692,10 @@ def make_options_spec(
680
692
  spec: Union[ConfigurableFieldSingleOption, ConfigurableFieldMultiOption],
681
693
  description: Optional[str],
682
694
  ) -> ConfigurableFieldSpec:
683
- """Make a ConfigurableFieldSpec for a ConfigurableFieldSingleOption or ConfigurableFieldMultiOption.
695
+ """Make options spec.
696
+
697
+ Make a ConfigurableFieldSpec for a ConfigurableFieldSingleOption or
698
+ ConfigurableFieldMultiOption.
684
699
 
685
700
  Args:
686
701
  spec: The ConfigurableFieldSingleOption or ConfigurableFieldMultiOption.
@@ -688,7 +703,7 @@ def make_options_spec(
688
703
 
689
704
  Returns:
690
705
  The ConfigurableFieldSpec.
691
- """ # noqa: E501
706
+ """
692
707
  with _enums_for_spec_lock:
693
708
  if enum := _enums_for_spec.get(spec):
694
709
  pass
@@ -10,6 +10,7 @@ from typing import TYPE_CHECKING, Any, Optional, Union, cast
10
10
  from pydantic import BaseModel, ConfigDict
11
11
  from typing_extensions import override
12
12
 
13
+ from langchain_core.callbacks.manager import AsyncCallbackManager, CallbackManager
13
14
  from langchain_core.runnables.base import Runnable, RunnableSerializable
14
15
  from langchain_core.runnables.config import (
15
16
  RunnableConfig,
@@ -56,12 +57,12 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]):
56
57
  from langchain_core.chat_models.openai import ChatOpenAI
57
58
  from langchain_core.chat_models.anthropic import ChatAnthropic
58
59
 
59
- model = ChatAnthropic(
60
- model="claude-3-haiku-20240307"
61
- ).with_fallbacks([ChatOpenAI(model="gpt-3.5-turbo-0125")])
60
+ model = ChatAnthropic(model="claude-3-haiku-20240307").with_fallbacks(
61
+ [ChatOpenAI(model="gpt-3.5-turbo-0125")]
62
+ )
62
63
  # Will usually use ChatAnthropic, but fallback to ChatOpenAI
63
64
  # if ChatAnthropic fails.
64
- model.invoke('hello')
65
+ model.invoke("hello")
65
66
 
66
67
  # And you can also use fallbacks at the level of a chain.
67
68
  # Here if both LLM providers fail, we'll fallback to a good hardcoded
@@ -71,12 +72,16 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]):
71
72
  from langchain_core.output_parser import StrOutputParser
72
73
  from langchain_core.runnables import RunnableLambda
73
74
 
75
+
74
76
  def when_all_is_lost(inputs):
75
- return ("Looks like our LLM providers are down. "
76
- "Here's a nice 🦜️ emoji for you instead.")
77
+ return (
78
+ "Looks like our LLM providers are down. "
79
+ "Here's a nice 🦜️ emoji for you instead."
80
+ )
81
+
77
82
 
78
83
  chain_with_fallback = (
79
- PromptTemplate.from_template('Tell me a joke about {topic}')
84
+ PromptTemplate.from_template("Tell me a joke about {topic}")
80
85
  | model
81
86
  | StrOutputParser()
82
87
  ).with_fallbacks([RunnableLambda(when_all_is_lost)])
@@ -136,6 +141,7 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]):
136
141
  @classmethod
137
142
  @override
138
143
  def is_lc_serializable(cls) -> bool:
144
+ """Return True as this class is serializable."""
139
145
  return True
140
146
 
141
147
  @classmethod
@@ -143,13 +149,18 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]):
143
149
  def get_lc_namespace(cls) -> list[str]:
144
150
  """Get the namespace of the langchain object.
145
151
 
146
- Defaults to ["langchain", "schema", "runnable"].
152
+ Returns:
153
+ ``["langchain", "schema", "runnable"]``
147
154
  """
148
155
  return ["langchain", "schema", "runnable"]
149
156
 
150
157
  @property
151
158
  def runnables(self) -> Iterator[Runnable[Input, Output]]:
152
- """Iterator over the Runnable and its fallbacks."""
159
+ """Iterator over the Runnable and its fallbacks.
160
+
161
+ Yields:
162
+ The Runnable then its fallbacks.
163
+ """
153
164
  yield self.runnable
154
165
  yield from self.fallbacks
155
166
 
@@ -262,8 +273,6 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]):
262
273
  return_exceptions: bool = False,
263
274
  **kwargs: Optional[Any],
264
275
  ) -> list[Output]:
265
- from langchain_core.callbacks.manager import CallbackManager
266
-
267
276
  if self.exception_key is not None and not all(
268
277
  isinstance(input_, dict) for input_ in inputs
269
278
  ):
@@ -356,8 +365,6 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]):
356
365
  return_exceptions: bool = False,
357
366
  **kwargs: Optional[Any],
358
367
  ) -> list[Output]:
359
- from langchain_core.callbacks.manager import AsyncCallbackManager
360
-
361
368
  if self.exception_key is not None and not all(
362
369
  isinstance(input_, dict) for input_ in inputs
363
370
  ):
@@ -19,6 +19,8 @@ from typing import (
19
19
  )
20
20
  from uuid import UUID, uuid4
21
21
 
22
+ from langchain_core.load.serializable import to_json_not_implemented
23
+ from langchain_core.runnables.base import Runnable, RunnableSerializable
22
24
  from langchain_core.utils.pydantic import _IgnoreUnserializable, is_basemodel_subclass
23
25
 
24
26
  if TYPE_CHECKING:
@@ -62,19 +64,16 @@ def is_uuid(value: str) -> bool:
62
64
 
63
65
 
64
66
  class Edge(NamedTuple):
65
- """Edge in a graph.
66
-
67
- Parameters:
68
- source: The source node id.
69
- target: The target node id.
70
- data: Optional data associated with the edge. Defaults to None.
71
- conditional: Whether the edge is conditional. Defaults to False.
72
- """
67
+ """Edge in a graph."""
73
68
 
74
69
  source: str
70
+ """The source node id."""
75
71
  target: str
72
+ """The target node id."""
76
73
  data: Optional[Stringifiable] = None
74
+ """Optional data associated with the edge. Defaults to None."""
77
75
  conditional: bool = False
76
+ """Whether the edge is conditional. Defaults to False."""
78
77
 
79
78
  def copy(
80
79
  self, *, source: Optional[str] = None, target: Optional[str] = None
@@ -97,19 +96,16 @@ class Edge(NamedTuple):
97
96
 
98
97
 
99
98
  class Node(NamedTuple):
100
- """Node in a graph.
101
-
102
- Parameters:
103
- id: The unique identifier of the node.
104
- name: The name of the node.
105
- data: The data of the node.
106
- metadata: Optional metadata for the node. Defaults to None.
107
- """
99
+ """Node in a graph."""
108
100
 
109
101
  id: str
102
+ """The unique identifier of the node."""
110
103
  name: str
104
+ """The name of the node."""
111
105
  data: Union[type[BaseModel], RunnableType, None]
106
+ """The data of the node."""
112
107
  metadata: Optional[dict[str, Any]]
108
+ """Optional metadata for the node. Defaults to None."""
113
109
 
114
110
  def copy(
115
111
  self,
@@ -135,16 +131,12 @@ class Node(NamedTuple):
135
131
 
136
132
 
137
133
  class Branch(NamedTuple):
138
- """Branch in a graph.
139
-
140
- Parameters:
141
- condition: A callable that returns a string representation of the condition.
142
- ends: Optional dictionary of end node ids for the branches. Defaults
143
- to None.
144
- """
134
+ """Branch in a graph."""
145
135
 
146
136
  condition: Callable[..., str]
137
+ """A callable that returns a string representation of the condition."""
147
138
  ends: Optional[dict[str, str]]
139
+ """Optional dictionary of end node ids for the branches. Defaults to None."""
148
140
 
149
141
 
150
142
  class CurveStyle(Enum):
@@ -168,7 +160,7 @@ class CurveStyle(Enum):
168
160
  class NodeStyles:
169
161
  """Schema for Hexadecimal color codes for different node types.
170
162
 
171
- Parameters:
163
+ Args:
172
164
  default: The default color code. Defaults to "fill:#f2f0ff,line-height:1.2".
173
165
  first: The color code for the first node. Defaults to "fill-opacity:0".
174
166
  last: The color code for the last node. Defaults to "fill:#bfb6fc".
@@ -182,8 +174,10 @@ class NodeStyles:
182
174
  class MermaidDrawMethod(Enum):
183
175
  """Enum for different draw methods supported by Mermaid."""
184
176
 
185
- PYPPETEER = "pyppeteer" # Uses Pyppeteer to render the graph
186
- API = "api" # Uses Mermaid.INK API to render the graph
177
+ PYPPETEER = "pyppeteer"
178
+ """Uses Pyppeteer to render the graph"""
179
+ API = "api"
180
+ """Uses Mermaid.INK API to render the graph"""
187
181
 
188
182
 
189
183
  def node_data_str(
@@ -199,8 +193,6 @@ def node_data_str(
199
193
  Returns:
200
194
  A string representation of the data.
201
195
  """
202
- from langchain_core.runnables.base import Runnable
203
-
204
196
  if not is_uuid(id) or data is None:
205
197
  return id
206
198
  data_str = data.get_name() if isinstance(data, Runnable) else data.__name__
@@ -220,9 +212,6 @@ def node_data_json(
220
212
  Returns:
221
213
  A dictionary with the type of the data and the data itself.
222
214
  """
223
- from langchain_core.load.serializable import to_json_not_implemented
224
- from langchain_core.runnables.base import Runnable, RunnableSerializable
225
-
226
215
  if node.data is None:
227
216
  json: dict[str, Any] = {}
228
217
  elif isinstance(node.data, RunnableSerializable):
@@ -269,7 +258,7 @@ def node_data_json(
269
258
  class Graph:
270
259
  """Graph of nodes and edges.
271
260
 
272
- Parameters:
261
+ Args:
273
262
  nodes: Dictionary of nodes in the graph. Defaults to an empty dictionary.
274
263
  edges: List of edges in the graph. Defaults to an empty list.
275
264
  """
@@ -475,6 +464,10 @@ class Graph:
475
464
 
476
465
  If there is no such node, or there are multiple, return None.
477
466
  When drawing the graph, this node would be the origin.
467
+
468
+ Returns:
469
+ The first node, or None if there is no such node or multiple
470
+ candidates.
478
471
  """
479
472
  return _first_node(self)
480
473
 
@@ -483,6 +476,10 @@ class Graph:
483
476
 
484
477
  If there is no such node, or there are multiple, return None.
485
478
  When drawing the graph, this node would be the destination.
479
+
480
+ Returns:
481
+ The last node, or None if there is no such node or multiple
482
+ candidates.
486
483
  """
487
484
  return _last_node(self)
488
485
 
@@ -513,8 +510,13 @@ class Graph:
513
510
  self.remove_node(last_node)
514
511
 
515
512
  def draw_ascii(self) -> str:
516
- """Draw the graph as an ASCII art string."""
517
- from langchain_core.runnables.graph_ascii import draw_ascii
513
+ """Draw the graph as an ASCII art string.
514
+
515
+ Returns:
516
+ The ASCII art string.
517
+ """
518
+ # Import locally to prevent circular import
519
+ from langchain_core.runnables.graph_ascii import draw_ascii # noqa: PLC0415
518
520
 
519
521
  return draw_ascii(
520
522
  {node.id: node.name for node in self.nodes.values()},
@@ -558,7 +560,8 @@ class Graph:
558
560
  Returns:
559
561
  The PNG image as bytes if output_file_path is None, None otherwise.
560
562
  """
561
- from langchain_core.runnables.graph_png import PngDrawer
563
+ # Import locally to prevent circular import
564
+ from langchain_core.runnables.graph_png import PngDrawer # noqa: PLC0415
562
565
 
563
566
  default_node_labels = {node.id: node.name for node in self.nodes.values()}
564
567
 
@@ -611,9 +614,9 @@ class Graph:
611
614
 
612
615
  Returns:
613
616
  The Mermaid syntax string.
614
-
615
617
  """
616
- from langchain_core.runnables.graph_mermaid import draw_mermaid
618
+ # Import locally to prevent circular import
619
+ from langchain_core.runnables.graph_mermaid import draw_mermaid # noqa: PLC0415
617
620
 
618
621
  graph = self.reid()
619
622
  first_node = graph.first_node()
@@ -644,6 +647,7 @@ class Graph:
644
647
  max_retries: int = 1,
645
648
  retry_delay: float = 1.0,
646
649
  frontmatter_config: Optional[dict[str, Any]] = None,
650
+ base_url: Optional[str] = None,
647
651
  ) -> bytes:
648
652
  """Draw the graph as a PNG image using Mermaid.
649
653
 
@@ -679,12 +683,17 @@ class Graph:
679
683
  "themeVariables": { "primaryColor": "#e2e2e2"},
680
684
  }
681
685
  }
686
+ base_url: The base URL of the Mermaid server for rendering via API.
687
+ Defaults to None.
682
688
 
683
689
  Returns:
684
690
  The PNG image as bytes.
685
691
 
686
692
  """
687
- from langchain_core.runnables.graph_mermaid import draw_mermaid_png
693
+ # Import locally to prevent circular import
694
+ from langchain_core.runnables.graph_mermaid import ( # noqa: PLC0415
695
+ draw_mermaid_png,
696
+ )
688
697
 
689
698
  mermaid_syntax = self.draw_mermaid(
690
699
  curve_style=curve_style,
@@ -700,6 +709,7 @@ class Graph:
700
709
  padding=padding,
701
710
  max_retries=max_retries,
702
711
  retry_delay=retry_delay,
712
+ base_url=base_url,
703
713
  )
704
714
 
705
715