Skip to content

feat(skill): add JarSkillRepositoryAdapter for loading skills from Jar#546

Merged
AlbumenJ merged 3 commits intoagentscope-ai:mainfrom
fang-tech:fang-tech/feat-fileSystemSkillRepo-support-jar-path
Jan 14, 2026
Merged

feat(skill): add JarSkillRepositoryAdapter for loading skills from Jar#546
AlbumenJ merged 3 commits intoagentscope-ai:mainfrom
fang-tech:fang-tech/feat-fileSystemSkillRepo-support-jar-path

Conversation

@fang-tech
Copy link
Contributor

@fang-tech fang-tech commented Jan 13, 2026

AgentScope-Java Version

1.0.7-SNAPSHOT

Description

Add JarSkillRepositoryAdapter to enable loading skills from JAR files in production environments.

What's Changed

  • New Feature: JarSkillRepositoryAdapter class that bridges JAR resources and FileSystemSkillRepository
  • Key Capabilities:
    • Loads skills from JAR files using virtual filesystem
    • Supports both development (filesystem) and production (JAR) environments
    • Auto-detects environment and adapts loading strategy
    • Implements AutoCloseable for proper resource management

close #533

Checklist

Please check the following items before code is ready to be reviewed.

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test)
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g. links, examples, etc.)
  • Code is ready for review

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds JarSkillRepositoryAdapter, a new utility class that enables loading skills from JAR files in production environments. The adapter creates a virtual filesystem for JAR resources and delegates to the existing FileSystemSkillRepository for skill loading, providing seamless environment detection and adaptation.

Changes:

  • Introduces JarSkillRepositoryAdapter class that bridges JAR resources with filesystem-based skill loading
  • Adds comprehensive test suite with both filesystem and JAR environment test coverage
  • Includes test resource files (SKILL.md files) for testing skill loading functionality

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
agentscope-core/src/main/java/io/agentscope/core/skill/util/JarSkillRepositoryAdapter.java New adapter class implementing AutoCloseable for loading skills from JAR files with automatic environment detection
agentscope-core/src/test/java/io/agentscope/core/skill/util/JarSkillRepositoryAdapterTest.java Comprehensive test suite covering filesystem loading, JAR loading, error handling, and AutoCloseable behavior
agentscope-core/src/test/resources/test-skills/writing-skill/SKILL.md Test resource file defining a writing skill with metadata
agentscope-core/src/test/resources/test-skills/writing-skill/references/guide.md Test resource file with nested skill reference documentation
agentscope-core/src/test/resources/test-skills/calculation-skill/SKILL.md Test resource file defining a calculation skill with metadata

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

// Use FileSystemSkillRepository for actual skill loading
this.repository = new FileSystemSkillRepository(skillBasePath.getParent(), false);
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a potential NullPointerException risk if skillBasePath.getParent() returns null. This could happen if resourcePath points to a root-level resource (e.g., just "skill-name" without a parent directory). The FileSystemSkillRepository constructor would receive null and throw a NullPointerException or IllegalArgumentException. Consider adding validation to ensure the resourcePath has a parent directory, or provide a more descriptive error message for this case.

Suggested change
this.repository = new FileSystemSkillRepository(skillBasePath.getParent(), false);
Path skillDirectory = skillBasePath.getParent();
if (skillDirectory == null) {
throw new IOException(
"Resource path must have a parent directory: " + resourcePath);
}
this.repository = new FileSystemSkillRepository(skillDirectory, false);

Copilot uses AI. Check for mistakes.
}

/**
* gets a skill by name.
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first word of the Javadoc summary should be capitalized. Change "gets" to "Gets" to maintain consistency with other method documentation in this class (lines 116, 125, 134).

Suggested change
* gets a skill by name.
* Gets a skill by name.

Copilot uses AI. Check for mistakes.
*
* @param skillName The skill name (directory name)
* @return The loaded AgentSkill object
* @throws IOException if loading fails
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @throws IOException Javadoc tag is documented but the method signature doesn't declare this exception. The getSkill method delegates to repository.getSkill(skillName) which doesn't throw IOException. Either remove the @throws tag or add throws IOException to the method signature if exceptions should be propagated.

Suggested change
* @throws IOException if loading fails

Copilot uses AI. Check for mistakes.
}

// Use FileSystemSkillRepository for actual skill loading
this.repository = new FileSystemSkillRepository(skillBasePath.getParent(), false);
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential resource leak: If FileSystemSkillRepository constructor throws an IllegalArgumentException (lines 82-98 in FileSystemSkillRepository.java), the fileSystem created at line 87 will not be closed. Consider wrapping the FileSystemSkillRepository construction in a try-catch block that closes the fileSystem on exception, or restructuring to ensure proper cleanup.

Suggested change
this.repository = new FileSystemSkillRepository(skillBasePath.getParent(), false);
try {
this.repository = new FileSystemSkillRepository(skillBasePath.getParent(), false);
} catch (RuntimeException e) {
if (this.fileSystem != null) {
try {
this.fileSystem.close();
} catch (IOException closeException) {
e.addSuppressed(closeException);
}
}
throw e;
}

Copilot uses AI. Check for mistakes.
Comment on lines 41 to 47
* <p>Usage example:
* <pre>{@code
* try (JarSkillRepositoryAdapter adapter =
* new JarSkillRepositoryAdapter("writing-skills")) {
* AgentSkill skill = adapter.getSkill("writing-skills");
* }
* }</pre>
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usage example is misleading. If the adapter is created with resource path "writing-skills", the skill name passed to getSkill() should be "writing-skill" (a subdirectory inside writing-skills directory), not "writing-skills" again. Based on the implementation (line 97), the repository is created with skillBasePath.getParent(), so skills are loaded from the parent directory of the resource path. Consider updating the example to clarify this behavior, such as: new JarSkillRepositoryAdapter("skills/writing-skill") followed by adapter.getSkill("writing-skill") or adapter.getAllSkills().

Copilot uses AI. Check for mistakes.
/**
* Creates an adapter for loading skills from resources.
*
* @param resourcePath The path to the skill under resources, e.g., "writing-skills"
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter documentation is misleading. The description states "The path to the skill under resources" but the actual behavior (line 97) creates a repository from skillBasePath.getParent(). This means resourcePath should point to a specific skill directory, and the adapter will load all skills from its parent directory. Consider clarifying this as: "The path to a skill directory under resources (e.g., 'skills/writing-skill'). The adapter will load all skills from the parent directory."

Copilot uses AI. Check for mistakes.
/**
* Creates an adapter for loading skills from resources using a specific ClassLoader.
*
* @param resourcePath The path to the skill under resources, e.g., "writing-skills"
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter documentation is misleading. The description states "The path to the skill under resources" but the actual behavior (line 97) creates a repository from skillBasePath.getParent(). This means resourcePath should point to a specific skill directory, and the adapter will load all skills from its parent directory. Consider clarifying this as: "The path to a skill directory under resources (e.g., 'skills/writing-skill'). The adapter will load all skills from the parent directory."

Copilot uses AI. Check for mistakes.
Comment on lines 146 to 149
public void close() throws IOException {
if (fileSystem != null) {
fileSystem.close();
}
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The close() method may not be idempotent as expected by the test at line 273-285. Calling FileSystem.close() multiple times can throw ClosedFileSystemException. Consider adding a flag to track if the filesystem has already been closed, or catch and ignore ClosedFileSystemException to ensure the method can be safely called multiple times as per AutoCloseable best practices.

Copilot uses AI. Check for mistakes.
@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

❌ Patch coverage is 94.44444% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ope/core/skill/util/JarSkillRepositoryAdapter.java 94.44% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@AlbumenJ AlbumenJ merged commit 0e50c03 into agentscope-ai:main Jan 14, 2026
4 checks passed
@fang-tech fang-tech deleted the fang-tech/feat-fileSystemSkillRepo-support-jar-path branch January 23, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Support FileSystemSkillRepo to read the virtual file paths in the jar file

2 participants