Merge pull request #323 from angeligareta/improve_visualization_notebook

Enrich visualization notebook to showcase new capabilities
This commit is contained in:
Nuno Campos
2024-04-18 10:20:55 -07:00
committed by GitHub
7 changed files with 1036 additions and 559 deletions
File diff suppressed because one or more lines are too long
+4 -2
View File
@@ -413,9 +413,11 @@ class CompiledGraph(Pregel):
cond = graph.add_node(branch.condition, name)
graph.add_edge(start_nodes[start], cond)
for label, end in ends.items():
graph.add_edge(cond, end_nodes[end], label)
graph.add_edge(cond, end_nodes[end], label, conditional=True)
else:
for label, end in ends.items():
graph.add_edge(start_nodes[start], end_nodes[end], label)
graph.add_edge(
start_nodes[start], end_nodes[end], label, conditional=True
)
return graph
Generated
+3 -3
View File
@@ -1712,13 +1712,13 @@ extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.
[[package]]
name = "langchain-core"
version = "0.1.42"
version = "0.1.44"
description = "Building applications with LLMs through composability"
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
{file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"},
{file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"},
{file = "langchain_core-0.1.44-py3-none-any.whl", hash = "sha256:d8772dccef95fc97bfa2dcd19412e620ebe14def1f0e218374971f6e30a46a49"},
{file = "langchain_core-0.1.44.tar.gz", hash = "sha256:e313975d9ae2926342e6f2ad760338d31f18b1223e9b8b4dc408daeeade46a83"},
]
[package.dependencies]
File diff suppressed because one or more lines are too long
+174
View File
@@ -0,0 +1,174 @@
# serializer version: 1
# name: test_in_one_fan_out_state_graph_waiting_edge_custom_state_class[end_of_run]
'''
+-----------+
| __start__ |
+-----------+
*
*
*
+---------------+
| rewrite_query |
+---------------+
*** ***
* *
** **
+--------------+ +---------+
| analyzer_one | | decider |
+--------------+ +---------+
* .
* .
* .
+---------------+ +---------------+
| retriever_one | | retriever_two |
+---------------+ +---------------+
*** ***
* *
** **
+----+
| qa |
+----+
*
*
*
+---------+
| __end__ |
+---------+
'''
# ---
# name: test_in_one_fan_out_state_graph_waiting_edge_custom_state_class[end_of_step]
'''
+-----------+
| __start__ |
+-----------+
*
*
*
+---------------+
| rewrite_query |
+---------------+
*** ***
* *
** **
+--------------+ +---------+
| analyzer_one | | decider |
+--------------+ +---------+
* .
* .
* .
+---------------+ +---------------+
| retriever_one | | retriever_two |
+---------------+ +---------------+
*** ***
* *
** **
+----+
| qa |
+----+
*
*
*
+---------+
| __end__ |
+---------+
'''
# ---
# name: test_in_one_fan_out_state_graph_waiting_edge_via_branch[end_of_run]
'''
+-----------+
| __start__ |
+-----------+
*
*
*
+---------------+
| rewrite_query |
+---------------+
*** ***
* *
** **
+--------------+ +-----------+
| analyzer_one | | condition |
+--------------+ +-----------+
* .
* .
* .
+---------------+ +---------------+
| retriever_one | | retriever_two |
+---------------+ +---------------+
*** ***
* *
** **
+----+
| qa |
+----+
*
*
*
+---------+
| __end__ |
+---------+
'''
# ---
# name: test_in_one_fan_out_state_graph_waiting_edge_via_branch[end_of_step]
'''
+-----------+
| __start__ |
+-----------+
*
*
*
+---------------+
| rewrite_query |
+---------------+
*** ***
* *
** **
+--------------+ +-----------+
| analyzer_one | | condition |
+--------------+ +-----------+
* .
* .
* .
+---------------+ +---------------+
| retriever_one | | retriever_two |
+---------------+ +---------------+
*** ***
* *
** **
+----+
| qa |
+----+
*
*
*
+---------+
| __end__ |
+---------+
'''
# ---
# name: test_nested_graph
'''
+-----------+
| __start__ |
+-----------+
*
*
*
+-------+
| inner |
+-------+
*
*
*
+------+
| side |
+------+
*
*
*
+---------+
| __end__ |
+---------+
'''
# ---
+23 -163
View File
@@ -796,10 +796,18 @@ def test_conditional_graph(
assert json.dumps(app.get_graph().to_json(), indent=2) == snapshot
assert app.get_graph().draw_ascii() == snapshot
assert app.get_graph(add_condition_nodes=False).draw_ascii() == snapshot
assert (
app.get_graph(add_condition_nodes=False).draw_mermaid(with_styles=False)
== snapshot
)
assert json.dumps(app.get_graph(xray=True).to_json(), indent=2) == snapshot
assert app.get_graph(xray=True).draw_ascii() == snapshot
assert app.get_graph(xray=True, add_condition_nodes=False).draw_ascii() == snapshot
assert (
app.get_graph(xray=True, add_condition_nodes=False).draw_mermaid(
with_styles=False
)
== snapshot
)
assert app.invoke({"input": "what is weather in sf"}) == {
"input": "what is weather in sf",
@@ -1819,7 +1827,7 @@ def test_conditional_entrypoint_graph_state(snapshot: SnapshotAssertion) -> None
should_start, {"go-left": "left", "go-right": "right"}
)
workflow.add_conditional_edges("left", lambda data: END)
workflow.add_conditional_edges("left", lambda data: END, {END: END})
workflow.add_edge("right", END)
app = workflow.compile()
@@ -2912,7 +2920,9 @@ def test_in_one_fan_out_out_one_graph_state() -> None:
@pytest.mark.parametrize(
"checkpoint_at", [CheckpointAt.END_OF_RUN, CheckpointAt.END_OF_STEP]
)
def test_in_one_fan_out_state_graph_waiting_edge(checkpoint_at: CheckpointAt) -> None:
def test_in_one_fan_out_state_graph_waiting_edge(
snapshot: SnapshotAssertion, checkpoint_at: CheckpointAt
) -> None:
def sorted_add(
x: list[str], y: Union[list[str], list[tuple[str, str]]]
) -> list[str]:
@@ -2959,41 +2969,7 @@ def test_in_one_fan_out_state_graph_waiting_edge(checkpoint_at: CheckpointAt) ->
app = workflow.compile()
assert app.get_graph().draw_ascii() == (
""" +-----------+
| __start__ |
+-----------+
*
*
*
+---------------+
| rewrite_query |
+---------------+
*** ***
* *
** ***
+--------------+ *
| analyzer_one | *
+--------------+ *
* *
* *
* *
+---------------+ +---------------+
| retriever_one | | retriever_two |
+---------------+ +---------------+
*** ***
* *
** **
+----+
| qa |
+----+
*
*
*
+---------+
| __end__ |
+---------+ """
)
assert app.get_graph().draw_ascii() == snapshot
assert app.invoke({"query": "what is weather in sf"}) == {
"query": "analyzed: query: what is weather in sf",
@@ -3037,6 +3013,7 @@ def test_in_one_fan_out_state_graph_waiting_edge(checkpoint_at: CheckpointAt) ->
"checkpoint_at", [CheckpointAt.END_OF_RUN, CheckpointAt.END_OF_STEP]
)
def test_in_one_fan_out_state_graph_waiting_edge_via_branch(
snapshot: SnapshotAssertion,
checkpoint_at: CheckpointAt,
) -> None:
def sorted_add(
@@ -3087,41 +3064,7 @@ def test_in_one_fan_out_state_graph_waiting_edge_via_branch(
app = workflow.compile()
assert app.get_graph().draw_ascii() == (
""" +-----------+
| __start__ |
+-----------+
*
*
*
+---------------+
| rewrite_query |
+---------------+
*** ***
* *
** **
+--------------+ +-----------+
| analyzer_one | | condition |
+--------------+ +-----------+
* *
* *
* *
+---------------+ +---------------+
| retriever_one | | retriever_two |
+---------------+ +---------------+
*** ***
* *
** **
+----+
| qa |
+----+
*
*
*
+---------+
| __end__ |
+---------+ """
)
assert app.get_graph().draw_ascii() == snapshot
assert app.invoke({"query": "what is weather in sf"}, debug=True) == {
"query": "analyzed: query: what is weather in sf",
@@ -3165,6 +3108,7 @@ def test_in_one_fan_out_state_graph_waiting_edge_via_branch(
"checkpoint_at", [CheckpointAt.END_OF_RUN, CheckpointAt.END_OF_STEP]
)
def test_in_one_fan_out_state_graph_waiting_edge_custom_state_class(
snapshot: SnapshotAssertion,
checkpoint_at: CheckpointAt,
) -> None:
from langchain_core.pydantic_v1 import BaseModel, ValidationError
@@ -3221,41 +3165,7 @@ def test_in_one_fan_out_state_graph_waiting_edge_custom_state_class(
app = workflow.compile()
assert app.get_graph().draw_ascii() == (
""" +-----------+
| __start__ |
+-----------+
*
*
*
+---------------+
| rewrite_query |
+---------------+
*** ***
* *
** **
+--------------+ +---------+
| analyzer_one | | decider |
+--------------+ +---------+
* *
* *
* *
+---------------+ +---------------+
| retriever_one | | retriever_two |
+---------------+ +---------------+
*** ***
* *
** **
+----+
| qa |
+----+
*
*
*
+---------+
| __end__ |
+---------+ """
)
assert app.get_graph().draw_ascii() == snapshot
with pytest.raises(ValidationError):
app.invoke({"query": {}})
@@ -3566,7 +3476,7 @@ def test_in_one_fan_out_state_graph_waiting_edge_multiple_cond_edge() -> None:
]
def test_simple_multi_edge() -> None:
def test_simple_multi_edge(snapshot: SnapshotAssertion) -> None:
class State(TypedDict):
my_key: Annotated[str, operator.add]
@@ -3592,39 +3502,11 @@ def test_simple_multi_edge() -> None:
app = graph.compile()
assert app.get_graph().draw_ascii() == (
""" +-----------+
| __start__ |
+-----------+
*
*
*
+----+
| up |
+----+
** **
* *
* *
+------+ *
| side | *
+------+ *
** **
* *
* *
+------+
| down |
+------+
*
*
*
+---------+
| __end__ |
+---------+ """
)
assert app.get_graph().draw_ascii() == snapshot
assert app.invoke({"my_key": "my_value"}) == {"my_key": "my_value"}
def test_nested_graph() -> None:
def test_nested_graph(snapshot: SnapshotAssertion) -> None:
class State(TypedDict):
my_key: str
@@ -3648,29 +3530,7 @@ def test_nested_graph() -> None:
app = graph.compile()
assert app.get_graph().draw_ascii() == (
"""+-----------+
| __start__ |
+-----------+
*
*
*
+-------+
| inner |
+-------+
*
*
*
+------+
| side |
+------+
*
*
*
+---------+
| __end__ |
+---------+ """
)
assert app.get_graph().draw_ascii() == snapshot
assert app.invoke({"my_key": "my value"}) == {
"my_key": "my value there and back again"
}
+7 -94
View File
@@ -17,6 +17,7 @@ from uuid import UUID
import pytest
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from pytest_mock import MockerFixture
from syrupy import SnapshotAssertion
from langgraph.channels.base import InvalidUpdateError
from langgraph.channels.binop import BinaryOperatorAggregate
@@ -2775,6 +2776,7 @@ async def test_in_one_fan_out_state_graph_waiting_edge(
"checkpoint_at", [CheckpointAt.END_OF_RUN, CheckpointAt.END_OF_STEP]
)
async def test_in_one_fan_out_state_graph_waiting_edge_via_branch(
snapshot: SnapshotAssertion,
checkpoint_at: CheckpointAt,
) -> None:
def sorted_add(
@@ -2825,41 +2827,7 @@ async def test_in_one_fan_out_state_graph_waiting_edge_via_branch(
app = workflow.compile()
assert app.get_graph().draw_ascii() == (
""" +-----------+
| __start__ |
+-----------+
*
*
*
+---------------+
| rewrite_query |
+---------------+
*** ***
* *
** **
+--------------+ +-----------+
| analyzer_one | | condition |
+--------------+ +-----------+
* *
* *
* *
+---------------+ +---------------+
| retriever_one | | retriever_two |
+---------------+ +---------------+
*** ***
* *
** **
+----+
| qa |
+----+
*
*
*
+---------+
| __end__ |
+---------+ """
)
assert app.get_graph().draw_ascii() == snapshot
assert await app.ainvoke({"query": "what is weather in sf"}, debug=True) == {
"query": "analyzed: query: what is weather in sf",
@@ -2906,6 +2874,7 @@ async def test_in_one_fan_out_state_graph_waiting_edge_via_branch(
"checkpoint_at", [CheckpointAt.END_OF_RUN, CheckpointAt.END_OF_STEP]
)
async def test_in_one_fan_out_state_graph_waiting_edge_custom_state_class(
snapshot: SnapshotAssertion,
checkpoint_at: CheckpointAt,
) -> None:
from langchain_core.pydantic_v1 import BaseModel, ValidationError
@@ -2962,41 +2931,7 @@ async def test_in_one_fan_out_state_graph_waiting_edge_custom_state_class(
app = workflow.compile()
assert app.get_graph().draw_ascii() == (
""" +-----------+
| __start__ |
+-----------+
*
*
*
+---------------+
| rewrite_query |
+---------------+
*** ***
* *
** **
+--------------+ +---------+
| analyzer_one | | decider |
+--------------+ +---------+
* *
* *
* *
+---------------+ +---------------+
| retriever_one | | retriever_two |
+---------------+ +---------------+
*** ***
* *
** **
+----+
| qa |
+----+
*
*
*
+---------+
| __end__ |
+---------+ """
)
assert app.get_graph().draw_ascii() == snapshot
with pytest.raises(ValidationError):
await app.ainvoke({"query": {}})
@@ -3313,7 +3248,7 @@ async def test_in_one_fan_out_state_graph_waiting_edge_multiple_cond_edge() -> N
]
async def test_nested_graph() -> None:
async def test_nested_graph(snapshot: SnapshotAssertion) -> None:
class State(TypedDict):
my_key: str
@@ -3337,29 +3272,7 @@ async def test_nested_graph() -> None:
app = graph.compile()
assert app.get_graph().draw_ascii() == (
"""+-----------+
| __start__ |
+-----------+
*
*
*
+-------+
| inner |
+-------+
*
*
*
+------+
| side |
+------+
*
*
*
+---------+
| __end__ |
+---------+ """
)
assert app.get_graph().draw_ascii() == snapshot
assert await app.ainvoke({"my_key": "my value"}) == {
"my_key": "my value there and back again"
}