fix(attachments): merge state files by /attachments namespace

This commit is contained in:
肖泽涛 2026-02-21 00:59:29 +08:00
parent bfae184e1c
commit dcb3d2c939
2 changed files with 37 additions and 7 deletions

View File

@ -77,11 +77,26 @@ async def _sync_thread_attachment_state(
return
graph = await agent.get_graph()
config = {"configurable": {"thread_id": thread_id, "user_id": str(user_id)}}
state = await graph.aget_state(config)
state_values = getattr(state, "values", {}) if state else {}
existing_files = state_values.get("files", {}) if isinstance(state_values, dict) else {}
if not isinstance(existing_files, dict):
existing_files = {}
attachment_files = _build_state_files(attachments)
merged_files = {
path: file_data
for path, file_data in existing_files.items()
if isinstance(path, str) and not path.startswith("/attachments/")
}
merged_files.update(attachment_files)
await graph.aupdate_state(
config={"configurable": {"thread_id": thread_id, "user_id": str(user_id)}},
config=config,
values={
"attachments": attachments,
"files": _build_state_files(attachments),
"files": merged_files,
},
)
except Exception as e:

View File

@ -37,11 +37,23 @@ def test_build_state_files_only_parsed_and_with_content():
@pytest.mark.asyncio
async def test_sync_thread_attachment_state_updates_graph(monkeypatch: pytest.MonkeyPatch):
captured: dict = {}
fake_state = SimpleNamespace(
values={
"files": {
"/attachments/old.md": {"content": ["old"]},
"/work/result.md": {"content": ["keep"]},
}
}
)
class FakeGraph:
async def aget_state(self, config):
captured["read_config"] = config
return fake_state
async def aupdate_state(self, *, config, values):
captured["config"] = config
captured["values"] = values
captured["write_config"] = config
captured["write_values"] = values
class FakeAgent:
async def get_graph(self):
@ -64,9 +76,12 @@ async def test_sync_thread_attachment_state_updates_graph(monkeypatch: pytest.Mo
attachments=attachments,
)
assert captured["config"] == {"configurable": {"thread_id": "thread-1", "user_id": "u1"}}
assert captured["values"]["attachments"] == attachments
assert "/attachments/resume.md" in captured["values"]["files"]
assert captured["read_config"] == {"configurable": {"thread_id": "thread-1", "user_id": "u1"}}
assert captured["write_config"] == {"configurable": {"thread_id": "thread-1", "user_id": "u1"}}
assert captured["write_values"]["attachments"] == attachments
assert "/attachments/resume.md" in captured["write_values"]["files"]
assert "/attachments/old.md" not in captured["write_values"]["files"]
assert "/work/result.md" in captured["write_values"]["files"]
@pytest.mark.asyncio