langchain-core 1.0.0a5__py3-none-any.whl → 1.0.3__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.
- langchain_core/__init__.py +1 -1
- langchain_core/_api/__init__.py +3 -4
- langchain_core/_api/beta_decorator.py +23 -26
- langchain_core/_api/deprecation.py +51 -64
- langchain_core/_api/path.py +3 -6
- langchain_core/_import_utils.py +3 -4
- langchain_core/agents.py +20 -22
- langchain_core/caches.py +65 -66
- langchain_core/callbacks/__init__.py +1 -8
- langchain_core/callbacks/base.py +321 -336
- langchain_core/callbacks/file.py +44 -44
- langchain_core/callbacks/manager.py +436 -513
- langchain_core/callbacks/stdout.py +29 -30
- langchain_core/callbacks/streaming_stdout.py +32 -32
- langchain_core/callbacks/usage.py +60 -57
- langchain_core/chat_history.py +53 -68
- langchain_core/document_loaders/base.py +27 -25
- langchain_core/document_loaders/blob_loaders.py +1 -1
- langchain_core/document_loaders/langsmith.py +44 -48
- langchain_core/documents/__init__.py +23 -3
- langchain_core/documents/base.py +98 -90
- langchain_core/documents/compressor.py +10 -10
- langchain_core/documents/transformers.py +34 -35
- langchain_core/embeddings/fake.py +50 -54
- langchain_core/example_selectors/length_based.py +1 -1
- langchain_core/example_selectors/semantic_similarity.py +28 -32
- langchain_core/exceptions.py +21 -20
- langchain_core/globals.py +3 -151
- langchain_core/indexing/__init__.py +1 -1
- langchain_core/indexing/api.py +121 -126
- langchain_core/indexing/base.py +73 -75
- langchain_core/indexing/in_memory.py +4 -6
- langchain_core/language_models/__init__.py +14 -29
- langchain_core/language_models/_utils.py +58 -61
- langchain_core/language_models/base.py +53 -162
- langchain_core/language_models/chat_models.py +298 -387
- langchain_core/language_models/fake.py +11 -11
- langchain_core/language_models/fake_chat_models.py +42 -36
- langchain_core/language_models/llms.py +125 -235
- langchain_core/load/dump.py +9 -12
- langchain_core/load/load.py +18 -28
- langchain_core/load/mapping.py +2 -4
- langchain_core/load/serializable.py +42 -40
- langchain_core/messages/__init__.py +10 -16
- langchain_core/messages/ai.py +148 -148
- langchain_core/messages/base.py +58 -52
- langchain_core/messages/block_translators/__init__.py +27 -17
- langchain_core/messages/block_translators/anthropic.py +6 -6
- langchain_core/messages/block_translators/bedrock_converse.py +5 -5
- langchain_core/messages/block_translators/google_genai.py +505 -20
- langchain_core/messages/block_translators/google_vertexai.py +4 -32
- langchain_core/messages/block_translators/groq.py +117 -21
- langchain_core/messages/block_translators/langchain_v0.py +5 -5
- langchain_core/messages/block_translators/openai.py +11 -11
- langchain_core/messages/chat.py +2 -6
- langchain_core/messages/content.py +337 -328
- langchain_core/messages/function.py +6 -10
- langchain_core/messages/human.py +24 -31
- langchain_core/messages/modifier.py +2 -2
- langchain_core/messages/system.py +19 -29
- langchain_core/messages/tool.py +74 -90
- langchain_core/messages/utils.py +474 -504
- langchain_core/output_parsers/__init__.py +13 -10
- langchain_core/output_parsers/base.py +61 -61
- langchain_core/output_parsers/format_instructions.py +9 -4
- langchain_core/output_parsers/json.py +12 -10
- langchain_core/output_parsers/list.py +21 -23
- langchain_core/output_parsers/openai_functions.py +49 -47
- langchain_core/output_parsers/openai_tools.py +16 -21
- langchain_core/output_parsers/pydantic.py +13 -14
- langchain_core/output_parsers/string.py +5 -5
- langchain_core/output_parsers/transform.py +15 -17
- langchain_core/output_parsers/xml.py +35 -34
- langchain_core/outputs/__init__.py +1 -1
- langchain_core/outputs/chat_generation.py +18 -18
- langchain_core/outputs/chat_result.py +1 -3
- langchain_core/outputs/generation.py +10 -11
- langchain_core/outputs/llm_result.py +10 -10
- langchain_core/prompt_values.py +11 -17
- langchain_core/prompts/__init__.py +3 -27
- langchain_core/prompts/base.py +48 -56
- langchain_core/prompts/chat.py +275 -325
- langchain_core/prompts/dict.py +5 -5
- langchain_core/prompts/few_shot.py +81 -88
- langchain_core/prompts/few_shot_with_templates.py +11 -13
- langchain_core/prompts/image.py +12 -14
- langchain_core/prompts/loading.py +4 -6
- langchain_core/prompts/message.py +3 -3
- langchain_core/prompts/prompt.py +24 -39
- langchain_core/prompts/string.py +26 -10
- langchain_core/prompts/structured.py +49 -53
- langchain_core/rate_limiters.py +51 -60
- langchain_core/retrievers.py +61 -198
- langchain_core/runnables/base.py +1478 -1630
- langchain_core/runnables/branch.py +53 -57
- langchain_core/runnables/config.py +72 -89
- langchain_core/runnables/configurable.py +120 -137
- langchain_core/runnables/fallbacks.py +83 -79
- langchain_core/runnables/graph.py +91 -97
- langchain_core/runnables/graph_ascii.py +27 -28
- langchain_core/runnables/graph_mermaid.py +38 -50
- langchain_core/runnables/graph_png.py +15 -16
- langchain_core/runnables/history.py +135 -148
- langchain_core/runnables/passthrough.py +124 -150
- langchain_core/runnables/retry.py +46 -51
- langchain_core/runnables/router.py +25 -30
- langchain_core/runnables/schema.py +75 -80
- langchain_core/runnables/utils.py +60 -67
- langchain_core/stores.py +85 -121
- langchain_core/structured_query.py +8 -8
- langchain_core/sys_info.py +27 -29
- langchain_core/tools/__init__.py +1 -14
- langchain_core/tools/base.py +285 -229
- langchain_core/tools/convert.py +160 -155
- langchain_core/tools/render.py +10 -10
- langchain_core/tools/retriever.py +12 -11
- langchain_core/tools/simple.py +19 -24
- langchain_core/tools/structured.py +32 -39
- langchain_core/tracers/__init__.py +1 -9
- langchain_core/tracers/base.py +97 -99
- langchain_core/tracers/context.py +29 -52
- langchain_core/tracers/core.py +49 -53
- langchain_core/tracers/evaluation.py +11 -11
- langchain_core/tracers/event_stream.py +65 -64
- langchain_core/tracers/langchain.py +21 -21
- langchain_core/tracers/log_stream.py +45 -45
- langchain_core/tracers/memory_stream.py +3 -3
- langchain_core/tracers/root_listeners.py +16 -16
- langchain_core/tracers/run_collector.py +2 -4
- langchain_core/tracers/schemas.py +0 -129
- langchain_core/tracers/stdout.py +3 -3
- langchain_core/utils/__init__.py +1 -4
- langchain_core/utils/_merge.py +2 -2
- langchain_core/utils/aiter.py +57 -61
- langchain_core/utils/env.py +9 -9
- langchain_core/utils/function_calling.py +89 -186
- langchain_core/utils/html.py +7 -8
- langchain_core/utils/input.py +6 -6
- langchain_core/utils/interactive_env.py +1 -1
- langchain_core/utils/iter.py +36 -40
- langchain_core/utils/json.py +4 -3
- langchain_core/utils/json_schema.py +9 -9
- langchain_core/utils/mustache.py +8 -10
- langchain_core/utils/pydantic.py +33 -35
- langchain_core/utils/strings.py +6 -9
- langchain_core/utils/usage.py +1 -1
- langchain_core/utils/utils.py +66 -62
- langchain_core/vectorstores/base.py +182 -216
- langchain_core/vectorstores/in_memory.py +101 -176
- langchain_core/vectorstores/utils.py +5 -5
- langchain_core/version.py +1 -1
- langchain_core-1.0.3.dist-info/METADATA +69 -0
- langchain_core-1.0.3.dist-info/RECORD +172 -0
- {langchain_core-1.0.0a5.dist-info → langchain_core-1.0.3.dist-info}/WHEEL +1 -1
- langchain_core/memory.py +0 -120
- langchain_core/messages/block_translators/ollama.py +0 -47
- langchain_core/prompts/pipeline.py +0 -138
- 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 -31
- langchain_core/utils/loading.py +0 -35
- langchain_core-1.0.0a5.dist-info/METADATA +0 -77
- langchain_core-1.0.0a5.dist-info/RECORD +0 -181
- langchain_core-1.0.0a5.dist-info/entry_points.txt +0 -4
|
@@ -4,17 +4,15 @@ 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
|
|
@@ -54,7 +52,7 @@ def is_uuid(value: str) -> bool:
|
|
|
54
52
|
value: The string to check.
|
|
55
53
|
|
|
56
54
|
Returns:
|
|
57
|
-
True if the string is a valid UUID, False otherwise.
|
|
55
|
+
`True` if the string is a valid UUID, `False` otherwise.
|
|
58
56
|
"""
|
|
59
57
|
try:
|
|
60
58
|
UUID(value)
|
|
@@ -70,19 +68,17 @@ class Edge(NamedTuple):
|
|
|
70
68
|
"""The source node id."""
|
|
71
69
|
target: str
|
|
72
70
|
"""The target node id."""
|
|
73
|
-
data:
|
|
74
|
-
"""Optional data associated with the edge.
|
|
71
|
+
data: Stringifiable | None = None
|
|
72
|
+
"""Optional data associated with the edge. """
|
|
75
73
|
conditional: bool = False
|
|
76
|
-
"""Whether the edge is conditional.
|
|
74
|
+
"""Whether the edge is conditional."""
|
|
77
75
|
|
|
78
|
-
def copy(
|
|
79
|
-
self, *, source: Optional[str] = None, target: Optional[str] = None
|
|
80
|
-
) -> Edge:
|
|
76
|
+
def copy(self, *, source: str | None = None, target: str | None = None) -> Edge:
|
|
81
77
|
"""Return a copy of the edge with optional new source and target nodes.
|
|
82
78
|
|
|
83
79
|
Args:
|
|
84
|
-
source: The new source node id.
|
|
85
|
-
target: The new target node id.
|
|
80
|
+
source: The new source node id.
|
|
81
|
+
target: The new target node id.
|
|
86
82
|
|
|
87
83
|
Returns:
|
|
88
84
|
A copy of the edge with the new source and target nodes.
|
|
@@ -102,22 +98,22 @@ class Node(NamedTuple):
|
|
|
102
98
|
"""The unique identifier of the node."""
|
|
103
99
|
name: str
|
|
104
100
|
"""The name of the node."""
|
|
105
|
-
data:
|
|
101
|
+
data: type[BaseModel] | RunnableType | None
|
|
106
102
|
"""The data of the node."""
|
|
107
|
-
metadata:
|
|
108
|
-
"""Optional metadata for the node.
|
|
103
|
+
metadata: dict[str, Any] | None
|
|
104
|
+
"""Optional metadata for the node. """
|
|
109
105
|
|
|
110
106
|
def copy(
|
|
111
107
|
self,
|
|
112
108
|
*,
|
|
113
|
-
id:
|
|
114
|
-
name:
|
|
109
|
+
id: str | None = None,
|
|
110
|
+
name: str | None = None,
|
|
115
111
|
) -> Node:
|
|
116
112
|
"""Return a copy of the node with optional new id and name.
|
|
117
113
|
|
|
118
114
|
Args:
|
|
119
|
-
id: The new node id.
|
|
120
|
-
name: The new node name.
|
|
115
|
+
id: The new node id.
|
|
116
|
+
name: The new node name.
|
|
121
117
|
|
|
122
118
|
Returns:
|
|
123
119
|
A copy of the node with the new id and name.
|
|
@@ -135,8 +131,8 @@ class Branch(NamedTuple):
|
|
|
135
131
|
|
|
136
132
|
condition: Callable[..., str]
|
|
137
133
|
"""A callable that returns a string representation of the condition."""
|
|
138
|
-
ends:
|
|
139
|
-
"""Optional dictionary of end node
|
|
134
|
+
ends: dict[str, str] | None
|
|
135
|
+
"""Optional dictionary of end node IDs for the branches. """
|
|
140
136
|
|
|
141
137
|
|
|
142
138
|
class CurveStyle(Enum):
|
|
@@ -161,9 +157,9 @@ class NodeStyles:
|
|
|
161
157
|
"""Schema for Hexadecimal color codes for different node types.
|
|
162
158
|
|
|
163
159
|
Args:
|
|
164
|
-
default: The default color code.
|
|
165
|
-
first: The color code for the first node.
|
|
166
|
-
last: The color code for the last node.
|
|
160
|
+
default: The default color code.
|
|
161
|
+
first: The color code for the first node.
|
|
162
|
+
last: The color code for the last node.
|
|
167
163
|
"""
|
|
168
164
|
|
|
169
165
|
default: str = "fill:#f2f0ff,line-height:1.2"
|
|
@@ -182,7 +178,7 @@ class MermaidDrawMethod(Enum):
|
|
|
182
178
|
|
|
183
179
|
def node_data_str(
|
|
184
180
|
id: str,
|
|
185
|
-
data:
|
|
181
|
+
data: type[BaseModel] | RunnableType | None,
|
|
186
182
|
) -> str:
|
|
187
183
|
"""Convert the data of a node to a string.
|
|
188
184
|
|
|
@@ -201,13 +197,13 @@ def node_data_str(
|
|
|
201
197
|
|
|
202
198
|
def node_data_json(
|
|
203
199
|
node: Node, *, with_schemas: bool = False
|
|
204
|
-
) -> dict[str,
|
|
200
|
+
) -> dict[str, str | dict[str, Any]]:
|
|
205
201
|
"""Convert the data of a node to a JSON-serializable format.
|
|
206
202
|
|
|
207
203
|
Args:
|
|
208
|
-
node: The
|
|
209
|
-
with_schemas: Whether to include the schema of the data if
|
|
210
|
-
|
|
204
|
+
node: The `Node` to convert.
|
|
205
|
+
with_schemas: Whether to include the schema of the data if it is a Pydantic
|
|
206
|
+
model.
|
|
211
207
|
|
|
212
208
|
Returns:
|
|
213
209
|
A dictionary with the type of the data and the data itself.
|
|
@@ -271,7 +267,7 @@ class Graph:
|
|
|
271
267
|
|
|
272
268
|
Args:
|
|
273
269
|
with_schemas: Whether to include the schemas of the nodes if they are
|
|
274
|
-
Pydantic models.
|
|
270
|
+
Pydantic models.
|
|
275
271
|
|
|
276
272
|
Returns:
|
|
277
273
|
A dictionary with the nodes and edges of the graph.
|
|
@@ -316,17 +312,17 @@ class Graph:
|
|
|
316
312
|
|
|
317
313
|
def add_node(
|
|
318
314
|
self,
|
|
319
|
-
data:
|
|
320
|
-
id:
|
|
315
|
+
data: type[BaseModel] | RunnableType | None,
|
|
316
|
+
id: str | None = None,
|
|
321
317
|
*,
|
|
322
|
-
metadata:
|
|
318
|
+
metadata: dict[str, Any] | None = None,
|
|
323
319
|
) -> Node:
|
|
324
320
|
"""Add a node to the graph and return it.
|
|
325
321
|
|
|
326
322
|
Args:
|
|
327
323
|
data: The data of the node.
|
|
328
|
-
id: The id of the node.
|
|
329
|
-
metadata: Optional metadata for the node.
|
|
324
|
+
id: The id of the node.
|
|
325
|
+
metadata: Optional metadata for the node.
|
|
330
326
|
|
|
331
327
|
Returns:
|
|
332
328
|
The node that was added to the graph.
|
|
@@ -357,7 +353,7 @@ class Graph:
|
|
|
357
353
|
self,
|
|
358
354
|
source: Node,
|
|
359
355
|
target: Node,
|
|
360
|
-
data:
|
|
356
|
+
data: Stringifiable | None = None,
|
|
361
357
|
conditional: bool = False, # noqa: FBT001,FBT002
|
|
362
358
|
) -> Edge:
|
|
363
359
|
"""Add an edge to the graph and return it.
|
|
@@ -365,8 +361,8 @@ class Graph:
|
|
|
365
361
|
Args:
|
|
366
362
|
source: The source node of the edge.
|
|
367
363
|
target: The target node of the edge.
|
|
368
|
-
data: Optional data associated with the edge.
|
|
369
|
-
conditional: Whether the edge is conditional.
|
|
364
|
+
data: Optional data associated with the edge.
|
|
365
|
+
conditional: Whether the edge is conditional.
|
|
370
366
|
|
|
371
367
|
Returns:
|
|
372
368
|
The edge that was added to the graph.
|
|
@@ -388,14 +384,14 @@ class Graph:
|
|
|
388
384
|
|
|
389
385
|
def extend(
|
|
390
386
|
self, graph: Graph, *, prefix: str = ""
|
|
391
|
-
) -> tuple[
|
|
387
|
+
) -> tuple[Node | None, Node | None]:
|
|
392
388
|
"""Add all nodes and edges from another graph.
|
|
393
389
|
|
|
394
390
|
Note this doesn't check for duplicates, nor does it connect the graphs.
|
|
395
391
|
|
|
396
392
|
Args:
|
|
397
393
|
graph: The graph to add.
|
|
398
|
-
prefix: The prefix to add to the node ids.
|
|
394
|
+
prefix: The prefix to add to the node ids.
|
|
399
395
|
|
|
400
396
|
Returns:
|
|
401
397
|
A tuple of the first and last nodes of the subgraph.
|
|
@@ -459,10 +455,10 @@ class Graph:
|
|
|
459
455
|
],
|
|
460
456
|
)
|
|
461
457
|
|
|
462
|
-
def first_node(self) ->
|
|
458
|
+
def first_node(self) -> Node | None:
|
|
463
459
|
"""Find the single node that is not a target of any edge.
|
|
464
460
|
|
|
465
|
-
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`.
|
|
466
462
|
When drawing the graph, this node would be the origin.
|
|
467
463
|
|
|
468
464
|
Returns:
|
|
@@ -471,10 +467,10 @@ class Graph:
|
|
|
471
467
|
"""
|
|
472
468
|
return _first_node(self)
|
|
473
469
|
|
|
474
|
-
def last_node(self) ->
|
|
470
|
+
def last_node(self) -> Node | None:
|
|
475
471
|
"""Find the single node that is not a source of any edge.
|
|
476
472
|
|
|
477
|
-
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`.
|
|
478
474
|
When drawing the graph, this node would be the destination.
|
|
479
475
|
|
|
480
476
|
Returns:
|
|
@@ -531,31 +527,32 @@ class Graph:
|
|
|
531
527
|
def draw_png(
|
|
532
528
|
self,
|
|
533
529
|
output_file_path: str,
|
|
534
|
-
fontname:
|
|
535
|
-
labels:
|
|
530
|
+
fontname: str | None = None,
|
|
531
|
+
labels: LabelsDict | None = None,
|
|
536
532
|
) -> None: ...
|
|
537
533
|
|
|
538
534
|
@overload
|
|
539
535
|
def draw_png(
|
|
540
536
|
self,
|
|
541
537
|
output_file_path: None,
|
|
542
|
-
fontname:
|
|
543
|
-
labels:
|
|
538
|
+
fontname: str | None = None,
|
|
539
|
+
labels: LabelsDict | None = None,
|
|
544
540
|
) -> bytes: ...
|
|
545
541
|
|
|
546
542
|
def draw_png(
|
|
547
543
|
self,
|
|
548
|
-
output_file_path:
|
|
549
|
-
fontname:
|
|
550
|
-
labels:
|
|
551
|
-
) ->
|
|
544
|
+
output_file_path: str | None = None,
|
|
545
|
+
fontname: str | None = None,
|
|
546
|
+
labels: LabelsDict | None = None,
|
|
547
|
+
) -> bytes | None:
|
|
552
548
|
"""Draw the graph as a PNG image.
|
|
553
549
|
|
|
554
550
|
Args:
|
|
555
|
-
output_file_path: The path to save the image to. If None
|
|
556
|
-
is not saved.
|
|
557
|
-
fontname: The name of the font to use.
|
|
558
|
-
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`.
|
|
559
556
|
|
|
560
557
|
Returns:
|
|
561
558
|
The PNG image as bytes if output_file_path is None, None otherwise.
|
|
@@ -581,37 +578,34 @@ class Graph:
|
|
|
581
578
|
*,
|
|
582
579
|
with_styles: bool = True,
|
|
583
580
|
curve_style: CurveStyle = CurveStyle.LINEAR,
|
|
584
|
-
node_colors:
|
|
581
|
+
node_colors: NodeStyles | None = None,
|
|
585
582
|
wrap_label_n_words: int = 9,
|
|
586
|
-
frontmatter_config:
|
|
583
|
+
frontmatter_config: dict[str, Any] | None = None,
|
|
587
584
|
) -> str:
|
|
588
585
|
"""Draw the graph as a Mermaid syntax string.
|
|
589
586
|
|
|
590
587
|
Args:
|
|
591
|
-
with_styles: Whether to include styles in the syntax.
|
|
592
|
-
curve_style: The style of the edges.
|
|
593
|
-
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.
|
|
594
591
|
wrap_label_n_words: The number of words to wrap the node labels at.
|
|
595
|
-
|
|
596
|
-
frontmatter_config (dict[str, Any], optional): Mermaid frontmatter config.
|
|
592
|
+
frontmatter_config: Mermaid frontmatter config.
|
|
597
593
|
Can be used to customize theme and styles. Will be converted to YAML and
|
|
598
|
-
added to the beginning of the mermaid graph.
|
|
594
|
+
added to the beginning of the mermaid graph.
|
|
599
595
|
|
|
600
596
|
See more here: https://mermaid.js.org/config/configuration.html.
|
|
601
597
|
|
|
602
598
|
Example config:
|
|
603
599
|
|
|
604
|
-
|
|
605
|
-
|
|
600
|
+
```python
|
|
606
601
|
{
|
|
607
602
|
"config": {
|
|
608
603
|
"theme": "neutral",
|
|
609
604
|
"look": "handDrawn",
|
|
610
|
-
"themeVariables": {
|
|
605
|
+
"themeVariables": {"primaryColor": "#e2e2e2"},
|
|
611
606
|
}
|
|
612
607
|
}
|
|
613
|
-
|
|
614
|
-
|
|
608
|
+
```
|
|
615
609
|
Returns:
|
|
616
610
|
The Mermaid syntax string.
|
|
617
611
|
"""
|
|
@@ -638,53 +632,49 @@ class Graph:
|
|
|
638
632
|
self,
|
|
639
633
|
*,
|
|
640
634
|
curve_style: CurveStyle = CurveStyle.LINEAR,
|
|
641
|
-
node_colors:
|
|
635
|
+
node_colors: NodeStyles | None = None,
|
|
642
636
|
wrap_label_n_words: int = 9,
|
|
643
|
-
output_file_path:
|
|
637
|
+
output_file_path: str | None = None,
|
|
644
638
|
draw_method: MermaidDrawMethod = MermaidDrawMethod.API,
|
|
645
639
|
background_color: str = "white",
|
|
646
640
|
padding: int = 10,
|
|
647
641
|
max_retries: int = 1,
|
|
648
642
|
retry_delay: float = 1.0,
|
|
649
|
-
frontmatter_config:
|
|
650
|
-
base_url:
|
|
643
|
+
frontmatter_config: dict[str, Any] | None = None,
|
|
644
|
+
base_url: str | None = None,
|
|
651
645
|
) -> bytes:
|
|
652
646
|
"""Draw the graph as a PNG image using Mermaid.
|
|
653
647
|
|
|
654
648
|
Args:
|
|
655
|
-
curve_style: The style of the edges.
|
|
656
|
-
node_colors: The colors of the nodes.
|
|
649
|
+
curve_style: The style of the edges.
|
|
650
|
+
node_colors: The colors of the nodes.
|
|
657
651
|
wrap_label_n_words: The number of words to wrap the node labels at.
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
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.
|
|
661
654
|
draw_method: The method to use to draw the graph.
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
retry_delay: The delay between retries (MermaidDrawMethod.API).
|
|
668
|
-
Defaults to 1.0.
|
|
669
|
-
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.
|
|
670
660
|
Can be used to customize theme and styles. Will be converted to YAML and
|
|
671
|
-
added to the beginning of the mermaid graph.
|
|
661
|
+
added to the beginning of the mermaid graph.
|
|
672
662
|
|
|
673
663
|
See more here: https://mermaid.js.org/config/configuration.html.
|
|
674
664
|
|
|
675
665
|
Example config:
|
|
676
666
|
|
|
677
|
-
|
|
678
|
-
|
|
667
|
+
```python
|
|
679
668
|
{
|
|
680
669
|
"config": {
|
|
681
670
|
"theme": "neutral",
|
|
682
671
|
"look": "handDrawn",
|
|
683
|
-
"themeVariables": {
|
|
672
|
+
"themeVariables": {"primaryColor": "#e2e2e2"},
|
|
684
673
|
}
|
|
685
674
|
}
|
|
675
|
+
```
|
|
686
676
|
base_url: The base URL of the Mermaid server for rendering via API.
|
|
687
|
-
|
|
677
|
+
|
|
688
678
|
|
|
689
679
|
Returns:
|
|
690
680
|
The PNG image as bytes.
|
|
@@ -713,11 +703,13 @@ class Graph:
|
|
|
713
703
|
)
|
|
714
704
|
|
|
715
705
|
|
|
716
|
-
def _first_node(graph: Graph, exclude: Sequence[str] = ()) ->
|
|
706
|
+
def _first_node(graph: Graph, exclude: Sequence[str] = ()) -> Node | None:
|
|
717
707
|
"""Find the single node that is not a target of any edge.
|
|
718
708
|
|
|
719
|
-
Exclude nodes/sources with
|
|
720
|
-
|
|
709
|
+
Exclude nodes/sources with IDs in the exclude list.
|
|
710
|
+
|
|
711
|
+
If there is no such node, or there are multiple, return `None`.
|
|
712
|
+
|
|
721
713
|
When drawing the graph, this node would be the origin.
|
|
722
714
|
"""
|
|
723
715
|
targets = {edge.target for edge in graph.edges if edge.source not in exclude}
|
|
@@ -729,11 +721,13 @@ def _first_node(graph: Graph, exclude: Sequence[str] = ()) -> Optional[Node]:
|
|
|
729
721
|
return found[0] if len(found) == 1 else None
|
|
730
722
|
|
|
731
723
|
|
|
732
|
-
def _last_node(graph: Graph, exclude: Sequence[str] = ()) ->
|
|
724
|
+
def _last_node(graph: Graph, exclude: Sequence[str] = ()) -> Node | None:
|
|
733
725
|
"""Find the single node that is not a source of any edge.
|
|
734
726
|
|
|
735
|
-
Exclude nodes/targets with
|
|
736
|
-
|
|
727
|
+
Exclude nodes/targets with IDs in the exclude list.
|
|
728
|
+
|
|
729
|
+
If there is no such node, or there are multiple, return `None`.
|
|
730
|
+
|
|
737
731
|
When drawing the graph, this node would be the destination.
|
|
738
732
|
"""
|
|
739
733
|
sources = {edge.source for edge in graph.edges if edge.target not in exclude}
|
|
@@ -62,8 +62,8 @@ class AsciiCanvas:
|
|
|
62
62
|
"""Create an ASCII canvas.
|
|
63
63
|
|
|
64
64
|
Args:
|
|
65
|
-
cols: number of columns in the canvas. Should be
|
|
66
|
-
lines: number of lines in the canvas. Should be
|
|
65
|
+
cols: number of columns in the canvas. Should be `> 1`.
|
|
66
|
+
lines: number of lines in the canvas. Should be `> 1`.
|
|
67
67
|
|
|
68
68
|
Raises:
|
|
69
69
|
ValueError: if canvas dimensions are invalid.
|
|
@@ -90,9 +90,9 @@ class AsciiCanvas:
|
|
|
90
90
|
"""Create a point on ASCII canvas.
|
|
91
91
|
|
|
92
92
|
Args:
|
|
93
|
-
x: x coordinate. Should be
|
|
93
|
+
x: x coordinate. Should be `>= 0` and `<` number of columns in
|
|
94
94
|
the canvas.
|
|
95
|
-
y: y coordinate. Should be
|
|
95
|
+
y: y coordinate. Should be `>= 0` an `<` number of lines in the
|
|
96
96
|
canvas.
|
|
97
97
|
char: character to place in the specified point on the
|
|
98
98
|
canvas.
|
|
@@ -117,11 +117,11 @@ class AsciiCanvas:
|
|
|
117
117
|
"""Create a line on ASCII canvas.
|
|
118
118
|
|
|
119
119
|
Args:
|
|
120
|
-
x0
|
|
121
|
-
y0
|
|
122
|
-
x1
|
|
123
|
-
y1
|
|
124
|
-
char
|
|
120
|
+
x0: x coordinate where the line should start.
|
|
121
|
+
y0: y coordinate where the line should start.
|
|
122
|
+
x1: x coordinate where the line should end.
|
|
123
|
+
y1: y coordinate where the line should end.
|
|
124
|
+
char: character to draw the line with.
|
|
125
125
|
"""
|
|
126
126
|
if x0 > x1:
|
|
127
127
|
x1, x0 = x0, x1
|
|
@@ -149,9 +149,9 @@ class AsciiCanvas:
|
|
|
149
149
|
"""Print a text on ASCII canvas.
|
|
150
150
|
|
|
151
151
|
Args:
|
|
152
|
-
x
|
|
153
|
-
y
|
|
154
|
-
text
|
|
152
|
+
x: x coordinate where the text should start.
|
|
153
|
+
y: y coordinate where the text should start.
|
|
154
|
+
text: string that should be printed.
|
|
155
155
|
"""
|
|
156
156
|
for i, char in enumerate(text):
|
|
157
157
|
self.point(x + i, y, char)
|
|
@@ -160,10 +160,10 @@ class AsciiCanvas:
|
|
|
160
160
|
"""Create a box on ASCII canvas.
|
|
161
161
|
|
|
162
162
|
Args:
|
|
163
|
-
x0
|
|
164
|
-
y0
|
|
165
|
-
width
|
|
166
|
-
height
|
|
163
|
+
x0: x coordinate of the box corner.
|
|
164
|
+
y0: y coordinate of the box corner.
|
|
165
|
+
width: box width.
|
|
166
|
+
height: box height.
|
|
167
167
|
"""
|
|
168
168
|
if width <= 1 or height <= 1:
|
|
169
169
|
msg = "Box dimensions should be > 1"
|
|
@@ -255,21 +255,20 @@ def draw_ascii(vertices: Mapping[str, str], edges: Sequence[LangEdge]) -> str:
|
|
|
255
255
|
ASCII representation
|
|
256
256
|
|
|
257
257
|
Example:
|
|
258
|
+
```python
|
|
259
|
+
from langchain_core.runnables.graph_ascii import draw_ascii
|
|
258
260
|
|
|
259
|
-
|
|
261
|
+
vertices = {1: "1", 2: "2", 3: "3", 4: "4"}
|
|
262
|
+
edges = [
|
|
263
|
+
(source, target, None, None)
|
|
264
|
+
for source, target in [(1, 2), (2, 3), (2, 4), (1, 4)]
|
|
265
|
+
]
|
|
260
266
|
|
|
261
|
-
from langchain_core.runnables.graph_ascii import draw_ascii
|
|
262
267
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
(source, target, None, None)
|
|
266
|
-
for source, target in [(1, 2), (2, 3), (2, 4), (1, 4)]
|
|
267
|
-
]
|
|
268
|
+
print(draw_ascii(vertices, edges))
|
|
269
|
+
```
|
|
268
270
|
|
|
269
|
-
|
|
270
|
-
print(draw_ascii(vertices, edges))
|
|
271
|
-
|
|
272
|
-
.. code-block::
|
|
271
|
+
```txt
|
|
273
272
|
|
|
274
273
|
+---+
|
|
275
274
|
| 1 |
|
|
@@ -286,7 +285,7 @@ def draw_ascii(vertices: Mapping[str, str], edges: Sequence[LangEdge]) -> str:
|
|
|
286
285
|
+---+ +---+
|
|
287
286
|
| 3 | | 4 |
|
|
288
287
|
+---+ +---+
|
|
289
|
-
|
|
288
|
+
```
|
|
290
289
|
"""
|
|
291
290
|
# NOTE: coordinates might me negative, so we need to shift
|
|
292
291
|
# everything to the positive plane before we actually draw it.
|