mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-08-01 10:56:02 +00:00
Fix AttributeError in ThreadDataMiddleware when runtime.context is None (#3989)
`before_agent` guards `context = runtime.context or {}` at the top, but the
`run_id` stamp on a trailing HumanMessage still read the raw `runtime.context`,
so a None context (thread_id resolved from `config.configurable`) plus a
HumanMessage last message raised `AttributeError: 'NoneType' object has no
attribute 'get'`. Use the guarded local `context` instead.
Adds a regression test.
This commit is contained in:
parent
446ae98649
commit
1fa91fa39d
@ -107,7 +107,7 @@ class ThreadDataMiddleware(AgentMiddleware[ThreadDataMiddlewareState]):
|
|||||||
content=last_message.content,
|
content=last_message.content,
|
||||||
id=last_message.id,
|
id=last_message.id,
|
||||||
name=last_message.name or "user-input",
|
name=last_message.name or "user-input",
|
||||||
additional_kwargs={**last_message.additional_kwargs, "run_id": runtime.context.get("run_id"), "timestamp": datetime.now(UTC).isoformat()},
|
additional_kwargs={**last_message.additional_kwargs, "run_id": context.get("run_id"), "timestamp": datetime.now(UTC).isoformat()},
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -47,6 +47,23 @@ class TestThreadDataMiddleware:
|
|||||||
assert _as_posix(result["thread_data"]["uploads_path"]).endswith("threads/thread-from-config/user-data/uploads")
|
assert _as_posix(result["thread_data"]["uploads_path"]).endswith("threads/thread-from-config/user-data/uploads")
|
||||||
assert runtime.context == {}
|
assert runtime.context == {}
|
||||||
|
|
||||||
|
def test_before_agent_handles_none_context_with_trailing_human_message(self, tmp_path, monkeypatch):
|
||||||
|
# Regression: run_id was read via the unguarded `runtime.context`, so a None context plus a
|
||||||
|
# trailing HumanMessage raised AttributeError (thread_id still resolves from config.configurable).
|
||||||
|
from langchain_core.messages import HumanMessage
|
||||||
|
|
||||||
|
middleware = ThreadDataMiddleware(base_dir=str(tmp_path), lazy_init=True)
|
||||||
|
runtime = Runtime(context=None)
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"deerflow.agents.middlewares.thread_data_middleware.get_config",
|
||||||
|
lambda: {"configurable": {"thread_id": "thread-from-config"}},
|
||||||
|
)
|
||||||
|
|
||||||
|
result = middleware.before_agent(state={"messages": [HumanMessage(content="hello", id="m1")]}, runtime=runtime)
|
||||||
|
|
||||||
|
assert result is not None
|
||||||
|
assert runtime.context is None
|
||||||
|
|
||||||
def test_before_agent_raises_clear_error_when_thread_id_missing_everywhere(self, tmp_path, monkeypatch):
|
def test_before_agent_raises_clear_error_when_thread_id_missing_everywhere(self, tmp_path, monkeypatch):
|
||||||
middleware = ThreadDataMiddleware(base_dir=str(tmp_path), lazy_init=True)
|
middleware = ThreadDataMiddleware(base_dir=str(tmp_path), lazy_init=True)
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user