langchain-core 0.4.0.dev0__py3-none-any.whl → 1.0.0__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.
- langchain_core/__init__.py +1 -1
- langchain_core/_api/__init__.py +3 -4
- langchain_core/_api/beta_decorator.py +45 -70
- langchain_core/_api/deprecation.py +80 -80
- langchain_core/_api/path.py +22 -8
- langchain_core/_import_utils.py +10 -4
- langchain_core/agents.py +25 -21
- langchain_core/caches.py +53 -63
- langchain_core/callbacks/__init__.py +1 -8
- langchain_core/callbacks/base.py +341 -348
- langchain_core/callbacks/file.py +55 -44
- langchain_core/callbacks/manager.py +546 -683
- langchain_core/callbacks/stdout.py +29 -30
- langchain_core/callbacks/streaming_stdout.py +35 -36
- langchain_core/callbacks/usage.py +65 -70
- langchain_core/chat_history.py +48 -55
- langchain_core/document_loaders/base.py +46 -21
- langchain_core/document_loaders/langsmith.py +39 -36
- langchain_core/documents/__init__.py +0 -1
- langchain_core/documents/base.py +96 -74
- langchain_core/documents/compressor.py +12 -9
- langchain_core/documents/transformers.py +29 -28
- langchain_core/embeddings/fake.py +56 -57
- langchain_core/env.py +2 -3
- langchain_core/example_selectors/base.py +12 -0
- langchain_core/example_selectors/length_based.py +1 -1
- langchain_core/example_selectors/semantic_similarity.py +21 -25
- langchain_core/exceptions.py +15 -9
- langchain_core/globals.py +4 -163
- langchain_core/indexing/api.py +132 -125
- langchain_core/indexing/base.py +64 -67
- langchain_core/indexing/in_memory.py +26 -6
- langchain_core/language_models/__init__.py +15 -27
- langchain_core/language_models/_utils.py +267 -117
- langchain_core/language_models/base.py +92 -177
- langchain_core/language_models/chat_models.py +547 -407
- langchain_core/language_models/fake.py +11 -11
- langchain_core/language_models/fake_chat_models.py +72 -118
- langchain_core/language_models/llms.py +168 -242
- langchain_core/load/dump.py +8 -11
- langchain_core/load/load.py +32 -28
- langchain_core/load/mapping.py +2 -4
- langchain_core/load/serializable.py +50 -56
- langchain_core/messages/__init__.py +36 -51
- langchain_core/messages/ai.py +377 -150
- langchain_core/messages/base.py +239 -47
- langchain_core/messages/block_translators/__init__.py +111 -0
- langchain_core/messages/block_translators/anthropic.py +470 -0
- langchain_core/messages/block_translators/bedrock.py +94 -0
- langchain_core/messages/block_translators/bedrock_converse.py +297 -0
- langchain_core/messages/block_translators/google_genai.py +530 -0
- langchain_core/messages/block_translators/google_vertexai.py +21 -0
- langchain_core/messages/block_translators/groq.py +143 -0
- langchain_core/messages/block_translators/langchain_v0.py +301 -0
- langchain_core/messages/block_translators/openai.py +1010 -0
- langchain_core/messages/chat.py +2 -3
- langchain_core/messages/content.py +1423 -0
- langchain_core/messages/function.py +7 -7
- langchain_core/messages/human.py +44 -38
- langchain_core/messages/modifier.py +3 -2
- langchain_core/messages/system.py +40 -27
- langchain_core/messages/tool.py +160 -58
- langchain_core/messages/utils.py +527 -638
- langchain_core/output_parsers/__init__.py +1 -14
- langchain_core/output_parsers/base.py +68 -104
- langchain_core/output_parsers/json.py +13 -17
- langchain_core/output_parsers/list.py +11 -33
- langchain_core/output_parsers/openai_functions.py +56 -74
- langchain_core/output_parsers/openai_tools.py +68 -109
- langchain_core/output_parsers/pydantic.py +15 -13
- langchain_core/output_parsers/string.py +6 -2
- langchain_core/output_parsers/transform.py +17 -60
- langchain_core/output_parsers/xml.py +34 -44
- langchain_core/outputs/__init__.py +1 -1
- langchain_core/outputs/chat_generation.py +26 -11
- langchain_core/outputs/chat_result.py +1 -3
- langchain_core/outputs/generation.py +17 -6
- langchain_core/outputs/llm_result.py +15 -8
- langchain_core/prompt_values.py +29 -123
- langchain_core/prompts/__init__.py +3 -27
- langchain_core/prompts/base.py +48 -63
- langchain_core/prompts/chat.py +259 -288
- langchain_core/prompts/dict.py +19 -11
- langchain_core/prompts/few_shot.py +84 -90
- langchain_core/prompts/few_shot_with_templates.py +14 -12
- langchain_core/prompts/image.py +19 -14
- langchain_core/prompts/loading.py +6 -8
- langchain_core/prompts/message.py +7 -8
- langchain_core/prompts/prompt.py +42 -43
- langchain_core/prompts/string.py +37 -16
- langchain_core/prompts/structured.py +43 -46
- langchain_core/rate_limiters.py +51 -60
- langchain_core/retrievers.py +52 -192
- langchain_core/runnables/base.py +1727 -1683
- langchain_core/runnables/branch.py +52 -73
- langchain_core/runnables/config.py +89 -103
- langchain_core/runnables/configurable.py +128 -130
- langchain_core/runnables/fallbacks.py +93 -82
- langchain_core/runnables/graph.py +127 -127
- langchain_core/runnables/graph_ascii.py +63 -41
- langchain_core/runnables/graph_mermaid.py +87 -70
- langchain_core/runnables/graph_png.py +31 -36
- langchain_core/runnables/history.py +145 -161
- langchain_core/runnables/passthrough.py +141 -144
- langchain_core/runnables/retry.py +84 -68
- langchain_core/runnables/router.py +33 -37
- langchain_core/runnables/schema.py +79 -72
- langchain_core/runnables/utils.py +95 -139
- langchain_core/stores.py +85 -131
- langchain_core/structured_query.py +11 -15
- langchain_core/sys_info.py +31 -32
- langchain_core/tools/__init__.py +1 -14
- langchain_core/tools/base.py +221 -247
- langchain_core/tools/convert.py +144 -161
- langchain_core/tools/render.py +10 -10
- langchain_core/tools/retriever.py +12 -19
- langchain_core/tools/simple.py +52 -29
- langchain_core/tools/structured.py +56 -60
- langchain_core/tracers/__init__.py +1 -9
- langchain_core/tracers/_streaming.py +6 -7
- langchain_core/tracers/base.py +103 -112
- langchain_core/tracers/context.py +29 -48
- langchain_core/tracers/core.py +142 -105
- langchain_core/tracers/evaluation.py +30 -34
- langchain_core/tracers/event_stream.py +162 -117
- langchain_core/tracers/langchain.py +34 -36
- langchain_core/tracers/log_stream.py +87 -49
- langchain_core/tracers/memory_stream.py +3 -3
- langchain_core/tracers/root_listeners.py +18 -34
- langchain_core/tracers/run_collector.py +8 -20
- langchain_core/tracers/schemas.py +0 -125
- langchain_core/tracers/stdout.py +3 -3
- langchain_core/utils/__init__.py +1 -4
- langchain_core/utils/_merge.py +47 -9
- langchain_core/utils/aiter.py +70 -66
- langchain_core/utils/env.py +12 -9
- langchain_core/utils/function_calling.py +139 -206
- langchain_core/utils/html.py +7 -8
- langchain_core/utils/input.py +6 -6
- langchain_core/utils/interactive_env.py +6 -2
- langchain_core/utils/iter.py +48 -45
- langchain_core/utils/json.py +14 -4
- langchain_core/utils/json_schema.py +159 -43
- langchain_core/utils/mustache.py +32 -25
- langchain_core/utils/pydantic.py +67 -40
- langchain_core/utils/strings.py +5 -5
- langchain_core/utils/usage.py +1 -1
- langchain_core/utils/utils.py +104 -62
- langchain_core/vectorstores/base.py +131 -179
- langchain_core/vectorstores/in_memory.py +113 -182
- langchain_core/vectorstores/utils.py +23 -17
- langchain_core/version.py +1 -1
- langchain_core-1.0.0.dist-info/METADATA +68 -0
- langchain_core-1.0.0.dist-info/RECORD +172 -0
- {langchain_core-0.4.0.dev0.dist-info → langchain_core-1.0.0.dist-info}/WHEEL +1 -1
- langchain_core/beta/__init__.py +0 -1
- langchain_core/beta/runnables/__init__.py +0 -1
- langchain_core/beta/runnables/context.py +0 -448
- langchain_core/memory.py +0 -116
- langchain_core/messages/content_blocks.py +0 -1435
- langchain_core/prompts/pipeline.py +0 -133
- langchain_core/pydantic_v1/__init__.py +0 -30
- langchain_core/pydantic_v1/dataclasses.py +0 -23
- langchain_core/pydantic_v1/main.py +0 -23
- langchain_core/tracers/langchain_v1.py +0 -23
- langchain_core/utils/loading.py +0 -31
- langchain_core/v1/__init__.py +0 -1
- langchain_core/v1/chat_models.py +0 -1047
- langchain_core/v1/messages.py +0 -755
- langchain_core-0.4.0.dev0.dist-info/METADATA +0 -108
- langchain_core-0.4.0.dev0.dist-info/RECORD +0 -177
- langchain_core-0.4.0.dev0.dist-info/entry_points.txt +0 -4
|
@@ -4,21 +4,21 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import inspect
|
|
6
6
|
from collections import defaultdict
|
|
7
|
+
from collections.abc import Callable
|
|
7
8
|
from dataclasses import dataclass, field
|
|
8
9
|
from enum import Enum
|
|
9
10
|
from typing import (
|
|
10
11
|
TYPE_CHECKING,
|
|
11
12
|
Any,
|
|
12
|
-
Callable,
|
|
13
13
|
NamedTuple,
|
|
14
|
-
Optional,
|
|
15
14
|
Protocol,
|
|
16
15
|
TypedDict,
|
|
17
|
-
Union,
|
|
18
16
|
overload,
|
|
19
17
|
)
|
|
20
18
|
from uuid import UUID, uuid4
|
|
21
19
|
|
|
20
|
+
from langchain_core.load.serializable import to_json_not_implemented
|
|
21
|
+
from langchain_core.runnables.base import Runnable, RunnableSerializable
|
|
22
22
|
from langchain_core.utils.pydantic import _IgnoreUnserializable, is_basemodel_subclass
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
@@ -52,7 +52,7 @@ def is_uuid(value: str) -> bool:
|
|
|
52
52
|
value: The string to check.
|
|
53
53
|
|
|
54
54
|
Returns:
|
|
55
|
-
True if the string is a valid UUID, False otherwise.
|
|
55
|
+
`True` if the string is a valid UUID, `False` otherwise.
|
|
56
56
|
"""
|
|
57
57
|
try:
|
|
58
58
|
UUID(value)
|
|
@@ -62,28 +62,23 @@ def is_uuid(value: str) -> bool:
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
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
|
-
"""
|
|
65
|
+
"""Edge in a graph."""
|
|
73
66
|
|
|
74
67
|
source: str
|
|
68
|
+
"""The source node id."""
|
|
75
69
|
target: str
|
|
76
|
-
|
|
70
|
+
"""The target node id."""
|
|
71
|
+
data: Stringifiable | None = None
|
|
72
|
+
"""Optional data associated with the edge. """
|
|
77
73
|
conditional: bool = False
|
|
74
|
+
"""Whether the edge is conditional."""
|
|
78
75
|
|
|
79
|
-
def copy(
|
|
80
|
-
self, *, source: Optional[str] = None, target: Optional[str] = None
|
|
81
|
-
) -> Edge:
|
|
76
|
+
def copy(self, *, source: str | None = None, target: str | None = None) -> Edge:
|
|
82
77
|
"""Return a copy of the edge with optional new source and target nodes.
|
|
83
78
|
|
|
84
79
|
Args:
|
|
85
|
-
source: The new source node id.
|
|
86
|
-
target: The new target node id.
|
|
80
|
+
source: The new source node id.
|
|
81
|
+
target: The new target node id.
|
|
87
82
|
|
|
88
83
|
Returns:
|
|
89
84
|
A copy of the edge with the new source and target nodes.
|
|
@@ -97,31 +92,28 @@ class Edge(NamedTuple):
|
|
|
97
92
|
|
|
98
93
|
|
|
99
94
|
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
|
-
"""
|
|
95
|
+
"""Node in a graph."""
|
|
108
96
|
|
|
109
97
|
id: str
|
|
98
|
+
"""The unique identifier of the node."""
|
|
110
99
|
name: str
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
"""The name of the node."""
|
|
101
|
+
data: type[BaseModel] | RunnableType | None
|
|
102
|
+
"""The data of the node."""
|
|
103
|
+
metadata: dict[str, Any] | None
|
|
104
|
+
"""Optional metadata for the node. """
|
|
113
105
|
|
|
114
106
|
def copy(
|
|
115
107
|
self,
|
|
116
108
|
*,
|
|
117
|
-
id:
|
|
118
|
-
name:
|
|
109
|
+
id: str | None = None,
|
|
110
|
+
name: str | None = None,
|
|
119
111
|
) -> Node:
|
|
120
112
|
"""Return a copy of the node with optional new id and name.
|
|
121
113
|
|
|
122
114
|
Args:
|
|
123
|
-
id: The new node id.
|
|
124
|
-
name: The new node name.
|
|
115
|
+
id: The new node id.
|
|
116
|
+
name: The new node name.
|
|
125
117
|
|
|
126
118
|
Returns:
|
|
127
119
|
A copy of the node with the new id and name.
|
|
@@ -135,16 +127,12 @@ class Node(NamedTuple):
|
|
|
135
127
|
|
|
136
128
|
|
|
137
129
|
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
|
-
"""
|
|
130
|
+
"""Branch in a graph."""
|
|
145
131
|
|
|
146
132
|
condition: Callable[..., str]
|
|
147
|
-
|
|
133
|
+
"""A callable that returns a string representation of the condition."""
|
|
134
|
+
ends: dict[str, str] | None
|
|
135
|
+
"""Optional dictionary of end node ids for the branches. """
|
|
148
136
|
|
|
149
137
|
|
|
150
138
|
class CurveStyle(Enum):
|
|
@@ -168,10 +156,10 @@ class CurveStyle(Enum):
|
|
|
168
156
|
class NodeStyles:
|
|
169
157
|
"""Schema for Hexadecimal color codes for different node types.
|
|
170
158
|
|
|
171
|
-
|
|
172
|
-
default: The default color code.
|
|
173
|
-
first: The color code for the first node.
|
|
174
|
-
last: The color code for the last node.
|
|
159
|
+
Args:
|
|
160
|
+
default: The default color code.
|
|
161
|
+
first: The color code for the first node.
|
|
162
|
+
last: The color code for the last node.
|
|
175
163
|
"""
|
|
176
164
|
|
|
177
165
|
default: str = "fill:#f2f0ff,line-height:1.2"
|
|
@@ -182,13 +170,15 @@ class NodeStyles:
|
|
|
182
170
|
class MermaidDrawMethod(Enum):
|
|
183
171
|
"""Enum for different draw methods supported by Mermaid."""
|
|
184
172
|
|
|
185
|
-
PYPPETEER = "pyppeteer"
|
|
186
|
-
|
|
173
|
+
PYPPETEER = "pyppeteer"
|
|
174
|
+
"""Uses Pyppeteer to render the graph"""
|
|
175
|
+
API = "api"
|
|
176
|
+
"""Uses Mermaid.INK API to render the graph"""
|
|
187
177
|
|
|
188
178
|
|
|
189
179
|
def node_data_str(
|
|
190
180
|
id: str,
|
|
191
|
-
data:
|
|
181
|
+
data: type[BaseModel] | RunnableType | None,
|
|
192
182
|
) -> str:
|
|
193
183
|
"""Convert the data of a node to a string.
|
|
194
184
|
|
|
@@ -199,8 +189,6 @@ def node_data_str(
|
|
|
199
189
|
Returns:
|
|
200
190
|
A string representation of the data.
|
|
201
191
|
"""
|
|
202
|
-
from langchain_core.runnables.base import Runnable
|
|
203
|
-
|
|
204
192
|
if not is_uuid(id) or data is None:
|
|
205
193
|
return id
|
|
206
194
|
data_str = data.get_name() if isinstance(data, Runnable) else data.__name__
|
|
@@ -209,20 +197,17 @@ def node_data_str(
|
|
|
209
197
|
|
|
210
198
|
def node_data_json(
|
|
211
199
|
node: Node, *, with_schemas: bool = False
|
|
212
|
-
) -> dict[str,
|
|
200
|
+
) -> dict[str, str | dict[str, Any]]:
|
|
213
201
|
"""Convert the data of a node to a JSON-serializable format.
|
|
214
202
|
|
|
215
203
|
Args:
|
|
216
|
-
node: The
|
|
217
|
-
with_schemas: Whether to include the schema of the data if
|
|
218
|
-
|
|
204
|
+
node: The `Node` to convert.
|
|
205
|
+
with_schemas: Whether to include the schema of the data if it is a Pydantic
|
|
206
|
+
model.
|
|
219
207
|
|
|
220
208
|
Returns:
|
|
221
209
|
A dictionary with the type of the data and the data itself.
|
|
222
210
|
"""
|
|
223
|
-
from langchain_core.load.serializable import to_json_not_implemented
|
|
224
|
-
from langchain_core.runnables.base import Runnable, RunnableSerializable
|
|
225
|
-
|
|
226
211
|
if node.data is None:
|
|
227
212
|
json: dict[str, Any] = {}
|
|
228
213
|
elif isinstance(node.data, RunnableSerializable):
|
|
@@ -269,7 +254,7 @@ def node_data_json(
|
|
|
269
254
|
class Graph:
|
|
270
255
|
"""Graph of nodes and edges.
|
|
271
256
|
|
|
272
|
-
|
|
257
|
+
Args:
|
|
273
258
|
nodes: Dictionary of nodes in the graph. Defaults to an empty dictionary.
|
|
274
259
|
edges: List of edges in the graph. Defaults to an empty list.
|
|
275
260
|
"""
|
|
@@ -282,7 +267,7 @@ class Graph:
|
|
|
282
267
|
|
|
283
268
|
Args:
|
|
284
269
|
with_schemas: Whether to include the schemas of the nodes if they are
|
|
285
|
-
Pydantic models.
|
|
270
|
+
Pydantic models.
|
|
286
271
|
|
|
287
272
|
Returns:
|
|
288
273
|
A dictionary with the nodes and edges of the graph.
|
|
@@ -327,17 +312,17 @@ class Graph:
|
|
|
327
312
|
|
|
328
313
|
def add_node(
|
|
329
314
|
self,
|
|
330
|
-
data:
|
|
331
|
-
id:
|
|
315
|
+
data: type[BaseModel] | RunnableType | None,
|
|
316
|
+
id: str | None = None,
|
|
332
317
|
*,
|
|
333
|
-
metadata:
|
|
318
|
+
metadata: dict[str, Any] | None = None,
|
|
334
319
|
) -> Node:
|
|
335
320
|
"""Add a node to the graph and return it.
|
|
336
321
|
|
|
337
322
|
Args:
|
|
338
323
|
data: The data of the node.
|
|
339
|
-
id: The id of the node.
|
|
340
|
-
metadata: Optional metadata for the node.
|
|
324
|
+
id: The id of the node.
|
|
325
|
+
metadata: Optional metadata for the node.
|
|
341
326
|
|
|
342
327
|
Returns:
|
|
343
328
|
The node that was added to the graph.
|
|
@@ -368,7 +353,7 @@ class Graph:
|
|
|
368
353
|
self,
|
|
369
354
|
source: Node,
|
|
370
355
|
target: Node,
|
|
371
|
-
data:
|
|
356
|
+
data: Stringifiable | None = None,
|
|
372
357
|
conditional: bool = False, # noqa: FBT001,FBT002
|
|
373
358
|
) -> Edge:
|
|
374
359
|
"""Add an edge to the graph and return it.
|
|
@@ -376,8 +361,8 @@ class Graph:
|
|
|
376
361
|
Args:
|
|
377
362
|
source: The source node of the edge.
|
|
378
363
|
target: The target node of the edge.
|
|
379
|
-
data: Optional data associated with the edge.
|
|
380
|
-
conditional: Whether the edge is conditional.
|
|
364
|
+
data: Optional data associated with the edge.
|
|
365
|
+
conditional: Whether the edge is conditional.
|
|
381
366
|
|
|
382
367
|
Returns:
|
|
383
368
|
The edge that was added to the graph.
|
|
@@ -399,14 +384,14 @@ class Graph:
|
|
|
399
384
|
|
|
400
385
|
def extend(
|
|
401
386
|
self, graph: Graph, *, prefix: str = ""
|
|
402
|
-
) -> tuple[
|
|
387
|
+
) -> tuple[Node | None, Node | None]:
|
|
403
388
|
"""Add all nodes and edges from another graph.
|
|
404
389
|
|
|
405
390
|
Note this doesn't check for duplicates, nor does it connect the graphs.
|
|
406
391
|
|
|
407
392
|
Args:
|
|
408
393
|
graph: The graph to add.
|
|
409
|
-
prefix: The prefix to add to the node ids.
|
|
394
|
+
prefix: The prefix to add to the node ids.
|
|
410
395
|
|
|
411
396
|
Returns:
|
|
412
397
|
A tuple of the first and last nodes of the subgraph.
|
|
@@ -470,19 +455,27 @@ class Graph:
|
|
|
470
455
|
],
|
|
471
456
|
)
|
|
472
457
|
|
|
473
|
-
def first_node(self) ->
|
|
458
|
+
def first_node(self) -> Node | None:
|
|
474
459
|
"""Find the single node that is not a target of any edge.
|
|
475
460
|
|
|
476
|
-
If there is no such node, or there are multiple, return None
|
|
461
|
+
If there is no such node, or there are multiple, return `None`.
|
|
477
462
|
When drawing the graph, this node would be the origin.
|
|
463
|
+
|
|
464
|
+
Returns:
|
|
465
|
+
The first node, or None if there is no such node or multiple
|
|
466
|
+
candidates.
|
|
478
467
|
"""
|
|
479
468
|
return _first_node(self)
|
|
480
469
|
|
|
481
|
-
def last_node(self) ->
|
|
470
|
+
def last_node(self) -> Node | None:
|
|
482
471
|
"""Find the single node that is not a source of any edge.
|
|
483
472
|
|
|
484
|
-
If there is no such node, or there are multiple, return None
|
|
473
|
+
If there is no such node, or there are multiple, return `None`.
|
|
485
474
|
When drawing the graph, this node would be the destination.
|
|
475
|
+
|
|
476
|
+
Returns:
|
|
477
|
+
The last node, or None if there is no such node or multiple
|
|
478
|
+
candidates.
|
|
486
479
|
"""
|
|
487
480
|
return _last_node(self)
|
|
488
481
|
|
|
@@ -513,8 +506,13 @@ class Graph:
|
|
|
513
506
|
self.remove_node(last_node)
|
|
514
507
|
|
|
515
508
|
def draw_ascii(self) -> str:
|
|
516
|
-
"""Draw the graph as an ASCII art string.
|
|
517
|
-
|
|
509
|
+
"""Draw the graph as an ASCII art string.
|
|
510
|
+
|
|
511
|
+
Returns:
|
|
512
|
+
The ASCII art string.
|
|
513
|
+
"""
|
|
514
|
+
# Import locally to prevent circular import
|
|
515
|
+
from langchain_core.runnables.graph_ascii import draw_ascii # noqa: PLC0415
|
|
518
516
|
|
|
519
517
|
return draw_ascii(
|
|
520
518
|
{node.id: node.name for node in self.nodes.values()},
|
|
@@ -529,36 +527,38 @@ class Graph:
|
|
|
529
527
|
def draw_png(
|
|
530
528
|
self,
|
|
531
529
|
output_file_path: str,
|
|
532
|
-
fontname:
|
|
533
|
-
labels:
|
|
530
|
+
fontname: str | None = None,
|
|
531
|
+
labels: LabelsDict | None = None,
|
|
534
532
|
) -> None: ...
|
|
535
533
|
|
|
536
534
|
@overload
|
|
537
535
|
def draw_png(
|
|
538
536
|
self,
|
|
539
537
|
output_file_path: None,
|
|
540
|
-
fontname:
|
|
541
|
-
labels:
|
|
538
|
+
fontname: str | None = None,
|
|
539
|
+
labels: LabelsDict | None = None,
|
|
542
540
|
) -> bytes: ...
|
|
543
541
|
|
|
544
542
|
def draw_png(
|
|
545
543
|
self,
|
|
546
|
-
output_file_path:
|
|
547
|
-
fontname:
|
|
548
|
-
labels:
|
|
549
|
-
) ->
|
|
544
|
+
output_file_path: str | None = None,
|
|
545
|
+
fontname: str | None = None,
|
|
546
|
+
labels: LabelsDict | None = None,
|
|
547
|
+
) -> bytes | None:
|
|
550
548
|
"""Draw the graph as a PNG image.
|
|
551
549
|
|
|
552
550
|
Args:
|
|
553
|
-
output_file_path: The path to save the image to. If None
|
|
554
|
-
is not saved.
|
|
555
|
-
fontname: The name of the font to use.
|
|
556
|
-
labels: Optional labels for nodes and edges in the graph. Defaults to
|
|
551
|
+
output_file_path: The path to save the image to. If `None`, the image
|
|
552
|
+
is not saved.
|
|
553
|
+
fontname: The name of the font to use.
|
|
554
|
+
labels: Optional labels for nodes and edges in the graph. Defaults to
|
|
555
|
+
`None`.
|
|
557
556
|
|
|
558
557
|
Returns:
|
|
559
558
|
The PNG image as bytes if output_file_path is None, None otherwise.
|
|
560
559
|
"""
|
|
561
|
-
|
|
560
|
+
# Import locally to prevent circular import
|
|
561
|
+
from langchain_core.runnables.graph_png import PngDrawer # noqa: PLC0415
|
|
562
562
|
|
|
563
563
|
default_node_labels = {node.id: node.name for node in self.nodes.values()}
|
|
564
564
|
|
|
@@ -578,42 +578,39 @@ class Graph:
|
|
|
578
578
|
*,
|
|
579
579
|
with_styles: bool = True,
|
|
580
580
|
curve_style: CurveStyle = CurveStyle.LINEAR,
|
|
581
|
-
node_colors:
|
|
581
|
+
node_colors: NodeStyles | None = None,
|
|
582
582
|
wrap_label_n_words: int = 9,
|
|
583
|
-
frontmatter_config:
|
|
583
|
+
frontmatter_config: dict[str, Any] | None = None,
|
|
584
584
|
) -> str:
|
|
585
585
|
"""Draw the graph as a Mermaid syntax string.
|
|
586
586
|
|
|
587
587
|
Args:
|
|
588
|
-
with_styles: Whether to include styles in the syntax.
|
|
589
|
-
curve_style: The style of the edges.
|
|
590
|
-
node_colors: The colors of the nodes.
|
|
588
|
+
with_styles: Whether to include styles in the syntax.
|
|
589
|
+
curve_style: The style of the edges.
|
|
590
|
+
node_colors: The colors of the nodes.
|
|
591
591
|
wrap_label_n_words: The number of words to wrap the node labels at.
|
|
592
|
-
|
|
593
|
-
frontmatter_config (dict[str, Any], optional): Mermaid frontmatter config.
|
|
592
|
+
frontmatter_config: Mermaid frontmatter config.
|
|
594
593
|
Can be used to customize theme and styles. Will be converted to YAML and
|
|
595
|
-
added to the beginning of the mermaid graph.
|
|
594
|
+
added to the beginning of the mermaid graph.
|
|
596
595
|
|
|
597
596
|
See more here: https://mermaid.js.org/config/configuration.html.
|
|
598
597
|
|
|
599
598
|
Example config:
|
|
600
599
|
|
|
601
|
-
|
|
602
|
-
|
|
600
|
+
```python
|
|
603
601
|
{
|
|
604
602
|
"config": {
|
|
605
603
|
"theme": "neutral",
|
|
606
604
|
"look": "handDrawn",
|
|
607
|
-
"themeVariables": {
|
|
605
|
+
"themeVariables": {"primaryColor": "#e2e2e2"},
|
|
608
606
|
}
|
|
609
607
|
}
|
|
610
|
-
|
|
611
|
-
|
|
608
|
+
```
|
|
612
609
|
Returns:
|
|
613
610
|
The Mermaid syntax string.
|
|
614
|
-
|
|
615
611
|
"""
|
|
616
|
-
|
|
612
|
+
# Import locally to prevent circular import
|
|
613
|
+
from langchain_core.runnables.graph_mermaid import draw_mermaid # noqa: PLC0415
|
|
617
614
|
|
|
618
615
|
graph = self.reid()
|
|
619
616
|
first_node = graph.first_node()
|
|
@@ -635,56 +632,58 @@ class Graph:
|
|
|
635
632
|
self,
|
|
636
633
|
*,
|
|
637
634
|
curve_style: CurveStyle = CurveStyle.LINEAR,
|
|
638
|
-
node_colors:
|
|
635
|
+
node_colors: NodeStyles | None = None,
|
|
639
636
|
wrap_label_n_words: int = 9,
|
|
640
|
-
output_file_path:
|
|
637
|
+
output_file_path: str | None = None,
|
|
641
638
|
draw_method: MermaidDrawMethod = MermaidDrawMethod.API,
|
|
642
639
|
background_color: str = "white",
|
|
643
640
|
padding: int = 10,
|
|
644
641
|
max_retries: int = 1,
|
|
645
642
|
retry_delay: float = 1.0,
|
|
646
|
-
frontmatter_config:
|
|
643
|
+
frontmatter_config: dict[str, Any] | None = None,
|
|
644
|
+
base_url: str | None = None,
|
|
647
645
|
) -> bytes:
|
|
648
646
|
"""Draw the graph as a PNG image using Mermaid.
|
|
649
647
|
|
|
650
648
|
Args:
|
|
651
|
-
curve_style: The style of the edges.
|
|
652
|
-
node_colors: The colors of the nodes.
|
|
649
|
+
curve_style: The style of the edges.
|
|
650
|
+
node_colors: The colors of the nodes.
|
|
653
651
|
wrap_label_n_words: The number of words to wrap the node labels at.
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
is not saved. Defaults to None.
|
|
652
|
+
output_file_path: The path to save the image to. If `None`, the image
|
|
653
|
+
is not saved.
|
|
657
654
|
draw_method: The method to use to draw the graph.
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
retry_delay: The delay between retries (MermaidDrawMethod.API).
|
|
664
|
-
Defaults to 1.0.
|
|
665
|
-
frontmatter_config (dict[str, Any], optional): Mermaid frontmatter config.
|
|
655
|
+
background_color: The color of the background.
|
|
656
|
+
padding: The padding around the graph.
|
|
657
|
+
max_retries: The maximum number of retries (`MermaidDrawMethod.API`).
|
|
658
|
+
retry_delay: The delay between retries (`MermaidDrawMethod.API`).
|
|
659
|
+
frontmatter_config: Mermaid frontmatter config.
|
|
666
660
|
Can be used to customize theme and styles. Will be converted to YAML and
|
|
667
|
-
added to the beginning of the mermaid graph.
|
|
661
|
+
added to the beginning of the mermaid graph.
|
|
668
662
|
|
|
669
663
|
See more here: https://mermaid.js.org/config/configuration.html.
|
|
670
664
|
|
|
671
665
|
Example config:
|
|
672
666
|
|
|
673
|
-
|
|
674
|
-
|
|
667
|
+
```python
|
|
675
668
|
{
|
|
676
669
|
"config": {
|
|
677
670
|
"theme": "neutral",
|
|
678
671
|
"look": "handDrawn",
|
|
679
|
-
"themeVariables": {
|
|
672
|
+
"themeVariables": {"primaryColor": "#e2e2e2"},
|
|
680
673
|
}
|
|
681
674
|
}
|
|
675
|
+
```
|
|
676
|
+
base_url: The base URL of the Mermaid server for rendering via API.
|
|
677
|
+
|
|
682
678
|
|
|
683
679
|
Returns:
|
|
684
680
|
The PNG image as bytes.
|
|
685
681
|
|
|
686
682
|
"""
|
|
687
|
-
|
|
683
|
+
# Import locally to prevent circular import
|
|
684
|
+
from langchain_core.runnables.graph_mermaid import ( # noqa: PLC0415
|
|
685
|
+
draw_mermaid_png,
|
|
686
|
+
)
|
|
688
687
|
|
|
689
688
|
mermaid_syntax = self.draw_mermaid(
|
|
690
689
|
curve_style=curve_style,
|
|
@@ -700,14 +699,15 @@ class Graph:
|
|
|
700
699
|
padding=padding,
|
|
701
700
|
max_retries=max_retries,
|
|
702
701
|
retry_delay=retry_delay,
|
|
702
|
+
base_url=base_url,
|
|
703
703
|
)
|
|
704
704
|
|
|
705
705
|
|
|
706
|
-
def _first_node(graph: Graph, exclude: Sequence[str] = ()) ->
|
|
706
|
+
def _first_node(graph: Graph, exclude: Sequence[str] = ()) -> Node | None:
|
|
707
707
|
"""Find the single node that is not a target of any edge.
|
|
708
708
|
|
|
709
709
|
Exclude nodes/sources with ids in the exclude list.
|
|
710
|
-
If there is no such node, or there are multiple, return None
|
|
710
|
+
If there is no such node, or there are multiple, return `None`.
|
|
711
711
|
When drawing the graph, this node would be the origin.
|
|
712
712
|
"""
|
|
713
713
|
targets = {edge.target for edge in graph.edges if edge.source not in exclude}
|
|
@@ -719,11 +719,11 @@ def _first_node(graph: Graph, exclude: Sequence[str] = ()) -> Optional[Node]:
|
|
|
719
719
|
return found[0] if len(found) == 1 else None
|
|
720
720
|
|
|
721
721
|
|
|
722
|
-
def _last_node(graph: Graph, exclude: Sequence[str] = ()) ->
|
|
722
|
+
def _last_node(graph: Graph, exclude: Sequence[str] = ()) -> Node | None:
|
|
723
723
|
"""Find the single node that is not a source of any edge.
|
|
724
724
|
|
|
725
725
|
Exclude nodes/targets with ids in the exclude list.
|
|
726
|
-
If there is no such node, or there are multiple, return None
|
|
726
|
+
If there is no such node, or there are multiple, return `None`.
|
|
727
727
|
When drawing the graph, this node would be the destination.
|
|
728
728
|
"""
|
|
729
729
|
sources = {edge.source for edge in graph.edges if edge.target not in exclude}
|