From 18007cf855476d954ecca5a4e8769c780babd969 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Sun, 10 May 2026 16:41:28 +0800 Subject: [PATCH] test(agent): cover skill box factory behavior --- .../agent/ReActAgentSkillFactoryTest.java | 84 +++++++++++++++++++ .../test/agent/tool/SkillEchoTool.java | 24 ++++++ .../test/resources/agent/skills/demo/SKILL.md | 8 ++ .../resources/agent/skills/research/SKILL.md | 8 ++ .../agent/skills/tool-skill/SKILL.md | 10 +++ 5 files changed, 134 insertions(+) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/ReActAgentSkillFactoryTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/tool/SkillEchoTool.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/demo/SKILL.md create mode 100644 liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/research/SKILL.md create mode 100644 liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/tool-skill/SKILL.md diff --git a/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/ReActAgentSkillFactoryTest.java b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/ReActAgentSkillFactoryTest.java new file mode 100644 index 000000000..267845151 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/ReActAgentSkillFactoryTest.java @@ -0,0 +1,84 @@ +package com.yomahub.liteflow.test.agent; + +import com.yomahub.liteflow.agent.exception.AgentConfigException; +import com.yomahub.liteflow.agent.skill.SkillBoxFactory; +import com.yomahub.liteflow.agent.skill.SkillLoadResult; +import com.yomahub.liteflow.property.agent.AgentConfig; +import com.yomahub.liteflow.test.agent.tool.SkillEchoTool; +import io.agentscope.core.skill.AgentSkill; +import io.agentscope.core.tool.Toolkit; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.nio.file.Path; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class ReActAgentSkillFactoryTest { + + private AgentConfig cfg; + + @BeforeEach + public void setUp() { + cfg = new AgentConfig(); + cfg.getSkills().setEnabled(true); + cfg.getSkills().setPath("src/test/resources/agent/skills"); + cfg.getSkills().setStrict(true); + SkillEchoTool.reset(); + } + + @Test + public void testEmptyAllowListLoadsAllSkills() { + SkillLoadResult result = SkillBoxFactory.build(new Toolkit(), cfg, List.of()); + Set expectedNames = Set.of("demo", "research", "tool-skill"); + + Set names = result.skillBox().getAllSkillIds().stream() + .map(id -> result.skillBox().getSkill(id)) + .map(AgentSkill::getName) + .collect(Collectors.toSet()); + + Assertions.assertEquals(expectedNames, names); + Assertions.assertEquals(expectedNames, Set.copyOf(result.skillNames())); + } + + @Test + public void testAllowListFiltersSkills() { + SkillLoadResult result = SkillBoxFactory.build(new Toolkit(), cfg, List.of("demo")); + + List names = result.skillBox().getAllSkillIds().stream() + .map(id -> result.skillBox().getSkill(id)) + .map(AgentSkill::getName) + .toList(); + + Assertions.assertEquals(List.of("demo"), names); + Assertions.assertEquals(List.of("demo"), result.skillNames()); + } + + @Test + public void testMissingAllowListedSkillFailsInStrictMode() { + AgentConfigException ex = Assertions.assertThrows(AgentConfigException.class, + () -> SkillBoxFactory.build(new Toolkit(), cfg, List.of("missing-skill"))); + + Assertions.assertTrue(ex.getMessage().contains("missing-skill")); + } + + @Test + public void testFrontmatterToolClassIsInstantiated() { + SkillLoadResult result = SkillBoxFactory.build(new Toolkit(), cfg, List.of("tool-skill")); + + Assertions.assertEquals(List.of("tool-skill"), result.skillNames()); + Assertions.assertEquals(1, SkillEchoTool.CONSTRUCT_COUNT.get()); + } + + @Test + public void testMissingSkillsDirectoryFailsInStrictMode() { + cfg.getSkills().setPath(Path.of("target", "missing-skills-dir").toString()); + + AgentConfigException ex = Assertions.assertThrows(AgentConfigException.class, + () -> SkillBoxFactory.build(new Toolkit(), cfg, List.of())); + + Assertions.assertTrue(ex.getMessage().contains("Skills root not found")); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/tool/SkillEchoTool.java b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/tool/SkillEchoTool.java new file mode 100644 index 000000000..512dbfdc9 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/tool/SkillEchoTool.java @@ -0,0 +1,24 @@ +package com.yomahub.liteflow.test.agent.tool; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; + +import java.util.concurrent.atomic.AtomicInteger; + +public class SkillEchoTool { + + public static final AtomicInteger CONSTRUCT_COUNT = new AtomicInteger(); + + public SkillEchoTool() { + CONSTRUCT_COUNT.incrementAndGet(); + } + + public static void reset() { + CONSTRUCT_COUNT.set(0); + } + + @Tool(name = "skill_echo", description = "Echo text from a skill-bound Java tool") + public String echo(@ToolParam(name = "text", description = "Text to echo") String text) { + return text; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/demo/SKILL.md b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/demo/SKILL.md new file mode 100644 index 000000000..147eac09c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/demo/SKILL.md @@ -0,0 +1,8 @@ +--- +name: demo +description: Demo skill for LiteFlow ReAct agent tests +--- + +# Demo Skill + +Use this skill when the request is about a simple demonstration. diff --git a/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/research/SKILL.md b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/research/SKILL.md new file mode 100644 index 000000000..0e224f7a4 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/research/SKILL.md @@ -0,0 +1,8 @@ +--- +name: research +description: Research skill for LiteFlow ReAct agent tests +--- + +# Research Skill + +Use this skill when the request requires research planning. diff --git a/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/tool-skill/SKILL.md b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/tool-skill/SKILL.md new file mode 100644 index 000000000..e9916adfd --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/resources/agent/skills/tool-skill/SKILL.md @@ -0,0 +1,10 @@ +--- +name: tool-skill +description: Skill that binds a Java tool for LiteFlow ReAct agent tests +tools: + - com.yomahub.liteflow.test.agent.tool.SkillEchoTool +--- + +# Tool Skill + +Use this skill when a Java tool should be available after loading the skill.