first commit
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
import os
|
||||
import sys
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if PROJECT_ROOT not in sys.path:
|
||||
sys.path.insert(0, PROJECT_ROOT)
|
||||
WORKSPACE_ROOT = os.path.join(PROJECT_ROOT, "workspace")
|
||||
|
||||
|
||||
import tools.requirements_tools as requirements_tools_module
|
||||
import tools.reference_image as reference_image_module
|
||||
from tools.requirements_tools import (
|
||||
create_requirement_refinement_subagent_tools,
|
||||
make_user_query_more_detailed,
|
||||
)
|
||||
|
||||
|
||||
def _tool_name(tool):
|
||||
if hasattr(tool, "_tool"):
|
||||
return tool._tool.name
|
||||
return getattr(tool, "name", getattr(tool, "__name__", None))
|
||||
|
||||
|
||||
def test_requirement_refinement_subagent_tools_use_workspace_tools_only():
|
||||
tools = create_requirement_refinement_subagent_tools()
|
||||
|
||||
assert [_tool_name(tool) for tool in tools] == [
|
||||
"execute_command",
|
||||
"sketch_pad_operations",
|
||||
"read_file",
|
||||
"grep",
|
||||
"sed",
|
||||
"echo_into",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_make_user_query_more_detailed_runs_specialist_subagent(
|
||||
monkeypatch, tmp_path
|
||||
):
|
||||
monkeypatch.chdir(WORKSPACE_ROOT)
|
||||
calls = {"specialist": 0}
|
||||
stored = {}
|
||||
image_path = tmp_path / "query_image_001.png"
|
||||
image_path.write_bytes(b"fake-png-bytes")
|
||||
|
||||
async def fake_run_subagent_with_events(**kwargs):
|
||||
calls["specialist"] += 1
|
||||
request = kwargs["specialist_kwargs"]["message"]
|
||||
text = request[0]["text"] if isinstance(request, list) else request
|
||||
assert kwargs["specialist_kwargs"]["history"] == []
|
||||
assert "SKILL.md" in text
|
||||
assert "Current working directory:" in text
|
||||
assert "Skill root: use the preferred skill root below." in text
|
||||
assert "Preferred skill root:" in text
|
||||
assert "references/docs/api/README.md" in text
|
||||
assert "## API Reference" in text
|
||||
assert "## Refined User Requirements" in text
|
||||
assert "## Parameter Table" in text
|
||||
assert "## Modeling Process" in text
|
||||
assert "## Notes" in text
|
||||
return (
|
||||
"## API Reference\n- skill doc evidence\n\n"
|
||||
"## Refined User Requirements\n- refined requirements\n\n"
|
||||
"## Parameter Table\n- none\n\n"
|
||||
"## Modeling Process\n- step one\n\n"
|
||||
"## Notes\n- note"
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
requirements_tools_module,
|
||||
"run_subagent_with_events",
|
||||
fake_run_subagent_with_events,
|
||||
)
|
||||
|
||||
class FakeSketchPad:
|
||||
async def set_item(self, key, value, ttl=None, summary=None, tags=None):
|
||||
stored["key"] = key
|
||||
stored["value"] = value
|
||||
stored["tags"] = tags
|
||||
return key
|
||||
|
||||
monkeypatch.setattr(
|
||||
requirements_tools_module,
|
||||
"get_current_sketch_pad",
|
||||
lambda: FakeSketchPad(),
|
||||
)
|
||||
|
||||
result = await make_user_query_more_detailed(
|
||||
query="Create a box",
|
||||
query_image_path=str(image_path),
|
||||
)
|
||||
|
||||
assert calls["specialist"] == 1
|
||||
assert "SketchPad Key" in result
|
||||
assert stored["key"].startswith("req_")
|
||||
assert "Refined User Requirements" in stored["value"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_make_user_query_more_detailed_uses_latest_uploaded_image_when_omitted(
|
||||
monkeypatch, tmp_path
|
||||
):
|
||||
monkeypatch.chdir(WORKSPACE_ROOT)
|
||||
calls = {"specialist": 0}
|
||||
stored = {}
|
||||
image_path = tmp_path / "query_image_001.png"
|
||||
image_path.write_bytes(b"fake-png-bytes")
|
||||
|
||||
async def fake_run_subagent_with_events(**kwargs):
|
||||
calls["specialist"] += 1
|
||||
request = kwargs["specialist_kwargs"]["message"]
|
||||
assert isinstance(request, list)
|
||||
assert request[0]["type"] == "text"
|
||||
assert request[1]["type"] == "image_url"
|
||||
assert request[1]["image_url"]["url"].startswith("data:image/png;base64,")
|
||||
assert kwargs["status_payload"]["query_image_path"] == str(image_path.resolve())
|
||||
return (
|
||||
"## API Reference\n- skill doc evidence\n\n"
|
||||
"## Refined User Requirements\n- refined requirements\n\n"
|
||||
"## Parameter Table\n- none\n\n"
|
||||
"## Modeling Process\n- step one\n\n"
|
||||
"## Notes\n- note"
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
requirements_tools_module,
|
||||
"run_subagent_with_events",
|
||||
fake_run_subagent_with_events,
|
||||
)
|
||||
|
||||
class FakeContext:
|
||||
def retrieve_full_messages(self):
|
||||
return [
|
||||
SimpleNamespace(
|
||||
role="user",
|
||||
content=[
|
||||
{"type": "text", "text": "Create a box"},
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": "data:image/png;base64,abcd",
|
||||
"local_path": str(image_path),
|
||||
},
|
||||
},
|
||||
],
|
||||
)
|
||||
]
|
||||
|
||||
monkeypatch.setattr(
|
||||
reference_image_module,
|
||||
"get_current_context",
|
||||
lambda: FakeContext(),
|
||||
)
|
||||
|
||||
class FakeSketchPad:
|
||||
async def set_item(self, key, value, ttl=None, summary=None, tags=None):
|
||||
stored["key"] = key
|
||||
stored["value"] = value
|
||||
stored["tags"] = tags
|
||||
return key
|
||||
|
||||
monkeypatch.setattr(
|
||||
requirements_tools_module,
|
||||
"get_current_sketch_pad",
|
||||
lambda: FakeSketchPad(),
|
||||
)
|
||||
|
||||
result = await make_user_query_more_detailed(query="Create a box")
|
||||
|
||||
assert calls["specialist"] == 1
|
||||
assert "SketchPad Key" in result
|
||||
assert stored["key"].startswith("req_")
|
||||
Reference in New Issue
Block a user