File size: 3,384 Bytes
dc893fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
"""
Test Skill Tool

Tests for skill tools after Progressive Disclosure optimization:
- Only GetSkillTool remains (ListSkillsTool and UseSkillTool removed)
- Tests verify the single-tool approach
"""

import tempfile
from pathlib import Path

import pytest

from mini_agent.tools.skill_loader import SkillLoader
from mini_agent.tools.skill_tool import GetSkillTool, create_skill_tools


def create_test_skill(skill_dir: Path, name: str, description: str, content: str):
    """Create a test skill"""
    skill_file = skill_dir / "SKILL.md"
    skill_content = f"""---
name: {name}
description: {description}
---

{content}
"""
    skill_file.write_text(skill_content, encoding="utf-8")


@pytest.fixture
def skill_loader():
    """Create a loader with test skills"""
    with tempfile.TemporaryDirectory() as tmpdir:
        # Create test skills
        for i in range(2):
            skill_dir = Path(tmpdir) / f"test-skill-{i}"
            skill_dir.mkdir()
            create_test_skill(
                skill_dir,
                f"test-skill-{i}",
                f"Test skill {i} description",
                f"Test skill {i} content and instructions.",
            )

        loader = SkillLoader(tmpdir)
        loader.discover_skills()
        yield loader


@pytest.mark.asyncio
async def test_get_skill_tool(skill_loader):
    """Test GetSkillTool"""
    tool = GetSkillTool(skill_loader)

    result = await tool.execute(skill_name="test-skill-0")

    assert result.success
    assert "test-skill-0" in result.content
    assert "Test skill 0 description" in result.content
    assert "Test skill 0 content" in result.content


@pytest.mark.asyncio
async def test_get_skill_tool_nonexistent(skill_loader):
    """Test getting non-existent skill"""
    tool = GetSkillTool(skill_loader)

    result = await tool.execute(skill_name="nonexistent-skill")

    assert not result.success
    assert "不存在" in result.error or "not exist" in result.error.lower()


def test_create_skill_tools_returns_single_tool(skill_loader):
    """Test that create_skill_tools only returns GetSkillTool after optimization"""
    with tempfile.TemporaryDirectory() as tmpdir:
        skill_dir = Path(tmpdir) / "test-skill"
        skill_dir.mkdir()
        create_test_skill(
            skill_dir, "test-skill", "Test skill", "Test content"
        )

        tools, loader = create_skill_tools(tmpdir)

        # Should only have one tool now (GetSkillTool)
        assert len(tools) == 1
        assert isinstance(tools[0], GetSkillTool)
        assert loader is not None


def test_tool_count_optimization():
    """Verify Progressive Disclosure optimization: 3 tools -> 1 tool"""
    with tempfile.TemporaryDirectory() as tmpdir:
        # Create a simple test skill
        skill_dir = Path(tmpdir) / "simple-skill"
        skill_dir.mkdir()
        create_test_skill(
            skill_dir, "simple-skill", "Simple test", "Content"
        )

        tools, _ = create_skill_tools(tmpdir)

        # After optimization, should only have 1 tool (GetSkillTool)
        # Before optimization, we had 3 tools (ListSkillsTool, GetSkillTool, UseSkillTool)
        assert len(tools) == 1

        # Verify it's GetSkillTool
        tool = tools[0]
        assert tool.name == "get_skill"
        assert "get complete content" in tool.description.lower() or "获取" in tool.description