FastGPT maintains full history server-side; LangGraph truncated the injected history at a hardcoded 50 messages, so long conversations behaved differently across backends. - Config.AGENT_HISTORY_MESSAGES (env): max messages injected into the model prompt (recent N, both roles counted); default 50 unchanged; larger values support long conversations; 0 = no truncation, matching FastGPT's full-history semantics. Only the injected window is affected - dialogue stays fully persisted in the checkpoint. - validate(): rejects negative values; 0 and positive accepted - conversation_history reads the config (import-time class attribute, monkeypatched in tests); explicit None-check keeps 0 falsy-safe - .env.example documents the knob Verified: 225 unit tests (6 new history-window tests)
63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
"""对话历史窗口配置测试(B3):env 可调最大注入条数,0 = 不截断。
|
|
|
|
对照 FastGPT:服务端全量维护历史、客户端只发单条消息;
|
|
LangGraph 侧历史注入曾硬编码截断 50 条,超长会话两端行为不对称。
|
|
现由 Config.AGENT_HISTORY_MESSAGES 控制(默认 50 不变)。
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from src.agent.collect import conversation_history
|
|
from src.core.config import Config
|
|
|
|
|
|
def _dialogue(n: int) -> dict:
|
|
return {"dialogue": [
|
|
{"role": "user", "content": f"第{i}条"} for i in range(n)
|
|
]}
|
|
|
|
|
|
def test_default_window_keeps_last_50(monkeypatch):
|
|
"""缺省 50:与工作流 chatNode history 配置一致(现状不变)。"""
|
|
monkeypatch.setattr(Config, "AGENT_HISTORY_MESSAGES", 50)
|
|
history = conversation_history(_dialogue(60))
|
|
assert len(history) == 50
|
|
assert history[0]["content"] == "第10条"
|
|
|
|
|
|
def test_large_window_supports_long_dialogues(monkeypatch):
|
|
"""调大窗口:长对话注入更多历史(B3 目标)。"""
|
|
monkeypatch.setattr(Config, "AGENT_HISTORY_MESSAGES", 500)
|
|
history = conversation_history(_dialogue(120))
|
|
assert len(history) == 120
|
|
|
|
|
|
def test_zero_window_disables_truncation(monkeypatch):
|
|
"""0 = 不截断:对齐 FastGPT 全量历史语义。"""
|
|
monkeypatch.setattr(Config, "AGENT_HISTORY_MESSAGES", 0)
|
|
history = conversation_history(_dialogue(300))
|
|
assert len(history) == 300
|
|
assert history[0]["content"] == "第0条"
|
|
|
|
|
|
def test_history_does_not_mutate_state(monkeypatch):
|
|
monkeypatch.setattr(Config, "AGENT_HISTORY_MESSAGES", 2)
|
|
state = _dialogue(10)
|
|
conversation_history(state)
|
|
assert len(state["dialogue"]) == 10 # 原文不动,截断只发生在拷贝
|
|
|
|
|
|
def test_validate_rejects_negative_window(monkeypatch):
|
|
monkeypatch.setattr(Config, "AGENT_HISTORY_MESSAGES", -1)
|
|
with pytest.raises(ValueError, match="AGENT_HISTORY_MESSAGES"):
|
|
Config.validate()
|
|
|
|
|
|
def test_validate_accepts_zero_and_positive(monkeypatch):
|
|
monkeypatch.setattr(Config, "AGENT_HISTORY_MESSAGES", 0)
|
|
monkeypatch.setattr(Config, "AGENT_BACKEND", "langgraph")
|
|
monkeypatch.setattr(Config, "LLM_PROVIDER", "fake")
|
|
Config.validate()
|
|
monkeypatch.setattr(Config, "AGENT_HISTORY_MESSAGES", 10)
|
|
Config.validate()
|