mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-10-16 21:25:35 +02:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91f6fea068 | ||
|
|
57f0e846e8 | ||
|
|
4b27c10aca | ||
|
|
0e8252fd31 | ||
|
|
d18da208b9 | ||
|
|
6deac3abdf | ||
|
|
f02f7a5a27 | ||
|
|
6669634a98 | ||
|
|
bbe8346c8b | ||
|
|
10abf2deb1 | ||
|
|
5796ca9a0a |
@@ -1,21 +1,21 @@
|
|||||||
name: "\U0001F41B Bug Report"
|
name: "\U0001F41B Bug Report"
|
||||||
description: Report a bug in LangGraph. To report a security issue, please instead use the security option below. For questions, please use the LangChain Forum at forum.langchain.com.
|
description: Report a bug in LangGraph. To report a security issue, please instead use the security option below. For questions, please use the LangChain Forum at forum.langchain.com.
|
||||||
labels: [pending,bug]
|
labels: [pending, bug]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Thank you for taking the time to file a bug report.
|
Thank you for taking the time to file a bug report.
|
||||||
|
|
||||||
Use this to report BUGS in LangGraph. For usage questions, feature requests and general design questions, please use the [LangChain Forum](https://forum.langchain.com/).
|
Use this to report BUGS in LangGraph. For usage questions, feature requests and general design questions, please use the [LangChain Forum](https://forum.langchain.com/).
|
||||||
|
|
||||||
Relevant links to check before filing a bug report to see if your issue has already been reported, fixed or
|
Relevant links to check before filing a bug report to see if your issue has already been reported, fixed or
|
||||||
if there's another way to solve your problem:
|
if there's another way to solve your problem:
|
||||||
|
|
||||||
* [LangChain Forum](https://forum.langchain.com/),
|
* [LangChain Forum](https://forum.langchain.com/),
|
||||||
* [LangGraph Github Issues](https://github.com/langchain-ai/langgraph/issues),
|
* [LangGraph Github Issues](https://github.com/langchain-ai/langgraph/issues),
|
||||||
* [LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/).
|
* [LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/).
|
||||||
* [LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
|
* [LangChain documentation with the integrated search](https://docs.langchain.com/),
|
||||||
* [GitHub search](https://github.com/langchain-ai/langgraph),
|
* [GitHub search](https://github.com/langchain-ai/langgraph),
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
id: checks
|
id: checks
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
|||||||
|
|
||||||
- [LangSmith](http://www.langchain.com/langsmith) — Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
|
- [LangSmith](http://www.langchain.com/langsmith) — Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
|
||||||
- [LangSmith Deployment](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
- [LangSmith Deployment](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
||||||
- [LangChain](https://python.langchain.com/docs/introduction/) – Provides integrations and composable components to streamline LLM application development.
|
- [LangChain](https://docs.langchain.com/oss/python/langchain/overview) – Provides integrations and composable components to streamline LLM application development.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Looking for the JS version of LangGraph? See the [JS repo](https://github.com/langchain-ai/langgraphjs) and the [JS docs](https://langchain-ai.github.io/langgraphjs/).
|
> Looking for the JS version of LangGraph? See the [JS repo](https://github.com/langchain-ai/langgraphjs) and the [JS docs](https://langchain-ai.github.io/langgraphjs/).
|
||||||
@@ -81,4 +81,4 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
|||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
|
|
||||||
LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
|
LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
|||||||
|
|
||||||
- [LangSmith](http://www.langchain.com/langsmith) — Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
|
- [LangSmith](http://www.langchain.com/langsmith) — Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
|
||||||
- [LangSmith Deployment](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
- [LangSmith Deployment](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
||||||
- [LangChain](https://python.langchain.com/docs/introduction/) – Provides integrations and composable components to streamline LLM application development.
|
- [LangChain](https://docs.langchain.com/oss/python/langchain/overview) – Provides integrations and composable components to streamline LLM application development.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Looking for the JS version of LangGraph? See the [JS repo](https://github.com/langchain-ai/langgraphjs) and the [JS docs](https://langchain-ai.github.io/langgraphjs/).
|
> Looking for the JS version of LangGraph? See the [JS repo](https://github.com/langchain-ai/langgraphjs) and the [JS docs](https://langchain-ai.github.io/langgraphjs/).
|
||||||
@@ -81,4 +81,4 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
|||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
|
|
||||||
LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
|
LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ class ErrorCode(Enum):
|
|||||||
def create_error_message(*, message: str, error_code: ErrorCode) -> str:
|
def create_error_message(*, message: str, error_code: ErrorCode) -> str:
|
||||||
return (
|
return (
|
||||||
f"{message}\n"
|
f"{message}\n"
|
||||||
"For troubleshooting, visit: https://python.langchain.com/docs/"
|
"For troubleshooting, visit: https://docs.langchain.com/oss/python/langgraph/"
|
||||||
f"troubleshooting/errors/{error_code.value}"
|
f"errors/{error_code.value}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ from langgraph._internal._scratchpad import PregelScratchpad
|
|||||||
from langgraph._internal._typing import EMPTY_SEQ, MISSING
|
from langgraph._internal._typing import EMPTY_SEQ, MISSING
|
||||||
from langgraph.channels.base import BaseChannel
|
from langgraph.channels.base import BaseChannel
|
||||||
from langgraph.channels.topic import Topic
|
from langgraph.channels.topic import Topic
|
||||||
|
from langgraph.channels.untracked_value import UntrackedValue
|
||||||
from langgraph.constants import TAG_HIDDEN
|
from langgraph.constants import TAG_HIDDEN
|
||||||
from langgraph.managed.base import ManagedValueMapping
|
from langgraph.managed.base import ManagedValueMapping
|
||||||
from langgraph.pregel._call import get_runnable_for_task, identifier
|
from langgraph.pregel._call import get_runnable_for_task, identifier
|
||||||
@@ -639,6 +640,7 @@ def prepare_single_task(
|
|||||||
f"Ignoring invalid packet type {type(packet)} in pending sends"
|
f"Ignoring invalid packet type {type(packet)} in pending sends"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if packet.node not in processes:
|
if packet.node not in processes:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Ignoring unknown node name {packet.node} in pending sends"
|
f"Ignoring unknown node name {packet.node} in pending sends"
|
||||||
@@ -1106,3 +1108,23 @@ class LazyAtomicCounter:
|
|||||||
if self._counter is None:
|
if self._counter is None:
|
||||||
self._counter = itertools.count(0).__next__
|
self._counter = itertools.count(0).__next__
|
||||||
return self._counter()
|
return self._counter()
|
||||||
|
|
||||||
|
|
||||||
|
def sanitize_untracked_values_in_send(
|
||||||
|
packet: Send, channels: Mapping[str, BaseChannel]
|
||||||
|
) -> Send:
|
||||||
|
"""Pop any UntrackedValue contents in Send.arg for safe checkpointing.
|
||||||
|
|
||||||
|
Send is not typed and arg may be a nested dict. We only look at the top level."""
|
||||||
|
|
||||||
|
if not isinstance(packet.arg, dict):
|
||||||
|
# Command
|
||||||
|
return packet
|
||||||
|
|
||||||
|
sanitized_arg = {
|
||||||
|
k: v
|
||||||
|
for k, v in packet.arg.items()
|
||||||
|
if not isinstance(channels.get(k), UntrackedValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Send(node=packet.node, arg=sanitized_arg)
|
||||||
|
|||||||
@@ -56,10 +56,12 @@ from langgraph._internal._constants import (
|
|||||||
NULL_TASK_ID,
|
NULL_TASK_ID,
|
||||||
PUSH,
|
PUSH,
|
||||||
RESUME,
|
RESUME,
|
||||||
|
TASKS,
|
||||||
)
|
)
|
||||||
from langgraph._internal._scratchpad import PregelScratchpad
|
from langgraph._internal._scratchpad import PregelScratchpad
|
||||||
from langgraph._internal._typing import EMPTY_SEQ, MISSING
|
from langgraph._internal._typing import EMPTY_SEQ, MISSING
|
||||||
from langgraph.channels.base import BaseChannel
|
from langgraph.channels.base import BaseChannel
|
||||||
|
from langgraph.channels.untracked_value import UntrackedValue
|
||||||
from langgraph.constants import TAG_HIDDEN
|
from langgraph.constants import TAG_HIDDEN
|
||||||
from langgraph.errors import (
|
from langgraph.errors import (
|
||||||
EmptyInputError,
|
EmptyInputError,
|
||||||
@@ -78,6 +80,7 @@ from langgraph.pregel._algo import (
|
|||||||
increment,
|
increment,
|
||||||
prepare_next_tasks,
|
prepare_next_tasks,
|
||||||
prepare_single_task,
|
prepare_single_task,
|
||||||
|
sanitize_untracked_values_in_send,
|
||||||
should_interrupt,
|
should_interrupt,
|
||||||
task_path_str,
|
task_path_str,
|
||||||
)
|
)
|
||||||
@@ -114,6 +117,7 @@ from langgraph.types import (
|
|||||||
Durability,
|
Durability,
|
||||||
PregelExecutableTask,
|
PregelExecutableTask,
|
||||||
RetryPolicy,
|
RetryPolicy,
|
||||||
|
Send,
|
||||||
StreamMode,
|
StreamMode,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -320,6 +324,24 @@ class PregelLoop:
|
|||||||
w for w in self.checkpoint_pending_writes if w[0] != task_id
|
w for w in self.checkpoint_pending_writes if w[0] != task_id
|
||||||
]
|
]
|
||||||
writes_to_save = writes
|
writes_to_save = writes
|
||||||
|
|
||||||
|
# check if any writes are to an UntrackedValue channel
|
||||||
|
if any(
|
||||||
|
isinstance(channel, UntrackedValue) for channel in self.channels.values()
|
||||||
|
):
|
||||||
|
# we do not persist untracked values in checkpoints
|
||||||
|
writes_to_save = [
|
||||||
|
# sanitize UntrackedValues that are nested within Send packets
|
||||||
|
(
|
||||||
|
(c, sanitize_untracked_values_in_send(v, self.channels))
|
||||||
|
if c == TASKS and isinstance(v, Send)
|
||||||
|
else (c, v)
|
||||||
|
)
|
||||||
|
for c, v in writes_to_save
|
||||||
|
# dont persist UntrackedValue channel writes
|
||||||
|
if not isinstance(self.specs.get(c), UntrackedValue)
|
||||||
|
]
|
||||||
|
|
||||||
# save writes
|
# save writes
|
||||||
self.checkpoint_pending_writes.extend((task_id, c, v) for c, v in writes)
|
self.checkpoint_pending_writes.extend((task_id, c, v) for c, v in writes)
|
||||||
if self.durability != "exit" and self.checkpointer_put_writes is not None:
|
if self.durability != "exit" and self.checkpointer_put_writes is not None:
|
||||||
@@ -735,6 +757,17 @@ class PregelLoop:
|
|||||||
id=self.checkpoint["id"] if exiting else None,
|
id=self.checkpoint["id"] if exiting else None,
|
||||||
updated_channels=self.updated_channels,
|
updated_channels=self.updated_channels,
|
||||||
)
|
)
|
||||||
|
# sanitize TASK channel in the checkpoint before saving (durability=="exit")
|
||||||
|
if TASKS in self.checkpoint["channel_values"] and any(
|
||||||
|
isinstance(channel, UntrackedValue) for channel in self.channels.values()
|
||||||
|
):
|
||||||
|
sanitized_tasks = [
|
||||||
|
sanitize_untracked_values_in_send(value, self.channels)
|
||||||
|
if isinstance(value, Send)
|
||||||
|
else value
|
||||||
|
for value in self.checkpoint["channel_values"][TASKS]
|
||||||
|
]
|
||||||
|
self.checkpoint["channel_values"][TASKS] = sanitized_tasks
|
||||||
# bail if no checkpointer
|
# bail if no checkpointer
|
||||||
if do_checkpoint and self._checkpointer_put_after_previous is not None:
|
if do_checkpoint and self._checkpointer_put_after_previous is not None:
|
||||||
self.prev_checkpoint_config = (
|
self.prev_checkpoint_config = (
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from langgraph._internal._typing import MISSING
|
|||||||
from langgraph.channels.binop import BinaryOperatorAggregate
|
from langgraph.channels.binop import BinaryOperatorAggregate
|
||||||
from langgraph.channels.last_value import LastValue
|
from langgraph.channels.last_value import LastValue
|
||||||
from langgraph.channels.topic import Topic
|
from langgraph.channels.topic import Topic
|
||||||
|
from langgraph.channels.untracked_value import UntrackedValue
|
||||||
from langgraph.errors import EmptyChannelError, InvalidUpdateError
|
from langgraph.errors import EmptyChannelError, InvalidUpdateError
|
||||||
|
|
||||||
pytestmark = pytest.mark.anyio
|
pytestmark = pytest.mark.anyio
|
||||||
@@ -87,3 +88,32 @@ def test_binop() -> None:
|
|||||||
checkpoint = channel.checkpoint()
|
checkpoint = channel.checkpoint()
|
||||||
channel = BinaryOperatorAggregate(int, operator.add).from_checkpoint(checkpoint)
|
channel = BinaryOperatorAggregate(int, operator.add).from_checkpoint(checkpoint)
|
||||||
assert channel.get() == 10
|
assert channel.get() == 10
|
||||||
|
|
||||||
|
|
||||||
|
def test_untracked_value() -> None:
|
||||||
|
channel = UntrackedValue(dict).from_checkpoint(MISSING)
|
||||||
|
assert channel.ValueType is dict
|
||||||
|
assert channel.UpdateType is dict
|
||||||
|
|
||||||
|
# UntrackedValue should start empty
|
||||||
|
with pytest.raises(EmptyChannelError):
|
||||||
|
channel.get()
|
||||||
|
|
||||||
|
# Should be able to update with a value
|
||||||
|
test_data = {"session": "test", "temp": "dir"}
|
||||||
|
channel.update([test_data])
|
||||||
|
assert channel.get() == test_data
|
||||||
|
|
||||||
|
# Update with new value
|
||||||
|
new_data = {"session": "updated", "temp": "newdir"}
|
||||||
|
channel.update([new_data])
|
||||||
|
assert channel.get() == new_data
|
||||||
|
|
||||||
|
# On checkpoint, UntrackedValue should return MISSING
|
||||||
|
checkpoint = channel.checkpoint()
|
||||||
|
assert checkpoint is MISSING
|
||||||
|
|
||||||
|
# Creating from checkpoint with MISSING should start empty
|
||||||
|
new_channel = UntrackedValue(dict).from_checkpoint(checkpoint)
|
||||||
|
with pytest.raises(EmptyChannelError):
|
||||||
|
new_channel.get()
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ from langgraph.channels.binop import BinaryOperatorAggregate
|
|||||||
from langgraph.channels.ephemeral_value import EphemeralValue
|
from langgraph.channels.ephemeral_value import EphemeralValue
|
||||||
from langgraph.channels.last_value import LastValue
|
from langgraph.channels.last_value import LastValue
|
||||||
from langgraph.channels.topic import Topic
|
from langgraph.channels.topic import Topic
|
||||||
|
from langgraph.channels.untracked_value import UntrackedValue
|
||||||
from langgraph.config import get_stream_writer
|
from langgraph.config import get_stream_writer
|
||||||
from langgraph.errors import GraphRecursionError, InvalidUpdateError, ParentCommand
|
from langgraph.errors import GraphRecursionError, InvalidUpdateError, ParentCommand
|
||||||
from langgraph.func import entrypoint, task
|
from langgraph.func import entrypoint, task
|
||||||
@@ -8597,3 +8598,102 @@ def test_multiple_writes_same_channel_from_same_node(
|
|||||||
"values": {"foo": ""},
|
"values": {"foo": ""},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_send_with_untracked_value(sync_checkpointer: BaseCheckpointSaver):
|
||||||
|
"""Test that Send objects work correctly with untracked values in state."""
|
||||||
|
|
||||||
|
class UnserializableResource:
|
||||||
|
def __init__(self, name: str):
|
||||||
|
self.name = name
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
|
||||||
|
class State(TypedDict):
|
||||||
|
messages: Annotated[list[str], operator.add]
|
||||||
|
session_resource: Annotated[UnserializableResource, UntrackedValue]
|
||||||
|
|
||||||
|
def setup_node(state: State) -> State:
|
||||||
|
resource = UnserializableResource("test_session")
|
||||||
|
return {"messages": ["setup complete"], "session_resource": resource}
|
||||||
|
|
||||||
|
def send_to_tool(state: State):
|
||||||
|
return [Send("tool_node", state)]
|
||||||
|
|
||||||
|
def tool_node(state: State) -> State:
|
||||||
|
resource = state["session_resource"]
|
||||||
|
assert isinstance(resource, UnserializableResource)
|
||||||
|
assert resource.name == "test_session"
|
||||||
|
|
||||||
|
new_resource = UnserializableResource("new_session")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"messages": [f"tool used resource: {resource.name}"],
|
||||||
|
"session_resource": new_resource,
|
||||||
|
}
|
||||||
|
|
||||||
|
graph = StateGraph(State)
|
||||||
|
graph.add_node("setup", setup_node)
|
||||||
|
graph.add_node("tool_node", tool_node)
|
||||||
|
graph.add_edge(START, "setup")
|
||||||
|
graph.add_conditional_edges("setup", send_to_tool)
|
||||||
|
|
||||||
|
app = graph.compile(checkpointer=sync_checkpointer)
|
||||||
|
config = {"configurable": {"thread_id": "1"}}
|
||||||
|
result = app.invoke({}, config)
|
||||||
|
|
||||||
|
assert len(result["messages"]) == 2
|
||||||
|
assert result["messages"][0] == "setup complete"
|
||||||
|
assert result["messages"][1] == "tool used resource: test_session"
|
||||||
|
assert result["session_resource"].name == "new_session"
|
||||||
|
|
||||||
|
state = app.get_state(config)
|
||||||
|
assert "session_resource" not in state.values
|
||||||
|
|
||||||
|
|
||||||
|
def test_send_with_untracked_value_overlapping_keys(
|
||||||
|
sync_checkpointer: BaseCheckpointSaver,
|
||||||
|
):
|
||||||
|
"""Test that Send objects work correctly with untracked values in state."""
|
||||||
|
|
||||||
|
class State(TypedDict):
|
||||||
|
dictionary: dict
|
||||||
|
session_resource: Annotated[str, UntrackedValue]
|
||||||
|
|
||||||
|
def setup_node(state: State) -> State:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def send_to_tool(state: State):
|
||||||
|
return [
|
||||||
|
Send(
|
||||||
|
"tool_node",
|
||||||
|
{
|
||||||
|
"dictionary": {"session_resource": "legal_value"},
|
||||||
|
"session_resource": "illegal_value",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
def tool_node(state: State) -> State:
|
||||||
|
print(f"STATE: {state}")
|
||||||
|
assert state["dictionary"] == {"session_resource": "legal_value"}
|
||||||
|
assert state["session_resource"] == "illegal_value"
|
||||||
|
|
||||||
|
return {
|
||||||
|
"dictionary": state["dictionary"],
|
||||||
|
"session_resource": "new_illegal_value",
|
||||||
|
}
|
||||||
|
|
||||||
|
graph = StateGraph(State)
|
||||||
|
graph.add_node("setup", setup_node)
|
||||||
|
graph.add_node("tool_node", tool_node)
|
||||||
|
graph.add_edge(START, "setup")
|
||||||
|
graph.add_conditional_edges("setup", send_to_tool)
|
||||||
|
|
||||||
|
app = graph.compile(checkpointer=sync_checkpointer)
|
||||||
|
config = {"configurable": {"thread_id": "1"}}
|
||||||
|
result = app.invoke({}, config)
|
||||||
|
|
||||||
|
assert result["session_resource"] == "new_illegal_value"
|
||||||
|
state = app.get_state(config)
|
||||||
|
assert "session_resource" not in state.values
|
||||||
|
assert state.values.get("dictionary") == {"session_resource": "legal_value"}
|
||||||
|
|||||||
@@ -194,7 +194,6 @@ class Auth:
|
|||||||
by name:
|
by name:
|
||||||
|
|
||||||
- request (Request): The raw ASGI request object
|
- request (Request): The raw ASGI request object
|
||||||
- body (dict): The parsed request body
|
|
||||||
- path (str): The request path, e.g., "/threads/abcd-1234-abcd-1234/runs/abcd-1234-abcd-1234/stream"
|
- path (str): The request path, e.g., "/threads/abcd-1234-abcd-1234/runs/abcd-1234-abcd-1234/stream"
|
||||||
- method (str): The HTTP method, e.g., "GET"
|
- method (str): The HTTP method, e.g., "GET"
|
||||||
- path_params (dict[str, str]): URL path parameters, e.g., {"thread_id": "abcd-1234-abcd-1234", "run_id": "abcd-1234-abcd-1234"}
|
- path_params (dict[str, str]): URL path parameters, e.g., {"thread_id": "abcd-1234-abcd-1234", "run_id": "abcd-1234-abcd-1234"}
|
||||||
|
|||||||
+6
-6
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
## Reporting OSS Vulnerabilities
|
## Reporting OSS Vulnerabilities
|
||||||
|
|
||||||
LangChain is partnered with [huntr by Protect AI](https://huntr.com/) to provide
|
LangChain is partnered with [huntr by Protect AI](https://huntr.com/) to provide
|
||||||
a bounty program for our open source projects.
|
a bounty program for our open source projects.
|
||||||
|
|
||||||
Please report security vulnerabilities associated with the LangChain
|
Please report security vulnerabilities associated with the LangChain
|
||||||
open source projects by visiting the following link:
|
open source projects by visiting the following link:
|
||||||
|
|
||||||
[https://huntr.com/bounties/disclose/](https://huntr.com/bounties/disclose/?target=https%3A%2F%2Fgithub.com%2Flangchain-ai%2Flangchain&validSearch=true)
|
[https://huntr.com/bounties/disclose/](https://huntr.com/bounties/disclose/?target=https%3A%2F%2Fgithub.com%2Flangchain-ai%2Flangchain&validSearch=true)
|
||||||
@@ -13,7 +13,7 @@ open source projects by visiting the following link:
|
|||||||
Before reporting a vulnerability, please review:
|
Before reporting a vulnerability, please review:
|
||||||
|
|
||||||
1) In-Scope Targets and Out-of-Scope Targets below.
|
1) In-Scope Targets and Out-of-Scope Targets below.
|
||||||
2) The [langchain-ai/langchain](https://python.langchain.com/docs/contributing/repo_structure) monorepo structure.
|
2) The [langchain-ai/langchain](https://github.com/langchain-ai/langchain) monorepo structure.
|
||||||
3) LangChain [security guidelines](https://python.langchain.com/docs/security) to
|
3) LangChain [security guidelines](https://python.langchain.com/docs/security) to
|
||||||
understand what we consider to be a security vulnerability vs. developer
|
understand what we consider to be a security vulnerability vs. developer
|
||||||
responsibility.
|
responsibility.
|
||||||
@@ -53,8 +53,8 @@ All out of scope targets defined by huntr as well as:
|
|||||||
|
|
||||||
Please report security vulnerabilities associated with LangSmith by email to `security@langchain.dev`.
|
Please report security vulnerabilities associated with LangSmith by email to `security@langchain.dev`.
|
||||||
|
|
||||||
- LangSmith site: https://smith.langchain.com
|
- LangSmith site: <https://smith.langchain.com>
|
||||||
- SDK client: https://github.com/langchain-ai/langsmith-sdk
|
- SDK client: <https://github.com/langchain-ai/langsmith-sdk>
|
||||||
|
|
||||||
### Other Security Concerns
|
### Other Security Concerns
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user