feat: release 2.2.0 with PC-only tests and execution reliability fixes
Unify task scheduling and queue state, fix Android input and observation recovery, preserve screenshot paths, and match final review criteria accurately. Add collapsible copyable results and publish the complete 2.1.0 upgrade notes. Validation: 3189 backend tests, 326 frontend tests, 24 client tests, production build and quality gates.
This commit is contained in:
1 parent
fac4ccb760
commit
be6e8c2abd
79 files changed
+2263
-277
No files matched your search
@@ -103,6 +103,84 @@ async def test_wrap_update_note_tool_valid_status_change(tmp_path):
|
||||
assert ctx.planner_task is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_short_plan_replacement_cannot_duplicate_untouched_tail(tmp_path):
|
||||
original = "- [/] Enter text\n- [ ] Clear text\n - verify: Input is empty\n"
|
||||
path = _setup_plan(tmp_path, original)
|
||||
ctx = _make_ctx(tmp_path, disable_planner_validation=True)
|
||||
with patch(
|
||||
"artemis.graph.graph.invoke_tool_with_injection",
|
||||
side_effect=_fake_update_invoke(path),
|
||||
):
|
||||
result = await wrap_update_note_tool(ctx, _mock_tool("update_note")).ainvoke(
|
||||
{
|
||||
"key": "task_plan",
|
||||
"target": "- [/] Enter text",
|
||||
"replacement": "- [x] Enter text\n- [/] Clear text",
|
||||
"tool_call_id": "duplicate-tail",
|
||||
}
|
||||
)
|
||||
assert isinstance(result, ToolMessage)
|
||||
assert result.status == "error"
|
||||
assert "Clear text" in result.content
|
||||
assert "target" in result.content
|
||||
assert path.read_text(encoding="utf-8") == original
|
||||
assert ctx.planner_task is None
|
||||
assert ctx.pending_checkpoints == []
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("keep_existing_duplicate", [False, True])
|
||||
async def test_duplicate_plan_can_be_repaired_with_a_complete_target(
|
||||
tmp_path, keep_existing_duplicate
|
||||
):
|
||||
original = "- [x] Enter text\n- [/] Clear text\n- [ ] Clear text\n"
|
||||
path = _setup_plan(tmp_path, original)
|
||||
ctx = _make_ctx(tmp_path, disable_planner_validation=True)
|
||||
replacement = "- [x] Enter text\n- [/] Clear text\n"
|
||||
if keep_existing_duplicate:
|
||||
replacement += "- [x] Clear text\n"
|
||||
with patch(
|
||||
"artemis.graph.graph.invoke_tool_with_injection",
|
||||
side_effect=_fake_update_invoke(path),
|
||||
):
|
||||
result = await wrap_update_note_tool(ctx, _mock_tool("update_note")).ainvoke(
|
||||
{
|
||||
"key": "task_plan",
|
||||
"target": original,
|
||||
"replacement": replacement,
|
||||
"tool_call_id": "repair-tail",
|
||||
}
|
||||
)
|
||||
assert result == "Success"
|
||||
assert path.read_text(encoding="utf-8") == replacement
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("tool_name", ["save_note", "append_note"])
|
||||
async def test_other_plan_writes_cannot_introduce_duplicate_milestones(tmp_path, tool_name):
|
||||
original = "- [/] Enter text\n- [ ] Clear text\n"
|
||||
path = _setup_plan(tmp_path, original)
|
||||
ctx = _make_ctx(tmp_path, disable_planner_validation=True)
|
||||
|
||||
async def fake_invoke(tool, args, tool_call_id, state, record_trace=None):
|
||||
content = args["content"]
|
||||
if tool_name == "append_note":
|
||||
content = path.read_text(encoding="utf-8") + content
|
||||
path.write_text(content, encoding="utf-8")
|
||||
return "Success"
|
||||
|
||||
content = "- [/] Clear text\n"
|
||||
if tool_name == "save_note":
|
||||
content = original + content
|
||||
with patch("artemis.graph.graph.invoke_tool_with_injection", side_effect=fake_invoke):
|
||||
result = await wrap_note_tool(ctx, _mock_tool(tool_name)).ainvoke(
|
||||
{"key": "task_plan", "content": content, "tool_call_id": "duplicate"}
|
||||
)
|
||||
assert result.status == "error"
|
||||
assert path.read_text(encoding="utf-8") == original
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_wrap_update_note_tool_intentional_rename_triggers_validation(tmp_path):
|
||||
task_plan_path = _setup_plan(tmp_path)
|
||||
|
||||
Reference in new issue
Block a user