Files
Artemis-Eapil/tests/unit/agents/test_checker_native_evidence.py

104 lines
4.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Guard the prompt evidence contract; no model or device is invoked here."""
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from artemis.agents.checker.checker import (
CheckReport,
assemble_checker_prompt_segments,
run_final_check,
)
from artemis.context import ArtemisContext, ExecutionSetup
@pytest.mark.parametrize("entry", ["checkpoint", "final"])
def test_bound_persistent_readout_can_supply_precision_beyond_pixel_ticks(entry):
prompt = assemble_checker_prompt_segments(entry, [], probe_tool_registered=False)
# Native origin alone is insufficient: the rule must bind the displayed value
# to the selected state and require stability plus the visible pointer check.
for requirement in (
"标签、节点角色/层级",
"目标控件当前所选值或固定指针所选时间",
"不能仅因原生节点含有数值或执行者称其可信",
"在被验收状态中持续显示",
"引用已停稳或暂停的证据",
"与同一控件的指针及可辨刻度一致",
"结合读数精度与用户容差",
"粗刻度无法独立区分秒数,不等于",
"无需再由粗像素刻度独立插值证明同一精确值",
):
assert requirement in prompt
assert "拖动浮层或原生时间读数与固定指针刻度冲突时" not in prompt
@pytest.mark.parametrize("entry", ["checkpoint", "final"])
def test_native_origin_does_not_promote_unbound_or_conflicting_evidence(entry):
prompt = assemble_checker_prompt_segments(entry, [], probe_tool_registered=False)
for excluded_source in ("事件卡片时间", "视频画面水印", "录制起止时间", "拖动/松手浮层"):
assert excluded_source in prompt
assert "即使它们也能通过原生节点读取,仍须先证明上述绑定与持久性" in prompt
assert "可辨精度上存在实际冲突" in prompt
assert "读数仍在变化、绑定不明或无法确认已停稳/暂停" in prompt
assert "应判证据不足(inconclusive)" in prompt
assert "不得挑选有利读数或忽略矛盾" in prompt
assert "可信读数明确超出用户容差时仍按通用规则判定" in prompt
@pytest.mark.parametrize("entry", ["checkpoint", "final"])
def test_pixel_fallback_remains_quantitative_and_requires_post_action_evidence(entry):
prompt = assemble_checker_prompt_segments(entry, [], probe_tool_registered=False)
fallback = prompt.split("没有可信持久读数时,", 1)[1]
assert "动作后已停稳截图的两处真实数值刻度与固定指针位置作线性插值" in fallback
assert "单位换算、估读不确定性及目标误差" in fallback
assert "目标误差加估读不确定性不超过用户容差" in fallback
assert "刻度非线性或无法确定已停稳,仍应判证据不足" in fallback
assert "操作前的校准计划及回执误差不能替代动作后测量" in fallback
@pytest.mark.asyncio
async def test_final_review_receives_live_readout_and_rules_separately_from_report_claims():
ctx = MagicMock(spec=ArtemisContext)
ctx.execution_setup = ExecutionSetup()
ctx.data_engine = MagicMock()
ctx.data_engine.base_dir = "unused"
ctx.data_engine.get_agent_friendly_steps.return_value = []
ctx.data_engine.get_step_number.return_value = 7
elements = "[1] 当前所选值: 23.5; [2] 已暂停"
review = AsyncMock(return_value=CheckReport(verdicts=[]))
with (
patch("artemis.agents.checker.checker._run_check_loop", new=review),
patch(
"artemis.agents.checker.checker._capture_final_screen",
new=AsyncMock(return_value=("captured-image", elements)),
),
):
await run_final_check(
ctx,
goal="核对当前所选值及容差",
plan_text="",
ledger=[],
check_items=[],
execution_report="执行者声称当前所选值为 88",
)
review.assert_awaited_once()
messages = review.await_args.args[1]
assert "无需再由粗像素刻度独立插值证明同一精确值" in messages[0].content
assert "不得挑选有利读数或忽略矛盾" in messages[0].content
content = messages[1].content
text = content[0]["text"]
assert "Executor's Final Report (claims to verify, not independent evidence)" in text
assert "执行者声称当前所选值为 88" in text
assert f"# Final Screen Elements\n{elements}" in text
assert any(
block.get("type") == "image_url"
and block["image_url"]["url"] == "data:image/jpeg;base64,captured-image"
for block in content
)