"""Architect 渲染三档裁剪(T-M3,采纳 llmrouter pinch keep/summarize/drop 设计)。""" from router_system.workspace import Workspace _GOAL = "用 Python 实现快速排序并分析时间复杂度" _BRIEF = { "goal": _GOAL, "constraints": ["标准库"], "tags": ["code"], "acceptance": [{"id": "a1", "check": "可运行", "machine_checkable": True}], "plan": [{"id": "s1", "task": "实现", "deps": [], "done_criteria": "过"}], } def _ws_with_archive(): ws = Workspace.new(request_id="abc123def456", query=_GOAL, api_token_cap=8000, rounds_cap=6) ws.apply_brief(_BRIEF) relevant = ("s1: 完成快速排序实现,基准选取三数取中,递归深度优化," "平均时间复杂度 O(n log n) 分析见附件。" + "快排边界处理细节" * 50) lines = [f"sX{i}: 无关行{i},今日食堂菜单有红烧肉、番茄炒蛋与清炒时蔬," f"周末计划去郊外徒步露营并整理旅行照片。" + "生活琐事记录" * 50 + f"独特结尾标记{i}号" # 唯一尾串:判断"该行是否还被输出" for i in range(7)] # 相关行放在中间:不在最新 4 行下限保护区内,检验相关性而非新近度 ws._data["archive"] = lines[:3] + [relevant] + lines[3:] return ws, relevant, lines def test_trim_keeps_relevant_line_full(): """高相关行全文保留,低相关行被丢弃/截断(尾段不再出现在输出)。""" ws, relevant, lines = _ws_with_archive() out = ws.render_for_architect() # 相关行全文(含尾段独特内容)仍在 assert relevant[-40:] in out # 至少一条低相关行的尾段消失(被丢或被截为摘要) assert lines[0][-40:] not in out def test_trim_respects_floor_of_four_lines(): """任何情况下至少保留 4 行(与旧实现下限一致)。""" ws, _, lines = _ws_with_archive() out = ws.render_for_architect() archive_shown = out.split("== archive ==")[1].strip().splitlines() assert len(archive_shown) >= 4 def test_render_deterministic(): """同输入两次渲染逐字节一致(裁剪决策确定性)。""" ws1, _, _ = _ws_with_archive() ws2, _, _ = _ws_with_archive() assert ws1.render_for_architect() == ws2.render_for_architect() def test_under_budget_untouched(): """预算内不触发裁剪:archive 行原样出现、无截断省略号。""" ws = Workspace.new(request_id="abc123def456", query="写个快排", api_token_cap=8000, rounds_cap=6) ws.apply_brief(_BRIEF) ws._data["archive"] = ["s1: 完成(产出: a://s1.py)"] out = ws.render_for_architect() assert "s1: 完成(产出: a://s1.py)" in out