fix: improve cross-device evidence, request diagnostics and prompt efficiency

This commit is contained in:
chenmingxuan committed 2026-10-17 14:55:45 +08:00
1 parent 621f30e437
commit a66803651a
60 files changed
+3097 -160

No files matched your search

+83 -7
View File
@@ -178,7 +178,11 @@ def test_server_substitutions_do_not_use_shell_or_expand_unknown_values(tmp_path
async def test_skill_load_and_reference_cannot_read_outside_package(store):
enable(store, manifest())
runtime = PluginRuntime(store=store)
assert {t.name for t in runtime.declarations()} == {"plugin_load", "plugin_read_file"}
assert {t.name for t in runtime.declarations()} == {
"plugin_load",
"plugin_read_file",
"plugin_read_result",
}
result = await runtime.call("plugin_load", {"plugin_id": "test-plugin"})
assert result.status == "success" and "先观察" in result.text()
assert (
@@ -659,7 +663,7 @@ server.run()
@pytest.mark.asyncio
@pytest.mark.parametrize("target", ["computer", "mixed"])
@pytest.mark.parametrize("target", ["computer", "mixed", "android"])
async def test_flash_plugin_images_never_replace_the_mixed_phone_observation(monkeypatch, target):
from types import SimpleNamespace
from unittest.mock import Mock, AsyncMock
@@ -689,6 +693,16 @@ async def test_flash_plugin_images_never_replace_the_mixed_phone_observation(mon
screenshot_bytes=b"desktop-after",
ui_elements_text="desktop-tree",
text_summary="Desktop observation",
raw_result=[
{"type": "text", "text": "Desktop observation"},
{
"type": "image_url",
"image_url": {
"url": "data:image/jpeg;base64,"
+ base64.b64encode(b"desktop-after").decode()
},
},
],
metadata={"plugin_id": "test-plugin"},
)
),
@@ -696,12 +710,13 @@ async def test_flash_plugin_images_never_replace_the_mixed_phone_observation(mon
runner._build_action_record = Mock(return_value={"action": name})
runner._record_action_step = Mock(return_value="step")
state = SimpleNamespace(latest_screenshot="old-phone-path")
messages = []
result = await runner._execute_and_record_action(
name,
{},
"tc",
state,
[],
messages,
"",
{},
b"phone-before",
@@ -714,10 +729,17 @@ async def test_flash_plugin_images_never_replace_the_mixed_phone_observation(mon
"",
b"desktop-after",
)
if target == "mixed":
assert result[:2] == (b"phone-after", "phone-tree-after")
assert state.latest_screenshot == "phone-path"
capture.assert_awaited_once()
assert messages[0].tool_call_id == "tc"
assert "Desktop observation" in str(messages[0].content)
assert base64.b64encode(b"desktop-after").decode() in str(messages)
if target != "computer":
assert result[0] is None
assert "安卓旧截图、元素编号和坐标已失效" in result[1]
assert state.latest_screenshot is None
assert state.indexed_elements == []
assert state.indexed_points == []
assert runner._android_observation_stale
capture.assert_not_awaited()
else:
assert result[:2] == (b"desktop-after", "desktop-tree")
capture.assert_not_awaited()
@@ -1012,3 +1034,57 @@ async def test_plugin_image_text_stays_with_its_own_observation(store, tmp_path,
assert engine.storage.get_image(names[1]).ui_tree == "changed"
finally:
await runtime.aclose()
@pytest.mark.asyncio
async def test_long_plugin_result_roundtrips_through_task_scoped_reader(store, tmp_path):
from types import SimpleNamespace
from unittest.mock import AsyncMock, MagicMock
from mcp.types import Tool, ToolAnnotations
from artemis.config.constants import PLUGIN_PROMPT_TEXT_CHARS
plugin = manifest()
enable(store, plugin)
engine = MagicMock(base_dir=tmp_path / "task-a")
ctx = SimpleNamespace(data_engine=engine)
runtime = PluginRuntime(store=store, ctx=ctx)
tool = Tool(
name="observe",
inputSchema={"type": "object"},
annotations=ToolAnnotations(readOnlyHint=True),
)
original = "private-value\n" + "node 中文\n" * 9000 + "END"
runtime.bindings["plug_test_observe"] = (plugin.id, tool)
session = SimpleNamespace(
call=AsyncMock(
return_value=CallToolResult(content=[TextContent(type="text", text=original)])
)
)
runtime.sessions[plugin.id] = session
try:
outcome = await runtime.call("plug_test_observe", {})
assert outcome.status == "success"
assert outcome.text_ref == outcome.call_id
assert runtime.is_read_only("plug_test_observe")
shown = runtime.content_blocks(outcome)[0]["text"]
assert len(shown) <= PLUGIN_PROMPT_TEXT_CHARS
assert outcome.text_ref in shown
text = outcome.text()
pages = []
for offset in range(0, len(text), PLUGIN_PROMPT_TEXT_CHARS):
page = await runtime.call(
"plugin_read_result", {"call_id": outcome.text_ref, "offset": offset}
)
assert page.status == "success"
delivered = runtime.content_blocks(page)[0]["text"]
pages.append(delivered.split("\n", 1)[1])
assert "".join(pages) == text
assert "private-value" not in text and "已隐藏密钥" in text
assert text.endswith("END")
engine.base_dir = tmp_path / "task-b"
inaccessible = await runtime.call("plugin_read_result", {"call_id": outcome.text_ref})
assert inaccessible.status == "error"
session.call.assert_awaited_once()
finally:
runtime.sessions.clear()
await runtime.aclose()