From 50579e3e4b52eaf95f5215896eef55d6fdece99e Mon Sep 17 00:00:00 2001 From: JGoP-L <741047428@qq.com> Date: Mon, 27 Apr 2026 15:32:00 +0800 Subject: [PATCH 1/2] fix(skill): validate resource path before activating skill --- .../core/skill/SkillToolFactory.java | 32 ++++++++++++------- .../core/skill/SkillBoxToolsTest.java | 32 +++++++++++++++++++ 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/agentscope-core/src/main/java/io/agentscope/core/skill/SkillToolFactory.java b/agentscope-core/src/main/java/io/agentscope/core/skill/SkillToolFactory.java index 35681f6eae..342bc8e44f 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/skill/SkillToolFactory.java +++ b/agentscope-core/src/main/java/io/agentscope/core/skill/SkillToolFactory.java @@ -79,10 +79,13 @@ public String getDescription() { + "**Functionality:**\n" + "1. Activates the specified skill (making its tools available)\n" + "2. Returns the requested resource content\n" - + " usage instructions)\n" - + "- 'SKILL.md': The skill's markdown documentation (name, description," - + "- Other paths: Additional resources like scripts, configs, templates, or" - + " data files"; + + "\n" + + "**Path rules:**\n" + + "- Use path=\"SKILL.md\" to load the skill's markdown documentation" + + " (name, description, usage instructions).\n" + + "- Use exact resource paths listed by the skill, such as" + + " \"references/guide.md\" or \"scripts/run.py\".\n" + + "- Do not use '.', './', the skill directory, or an absolute path."; } @Override @@ -108,9 +111,11 @@ public Map getParameters() { "type", "string", "description", - "The path to the resource file within the" - + " skill (e.g., 'SKILL.md," - + " references/references.md')")), + "The exact resource path within the skill." + + " Use 'SKILL.md' to load the" + + " skill instructions. Do not use" + + " '.', './', directories, or" + + " absolute paths.")), "required", List.of("skillId", "path")); } @@ -155,10 +160,11 @@ public Mono callAsync(ToolCallParam param) { * @throws IllegalArgumentException if skill doesn't exist or resource not found */ private String loadSkillResourceImpl(String skillId, String path) { - AgentSkill skill = validatedActiveSkill(skillId); + AgentSkill skill = validateSkillExists(skillId); // Special handling for SKILL.md - return the skill's markdown content if ("SKILL.md".equals(path)) { + activateSkill(skillId); return buildSkillMarkdownResponse(skillId, skill); } @@ -171,6 +177,7 @@ private String loadSkillResourceImpl(String skillId, String path) { } String resourceContent = resources.get(path); + activateSkill(skillId); return buildResourceResponse(skillId, path, resourceContent); } @@ -253,7 +260,7 @@ private String buildResourceNotFoundMessage( * @return The skill instance * @throws IllegalArgumentException if skill doesn't exist */ - private AgentSkill validatedActiveSkill(String skillId) { + private AgentSkill validateSkillExists(String skillId) { if (!skillRegistry.exists(skillId)) { throw new IllegalArgumentException( String.format("Skill not found: '%s'. Please check the skill ID.", skillId)); @@ -267,7 +274,10 @@ private AgentSkill validatedActiveSkill(String skillId) { + " error.", skillId)); } - // Set skill as active + return skill; + } + + private void activateSkill(String skillId) { skillRegistry.setSkillActive(skillId, true); logger.info("Activated skill: {}", skillId); @@ -279,7 +289,5 @@ private AgentSkill validatedActiveSkill(String skillId) { toolsGroupName, toolkit.getToolGroup(toolsGroupName).getTools()); } - - return skill; } } diff --git a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillBoxToolsTest.java b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillBoxToolsTest.java index 23246a1c22..50b592a1a5 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillBoxToolsTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillBoxToolsTest.java @@ -110,6 +110,8 @@ void testCreateLoadSkillResourceTool() { assertEquals("load_skill_through_path", tool.getName()); assertNotNull(tool.getDescription()); assertTrue(tool.getDescription().contains("Load and activate")); + assertTrue(tool.getDescription().contains("path=\"SKILL.md\"")); + assertTrue(tool.getDescription().contains("Do not use '.'")); } @Test @@ -136,6 +138,12 @@ void testLoadSkillResourceToolParameters() { @SuppressWarnings("unchecked") Map skillIdParam = (Map) properties.get("skillId"); assertNotNull(skillIdParam.get("enum")); + + @SuppressWarnings("unchecked") + Map pathParam = (Map) properties.get("path"); + String pathDescription = (String) pathParam.get("description"); + assertTrue(pathDescription.contains("Use 'SKILL.md'")); + assertTrue(pathDescription.contains("Do not use '.'")); } @Test @@ -483,4 +491,28 @@ void testLoadSkillWithNoToolsDoesNotFail() { assertNull( toolkit.getToolGroup(skillId + "_skill_tools"), "Tool group should not be created"); } + + @Test + @DisplayName("Should not activate skill when resource path is invalid") + void testInvalidResourcePathDoesNotActivateSkill() { + AgentTool tool = toolkit.getTool("load_skill_through_path"); + String skillId = "test_skill_custom"; + assertFalse(skillBox.isSkillActive(skillId)); + + Map input = Map.of("skillId", skillId, "path", "."); + ToolUseBlock toolUseBlock = + ToolUseBlock.builder() + .id("test-call-016") + .name("load_skill_through_path") + .input(input) + .build(); + ToolCallParam param = + ToolCallParam.builder().toolUseBlock(toolUseBlock).input(input).build(); + + ToolResultBlock result = tool.callAsync(param).block(TIMEOUT); + + assertNotNull(result); + assertTrue(isErrorResult(result)); + assertFalse(skillBox.isSkillActive(skillId)); + } } From 6c6ccd49b988d31a1b26763b81373aa378007a31 Mon Sep 17 00:00:00 2001 From: JGoP-L <741047428@qq.com> Date: Tue, 28 Apr 2026 18:43:02 +0800 Subject: [PATCH 2/2] fix doc --- .../java/io/agentscope/core/skill/SkillToolFactory.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/agentscope-core/src/main/java/io/agentscope/core/skill/SkillToolFactory.java b/agentscope-core/src/main/java/io/agentscope/core/skill/SkillToolFactory.java index 342bc8e44f..0ed6332312 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/skill/SkillToolFactory.java +++ b/agentscope-core/src/main/java/io/agentscope/core/skill/SkillToolFactory.java @@ -254,11 +254,12 @@ private String buildResourceNotFoundMessage( } /** - * Validate skill exists and activate it and its tool group. + * Validates that a skill is registered and returns its instance. * * @param skillId The unique identifier of the skill - * @return The skill instance - * @throws IllegalArgumentException if skill doesn't exist + * @return The registered skill instance + * @throws IllegalArgumentException if the skill is not registered + * @throws IllegalStateException if the skill cannot be loaded after validation */ private AgentSkill validateSkillExists(String skillId) { if (!skillRegistry.exists(skillId)) {