feat(server): 会话上下文保留(LLM 历史 + 确定性兜底双保险)

解决用户删除草稿后说'再提交'丢失上下文的问题:

- steward.py 新增 _inject_recent_conversation_history:build_plan 前读最近 10 条对话注入 context_json
- steward_intent_agent.py 的 _build_messages 把 recent_history 暴露给模型,system prompt 加确认类话术引导
- 新建 steward_context_resume.py:should_resume_recent_task 检测'再提交'类话术 + state 有可恢复 flow,attach_resumed_task 从 state 恢复 task
- 两个 plan 入口(/plans 和 /plans/stream)都已接入双保险
- 后端 67 passed,端到端验证'上海出差→再提交'成功恢复 task
This commit is contained in:
caoxiaozhu
2026-06-25 15:08:56 +08:00
parent 2ebc2756bf
commit e9d7c56d5b
5 changed files with 440 additions and 0 deletions

View File

@@ -98,3 +98,58 @@ def test_steward_intent_system_prompt_mentions_query_intent_guidance() -> None:
assert "query_travel_standard" in system_prompt
assert "差旅" in system_prompt
assert "住宿标准" in system_prompt
def test_steward_intent_system_prompt_includes_conversation_history_guidance() -> None:
"""system prompt 应包含'结合对话历史理解确认类话术'的引导。"""
from app.services import steward_intent_bootstrap # noqa: F401
messages = StewardIntentAgent._build_messages(
StewardPlanRequest(message="再提交"),
base_date=__import__("datetime").date(2026, 6, 24),
canonical_fields=["location", "time_range"],
)
system_prompt = messages[0]["content"]
assert "recent_history" in system_prompt
assert "再提交" in system_prompt
assert "确认类话术" in system_prompt
def test_steward_intent_context_payload_includes_recent_history() -> None:
"""context_payload 应携带 recent_history 结构化字段role + content"""
import json
request = StewardPlanRequest(
message="再提交",
context_json={
"recent_history": [
{"role": "user", "content": "2026-02-20 至 2026-02-23去上海出差火车"},
{"role": "assistant", "content": "好的,为您整理出差申请预览。"},
{"role": "user", "content": "直接提交"},
{"role": "assistant", "content": "检测到重复申请,已暂停提交。"},
],
},
)
messages = StewardIntentAgent._build_messages(
request,
base_date=__import__("datetime").date(2026, 6, 24),
canonical_fields=["location", "time_range"],
)
user_payload = json.loads(messages[1]["content"])
assert "recent_history" in user_payload
assert len(user_payload["recent_history"]) == 4
assert user_payload["recent_history"][0]["role"] == "user"
assert "上海" in user_payload["recent_history"][0]["content"]
def test_steward_intent_context_payload_omits_empty_recent_history() -> None:
"""无 recent_history 时不应注入空列表。"""
import json
messages = StewardIntentAgent._build_messages(
StewardPlanRequest(message="你好"),
base_date=__import__("datetime").date(2026, 6, 24),
canonical_fields=["location"],
)
user_payload = json.loads(messages[1]["content"])
assert user_payload.get("recent_history", []) == []